Skip to content
← Back

src/syntax/process/scopedvisitor.ghul

1
namespace Syntax.Process is
2
use IO.Std
3
4
5
use Logging
6
use Trees
7
8
class ScopedVisitor: ScopeVisitorBase abstract is
9
_logger: Logger
10
_symbol_table: Semantic.SYMBOL_TABLE
11
12
init(
13
logger: Logger,
14
symbol_table: Semantic.SYMBOL_TABLE,
15
namespaces: Semantic.NAMESPACES
16
)
17
is
18
super.init(
19
symbol_table,
20
namespaces
21
)
22
23
_logger = logger
24
_symbol_table = symbol_table
25
si
26
27
find(name: string) -> Semantic.Symbols.Symbol? => _symbol_table.current_scope.find_enclosing(name)
28
find_matches(prefix: string, matches: Collections.MutableMap[string,Semantic.Symbols.Symbol]) is
29
_symbol_table.current_scope.find_enclosing_matches(prefix, matches)
30
si
31
32
find(identifier: Identifiers.Identifier) -> Semantic.Symbols.Symbol? is
33
let result: Semantic.Symbols.Symbol? mut = null
34
35
if identifier.qualifier? then
36
let qualifier = find(identifier.qualifier)
37
38
if qualifier == null then
39
return null
40
fi
41
42
result = qualifier.find_member(identifier.name)
43
else
44
result =
45
_symbol_table
46
.current_scope
47
.find_enclosing(identifier.name)
48
fi
49
50
// A name the compiler synthesised carries an internal
51
// location, and a scope broken enough not to hold it - a
52
// file mixing globals with a namespace, say - has a real
53
// diagnostic of its own. Reporting a name nobody wrote on
54
// top of it points at nothing the author can fix.
55
if
56
result == null /\
57
!identifier.is_poisoned /\
58
!identifier.location.is_internal
59
then
60
_logger.error(identifier.location, "symbol not found: {identifier}")
61
fi
62
63
return result
64
si
65
66
// As find(identifier), but returns null silently instead of
67
// logging "symbol not found" — for callers that resolve a name
68
// speculatively and report their own diagnostic on failure.
69
try_find(identifier: Identifiers.Identifier) -> Semantic.Symbols.Symbol? is
70
if identifier.qualifier? then
71
let qualifier = try_find(identifier.qualifier)
72
73
if qualifier == null then
74
return null
75
fi
76
77
return qualifier.find_member(identifier.name)
78
fi
79
80
return
81
_symbol_table
82
.current_scope
83
.find_enclosing(identifier.name)
84
si
85
pre(`namespace: Definitions.NAMESPACE) -> bool is
86
enter_namespace(`namespace)
87
enter_uses(`namespace)
88
return false
89
si
90
91
visit(`namespace: Definitions.NAMESPACE) is
92
leave_uses(`namespace)
93
leave_namespace(`namespace)
94
si
95
96
pre(`class: Definitions.CLASS) -> bool is
97
enter_scope(`class)
98
return false
99
si
100
101
visit(`class: Definitions.CLASS) is
102
leave_scope(`class)
103
si
104
105
pre(`trait: Definitions.TRAIT) -> bool is
106
enter_scope(`trait)
107
return false
108
si
109
110
visit(`trait: Definitions.TRAIT) is
111
leave_scope(`trait)
112
si
113
114
pre(`struct: Definitions.STRUCT) -> bool is
115
enter_scope(`struct)
116
return false
117
si
118
119
pre(`union: Definitions.UNION) -> bool is
120
enter_scope(`union)
121
return false
122
si
123
124
visit(`union: Definitions.UNION) is
125
leave_scope(`union)
126
si
127
128
pre(variant: Definitions.VARIANT) -> bool is
129
enter_scope(variant)
130
return false
131
si
132
133
visit(variant: Definitions.VARIANT) is
134
leave_scope(variant)
135
si
136
137
visit(`struct: Definitions.STRUCT) is
138
leave_scope(`struct)
139
si
140
141
pre(`partial: Definitions.PARTIAL) -> bool is
142
enter_scope(`partial)
143
return false
144
si
145
146
visit(`partial: Definitions.PARTIAL) is
147
leave_scope(`partial)
148
si
149
150
pre(`impl: Definitions.IMPL) -> bool is
151
enter_scope(`impl)
152
return false
153
si
154
155
visit(`impl: Definitions.IMPL) is
156
leave_scope(`impl)
157
si
158
159
pre(`enum: Definitions.ENUM) -> bool is
160
enter_scope(`enum)
161
return false
162
si
163
164
visit(`enum: Definitions.ENUM) is
165
leave_scope(`enum)
166
si
167
168
pre(function: Definitions.FUNCTION) -> bool is
169
enter_scope(function)
170
return false
171
si
172
173
visit(function: Definitions.FUNCTION) is
174
leave_scope(function)
175
si
176
177
pre(property: Definitions.PROPERTY) -> bool => false
178
visit(property: Definitions.PROPERTY) is
179
si
180
181
pre(indexer: Definitions.INDEXER) -> bool is
182
// enter_scope(indexer);
183
return true
184
si
185
186
visit(indexer: Definitions.INDEXER) is
187
// leave_scope(indexer);
188
si
189
190
pre(if_branch: Statements.IF_BRANCH) -> bool is
191
enter_scope(if_branch)
192
return false
193
si
194
195
visit(if_branch: Statements.IF_BRANCH) is
196
leave_scope(if_branch)
197
si
198
199
pre(`case: Statements.CASE) -> bool is
200
enter_scope(`case)
201
return false
202
si
203
204
visit(`case: Statements.CASE) is
205
leave_scope(`case)
206
si
207
208
pre(case_match: Statements.CASE_MATCH) -> bool is
209
enter_scope(case_match)
210
return false
211
si
212
213
visit(case_match: Statements.CASE_MATCH) is
214
leave_scope(case_match)
215
si
216
217
pre(`try: Statements.TRY) -> bool is
218
enter_scope(`try)
219
return false
220
si
221
222
visit(`try: Statements.TRY) is
223
leave_scope(`try)
224
si
225
226
pre(`catch: Statements.CATCH) -> bool is
227
enter_scope(`catch)
228
return false
229
si
230
231
visit(`catch: Statements.CATCH) is
232
leave_scope(`catch)
233
si
234
235
pre(`do: Statements.DO) -> bool is
236
enter_scope(`do)
237
return false
238
si
239
240
visit(`do: Statements.DO) is
241
leave_scope(`do)
242
si
243
244
pre(`for: Statements.FOR) -> bool is
245
enter_scope(`for)
246
return false
247
si
248
249
visit(`for: Statements.FOR) is
250
leave_scope(`for)
251
si
252
253
pre(function: Expressions.FUNCTION) -> bool is
254
enter_scope(function)
255
return false
256
si
257
258
visit(function: Expressions.FUNCTION) is
259
leave_scope(function)
260
si
261
262
pre(let_in: Expressions.LET_IN) -> bool is
263
enter_scope(let_in)
264
return false
265
si
266
267
visit(let_in: Expressions.LET_IN) is
268
leave_scope(let_in)
269
si
270
271
pre(expression: Bodies.EXPRESSION) -> bool is
272
enter_scope(expression)
273
return false
274
si
275
276
visit(expression: Bodies.EXPRESSION) is
277
leave_scope(expression)
278
si
279
280
pre(block: Bodies.BLOCK) -> bool is
281
enter_scope(block)
282
return false
283
si
284
285
visit(block: Bodies.BLOCK) is
286
leave_scope(block)
287
si
288
si
289
si