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