Skip to content
← Back

src/semantic/symbols/namespace.ghul

1
namespace Semantic.Symbols is
2
use System.Text.StringBuilder;
3
4
use Logging;
5
use Source;
6
7
use IR.Values.Value;
8
9
use Types.Type;
10
11
// FIXME: doesn't really have a type, not sure how to represent this:
12
class NAMESPACE: ScopedWithEnclosingScope, NamespaceContext, Types.Typed is
13
qualified_name: string;
14
15
type: Type;
16
17
short_description: string => "namespace {name}";
18
19
describe(context: DESCRIBE_CONTEXT) -> SignaturePart is
20
let qn mut = qualified_name;
21
if qn.starts_with('.') then
22
qn = qn.substring(1);
23
fi
24
return PARTS.literal("namespace {qn}");
25
si
26
27
symbol_kind: SymbolKind => SymbolKind.NAMESPACE;
28
completion_kind: CompletionKind => CompletionKind.MODULE;
29
30
is_namespace: bool => true;
31
is_classy: bool => false;
32
is_internal: bool => false;
33
is_compiler_generated: bool;
34
35
init(
36
location: LOCATION,
37
name: string,
38
enclosing_scope: Scope,
39
qualified_name: string,
40
is_compiler_generated: bool
41
) is
42
super.init(location, self, name, enclosing_scope);
43
44
self.qualified_name = qualified_name;
45
self.is_compiler_generated = is_compiler_generated;
46
47
type = Types.NAMED(self);
48
si
49
50
qualify(name: string) -> string is
51
if is_compiler_generated then
52
return name;
53
fi
54
55
let q = qualified_name;
56
57
if q.length > 1 then
58
return "{qualified_name.substring(1)}.{name}";
59
fi
60
61
return name;
62
si
63
64
find_direct(name: string) -> Symbol? is
65
let result = super.find_direct(name);
66
67
if result? then
68
return result;
69
fi
70
71
let dotnet_symbol_table = IoC.CONTAINER.instance.dotnet_symbol_table.value;
72
73
let qn mut = qualified_name;
74
75
if qn =~ "." \/ qn.length == 0 then
76
return null;
77
fi
78
79
if qn.starts_with(".") then
80
qn = qn.substring(1);
81
fi
82
83
let direct = dotnet_symbol_table.get_symbol("{qn}.{name}");
84
85
if direct? then
86
return direct;
87
fi
88
89
// Fallback: globals from a referenced assembly live as static
90
// members of a synthetic `$globals` IL class. The .NET importer
91
// materialises each one as a GLOBAL_FUNCTION / GLOBAL_VARIABLE /
92
// GLOBAL_PROPERTY whose owner is *this* NAMESPACE — matching
93
// how source-side globals are declared — but stashes them on
94
// the Classy because that lookup-table outlives this
95
// NAMESPACE's clear-between-compiles lifecycle.
96
let globals_class = dotnet_symbol_table.get_symbol("{qn}.{DotNet.GLOBALS_CARRIER.name}");
97
98
if globals_class? /\ isa Classy(globals_class) then
99
let member = globals_class.find_member(name);
100
101
if member? then
102
return member;
103
fi
104
fi
105
106
// Several carriers can share a namespace, and the lookup above
107
// reaches only whichever one the carrier name resolves to.
108
return dotnet_symbol_table.find_global_member(qn, name);
109
si
110
111
find_member(name: string) -> Symbol?
112
=> find_direct(name);
113
114
find_member_matches(prefix: string, matches: Collections.MutableMap[string, Symbols.Symbol]) is
115
find_direct_matches(prefix, matches);
116
117
let qn mut = qualified_name;
118
119
let namespaces = IoC.CONTAINER.instance.namespaces;
120
let dotnet_symbol_table = IoC.CONTAINER.instance.dotnet_symbol_table.value;
121
122
if qn =~ "." \/ qn.length == 0 then
123
// FIXME: don't think this is ever hit:
124
namespaces.find_root_matches(matches);
125
dotnet_symbol_table.find_root_matches(matches);
126
127
return;
128
fi
129
130
if qn.starts_with(".") then
131
qn = qn.substring(1);
132
fi
133
134
namespaces.find_namespace_matches(qn, matches);
135
136
dotnet_symbol_table.find_member_matches(qn, matches);
137
si
138
139
declare_namespace(location: LOCATION, name: string, `namespace: Symbols.NAMESPACE, symbol_definition_listener: SymbolDefinitionListener?) is
140
declare(location, `namespace, symbol_definition_listener);
141
si
142
143
declare_class(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
144
let result = Symbols.CLASS(location, span, self, name, arguments, enclosing);
145
146
declare(location, result, symbol_definition_listener);
147
148
return result;
149
si
150
151
declare_trait(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
152
let result = Symbols.TRAIT(location, span, self, name, arguments, enclosing);
153
154
declare(location, result, symbol_definition_listener);
155
156
return result;
157
si
158
159
declare_struct(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
160
let result = Symbols.STRUCT(location, span, self, name, arguments, enclosing);
161
162
declare(location, result, symbol_definition_listener);
163
164
return result;
165
si
166
167
declare_union(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
168
let result = Symbols.UNION(location, span, self, name, arguments, enclosing);
169
170
declare(location, result, symbol_definition_listener);
171
172
return result;
173
si
174
175
declare_enum(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
176
let result = Symbols.ENUM_STRUCT(location, span, self, name, self);
177
178
declare(location, result, symbol_definition_listener);
179
180
return result;
181
si
182
183
declare_innate(location: LOCATION, name: string, innate_name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
184
let result = Symbols.INNATE_FUNCTION(location, self, name, enclosing, innate_name);
185
186
declare_function_group(location, result, symbol_definition_listener);
187
188
return result;
189
si
190
191
declare_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
192
let result = Symbols.GLOBAL_FUNCTION(location, span, self, name, enclosing);
193
194
if is_private /\ IoC.CONTAINER.instance.build_flags.underscore_access != Compiler.UnderscoreAccess.LEGACY then
195
result.emit_assembly = true;
196
fi
197
198
declare_function_group(location, result, symbol_definition_listener);
199
200
return result;
201
si
202
203
declare_generator_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
204
let result = Symbols.GLOBAL_GENERATOR_FUNCTION(location, span, self, name, enclosing);
205
206
declare_function_group(location, result, symbol_definition_listener);
207
208
return result;
209
si
210
211
declare_async_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
212
let result = Symbols.GLOBAL_ASYNC_FUNCTION(location, span, self, name, enclosing);
213
214
declare_function_group(location, result, symbol_definition_listener);
215
216
return result;
217
si
218
219
declare_variable(location: LOCATION, name: string, is_static: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
220
let result = Symbols.GLOBAL_VARIABLE(location, self, name);
221
222
declare(location, result, symbol_definition_listener);
223
224
return result;
225
si
226
227
declare_property(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, is_assignable: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is
228
let result = Symbols.GLOBAL_PROPERTY(location, span, self, name, is_assignable);
229
230
declare(location, result, symbol_definition_listener);
231
232
return result;
233
si
234
235
load(location: LOCATION, from: Value?, loader: SYMBOL_LOADER) -> Value => loader.load_namespace(self);
236
gen_reference(buffer: StringBuilder) is
237
gen_dotted_name(buffer, null);
238
si
239
240
gen_dot(buffer: System.Text.StringBuilder) is
241
buffer.append(".");
242
si
243
244
gen_dotted_name(buffer: System.Text.StringBuilder, qualifying: Scope?) is
245
if qualified_name.length <= 1 then
246
return;
247
fi
248
249
let parts = qualified_name.substring(1).split(['.']);
250
251
let seen_any mut = false;
252
253
for part in parts do
254
if seen_any then
255
buffer.append('.');
256
fi
257
258
buffer
259
.append("'")
260
.append(part)
261
.append("'");
262
263
seen_any = true;
264
od
265
266
if qualifying? then
267
qualifying.gen_dot(buffer);
268
else
269
buffer.append(' ');
270
fi
271
si
272
273
// Synthetic public sealed-abstract host for this namespace's globals.
274
// Importer recognises by trailing simple name `$globals`.
275
gen_globals_class_reference(buffer: System.Text.StringBuilder, il_assembly_name: string?) is
276
if il_assembly_name? then
277
buffer
278
.append("['")
279
.append(il_assembly_name)
280
.append("']");
281
fi
282
283
if qualified_name.length > 1 then
284
let parts = qualified_name.substring(1).split(['.']);
285
286
for part in parts do
287
buffer
288
.append("'")
289
.append(part)
290
.append("'.");
291
od
292
fi
293
294
buffer
295
.append("'")
296
.append(DotNet.GLOBALS_CARRIER.name)
297
.append("'");
298
si
299
si
300
si