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
if identifier.name == null then
34
return null;
35
fi
36
37
let result: Semantic.Symbols.Symbol? mut = null;
38
39
if identifier.qualifier? then
40
let qualifier = find(identifier.qualifier);
41
42
if qualifier == null then
43
return null;
44
fi
45
46
result = qualifier.find_member(identifier.name);
47
else
48
result =
49
_symbol_table
50
.current_scope
51
.find_enclosing(identifier.name);
52
fi
53
54
if result == null /\ !identifier.is_poisoned then
55
_logger.error(identifier.location, "symbol not found: {identifier}");
56
fi
57
58
return result;
59
si
60
61
// As find(identifier), but returns null silently instead of
62
// logging "symbol not found" — for callers that resolve a name
63
// speculatively and report their own diagnostic on failure.
64
try_find(identifier: Identifiers.Identifier) -> Semantic.Symbols.Symbol? is
65
if identifier.name == null then
66
return null;
67
fi
68
69
if identifier.qualifier? then
70
let qualifier = try_find(identifier.qualifier);
71
72
if qualifier == null then
73
return null;
74
fi
75
76
return qualifier.find_member(identifier.name);
77
fi
78
79
return
80
_symbol_table
81
.current_scope
82
.find_enclosing(identifier.name);
83
si
84
pre(`namespace: Definitions.NAMESPACE) -> bool is
85
enter_namespace(`namespace);
86
enter_uses(`namespace);
87
return false;
88
si
89
90
visit(`namespace: Definitions.NAMESPACE) is
91
leave_uses(`namespace);
92
leave_namespace(`namespace);
93
si
94
95
pre(`class: Definitions.CLASS) -> bool is
96
enter_scope(`class);
97
return false;
98
si
99
100
visit(`class: Definitions.CLASS) is
101
leave_scope(`class);
102
si
103
104
pre(`trait: Definitions.TRAIT) -> bool is
105
enter_scope(`trait);
106
return false;
107
si
108
109
visit(`trait: Definitions.TRAIT) is
110
leave_scope(`trait);
111
si
112
113
pre(`struct: Definitions.STRUCT) -> bool is
114
enter_scope(`struct);
115
return false;
116
si
117
118
pre(`union: Definitions.UNION) -> bool is
119
enter_scope(`union);
120
return false;
121
si
122
123
visit(`union: Definitions.UNION) is
124
leave_scope(`union);
125
si
126
127
pre(variant: Definitions.VARIANT) -> bool is
128
enter_scope(variant);
129
return false;
130
si
131
132
visit(variant: Definitions.VARIANT) is
133
leave_scope(variant);
134
si
135
136
visit(`struct: Definitions.STRUCT) is
137
leave_scope(`struct);
138
si
139
140
pre(`partial: Definitions.PARTIAL) -> bool is
141
enter_scope(`partial);
142
return false;
143
si
144
145
visit(`partial: Definitions.PARTIAL) is
146
leave_scope(`partial);
147
si
148
149
pre(`impl: Definitions.IMPL) -> bool is
150
enter_scope(`impl);
151
return false;
152
si
153
154
visit(`impl: Definitions.IMPL) is
155
leave_scope(`impl);
156
si
157
158
pre(`enum: Definitions.ENUM) -> bool is
159
enter_scope(`enum);
160
return false;
161
si
162
163
visit(`enum: Definitions.ENUM) is
164
leave_scope(`enum);
165
si
166
167
pre(function: Definitions.FUNCTION) -> bool is
168
enter_scope(function);
169
return false;
170
si
171
172
visit(function: Definitions.FUNCTION) is
173
leave_scope(function);
174
si
175
176
pre(property: Definitions.PROPERTY) -> bool => false;
177
visit(property: Definitions.PROPERTY) is
178
si
179
180
pre(indexer: Definitions.INDEXER) -> bool is
181
// enter_scope(indexer);
182
return true;
183
si
184
185
visit(indexer: Definitions.INDEXER) is
186
// leave_scope(indexer);
187
si
188
189
pre(if_branch: Statements.IF_BRANCH) -> bool is
190
enter_scope(if_branch);
191
return false;
192
si
193
194
visit(if_branch: Statements.IF_BRANCH) is
195
leave_scope(if_branch);
196
si
197
198
pre(`case: Statements.CASE) -> bool is
199
enter_scope(`case);
200
return false;
201
si
202
203
visit(`case: Statements.CASE) is
204
leave_scope(`case);
205
si
206
207
pre(case_match: Statements.CASE_MATCH) -> bool is
208
enter_scope(case_match);
209
return false;
210
si
211
212
visit(case_match: Statements.CASE_MATCH) is
213
leave_scope(case_match);
214
si
215
216
pre(`try: Statements.TRY) -> bool is
217
enter_scope(`try);
218
return false;
219
si
220
221
visit(`try: Statements.TRY) is
222
leave_scope(`try);
223
si
224
225
pre(`catch: Statements.CATCH) -> bool is
226
enter_scope(`catch);
227
return false;
228
si
229
230
visit(`catch: Statements.CATCH) is
231
leave_scope(`catch);
232
si
233
234
pre(`do: Statements.DO) -> bool is
235
enter_scope(`do);
236
return false;
237
si
238
239
visit(`do: Statements.DO) is
240
leave_scope(`do);
241
si
242
243
pre(`for: Statements.FOR) -> bool is
244
enter_scope(`for);
245
return false;
246
si
247
248
visit(`for: Statements.FOR) is
249
leave_scope(`for);
250
si
251
252
pre(function: Expressions.FUNCTION) -> bool is
253
enter_scope(function);
254
return false;
255
si
256
257
visit(function: Expressions.FUNCTION) is
258
leave_scope(function);
259
si
260
261
pre(let_in: Expressions.LET_IN) -> bool is
262
enter_scope(let_in);
263
return false;
264
si
265
266
visit(let_in: Expressions.LET_IN) is
267
leave_scope(let_in);
268
si
269
270
pre(expression: Bodies.EXPRESSION) -> bool is
271
enter_scope(expression);
272
return false;
273
si
274
275
visit(expression: Bodies.EXPRESSION) is
276
leave_scope(expression);
277
si
278
279
pre(block: Bodies.BLOCK) -> bool is
280
enter_scope(block);
281
return false;
282
si
283
284
visit(block: Bodies.BLOCK) is
285
leave_scope(block);
286
si
287
si
288
si