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