diff options
Diffstat (limited to 'src/cmd/compile/internal/types2/signature.go')
-rw-r--r-- | src/cmd/compile/internal/types2/signature.go | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/types2/signature.go b/src/cmd/compile/internal/types2/signature.go index 01158187ba..ab9a1c487e 100644 --- a/src/cmd/compile/internal/types2/signature.go +++ b/src/cmd/compile/internal/types2/signature.go @@ -9,6 +9,77 @@ import ( "fmt" ) +// ---------------------------------------------------------------------------- +// API + +// A Signature represents a (non-builtin) function or method type. +// The receiver is ignored when comparing signatures for identity. +type Signature struct { + // We need to keep the scope in Signature (rather than passing it around + // and store it in the Func Object) because when type-checking a function + // literal we call the general type checker which returns a general Type. + // We then unpack the *Signature and use the scope for the literal body. + rparams []*TypeName // receiver type parameters from left to right; or nil + tparams []*TypeName // type parameters from left to right; or nil + scope *Scope // function scope, present for package-local signatures + recv *Var // nil if not a method + params *Tuple // (incoming) parameters from left to right; or nil + results *Tuple // (outgoing) results from left to right; or nil + variadic bool // true if the last parameter's type is of the form ...T (or string, for append built-in only) +} + +// NewSignature returns a new function type for the given receiver, parameters, +// and results, either of which may be nil. If variadic is set, the function +// is variadic, it must have at least one parameter, and the last parameter +// must be of unnamed slice type. +func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature { + if variadic { + n := params.Len() + if n == 0 { + panic("types2.NewSignature: variadic function must have at least one parameter") + } + if _, ok := params.At(n - 1).typ.(*Slice); !ok { + panic("types2.NewSignature: variadic parameter must be of unnamed slice type") + } + } + return &Signature{recv: recv, params: params, results: results, variadic: variadic} +} + +// Recv returns the receiver of signature s (if a method), or nil if a +// function. It is ignored when comparing signatures for identity. +// +// For an abstract method, Recv returns the enclosing interface either +// as a *Named or an *Interface. Due to embedding, an interface may +// contain methods whose receiver type is a different interface. +func (s *Signature) Recv() *Var { return s.recv } + +// TParams returns the type parameters of signature s, or nil. +func (s *Signature) TParams() []*TypeName { return s.tparams } + +// RParams returns the receiver type params of signature s, or nil. +func (s *Signature) RParams() []*TypeName { return s.rparams } + +// SetTParams sets the type parameters of signature s. +func (s *Signature) SetTParams(tparams []*TypeName) { s.tparams = tparams } + +// SetRParams sets the receiver type params of signature s. +func (s *Signature) SetRParams(rparams []*TypeName) { s.rparams = rparams } + +// Params returns the parameters of signature s, or nil. +func (s *Signature) Params() *Tuple { return s.params } + +// Results returns the results of signature s, or nil. +func (s *Signature) Results() *Tuple { return s.results } + +// Variadic reports whether the signature s is variadic. +func (s *Signature) Variadic() bool { return s.variadic } + +func (s *Signature) Underlying() Type { return s } +func (s *Signature) String() string { return TypeString(s, nil) } + +// ---------------------------------------------------------------------------- +// Implementation + // Disabled by default, but enabled when running tests (via types_test.go). var acceptMethodTypeParams bool |