github.com/AndrienkoAleksandr/go@v0.0.19/src/go/types/interface.go (about) 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(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 EmbeddedType which is not restricted to defined (*Named) types. 107 func (t *Interface) Embedded(i int) *Named { tname, _ := t.embeddeds[i].(*Named); return tname } 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.check = nil 155 t.embedPos = nil 156 } 157 158 func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) { 159 addEmbedded := func(pos token.Pos, typ Type) { 160 ityp.embeddeds = append(ityp.embeddeds, typ) 161 if ityp.embedPos == nil { 162 ityp.embedPos = new([]token.Pos) 163 } 164 *ityp.embedPos = append(*ityp.embedPos, pos) 165 } 166 167 for _, f := range iface.Methods.List { 168 if len(f.Names) == 0 { 169 addEmbedded(f.Type.Pos(), parseUnion(check, f.Type)) 170 continue 171 } 172 // f.Name != nil 173 174 // We have a method with name f.Names[0]. 175 name := f.Names[0] 176 if name.Name == "_" { 177 check.error(name, BlankIfaceMethod, "methods must have a unique non-blank name") 178 continue // ignore 179 } 180 181 typ := check.typ(f.Type) 182 sig, _ := typ.(*Signature) 183 if sig == nil { 184 if typ != Typ[Invalid] { 185 check.errorf(f.Type, InvalidSyntaxTree, "%s is not a method signature", typ) 186 } 187 continue // ignore 188 } 189 190 // Always type-check method type parameters but complain if they are not enabled. 191 // (This extra check is needed here because interface method signatures don't have 192 // a receiver specification.) 193 if sig.tparams != nil { 194 var at positioner = f.Type 195 if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TypeParams != nil { 196 at = ftyp.TypeParams 197 } 198 check.error(at, InvalidMethodTypeParams, "methods cannot have type parameters") 199 } 200 201 // use named receiver type if available (for better error messages) 202 var recvTyp Type = ityp 203 if def != nil { 204 recvTyp = def 205 } 206 sig.recv = NewVar(name.Pos(), check.pkg, "", recvTyp) 207 208 m := NewFunc(name.Pos(), check.pkg, name.Name, sig) 209 check.recordDef(name, m) 210 ityp.methods = append(ityp.methods, m) 211 } 212 213 // All methods and embedded elements for this interface are collected; 214 // i.e., this interface may be used in a type set computation. 215 ityp.complete = true 216 217 if len(ityp.methods) == 0 && len(ityp.embeddeds) == 0 { 218 // empty interface 219 ityp.tset = &topTypeSet 220 return 221 } 222 223 // sort for API stability 224 sortMethods(ityp.methods) 225 // (don't sort embeddeds: they must correspond to *embedPos entries) 226 227 // Compute type set as soon as possible to report any errors. 228 // Subsequent uses of type sets will use this computed type 229 // set and won't need to pass in a *Checker. 230 check.later(func() { 231 computeInterfaceTypeSet(check, iface.Pos(), ityp) 232 }).describef(iface, "compute type set for %s", ityp) 233 }