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