Source file
src/go/ast/scope.go
1
2
3
4
5
6
7 package ast
8
9 import (
10 "bytes"
11 "fmt"
12 "go/token"
13 )
14
15
16
17
18
19 type Scope struct {
20 Outer *Scope
21 Objects map[string]*Object
22 }
23
24
25 func NewScope(outer *Scope) *Scope {
26 const n = 4
27 return &Scope{outer, make(map[string]*Object, n)}
28 }
29
30
31
32
33
34 func (s *Scope) Lookup(name string) *Object {
35 return s.Objects[name]
36 }
37
38
39
40
41
42
43 func (s *Scope) Insert(obj *Object) (alt *Object) {
44 if alt = s.Objects[obj.Name]; alt == nil {
45 s.Objects[obj.Name] = obj
46 }
47 return
48 }
49
50
51 func (s *Scope) String() string {
52 var buf bytes.Buffer
53 fmt.Fprintf(&buf, "scope %p {", s)
54 if s != nil && len(s.Objects) > 0 {
55 fmt.Fprintln(&buf)
56 for _, obj := range s.Objects {
57 fmt.Fprintf(&buf, "\t%s %s\n", obj.Kind, obj.Name)
58 }
59 }
60 fmt.Fprintf(&buf, "}\n")
61 return buf.String()
62 }
63
64
65
66
67
68
69
70
71
72
73
74
75
76 type Object struct {
77 Kind ObjKind
78 Name string
79 Decl any
80 Data any
81 Type any
82 }
83
84
85 func NewObj(kind ObjKind, name string) *Object {
86 return &Object{Kind: kind, Name: name}
87 }
88
89
90
91
92 func (obj *Object) Pos() token.Pos {
93 name := obj.Name
94 switch d := obj.Decl.(type) {
95 case *Field:
96 for _, n := range d.Names {
97 if n.Name == name {
98 return n.Pos()
99 }
100 }
101 case *ImportSpec:
102 if d.Name != nil && d.Name.Name == name {
103 return d.Name.Pos()
104 }
105 return d.Path.Pos()
106 case *ValueSpec:
107 for _, n := range d.Names {
108 if n.Name == name {
109 return n.Pos()
110 }
111 }
112 case *TypeSpec:
113 if d.Name.Name == name {
114 return d.Name.Pos()
115 }
116 case *FuncDecl:
117 if d.Name.Name == name {
118 return d.Name.Pos()
119 }
120 case *LabeledStmt:
121 if d.Label.Name == name {
122 return d.Label.Pos()
123 }
124 case *AssignStmt:
125 for _, x := range d.Lhs {
126 if ident, isIdent := x.(*Ident); isIdent && ident.Name == name {
127 return ident.Pos()
128 }
129 }
130 case *Scope:
131
132 }
133 return token.NoPos
134 }
135
136
137 type ObjKind int
138
139
140 const (
141 Bad ObjKind = iota
142 Pkg
143 Con
144 Typ
145 Var
146 Fun
147 Lbl
148 )
149
150 var objKindStrings = [...]string{
151 Bad: "bad",
152 Pkg: "package",
153 Con: "const",
154 Typ: "type",
155 Var: "var",
156 Fun: "func",
157 Lbl: "label",
158 }
159
160 func (kind ObjKind) String() string { return objKindStrings[kind] }
161
View as plain text