1
2
3
4
5 package types2
6
7 import (
8 "bytes"
9 "cmd/compile/internal/syntax"
10 "fmt"
11 "go/constant"
12 "unicode"
13 "unicode/utf8"
14 )
15
16
17
18
19
20 type Object interface {
21 Parent() *Scope
22 Pos() syntax.Pos
23 Pkg() *Package
24 Name() string
25 Type() Type
26 Exported() bool
27 Id() string
28
29
30 String() string
31
32
33
34
35
36 order() uint32
37
38
39 color() color
40
41
42 setType(Type)
43
44
45 setOrder(uint32)
46
47
48 setColor(color color)
49
50
51 setParent(*Scope)
52
53
54 sameId(pkg *Package, name string) bool
55
56
57 scopePos() syntax.Pos
58
59
60 setScopePos(pos syntax.Pos)
61 }
62
63 func isExported(name string) bool {
64 ch, _ := utf8.DecodeRuneInString(name)
65 return unicode.IsUpper(ch)
66 }
67
68
69
70 func Id(pkg *Package, name string) string {
71 if isExported(name) {
72 return name
73 }
74
75
76
77
78
79 path := "_"
80
81
82 if pkg != nil && pkg.path != "" {
83 path = pkg.path
84 }
85 return path + "." + name
86 }
87
88
89 type object struct {
90 parent *Scope
91 pos syntax.Pos
92 pkg *Package
93 name string
94 typ Type
95 order_ uint32
96 color_ color
97 scopePos_ syntax.Pos
98 }
99
100
101 type color uint32
102
103
104
105 const (
106 white color = iota
107 black
108 grey
109 )
110
111 func (c color) String() string {
112 switch c {
113 case white:
114 return "white"
115 case black:
116 return "black"
117 default:
118 return "grey"
119 }
120 }
121
122
123
124 func colorFor(t Type) color {
125 if t != nil {
126 return black
127 }
128 return white
129 }
130
131
132
133 func (obj *object) Parent() *Scope { return obj.parent }
134
135
136 func (obj *object) Pos() syntax.Pos { return obj.pos }
137
138
139
140 func (obj *object) Pkg() *Package { return obj.pkg }
141
142
143 func (obj *object) Name() string { return obj.name }
144
145
146 func (obj *object) Type() Type { return obj.typ }
147
148
149
150
151 func (obj *object) Exported() bool { return isExported(obj.name) }
152
153
154 func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
155
156 func (obj *object) String() string { panic("abstract") }
157 func (obj *object) order() uint32 { return obj.order_ }
158 func (obj *object) color() color { return obj.color_ }
159 func (obj *object) scopePos() syntax.Pos { return obj.scopePos_ }
160
161 func (obj *object) setParent(parent *Scope) { obj.parent = parent }
162 func (obj *object) setType(typ Type) { obj.typ = typ }
163 func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order }
164 func (obj *object) setColor(color color) { assert(color != white); obj.color_ = color }
165 func (obj *object) setScopePos(pos syntax.Pos) { obj.scopePos_ = pos }
166
167 func (obj *object) sameId(pkg *Package, name string) bool {
168
169
170
171
172 if name != obj.name {
173 return false
174 }
175
176 if obj.Exported() {
177 return true
178 }
179
180
181
182 if pkg == nil || obj.pkg == nil {
183 return pkg == obj.pkg
184 }
185
186 return pkg.path == obj.pkg.path
187 }
188
189
190
191
192
193
194 func (a *object) less(b *object) bool {
195 if a == b {
196 return false
197 }
198
199
200 if a == nil {
201 return true
202 }
203 if b == nil {
204 return false
205 }
206
207
208 ea := isExported(a.name)
209 eb := isExported(b.name)
210 if ea != eb {
211 return ea
212 }
213
214
215 if a.name != b.name {
216 return a.name < b.name
217 }
218 if !ea {
219 if a.pkg.height != b.pkg.height {
220 return a.pkg.height < b.pkg.height
221 }
222 return a.pkg.path < b.pkg.path
223 }
224
225 return false
226 }
227
228
229
230 type PkgName struct {
231 object
232 imported *Package
233 used bool
234 }
235
236
237
238 func NewPkgName(pos syntax.Pos, pkg *Package, name string, imported *Package) *PkgName {
239 return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported, false}
240 }
241
242
243
244 func (obj *PkgName) Imported() *Package { return obj.imported }
245
246
247 type Const struct {
248 object
249 val constant.Value
250 }
251
252
253
254 func NewConst(pos syntax.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
255 return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, val}
256 }
257
258
259 func (obj *Const) Val() constant.Value { return obj.val }
260
261 func (*Const) isDependency() {}
262
263
264 type TypeName struct {
265 object
266 }
267
268
269
270
271
272
273
274
275 func NewTypeName(pos syntax.Pos, pkg *Package, name string, typ Type) *TypeName {
276 return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
277 }
278
279
280
281 func NewTypeNameLazy(pos syntax.Pos, pkg *Package, name string, load func(named *Named) (tparams []*TypeParam, underlying Type, methods []*Func)) *TypeName {
282 obj := NewTypeName(pos, pkg, name, nil)
283
284 resolve := func(_ *Context, t *Named) (*TypeParamList, Type, *methodList) {
285 tparams, underlying, methods := load(t)
286
287 switch underlying.(type) {
288 case nil, *Named:
289 panic(fmt.Sprintf("invalid underlying type %T", t.underlying))
290 }
291
292 return bindTParams(tparams), underlying, newMethodList(methods)
293 }
294
295 NewNamed(obj, nil, nil).resolver = resolve
296 return obj
297 }
298
299
300 func (obj *TypeName) IsAlias() bool {
301 switch t := obj.typ.(type) {
302 case nil:
303 return false
304 case *Basic:
305
306 if obj.pkg == Unsafe {
307 return false
308 }
309
310
311
312
313
314
315 return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
316 case *Named:
317 return obj != t.obj
318 case *TypeParam:
319 return obj != t.obj
320 default:
321 return true
322 }
323 }
324
325
326 type Var struct {
327 object
328 embedded bool
329 isField bool
330 used bool
331 }
332
333
334
335 func NewVar(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
336 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
337 }
338
339
340 func NewParam(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
341 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, used: true}
342 }
343
344
345
346
347 func NewField(pos syntax.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
348 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, embedded: embedded, isField: true}
349 }
350
351
352
353 func (obj *Var) Anonymous() bool { return obj.embedded }
354
355
356 func (obj *Var) Embedded() bool { return obj.embedded }
357
358
359 func (obj *Var) IsField() bool { return obj.isField }
360
361 func (*Var) isDependency() {}
362
363
364
365
366 type Func struct {
367 object
368 hasPtrRecv_ bool
369 }
370
371
372
373 func NewFunc(pos syntax.Pos, pkg *Package, name string, sig *Signature) *Func {
374
375 var typ Type
376 if sig != nil {
377 typ = sig
378 }
379 return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false}
380 }
381
382
383
384 func (obj *Func) FullName() string {
385 var buf bytes.Buffer
386 writeFuncName(&buf, obj, nil)
387 return buf.String()
388 }
389
390
391
392
393 func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
394
395
396 func (obj *Func) hasPtrRecv() bool {
397
398
399
400
401 if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
402 _, isPtr := deref(sig.recv.typ)
403 return isPtr
404 }
405
406
407
408
409
410
411 return obj.hasPtrRecv_
412 }
413
414 func (*Func) isDependency() {}
415
416
417
418 type Label struct {
419 object
420 used bool
421 }
422
423
424 func NewLabel(pos syntax.Pos, pkg *Package, name string) *Label {
425 return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
426 }
427
428
429
430 type Builtin struct {
431 object
432 id builtinId
433 }
434
435 func newBuiltin(id builtinId) *Builtin {
436 return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
437 }
438
439
440 type Nil struct {
441 object
442 }
443
444 func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
445 var tname *TypeName
446 typ := obj.Type()
447
448 switch obj := obj.(type) {
449 case *PkgName:
450 fmt.Fprintf(buf, "package %s", obj.Name())
451 if path := obj.imported.path; path != "" && path != obj.name {
452 fmt.Fprintf(buf, " (%q)", path)
453 }
454 return
455
456 case *Const:
457 buf.WriteString("const")
458
459 case *TypeName:
460 tname = obj
461 buf.WriteString("type")
462 if isTypeParam(typ) {
463 buf.WriteString(" parameter")
464 }
465
466 case *Var:
467 if obj.isField {
468 buf.WriteString("field")
469 } else {
470 buf.WriteString("var")
471 }
472
473 case *Func:
474 buf.WriteString("func ")
475 writeFuncName(buf, obj, qf)
476 if typ != nil {
477 WriteSignature(buf, typ.(*Signature), qf)
478 }
479 return
480
481 case *Label:
482 buf.WriteString("label")
483 typ = nil
484
485 case *Builtin:
486 buf.WriteString("builtin")
487 typ = nil
488
489 case *Nil:
490 buf.WriteString("nil")
491 return
492
493 default:
494 panic(fmt.Sprintf("writeObject(%T)", obj))
495 }
496
497 buf.WriteByte(' ')
498
499
500 if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
501 writePackage(buf, obj.Pkg(), qf)
502 }
503 buf.WriteString(obj.Name())
504
505 if typ == nil {
506 return
507 }
508
509 if tname != nil {
510 switch t := typ.(type) {
511 case *Basic:
512
513
514 return
515 case *Named:
516 if t.TypeParams().Len() > 0 {
517 newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
518 }
519 }
520 if tname.IsAlias() {
521 buf.WriteString(" =")
522 } else if t, _ := typ.(*TypeParam); t != nil {
523 typ = t.bound
524 } else {
525
526 typ = under(typ)
527 }
528 }
529
530
531
532
533 if obj == universeAny {
534 assert(Identical(typ, &emptyInterface))
535 typ = &emptyInterface
536 }
537
538 buf.WriteByte(' ')
539 WriteType(buf, typ, qf)
540 }
541
542 func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) {
543 if pkg == nil {
544 return
545 }
546 var s string
547 if qf != nil {
548 s = qf(pkg)
549 } else {
550 s = pkg.Path()
551 }
552 if s != "" {
553 buf.WriteString(s)
554 buf.WriteByte('.')
555 }
556 }
557
558
559
560
561 func ObjectString(obj Object, qf Qualifier) string {
562 var buf bytes.Buffer
563 writeObject(&buf, obj, qf)
564 return buf.String()
565 }
566
567 func (obj *PkgName) String() string { return ObjectString(obj, nil) }
568 func (obj *Const) String() string { return ObjectString(obj, nil) }
569 func (obj *TypeName) String() string { return ObjectString(obj, nil) }
570 func (obj *Var) String() string { return ObjectString(obj, nil) }
571 func (obj *Func) String() string { return ObjectString(obj, nil) }
572 func (obj *Label) String() string { return ObjectString(obj, nil) }
573 func (obj *Builtin) String() string { return ObjectString(obj, nil) }
574 func (obj *Nil) String() string { return ObjectString(obj, nil) }
575
576 func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
577 if f.typ != nil {
578 sig := f.typ.(*Signature)
579 if recv := sig.Recv(); recv != nil {
580 buf.WriteByte('(')
581 if _, ok := recv.Type().(*Interface); ok {
582
583
584
585
586 buf.WriteString("interface")
587 } else {
588 WriteType(buf, recv.Type(), qf)
589 }
590 buf.WriteByte(')')
591 buf.WriteByte('.')
592 } else if f.pkg != nil {
593 writePackage(buf, f.pkg, qf)
594 }
595 }
596 buf.WriteString(f.name)
597 }
598
View as plain text