...
Source file
src/go/types/sanitize.go
1
2
3
4
5 package types
6
7
8
9
10
11
12
13
14 func sanitizeInfo(info *Info) {
15 var s sanitizer = make(map[Type]Type)
16
17
18
19
20 for e, tv := range info.Types {
21 if typ := s.typ(tv.Type); typ != tv.Type {
22 tv.Type = typ
23 info.Types[e] = tv
24 }
25 }
26
27 inferred := getInferred(info)
28 for e, inf := range inferred {
29 changed := false
30 for i, targ := range inf.Targs {
31 if typ := s.typ(targ); typ != targ {
32 inf.Targs[i] = typ
33 changed = true
34 }
35 }
36 if typ := s.typ(inf.Sig); typ != inf.Sig {
37 inf.Sig = typ.(*Signature)
38 changed = true
39 }
40 if changed {
41 inferred[e] = inf
42 }
43 }
44
45 for _, obj := range info.Defs {
46 if obj != nil {
47 if typ := s.typ(obj.Type()); typ != obj.Type() {
48 obj.setType(typ)
49 }
50 }
51 }
52
53 for _, obj := range info.Uses {
54 if obj != nil {
55 if typ := s.typ(obj.Type()); typ != obj.Type() {
56 obj.setType(typ)
57 }
58 }
59 }
60
61
62
63
64
65
66 }
67
68 type sanitizer map[Type]Type
69
70 func (s sanitizer) typ(typ Type) Type {
71 if typ == nil {
72 return nil
73 }
74
75 if t, found := s[typ]; found {
76 return t
77 }
78 s[typ] = typ
79
80 switch t := typ.(type) {
81 case *Basic, *bottom, *top:
82
83
84 case *Array:
85 if elem := s.typ(t.elem); elem != t.elem {
86 t.elem = elem
87 }
88
89 case *Slice:
90 if elem := s.typ(t.elem); elem != t.elem {
91 t.elem = elem
92 }
93
94 case *Struct:
95 s.varList(t.fields)
96
97 case *Pointer:
98 if base := s.typ(t.base); base != t.base {
99 t.base = base
100 }
101
102 case *Tuple:
103 s.tuple(t)
104
105 case *Signature:
106 s.var_(t.recv)
107 s.tuple(t.params)
108 s.tuple(t.results)
109
110 case *_Sum:
111 s.typeList(t.types)
112
113 case *Interface:
114 s.funcList(t.methods)
115 if types := s.typ(t.types); types != t.types {
116 t.types = types
117 }
118 s.typeList(t.embeddeds)
119 s.funcList(t.allMethods)
120 if allTypes := s.typ(t.allTypes); allTypes != t.allTypes {
121 t.allTypes = allTypes
122 }
123
124 case *Map:
125 if key := s.typ(t.key); key != t.key {
126 t.key = key
127 }
128 if elem := s.typ(t.elem); elem != t.elem {
129 t.elem = elem
130 }
131
132 case *Chan:
133 if elem := s.typ(t.elem); elem != t.elem {
134 t.elem = elem
135 }
136
137 case *Named:
138 if debug && t.check != nil {
139 panic("internal error: Named.check != nil")
140 }
141 if orig := s.typ(t.orig); orig != t.orig {
142 t.orig = orig
143 }
144 if under := s.typ(t.underlying); under != t.underlying {
145 t.underlying = under
146 }
147 s.typeList(t.targs)
148 s.funcList(t.methods)
149
150 case *_TypeParam:
151 if bound := s.typ(t.bound); bound != t.bound {
152 t.bound = bound
153 }
154
155 case *instance:
156 typ = t.expand()
157 s[t] = typ
158
159 default:
160 panic("unimplemented")
161 }
162
163 return typ
164 }
165
166 func (s sanitizer) var_(v *Var) {
167 if v != nil {
168 if typ := s.typ(v.typ); typ != v.typ {
169 v.typ = typ
170 }
171 }
172 }
173
174 func (s sanitizer) varList(list []*Var) {
175 for _, v := range list {
176 s.var_(v)
177 }
178 }
179
180 func (s sanitizer) tuple(t *Tuple) {
181 if t != nil {
182 s.varList(t.vars)
183 }
184 }
185
186 func (s sanitizer) func_(f *Func) {
187 if f != nil {
188 if typ := s.typ(f.typ); typ != f.typ {
189 f.typ = typ
190 }
191 }
192 }
193
194 func (s sanitizer) funcList(list []*Func) {
195 for _, f := range list {
196 s.func_(f)
197 }
198 }
199
200 func (s sanitizer) typeList(list []Type) {
201 for i, t := range list {
202 if typ := s.typ(t); typ != t {
203 list[i] = typ
204 }
205 }
206 }
207
View as plain text