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 used bool
246 }
247
248
249
250 func NewPkgName(pos syntax.Pos, pkg *Package, name string, imported *Package) *PkgName {
251 return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported, false}
252 }
253
254
255
256 func (obj *PkgName) Imported() *Package { return obj.imported }
257
258
259 type Const struct {
260 object
261 val constant.Value
262 }
263
264
265
266 func NewConst(pos syntax.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
267 return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, val}
268 }
269
270
271 func (obj *Const) Val() constant.Value { return obj.val }
272
273 func (*Const) isDependency() {}
274
275
276
277
278
279
280 type TypeName struct {
281 object
282 }
283
284
285
286
287
288
289
290
291 func NewTypeName(pos syntax.Pos, pkg *Package, name string, typ Type) *TypeName {
292 return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
293 }
294
295
296
297 func NewTypeNameLazy(pos syntax.Pos, pkg *Package, name string, load func(named *Named) (tparams []*TypeParam, underlying Type, methods []*Func)) *TypeName {
298 obj := NewTypeName(pos, pkg, name, nil)
299 NewNamed(obj, nil, nil).loader = load
300 return obj
301 }
302
303
304 func (obj *TypeName) IsAlias() bool {
305 switch t := obj.typ.(type) {
306 case nil:
307 return false
308
309
310 case *Basic:
311
312 if obj.pkg == Unsafe {
313 return false
314 }
315
316
317
318
319
320
321 return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
322 case *Named:
323 return obj != t.obj
324 case *TypeParam:
325 return obj != t.obj
326 default:
327 return true
328 }
329 }
330
331
332 type Var struct {
333 object
334 embedded bool
335 isField bool
336 used bool
337 origin *Var
338 }
339
340
341
342 func NewVar(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
343 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
344 }
345
346
347 func NewParam(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
348 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, used: true}
349 }
350
351
352
353
354 func NewField(pos syntax.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
355 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, embedded: embedded, isField: true}
356 }
357
358
359
360 func (obj *Var) Anonymous() bool { return obj.embedded }
361
362
363 func (obj *Var) Embedded() bool { return obj.embedded }
364
365
366 func (obj *Var) IsField() bool { return obj.isField }
367
368
369
370
371
372
373
374
375 func (obj *Var) Origin() *Var {
376 if obj.origin != nil {
377 return obj.origin
378 }
379 return obj
380 }
381
382 func (*Var) isDependency() {}
383
384
385
386
387 type Func struct {
388 object
389 hasPtrRecv_ bool
390 origin *Func
391 }
392
393
394
395 func NewFunc(pos syntax.Pos, pkg *Package, name string, sig *Signature) *Func {
396 var typ Type
397 if sig != nil {
398 typ = sig
399 } else {
400
401
402
403
404 }
405 return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false, nil}
406 }
407
408
409 func (obj *Func) Signature() *Signature {
410 if obj.typ != nil {
411 return obj.typ.(*Signature)
412 }
413
414
415
416
417
418
419
420
421 return new(Signature)
422 }
423
424
425
426 func (obj *Func) FullName() string {
427 var buf bytes.Buffer
428 writeFuncName(&buf, obj, nil)
429 return buf.String()
430 }
431
432
433
434
435 func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
436
437
438
439
440
441
442
443
444 func (obj *Func) Origin() *Func {
445 if obj.origin != nil {
446 return obj.origin
447 }
448 return obj
449 }
450
451
452
453
454
455 func (obj *Func) Pkg() *Package { return obj.object.Pkg() }
456
457
458 func (obj *Func) hasPtrRecv() bool {
459
460
461
462
463 if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
464 _, isPtr := deref(sig.recv.typ)
465 return isPtr
466 }
467
468
469
470
471
472
473 return obj.hasPtrRecv_
474 }
475
476 func (*Func) isDependency() {}
477
478
479
480 type Label struct {
481 object
482 used bool
483 }
484
485
486 func NewLabel(pos syntax.Pos, pkg *Package, name string) *Label {
487 return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
488 }
489
490
491
492 type Builtin struct {
493 object
494 id builtinId
495 }
496
497 func newBuiltin(id builtinId) *Builtin {
498 return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
499 }
500
501
502 type Nil struct {
503 object
504 }
505
506 func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
507 var tname *TypeName
508 typ := obj.Type()
509
510 switch obj := obj.(type) {
511 case *PkgName:
512 fmt.Fprintf(buf, "package %s", obj.Name())
513 if path := obj.imported.path; path != "" && path != obj.name {
514 fmt.Fprintf(buf, " (%q)", path)
515 }
516 return
517
518 case *Const:
519 buf.WriteString("const")
520
521 case *TypeName:
522 tname = obj
523 buf.WriteString("type")
524 if isTypeParam(typ) {
525 buf.WriteString(" parameter")
526 }
527
528 case *Var:
529 if obj.isField {
530 buf.WriteString("field")
531 } else {
532 buf.WriteString("var")
533 }
534
535 case *Func:
536 buf.WriteString("func ")
537 writeFuncName(buf, obj, qf)
538 if typ != nil {
539 WriteSignature(buf, typ.(*Signature), qf)
540 }
541 return
542
543 case *Label:
544 buf.WriteString("label")
545 typ = nil
546
547 case *Builtin:
548 buf.WriteString("builtin")
549 typ = nil
550
551 case *Nil:
552 buf.WriteString("nil")
553 return
554
555 default:
556 panic(fmt.Sprintf("writeObject(%T)", obj))
557 }
558
559 buf.WriteByte(' ')
560
561
562 if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
563 buf.WriteString(packagePrefix(obj.Pkg(), qf))
564 }
565 buf.WriteString(obj.Name())
566
567 if typ == nil {
568 return
569 }
570
571 if tname != nil {
572 switch t := typ.(type) {
573 case *Basic:
574
575
576 return
577 case genericType:
578 if t.TypeParams().Len() > 0 {
579 newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
580 }
581 }
582 if tname.IsAlias() {
583 buf.WriteString(" =")
584 if alias, ok := typ.(*Alias); ok {
585 typ = alias.fromRHS
586 }
587 } else if t, _ := typ.(*TypeParam); t != nil {
588 typ = t.bound
589 } else {
590
591
592 typ = under(typ)
593 }
594 }
595
596
597
598
599 if obj.Name() == "any" && obj.Parent() == Universe {
600 assert(Identical(typ, &emptyInterface))
601 typ = &emptyInterface
602 }
603
604 buf.WriteByte(' ')
605 WriteType(buf, typ, qf)
606 }
607
608 func packagePrefix(pkg *Package, qf Qualifier) string {
609 if pkg == nil {
610 return ""
611 }
612 var s string
613 if qf != nil {
614 s = qf(pkg)
615 } else {
616 s = pkg.Path()
617 }
618 if s != "" {
619 s += "."
620 }
621 return s
622 }
623
624
625
626
627 func ObjectString(obj Object, qf Qualifier) string {
628 var buf bytes.Buffer
629 writeObject(&buf, obj, qf)
630 return buf.String()
631 }
632
633 func (obj *PkgName) String() string { return ObjectString(obj, nil) }
634 func (obj *Const) String() string { return ObjectString(obj, nil) }
635 func (obj *TypeName) String() string { return ObjectString(obj, nil) }
636 func (obj *Var) String() string { return ObjectString(obj, nil) }
637 func (obj *Func) String() string { return ObjectString(obj, nil) }
638 func (obj *Label) String() string { return ObjectString(obj, nil) }
639 func (obj *Builtin) String() string { return ObjectString(obj, nil) }
640 func (obj *Nil) String() string { return ObjectString(obj, nil) }
641
642 func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
643 if f.typ != nil {
644 sig := f.typ.(*Signature)
645 if recv := sig.Recv(); recv != nil {
646 buf.WriteByte('(')
647 if _, ok := recv.Type().(*Interface); ok {
648
649
650
651
652 buf.WriteString("interface")
653 } else {
654 WriteType(buf, recv.Type(), qf)
655 }
656 buf.WriteByte(')')
657 buf.WriteByte('.')
658 } else if f.pkg != nil {
659 buf.WriteString(packagePrefix(f.pkg, qf))
660 }
661 }
662 buf.WriteString(f.name)
663 }
664
View as plain text