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