1
2
3
4
5
6
7 package types2
8
9 import (
10 "cmd/compile/internal/syntax"
11 "fmt"
12 "io"
13 "slices"
14 "strings"
15 "sync"
16 )
17
18
19
20
21
22 type Scope struct {
23 parent *Scope
24 children []*Scope
25 number int
26 elems map[string]Object
27 pos, end syntax.Pos
28 comment string
29 isFunc bool
30 }
31
32
33
34 func NewScope(parent *Scope, pos, end syntax.Pos, comment string) *Scope {
35 s := &Scope{parent, nil, 0, nil, pos, end, comment, false}
36
37 if parent != nil && parent != Universe {
38 parent.children = append(parent.children, s)
39 s.number = len(parent.children)
40 }
41 return s
42 }
43
44
45 func (s *Scope) Parent() *Scope { return s.parent }
46
47
48 func (s *Scope) Len() int { return len(s.elems) }
49
50
51 func (s *Scope) Names() []string {
52 names := make([]string, len(s.elems))
53 i := 0
54 for name := range s.elems {
55 names[i] = name
56 i++
57 }
58 slices.Sort(names)
59 return names
60 }
61
62
63 func (s *Scope) NumChildren() int { return len(s.children) }
64
65
66 func (s *Scope) Child(i int) *Scope { return s.children[i] }
67
68
69
70 func (s *Scope) Lookup(name string) Object {
71 obj := resolve(name, s.elems[name])
72
73
74
75
76
77
78
79
80 if obj == universeAnyAlias && !aliasAny() {
81 return universeAnyNoAlias
82 }
83 return obj
84 }
85
86
87
88
89 func (s *Scope) lookupIgnoringCase(name string, exported bool) []Object {
90 var matches []Object
91 for _, n := range s.Names() {
92 if (!exported || isExported(n)) && strings.EqualFold(n, name) {
93 matches = append(matches, s.Lookup(n))
94 }
95 }
96 return matches
97 }
98
99
100
101
102
103
104 func (s *Scope) Insert(obj Object) Object {
105 name := obj.Name()
106 if alt := s.Lookup(name); alt != nil {
107 return alt
108 }
109 s.insert(name, obj)
110
111
112
113
114
115 if obj.Parent() == nil {
116 obj.setParent(s)
117 }
118 return nil
119 }
120
121
122
123
124
125
126
127
128 func (s *Scope) InsertLazy(name string, resolve func() Object) bool {
129 if s.elems[name] != nil {
130 return false
131 }
132 s.insert(name, &lazyObject{parent: s, resolve: resolve})
133 return true
134 }
135
136 func (s *Scope) insert(name string, obj Object) {
137 if s.elems == nil {
138 s.elems = make(map[string]Object)
139 }
140 s.elems[name] = obj
141 }
142
143
144
145
146
147
148 func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) {
149 const ind = ". "
150 indn := strings.Repeat(ind, n)
151
152 fmt.Fprintf(w, "%s%s scope %p {\n", indn, s.comment, s)
153
154 indn1 := indn + ind
155 for _, name := range s.Names() {
156 fmt.Fprintf(w, "%s%s\n", indn1, s.Lookup(name))
157 }
158
159 if recurse {
160 for _, s := range s.children {
161 s.WriteTo(w, n+1, recurse)
162 }
163 }
164
165 fmt.Fprintf(w, "%s}\n", indn)
166 }
167
168
169 func (s *Scope) String() string {
170 var buf strings.Builder
171 s.WriteTo(&buf, 0, false)
172 return buf.String()
173 }
174
175
176
177 type lazyObject struct {
178 parent *Scope
179 resolve func() Object
180 obj Object
181 once sync.Once
182 }
183
184
185
186 func resolve(name string, obj Object) Object {
187 if lazy, ok := obj.(*lazyObject); ok {
188 lazy.once.Do(func() {
189 obj := lazy.resolve()
190
191 if _, ok := obj.(*lazyObject); ok {
192 panic("recursive lazy object")
193 }
194 if obj.Name() != name {
195 panic("lazy object has unexpected name")
196 }
197
198 if obj.Parent() == nil {
199 obj.setParent(lazy.parent)
200 }
201 lazy.obj = obj
202 })
203
204 obj = lazy.obj
205 }
206 return obj
207 }
208
209
210
211 func (*lazyObject) Parent() *Scope { panic("unreachable") }
212 func (*lazyObject) Pos() syntax.Pos { panic("unreachable") }
213 func (*lazyObject) Pkg() *Package { panic("unreachable") }
214 func (*lazyObject) Name() string { panic("unreachable") }
215 func (*lazyObject) Type() Type { panic("unreachable") }
216 func (*lazyObject) Exported() bool { panic("unreachable") }
217 func (*lazyObject) Id() string { panic("unreachable") }
218 func (*lazyObject) String() string { panic("unreachable") }
219 func (*lazyObject) order() uint32 { panic("unreachable") }
220 func (*lazyObject) color() color { panic("unreachable") }
221 func (*lazyObject) setType(Type) { panic("unreachable") }
222 func (*lazyObject) setOrder(uint32) { panic("unreachable") }
223 func (*lazyObject) setColor(color color) { panic("unreachable") }
224 func (*lazyObject) setParent(*Scope) { panic("unreachable") }
225 func (*lazyObject) sameId(*Package, string, bool) bool { panic("unreachable") }
226 func (*lazyObject) scopePos() syntax.Pos { panic("unreachable") }
227 func (*lazyObject) setScopePos(syntax.Pos) { panic("unreachable") }
228
View as plain text