github.com/bir3/gocompiler@v0.9.2202/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 "github.com/bir3/gocompiler/src/go/ast" 9 "github.com/bir3/gocompiler/src/go/token" 10 . "github.com/bir3/gocompiler/src/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 [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(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 }