interface.go raw

   1  // Copyright 2021 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package types
   6  
   7  import (
   8  	"go/ast"
   9  	"go/token"
  10  	. "internal/types/errors"
  11  )
  12  
  13  // ----------------------------------------------------------------------------
  14  // API
  15  
  16  // An Interface represents an interface type.
  17  type Interface struct {
  18  	check     *Checker     // for error reporting; nil once type set is computed
  19  	methods   []*Func      // ordered list of explicitly declared methods
  20  	embeddeds []Type       // ordered list of explicitly embedded elements
  21  	embedPos  *[]token.Pos // positions of embedded elements; or nil (for error messages) - use pointer to save space
  22  	implicit  bool         // interface is wrapper for type set literal (non-interface T, ~T, or A|B)
  23  	complete  bool         // indicates that obj, methods, and embeddeds are set and type set can be computed
  24  
  25  	tset *_TypeSet // type set described by this interface, computed lazily
  26  }
  27  
  28  // typeSet returns the type set for interface t.
  29  func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, nopos, t) }
  30  
  31  // emptyInterface represents the empty (completed) interface
  32  var emptyInterface = Interface{complete: true, tset: &topTypeSet}
  33  
  34  // NewInterface returns a new interface for the given methods and embedded types.
  35  // NewInterface takes ownership of the provided methods and may modify their types
  36  // by setting missing receivers.
  37  //
  38  // Deprecated: Use NewInterfaceType instead which allows arbitrary embedded types.
  39  func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
  40  	tnames := make([]Type, len(embeddeds))
  41  	for i, t := range embeddeds {
  42  		tnames[i] = t
  43  	}
  44  	return NewInterfaceType(methods, tnames)
  45  }
  46  
  47  // NewInterfaceType returns a new interface for the given methods and embedded
  48  // types. NewInterfaceType takes ownership of the provided methods and may
  49  // modify their types by setting missing receivers.
  50  //
  51  // To avoid race conditions, the interface's type set should be computed before
  52  // concurrent use of the interface, by explicitly calling Complete.
  53  func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
  54  	if len(methods) == 0 && len(embeddeds) == 0 {
  55  		return &emptyInterface
  56  	}
  57  
  58  	// set method receivers if necessary
  59  	typ := (*Checker)(nil).newInterface()
  60  	for _, m := range methods {
  61  		if sig := m.typ.(*Signature); sig.recv == nil {
  62  			sig.recv = newVar(RecvVar, m.pos, m.pkg, "", typ)
  63  		}
  64  	}
  65  
  66  	// sort for API stability
  67  	sortMethods(methods)
  68  
  69  	typ.methods = methods
  70  	typ.embeddeds = embeddeds
  71  	typ.complete = true
  72  
  73  	return typ
  74  }
  75  
  76  // check may be nil
  77  func (check *Checker) newInterface() *Interface {
  78  	typ := &Interface{check: check}
  79  	if check != nil {
  80  		check.needsCleanup(typ)
  81  	}
  82  	return typ
  83  }
  84  
  85  // MarkImplicit marks the interface t as implicit, meaning this interface
  86  // corresponds to a constraint literal such as ~T or A|B without explicit
  87  // interface embedding. MarkImplicit should be called before any concurrent use
  88  // of implicit interfaces.
  89  func (t *Interface) MarkImplicit() {
  90  	t.implicit = true
  91  }
  92  
  93  // NumExplicitMethods returns the number of explicitly declared methods of interface t.
  94  func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
  95  
  96  // ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
  97  // The methods are ordered by their unique [Id].
  98  func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
  99  
 100  // NumEmbeddeds returns the number of embedded types in interface t.
 101  func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
 102  
 103  // Embedded returns the i'th embedded defined (*[Named]) type of interface t for 0 <= i < t.NumEmbeddeds().
 104  // The result is nil if the i'th embedded type is not a defined type.
 105  //
 106  // Deprecated: Use [Interface.EmbeddedType] which is not restricted to defined (*[Named]) types.
 107  func (t *Interface) Embedded(i int) *Named { return asNamed(t.embeddeds[i]) }
 108  
 109  // EmbeddedType returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
 110  func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }
 111  
 112  // NumMethods returns the total number of methods of interface t.
 113  func (t *Interface) NumMethods() int { return t.typeSet().NumMethods() }
 114  
 115  // Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
 116  // The methods are ordered by their unique Id.
 117  func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }
 118  
 119  // Empty reports whether t is the empty interface.
 120  func (t *Interface) Empty() bool { return t.typeSet().IsAll() }
 121  
 122  // IsComparable reports whether each type in interface t's type set is comparable.
 123  func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable(nil) }
 124  
 125  // IsMethodSet reports whether the interface t is fully described by its method
 126  // set.
 127  func (t *Interface) IsMethodSet() bool { return t.typeSet().IsMethodSet() }
 128  
 129  // IsImplicit reports whether the interface t is a wrapper for a type set literal.
 130  func (t *Interface) IsImplicit() bool { return t.implicit }
 131  
 132  // Complete computes the interface's type set. It must be called by users of
 133  // [NewInterfaceType] and [NewInterface] after the interface's embedded types are
 134  // fully defined and before using the interface type in any way other than to
 135  // form other types. The interface must not contain duplicate methods or a
 136  // panic occurs. Complete returns the receiver.
 137  //
 138  // Interface types that have been completed are safe for concurrent use.
 139  func (t *Interface) Complete() *Interface {
 140  	if !t.complete {
 141  		t.complete = true
 142  	}
 143  	t.typeSet() // checks if t.tset is already set
 144  	return t
 145  }
 146  
 147  func (t *Interface) Underlying() Type { return t }
 148  func (t *Interface) String() string   { return TypeString(t, nil) }
 149  
 150  // ----------------------------------------------------------------------------
 151  // Implementation
 152  
 153  func (t *Interface) cleanup() {
 154  	t.typeSet() // any interface that escapes type checking must be safe for concurrent use
 155  	t.check = nil
 156  	t.embedPos = nil
 157  }
 158  
 159  func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *TypeName) {
 160  	addEmbedded := func(pos token.Pos, typ Type) {
 161  		ityp.embeddeds = append(ityp.embeddeds, typ)
 162  		if ityp.embedPos == nil {
 163  			ityp.embedPos = new([]token.Pos)
 164  		}
 165  		*ityp.embedPos = append(*ityp.embedPos, pos)
 166  	}
 167  
 168  	for _, f := range iface.Methods.List {
 169  		if len(f.Names) == 0 {
 170  			addEmbedded(f.Type.Pos(), parseUnion(check, f.Type))
 171  			continue
 172  		}
 173  		// f.Name != nil
 174  
 175  		// We have a method with name f.Names[0].
 176  		name := f.Names[0]
 177  		if name.Name == "_" {
 178  			check.error(name, BlankIfaceMethod, "methods must have a unique non-blank name")
 179  			continue // ignore
 180  		}
 181  
 182  		typ := check.typ(f.Type)
 183  		sig, _ := typ.(*Signature)
 184  		if sig == nil {
 185  			if isValid(typ) {
 186  				check.errorf(f.Type, InvalidSyntaxTree, "%s is not a method signature", typ)
 187  			}
 188  			continue // ignore
 189  		}
 190  
 191  		// The go/parser doesn't accept method type parameters but an ast.FuncType may have them.
 192  		if sig.tparams != nil {
 193  			var at positioner = f.Type
 194  			if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TypeParams != nil {
 195  				at = ftyp.TypeParams
 196  			}
 197  			check.error(at, InvalidSyntaxTree, "methods cannot have type parameters")
 198  		}
 199  
 200  		// use named receiver type if available (for better error messages)
 201  		var recvTyp Type = ityp
 202  		if def != nil {
 203  			if named := asNamed(def.typ); named != nil {
 204  				recvTyp = named
 205  			}
 206  		}
 207  		sig.recv = newVar(RecvVar, name.Pos(), check.pkg, "", recvTyp)
 208  
 209  		m := NewFunc(name.Pos(), check.pkg, name.Name, sig)
 210  		check.recordDef(name, m)
 211  		ityp.methods = append(ityp.methods, m)
 212  	}
 213  
 214  	// All methods and embedded elements for this interface are collected;
 215  	// i.e., this interface may be used in a type set computation.
 216  	ityp.complete = true
 217  
 218  	if len(ityp.methods) == 0 && len(ityp.embeddeds) == 0 {
 219  		// empty interface
 220  		ityp.tset = &topTypeSet
 221  		return
 222  	}
 223  
 224  	// sort for API stability
 225  	sortMethods(ityp.methods)
 226  	// (don't sort embeddeds: they must correspond to *embedPos entries)
 227  
 228  	// Compute type set as soon as possible to report any errors.
 229  	// Subsequent uses of type sets will use this computed type
 230  	// set and won't need to pass in a *Checker.
 231  	check.later(func() {
 232  		computeInterfaceTypeSet(check, iface.Pos(), ityp)
 233  	}).describef(iface, "compute type set for %s", ityp)
 234  }
 235