1
2
3
4
5 package types2
6
7 import "cmd/compile/internal/syntax"
8
9
10
11
12
13 type Interface struct {
14 check *Checker
15 obj *TypeName
16 methods []*Func
17 embeddeds []Type
18 embedPos *[]syntax.Pos
19 implicit bool
20 complete bool
21
22 tset *_TypeSet
23 }
24
25
26 func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, nopos, t) }
27
28
29 var emptyInterface = Interface{complete: true, tset: &topTypeSet}
30
31
32
33
34 func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
35 if len(methods) == 0 && len(embeddeds) == 0 {
36 return &emptyInterface
37 }
38
39
40 typ := (*Checker)(nil).newInterface()
41 for _, m := range methods {
42 if sig := m.typ.(*Signature); sig.recv == nil {
43 sig.recv = NewVar(m.pos, m.pkg, "", typ)
44 }
45 }
46
47
48 sortMethods(methods)
49
50 typ.methods = methods
51 typ.embeddeds = embeddeds
52 typ.complete = true
53
54 return typ
55 }
56
57
58 func (check *Checker) newInterface() *Interface {
59 typ := &Interface{check: check}
60 if check != nil {
61 check.needsCleanup(typ)
62 }
63 return typ
64 }
65
66
67
68
69
70 func (t *Interface) MarkImplicit() {
71 t.implicit = true
72 }
73
74
75 func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
76
77
78
79 func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
80
81
82 func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
83
84
85 func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }
86
87
88 func (t *Interface) NumMethods() int { return t.typeSet().NumMethods() }
89
90
91
92 func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }
93
94
95 func (t *Interface) Empty() bool { return t.typeSet().IsAll() }
96
97
98 func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable(nil) }
99
100
101 func (t *Interface) IsMethodSet() bool { return t.typeSet().IsMethodSet() }
102
103
104 func (t *Interface) IsImplicit() bool { return t.implicit }
105
106 func (t *Interface) Underlying() Type { return t }
107 func (t *Interface) String() string { return TypeString(t, nil) }
108
109
110
111
112 func (t *Interface) cleanup() {
113 t.check = nil
114 t.embedPos = nil
115 }
116
117 func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType, def *Named) {
118 addEmbedded := func(pos syntax.Pos, typ Type) {
119 ityp.embeddeds = append(ityp.embeddeds, typ)
120 if ityp.embedPos == nil {
121 ityp.embedPos = new([]syntax.Pos)
122 }
123 *ityp.embedPos = append(*ityp.embedPos, pos)
124 }
125
126 for _, f := range iface.MethodList {
127 if f.Name == nil {
128 addEmbedded(posFor(f.Type), parseUnion(check, f.Type))
129 continue
130 }
131
132
133
134 name := f.Name.Value
135 if name == "_" {
136 if check.conf.CompilerErrorMessages {
137 check.error(f.Name, "methods must have a unique non-blank name")
138 } else {
139 check.error(f.Name, "invalid method name _")
140 }
141 continue
142 }
143
144 typ := check.typ(f.Type)
145 sig, _ := typ.(*Signature)
146 if sig == nil {
147 if typ != Typ[Invalid] {
148 check.errorf(f.Type, invalidAST+"%s is not a method signature", typ)
149 }
150 continue
151 }
152
153
154 var recvTyp Type = ityp
155 if def != nil {
156 recvTyp = def
157 }
158 sig.recv = NewVar(f.Name.Pos(), check.pkg, "", recvTyp)
159
160 m := NewFunc(f.Name.Pos(), check.pkg, name, sig)
161 check.recordDef(f.Name, m)
162 ityp.methods = append(ityp.methods, m)
163 }
164
165
166
167 ityp.complete = true
168
169 if len(ityp.methods) == 0 && len(ityp.embeddeds) == 0 {
170
171 ityp.tset = &topTypeSet
172 return
173 }
174
175
176
177 sortMethods(ityp.methods)
178
179
180
181
182 check.later(func() {
183 computeInterfaceTypeSet(check, iface.Pos(), ityp)
184 }).describef(iface, "compute type set for %s", ityp)
185 }
186
View as plain text