Source file
src/go/types/recording.go
1
2
3
4
5
6
7
8
9
10
11 package types
12
13 import (
14 "go/ast"
15 "go/constant"
16 )
17
18 func (check *Checker) record(x *operand) {
19
20
21 var typ Type
22 var val constant.Value
23 switch x.mode {
24 case invalid:
25 typ = Typ[Invalid]
26 case novalue:
27 typ = (*Tuple)(nil)
28 case constant_:
29 typ = x.typ
30 val = x.val
31 default:
32 typ = x.typ
33 }
34 assert(x.expr != nil && typ != nil)
35
36 if isUntyped(typ) {
37
38
39 check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
40 } else {
41 check.recordTypeAndValue(x.expr, x.mode, typ, val)
42 }
43 }
44
45 func (check *Checker) recordUntyped() {
46 if !debug && !check.recordTypes() {
47 return
48 }
49
50 for x, info := range check.untyped {
51 if debug && isTyped(info.typ) {
52 check.dump("%v: %s (type %s) is typed", x.Pos(), x, info.typ)
53 panic("unreachable")
54 }
55 check.recordTypeAndValue(x, info.mode, info.typ, info.val)
56 }
57 }
58
59 func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val constant.Value) {
60 assert(x != nil)
61 assert(typ != nil)
62 if mode == invalid {
63 return
64 }
65 if mode == constant_ {
66 assert(val != nil)
67
68
69 assert(!isValid(typ) || allBasic(typ, IsConstType))
70 }
71 if m := check.Types; m != nil {
72 m[x] = TypeAndValue{mode, typ, val}
73 }
74 check.recordTypeAndValueInSyntax(x, mode, typ, val)
75 }
76
77 func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
78
79
80
81
82 for {
83 check.recordTypeAndValue(f, builtin, sig, nil)
84 switch p := f.(type) {
85 case *ast.Ident, *ast.SelectorExpr:
86 return
87 case *ast.ParenExpr:
88 f = p.X
89 default:
90 panic("unreachable")
91 }
92 }
93 }
94
95
96
97 func (check *Checker) recordCommaOkTypes(x ast.Expr, a []*operand) {
98 assert(x != nil)
99 assert(len(a) == 2)
100 if a[0].mode == invalid {
101 return
102 }
103 t0, t1 := a[0].typ, a[1].typ
104 assert(isTyped(t0) && isTyped(t1) && (allBoolean(t1) || t1 == universeError))
105 if m := check.Types; m != nil {
106 for {
107 tv := m[x]
108 assert(tv.Type != nil)
109 pos := x.Pos()
110 tv.Type = NewTuple(
111 NewVar(pos, check.pkg, "", t0),
112 NewVar(pos, check.pkg, "", t1),
113 )
114 m[x] = tv
115
116 p, _ := x.(*ast.ParenExpr)
117 if p == nil {
118 break
119 }
120 x = p.X
121 }
122 }
123 check.recordCommaOkTypesInSyntax(x, t0, t1)
124 }
125
126
127
128
129
130
131
132 func (check *Checker) recordInstance(expr ast.Expr, targs []Type, typ Type) {
133 ident := instantiatedIdent(expr)
134 assert(ident != nil)
135 assert(typ != nil)
136 if m := check.Instances; m != nil {
137 m[ident] = Instance{newTypeList(targs), typ}
138 }
139 }
140
141 func (check *Checker) recordDef(id *ast.Ident, obj Object) {
142 assert(id != nil)
143 if m := check.Defs; m != nil {
144 m[id] = obj
145 }
146 }
147
148 func (check *Checker) recordUse(id *ast.Ident, obj Object) {
149 assert(id != nil)
150 assert(obj != nil)
151 if m := check.Uses; m != nil {
152 m[id] = obj
153 }
154 }
155
156 func (check *Checker) recordImplicit(node ast.Node, obj Object) {
157 assert(node != nil)
158 assert(obj != nil)
159 if m := check.Implicits; m != nil {
160 m[node] = obj
161 }
162 }
163
164 func (check *Checker) recordSelection(x *ast.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) {
165 assert(obj != nil && (recv == nil || len(index) > 0))
166 check.recordUse(x.Sel, obj)
167 if m := check.Selections; m != nil {
168 m[x] = &Selection{kind, recv, obj, index, indirect}
169 }
170 }
171
172 func (check *Checker) recordScope(node ast.Node, scope *Scope) {
173 assert(node != nil)
174 assert(scope != nil)
175 if m := check.Scopes; m != nil {
176 m[node] = scope
177 }
178 }
179
View as plain text