tc_info.mx raw
1 package main
2
3 // TCTypeAndValue records the type and optional constant value for an expression.
4 type TCTypeAndValue struct {
5 Type Type
6 Value ConstVal // nil for non-constant expressions
7 mode exprMode
8 }
9
10 type exprMode uint8
11
12 const (
13 modeInvalid exprMode = iota
14 modeVoid // no value (statement context)
15 modeValue // an addressable or non-addressable value
16 modeVar // addressable variable
17 modeConst // constant expression
18 modeType // a type expression
19 modeBuiltin // a builtin identifier
20 modePkg // a package name
21 modeNil // the predeclared nil
22 )
23
24 func (tv TCTypeAndValue) IsValue() bool { return tv.mode == modeValue || tv.mode == modeVar || tv.mode == modeConst || tv.mode == modeNil }
25 func (tv TCTypeAndValue) IsType() bool { return tv.mode == modeType }
26 func (tv TCTypeAndValue) IsBuiltin() bool { return tv.mode == modeBuiltin }
27 func (tv TCTypeAndValue) IsConst() bool { return tv.mode == modeConst }
28 func (tv TCTypeAndValue) Addressable() bool { return tv.mode == modeVar }
29
30 // Info holds the result of type-checking a set of Files.
31 // Consumers access type info for each expression and identifier.
32 type Info struct {
33 // Types maps each expression to its type and value.
34 // For type expressions, TCTypeAndValue.IsType() is true.
35 // For constants, TCTypeAndValue.Value is non-nil.
36 Types map[Expr]TCTypeAndValue
37
38 // Defs maps each identifier that declares something to the object it declares.
39 // nil objects represent anonymous declarations (blank _ idents).
40 Defs map[*Name]Object
41
42 // Uses maps each identifier that is used (not declared) to the object it denotes.
43 Uses map[*Name]Object
44
45 // Implicits maps nodes to the object they implicitly declare.
46 // For imports: ImportDecl -> *PkgName
47 // For type switches: the guarded var in each case clause
48 Implicits map[Node]Object
49
50 // Scopes maps AST nodes to the scope they open.
51 // File -> file scope, FuncDecl/FuncLit -> function scope, etc.
52 Scopes map[Node]*Scope
53
54 // Selections maps selector expressions X.f to the selection.
55 Selections map[*SelectorExpr]*Selection
56 }
57
58 // Selection describes a field or method selection X.f.
59 type Selection struct {
60 kind SelectionKind
61 recv Type // type of X
62 obj Object // selected field or method
63 index []int // path of field indices (for embedded fields)
64 indir bool // true if recv contains a pointer indirection
65 }
66
67 type SelectionKind int
68
69 const (
70 FieldVal SelectionKind = iota
71 MethodVal
72 MethodExpr
73 )
74
75 func (s *Selection) Kind() SelectionKind { return s.kind }
76 func (s *Selection) Recv() Type { return s.recv }
77 func (s *Selection) Obj() Object { return s.obj }
78 func (s *Selection) Index() []int { return s.index }
79 func (s *Selection) Indirect() bool { return s.indir }
80 func (s *Selection) Type() Type {
81 switch s.kind {
82 case FieldVal:
83 return s.obj.Type()
84 case MethodVal:
85 sig := s.obj.(*TCFunc).Signature()
86 // bound method: drop the receiver parameter
87 return NewSignature(nil, sig.params, sig.results, sig.variadic)
88 case MethodExpr:
89 // unbound: receiver becomes first parameter
90 return s.obj.(*TCFunc).Signature()
91 }
92 return nil
93 }
94
95 func newInfo() *Info {
96 return &Info{
97 Types: map[Expr]TCTypeAndValue{},
98 Defs: map[*Name]Object{},
99 Uses: map[*Name]Object{},
100 Implicits: map[Node]Object{},
101 Scopes: map[Node]*Scope{},
102 Selections: map[*SelectorExpr]*Selection{},
103 }
104 }
105
106 // TypeOf returns the type of expression e, or nil if unknown.
107 func (info *Info) TypeOf(e Expr) Type {
108 if tv, ok := info.Types[e]; ok {
109 return tv.Type
110 }
111 return nil
112 }
113
114 // ObjectOf returns the object denoted by identifier id, or nil.
115 func (info *Info) ObjectOf(id *Name) Object {
116 if obj, ok := info.Defs[id]; ok {
117 return obj
118 }
119 return info.Uses[id]
120 }
121