...
1
2
3
4
5 package types2
6
7 import "fmt"
8
9
10
11
12
13
14
15 type Alias struct {
16 obj *TypeName
17 fromRHS Type
18 actual Type
19 }
20
21
22
23 func NewAlias(obj *TypeName, rhs Type) *Alias {
24 alias := (*Checker)(nil).newAlias(obj, rhs)
25
26 unalias(alias)
27 return alias
28 }
29
30 func (a *Alias) Obj() *TypeName { return a.obj }
31 func (a *Alias) Underlying() Type { return unalias(a).Underlying() }
32 func (a *Alias) String() string { return TypeString(a, nil) }
33
34
35
36
37
38
39
40 func Unalias(t Type) Type {
41 if a0, _ := t.(*Alias); a0 != nil {
42 return unalias(a0)
43 }
44 return t
45 }
46
47 func unalias(a0 *Alias) Type {
48 if a0.actual != nil {
49 return a0.actual
50 }
51 var t Type
52 for a := a0; a != nil; a, _ = t.(*Alias) {
53 t = a.fromRHS
54 }
55 if t == nil {
56 panic(fmt.Sprintf("non-terminated alias %s", a0.obj.name))
57 }
58 a0.actual = t
59 return t
60 }
61
62
63
64 func asNamed(t Type) *Named {
65 n, _ := Unalias(t).(*Named)
66 return n
67 }
68
69
70
71 func (check *Checker) newAlias(obj *TypeName, rhs Type) *Alias {
72 assert(rhs != nil)
73 a := &Alias{obj, rhs, nil}
74 if obj.typ == nil {
75 obj.typ = a
76 }
77
78
79 if check != nil {
80 check.needsCleanup(a)
81 }
82
83 return a
84 }
85
86 func (a *Alias) cleanup() {
87 Unalias(a)
88 }
89
View as plain text