Skip to content
← Back

src/semantic/symbols/symbol.ghul

1
namespace Semantic.Symbols is
2
use System.Exception;
3
use System.NotImplementedException;
4
use System.Text.StringBuilder;
5
6
use IO.Std;
7
8
use IoC;
9
use Logging;
10
use Source;
11
12
use IR.Values.Value;
13
14
use Semantic.Types.Type;
15
16
enum ACCESS is
17
PRIVATE, PUBLIC, PROTECTED
18
si
19
20
// FIXME: think the language server needs to declare it can
21
// use the newer list below for completions as well as symbol info:
22
enum CompletionKind is
23
UNDEFINED = 0,
24
METHOD = 2,
25
FUNCTION = 3,
26
CONSTRUCTOR = 4,
27
FIELD = 5,
28
VARIABLE = 6,
29
CLASS = 7,
30
INTERFACE = 8,
31
MODULE = 9,
32
PROPERTY = 10,
33
ENUM = 13,
34
KEYWORD = 14,
35
SNIPPET = 15,
36
COLOR = 16,
37
FILE = 17,
38
REFERENCE = 18,
39
FOLDER = 19,
40
ENUM_MEMBER = 20,
41
CONSTANT = 21,
42
STRUCT = 22,
43
EVENT = 23,
44
OPERATOR = 24,
45
TYPE_PARAMETER = 25
46
si
47
48
enum SymbolKind is
49
UNDEFINED = 0,
50
FILE = 1,
51
MODULE = 2,
52
NAMESPACE = 3,
53
PACKAGE = 4,
54
CLASS = 5,
55
METHOD = 6,
56
PROPERTY = 7,
57
FIELD = 8,
58
CONSTRUCTOR = 9,
59
ENUM = 10,
60
INTERFACE = 11,
61
FUNCTION = 12,
62
VARIABLE = 13,
63
CONSTANT = 14,
64
STRING = 15,
65
NUMBER = 16,
66
BOOLEAN = 17,
67
ARRAY = 18,
68
OBJECT = 19,
69
KEY = 20,
70
NULL = 21,
71
ENUM_MEMBER = 22,
72
STRUCT = 23,
73
EVENT = 24,
74
OPERATOR = 25,
75
TYPE_PARAMETER = 26
76
si
77
78
enum TypeParameterConstraintKind is
79
NONE = 0,
80
REFERENCE = 1,
81
VALUE = 2,
82
OPTIONAL = 3
83
si
84
85
class Symbol: Scope abstract is
86
_next_id: int static;
87
88
// Creation-ordered identity, unique per symbol within a process.
89
// Facts keyed by id survive a symbol being re-created by an
90
// incremental edit when the replacement adopts its predecessor's
91
// id — reference identity made transferable. Never use ids for
92
// ordering: assignment order differs between batch builds and
93
// analysis-mode edit histories.
94
_id: int;
95
96
_location: LOCATION;
97
_name: string?;
98
99
owner: Scope?;
100
type: Type? => Types.NONE.instance;
101
depth: int => 1;
102
103
symbols: Collections.Iterable[Symbol] => Collections.LIST[Symbol]();
104
105
overriders: Collections.Iterable[Symbol]? => null;
106
overridees: Collections.Iterable[Symbol]? => null;
107
108
implementors: Collections.Iterable[Symbol]? => null;
109
110
unspecialized_symbol: Symbol => self;
111
112
root_unspecialized_symbol: Symbol => self;
113
114
id: int => _id;
115
116
// Adopt a predecessor's identity, so id-keyed facts recorded
117
// against it are found by lookups through self. Only for an
118
// incremental reconcile replacing a declaration with its edited
119
// successor; the caller owns deciding which facts remain valid
120
// across the edit and resetting the ones that do not.
121
adopt_id(predecessor: Symbol) is
122
_id = predecessor._id;
123
si
124
125
location: LOCATION => _location;
126
span: LOCATION => _location;
127
128
// Move the symbol's definition location. Used by the incremental
129
// body re-walk: a retained interface symbol below an edited body
130
// is shifted into current coordinates rather than rebuilt.
131
set_location(location: LOCATION) is
132
_location = location;
133
si
134
135
// Move the symbol's declaration span. For a base symbol the span
136
// *is* the location (`span => _location`), so this is a no-op —
137
// `set_location` already handled it. Functions, classes / traits
138
// / structs / unions and properties carry a separate span field
139
// and override this to shift it. Called alongside `set_location`
140
// by the incremental body re-walk's reconciliation.
141
set_span(span_location: LOCATION) is si
142
143
name: string => _name!;
144
145
is_internal: bool => _name!.starts_with('$') \/ location.is_internal;
146
is_reflected: bool => location.is_reflected;
147
148
// True for symbols whose uses are confined to a single function body —
149
// locals, parameters, labels, function-level type parameters. Cross-file
150
// queries (references / implementation / etc.) need a full COMPILE only
151
// when a NON-local symbol's recorded uses are missing; locals can always
152
// be answered from the current file's parse alone.
153
is_local: bool => false;
154
is_object: bool => false;
155
is_root_value_type: bool => false;
156
is_void: bool => false;
157
is_type: bool => false;
158
is_generic_type_specialization: bool => false;
159
is_type_variable: bool => false;
160
is_argument: bool => false;
161
is_field: bool => false;
162
is_private: bool => false;
163
is_public_readable: bool => true;
164
165
// Compile-time access rule for the underscore policy, dispatched on the
166
// symbol's access kind. `accessor` is the class whose code is making
167
// the reference. Public symbols (the default) are reachable anywhere;
168
// the underscore method and field kinds narrow this to the declaring
169
// class (private) or the declaring class and its subclasses (protected).
170
is_accessible_to(accessor: Classy?) -> bool => true;
171
172
// Access modifier shown in a hover / describe. Empty for public
173
// symbols; the underscore method and field kinds return "private " or
174
// "protected " so the hover reads e.g. "pure private method".
175
access_prefix: string => "";
176
is_assignable: bool => false;
177
is_function: bool => false;
178
is_function_group: bool => false;
179
is_type_group: bool => false;
180
is_constructor: bool => false;
181
is_static_constructor: bool => false;
182
is_instance_context: bool => false;
183
is_union: bool => false;
184
is_variant: bool => false;
185
is_closed_root: bool => false;
186
is_unit_variant: bool => false;
187
is_specializable: bool => true;
188
can_accept_actual_type_arguments: bool => false;
189
can_hide_inherited: bool => false;
190
191
qualified_name: string =>
192
if owner? then
193
owner.qualify(name);
194
else
195
name;
196
fi;
197
198
// This symbol's name shortened relative to `scope`: as compact as
199
// the scope allows while still resolving back to this symbol. Bare
200
// when the bare name is in scope there (a same-scope declaration or
201
// any `use` import); `owner.member` when the symbol is a member of
202
// a type; the full namespace for a top-level type or global that is
203
// not in scope; and bare for a local. With no scope, the full
204
// qualified name. Overridden where a kind names itself differently
205
// (a constructed generic keeps its type arguments).
206
render_name(scope: Scope?) -> string =>
207
"{_render_scope_relative_name(scope)}{render_type_argument_suffix()}";
208
209
// The scope-relative name without any type-argument suffix. A member
210
// still qualifies through its owner's full `render_name`, so the
211
// owner keeps its own arguments (`LIST[T].count`).
212
_render_scope_relative_name(scope: Scope?) -> string is
213
if !scope? then
214
return qualified_name;
215
fi
216
217
if owner? /\ scope.find_enclosing(name) == self then
218
return name;
219
fi
220
221
let owning = owner;
222
223
if owning? /\ isa Symbol(owning) /\ owning.is_type then
224
// A variant carries the type arguments itself
225
// (`Result.OK[int,string]`), so its owning union is named
226
// without them; every other member keeps its owner's
227
// arguments (`BOX[T].bit`).
228
if is_variant then
229
return "{owning._render_scope_relative_name(scope)}.{name}";
230
fi
231
return "{owning.render_name(scope)}.{name}";
232
fi
233
234
if is_local then
235
return name;
236
fi
237
238
return qualified_name;
239
si
240
241
// A type that takes type parameters always renders them; a generic
242
// classy fills this in from its `argument_names`. Empty for everything
243
// else. A constructed generic renders its actual arguments through its
244
// own `render_name` override, off the bare scope-relative head.
245
render_type_argument_suffix() -> string => "";
246
247
248
il_name: string =>
249
if let self.il_name_override? then
250
il_name_override
251
else
252
"'{escape_il_quoted_identifier(name)}'"
253
fi;
254
255
// Escapes an identifier for placement inside an ilasm single-quoted
256
// name: the backslash is ilasm's escape character and the single
257
// quote is the delimiter, so both are doubled/escaped. Applied only
258
// where a raw identifier is wrapped in quotes (here and `gen_name`);
259
// a name with neither character is returned unchanged, so the common
260
// case allocates nothing and the emitted IL is byte-identical.
261
escape_il_quoted_identifier(name: string) -> string static =>
262
if name.index_of('\\') >= 0 \/ name.index_of('\'') >= 0 then
263
name.replace("\\", "\\\\").replace("'", "\\'")
264
else
265
name
266
fi;
267
268
il_name_override: string? public;
269
270
// FIXME: can these go somewhere more specific?
271
il_is_primitive_type: bool public;
272
273
is_unsafe_constraints: bool public;
274
275
argument_names: Collections.List[string] => Collections.LIST[string](0);
276
arguments: Collections.List[Type] => Collections.LIST[Type](0);
277
ancestors: Collections.List[Type] => Collections.LIST[Type](0);
278
279
set_ancestor_type(type: Type);
280
281
constraint_kind: TypeParameterConstraintKind => TypeParameterConstraintKind.NONE;
282
set_constraint_kind(kind: TypeParameterConstraintKind);
283
284
has_constructor_constraint: bool => false;
285
set_has_constructor_constraint(value: bool) is si
286
287
get_argument_constraint_kind(index: int) -> TypeParameterConstraintKind => TypeParameterConstraintKind.NONE;
288
289
get_argument_has_constructor_constraint(index: int) -> bool => false;
290
291
get_argument_type_bound(index: int) -> Type? => null;
292
293
specialized_from: Symbol? public;
294
295
root_specialized_from: Symbol =>
296
let sf = specialized_from in
297
298
if sf? then
299
sf.root_specialized_from;
300
else
301
self;
302
fi;
303
304
access: ACCESS => ACCESS.PUBLIC;
305
306
// The formatted declaration head with no trailing kind classifier —
307
// the structured counterpart to `kind_label`. Rendered from
308
// `describe(context)`; overriding it changes both this and the
309
// signature the hover renderer displays.
310
signature: string =>
311
TEXT_RENDERER(DESCRIBE_CONTEXT.instance).render(describe(DESCRIBE_CONTEXT.instance));
312
313
// The kind classifier (`instance method`, `class`, `variant`, …) or
314
// null when the symbol has none. Structured counterpart to
315
// `signature`.
316
kind_label: string? =>
317
describe_kind(DESCRIBE_CONTEXT.instance);
318
319
// Flat-text form — `signature` plus a trailing ` // kind` classifier
320
// when one is defined. Used for IL comments; the analysis wire keeps
321
// `signature` and `kind_label` separate.
322
description: string is
323
let kind = kind_label;
324
if kind? then
325
return "{signature} // {kind}";
326
fi
327
return signature;
328
si
329
330
short_description: string => name;
331
search_description: string => "{name}{render_type_argument_suffix()}";
332
333
// Structured signature body — no trailing ` // kind`. Subclasses
334
// override to produce a rich tree whose text render matches
335
// their own signature; the default here mirrors the plain
336
// `qualified_name`. The DOC-layout hover renderer walks this
337
// tree, so overrides determine which parts of a signature can
338
// wrap.
339
describe(context: DESCRIBE_CONTEXT) -> SignaturePart =>
340
SignaturePart.NAME(self);
341
342
// Human-readable classifier for the description trailer —
343
// `instance method`, `local variable`, `pure global function`,
344
// etc. Null when the symbol has no natural label (namespaces,
345
// labels).
346
describe_kind(context: DESCRIBE_CONTEXT) -> string? => null;
347
348
// Shared body for any typed symbol's `<name>: <type>` display.
349
// Renders the declared type on the primary line; when the
350
// context carries a narrowed observed type for this symbol
351
// that differs from the declared shape, emits the narrowed
352
// type on a second `► narrowed` line beneath, matching the
353
// direction sigil used by narrowing-introduction inlays.
354
// `!~` compares rendered forms because `!=` on strings is
355
// reference-only in ghūl; two Type instances that render the
356
// same qualified name are still distinct references.
357
_describe_typed(
358
context: DESCRIBE_CONTEXT,
359
name_part: SignaturePart,
360
declared: Type?
361
) -> SignaturePart is
362
let narrowed = context.observed_type_for(self);
363
if narrowed? /\ declared? /\ "{narrowed}" !~ "{declared}" then
364
return PARTS.sequence([
365
name_part,
366
PARTS.literal(": "),
367
PARTS.type_ref(declared),
368
PARTS.hanging(4, "► ", PARTS.type_ref(narrowed))
369
]);
370
fi
371
372
let display = narrowed ?? declared;
373
374
if !display? then
375
return name_part;
376
fi
377
378
return PARTS.sequence([
379
name_part,
380
PARTS.literal(": "),
381
PARTS.type_ref(display)
382
]);
383
si
384
385
symbol_kind: SymbolKind => SymbolKind.UNDEFINED;
386
completion_kind: CompletionKind => CompletionKind.UNDEFINED;
387
388
// .NET custom attributes applied to this symbol via attribute
389
// pragmas — resolved by ATTRIBUTE_RESOLVER, emitted by generate-il.
390
// Null until the first attribute is attached.
391
custom_attributes: Collections.LIST[Semantic.CUSTOM_ATTRIBUTE]? public;
392
393
is_value_type: bool => false;
394
is_instance: bool => false;
395
is_innate: bool => false;
396
is_inheritable: bool => false;
397
is_class: bool => false;
398
is_trait: bool => false;
399
is_variable: bool => false;
400
is_capture_context: bool => false;
401
is_closure: bool => false;
402
is_namespace: bool => false;
403
is_classy: bool => false;
404
is_workspace_visible: bool => false;
405
406
=~(other: object?) -> bool =>
407
if !other? /\ !isa Symbol(other) then
408
false;
409
else
410
self == other;
411
fi;
412
413
=~(other: Symbol) -> bool => self == other;
414
415
init(location: LOCATION, owner: Scope, name: string) is
416
_next_id = _next_id + 1;
417
_id = _next_id;
418
419
_location = location;
420
self.owner = owner;
421
_name = name;
422
si
423
424
define() is
425
si
426
427
add_member(function: Symbol) -> bool => throw System.NotImplementedException("cannot add member to {self}");
428
add_implementor(symbol: Symbol) is
429
throw System.NotImplementedException("cannot add implementor to {self}");
430
si
431
432
get_ancestor(i: int) -> Type is
433
if ancestors.count > 0 then
434
Std.error.write_line("oops: {self.get_type()} {self} has ancestors but expected none");
435
436
for a in ancestors do
437
Std.error.write_line("ancestor: {a}");
438
od
439
fi
440
441
throw NotImplementedException("{get_type()} has no ancestor {i}");
442
si
443
444
get_element_name(index: int) -> string?;
445
446
qualify(name: string) -> string => "{qualified_name}.{name}";
447
448
hide() is
449
if !il_name_override? then
450
il_name_override = _name!;
451
fi
452
453
_name = "${_name}";
454
si
455
456
compare_type(other: Symbol) -> Types.MATCH
457
=> Types.MATCH.DIFFERENT;
458
459
specialize(type_map: Collections.Map[string,Type], owner: GENERIC) -> Symbol => throw NotImplementedException("{get_type()} cannot be specialized: {self}");
460
specialize(arguments: Collections.List[Type]) -> Symbol => throw NotImplementedException("{get_type()} cannot be specialized: {self}");
461
try_specialize(
462
location: LOCATION,
463
logger: Logger,
464
actual_type_arguments: Collections.List[Type]
465
) -> Symbol? is
466
logger.error(location, "cannot supply explicit type arguments here");
467
return null;
468
si
469
470
freeze() -> Symbol? => null;
471
472
load(location: LOCATION, from: Value?, loader: SYMBOL_LOADER) -> Value =>
473
// will report error when consumed:
474
IR.Values.Load.SYMBOL(from, self);
475
476
load_outer(location: LOCATION, from: Value?, loader: SYMBOL_LOADER) -> Value =>
477
// will report error when consumed:
478
IR.Values.Load.SYMBOL(from, self);
479
480
store(location: LOCATION, from: Value?, value: Value, loader: SYMBOL_LOADER, is_initialize: bool) -> Value =>
481
// will report error when consumed:
482
IR.Values.Store.SYMBOL(from, self, value);
483
484
call(location: Source.LOCATION, from: Value?, arguments: Collections.List[Value], type: Type?, caller: FUNCTION_CALLER) -> Value => throw NotImplementedException("{get_type()} cannot be called: {self}");
485
try_pull_down_into(
486
into: Classy,
487
other_overridee_symbols: Collections.Iterable[Symbol],
488
logger: Logging.Logger
489
) is
490
into.add_member(self);
491
si
492
493
assert_symbols_pulled_down() => throw System.NotImplementedException("abstract method: implement me");
494
pull_down_super_symbols() => throw System.NotImplementedException("abstract method: implement me");
495
add_overrider(overrider: Symbol);
496
add_overridee(overridee: Symbol);
497
remove_overrider(overrider: Symbol);
498
remove_overridee(overridee: Symbol);
499
500
find_direct(name: string) -> Symbol? => null;
501
502
find_member(name: string) -> Symbol? => null;
503
504
get_destructure_member_name(index: int) -> string? =>
505
"{index}";
506
507
is_positional_member_name(name: string?) -> bool static is
508
if !name? \/ name.length == 0 then
509
return false;
510
fi
511
for i in 0..name.length do
512
let c = name.get_chars(i);
513
if c < '0' \/ c > '9' then
514
return false;
515
fi
516
od
517
return true;
518
si
519
520
find_enclosing(name: string) -> Symbol? => null;
521
522
// FIXME: the way we handle inheritance and specialization of generics makes it tricky to get the correctly specialized owner of methods that
523
// are interited from a super class or trait. The following works, but the fact that it's needed suggests we ought to be tracking this some other way
524
find_owning_ancestor(o: Scope) -> Scope? is
525
let search_symbol = o.unspecialized_symbol;
526
527
if !search_symbol? then
528
return null;
529
fi
530
531
if self.unspecialized_symbol == search_symbol then
532
return self;
533
fi
534
535
if ancestors.count == 0 then
536
return o;
537
fi
538
539
for i in 0..ancestors.count do
540
let aa = get_ancestor(i);
541
542
if aa.unspecialized_symbol == o.unspecialized_symbol then
543
return get_ancestor(i).symbol;
544
fi
545
546
let result = aa.symbol.find_owning_ancestor(o);
547
548
if result? then
549
return result;
550
fi
551
od
552
return null;
553
si
554
555
find_ancestor(search_type: Type) -> Type? is
556
if unspecialized_symbol == search_type.unspecialized_symbol then
557
return self.type;
558
fi
559
560
for a in ancestors do
561
let result = a.find_ancestor(search_type);
562
563
if result? then
564
return result;
565
fi
566
od
567
return null;
568
si
569
570
get_all_direct_ancestor_members() -> Collections.LIST[Symbol] is
571
let result = Collections.LIST[Symbol]();
572
573
for i in 0..ancestors.count do
574
let a = get_ancestor(i);
575
576
if a.scope? then
577
for member in a.scope!.symbols do
578
if isa FUNCTION_GROUP(member) then
579
for function in member.functions do
580
if
581
function.is_abstract \/
582
function.is_default_trait_method \/
583
(function.name !~ "init" /\ !a.is_trait)
584
then
585
result.add(function);
586
fi
587
od
588
elif isa Function(member) then
589
let function = member;
590
591
if
592
function.is_abstract \/
593
function.is_default_trait_method \/
594
(function.name !~ "init" /\ !a.is_trait)
595
then
596
result.add(function);
597
fi
598
elif !member.is_type_variable then
599
result.add(member);
600
fi
601
od
602
fi
603
od
604
605
return result;
606
si
607
608
find_direct_matches(prefix: string, matches: Collections.MutableMap[string, Symbol]) is
609
si
610
611
find_ancestor_matches(prefix: string, matches: Collections.MutableMap[string, Symbol]) is
612
si
613
614
find_member_matches(prefix: string, matches: Collections.MutableMap[string, Symbol]) is
615
si
616
617
find_enclosing_matches(prefix: string, matches: Collections.MutableMap[string, Symbol]) is
618
si
619
620
collapse_group_if_single_member() -> Symbol => self;
621
get_il_reference() -> string is
622
let buffer = StringBuilder();
623
624
gen_reference(buffer);
625
626
return buffer.to_string();
627
si
628
629
gen_dot(buffer: System.Text.StringBuilder) is
630
buffer.append(".");
631
si
632
633
gen_dotted_name(buffer: System.Text.StringBuilder, qualifying: Scope?) is
634
if owner? then
635
owner.gen_dotted_name(buffer, self);
636
fi
637
638
gen_name(buffer);
639
640
if qualifying? then
641
qualifying.gen_dot(buffer);
642
else
643
buffer.append(' ');
644
fi
645
si
646
647
gen_name(buffer: StringBuilder) is
648
let iln = il_name;
649
650
if !iln.starts_with('\'') then
651
buffer
652
.append('\'')
653
.append(escape_il_quoted_identifier(iln))
654
.append('\'');
655
else
656
buffer.append(iln);
657
fi
658
si
659
660
gen_definition_header(buffer: StringBuilder) => throw System.NotImplementedException("not implemented by {get_type()}");
661
gen_definition_header(context: IR.CONTEXT) is
662
let buffer = StringBuilder();
663
664
gen_definition_header(buffer);
665
666
context.write_line(buffer);
667
si
668
669
gen_type_prefix(buffer: StringBuilder) => throw System.NotImplementedException("not implemented by {get_type()}");
670
gen_reference(buffer: StringBuilder) => throw System.NotImplementedException("not implemented by {get_type()}");
671
gen_type(buffer: StringBuilder) => throw System.NotImplementedException("not implemented by {get_type()}");
672
gen_type_override(override: (Symbol, StringBuilder) -> void) => throw System.NotImplementedException("not implemented by {get_type()}");
673
current_gen_type_override: ((Symbol, StringBuilder) -> void)? => null;
674
675
gen_class_name(buffer: StringBuilder) => throw System.NotImplementedException("not implemented by {get_type()}");
676
to_string() -> string => short_description;
677
si
678
679
class Scoped: Symbol, DeclarationContext abstract is
680
_symbols: SYMBOL_STORE;
681
682
symbols: Collections.Iterable[Symbol] => _symbols.values;
683
is_empty: bool => _symbols.count == 0;
684
685
init(location: LOCATION, owner: Scope, name: string) is
686
super.init(location, owner, name);
687
_symbols = SYMBOL_STORE();
688
si
689
690
clear() is
691
_symbols.clear();
692
si
693
694
find_direct(name: string) -> Symbol? => _symbols[name];
695
696
find_direct_matches(prefix: string, matches: Collections.MutableMap[string, Symbol]) is
697
_symbols.find_matches(prefix, matches);
698
si
699
700
// Direct store mutators for INHERITANCE_JOURNAL undo: reverse an
701
// entry a pull-down added or promoted. Not for general use - the
702
// declare/add_member paths own the store's invariants.
703
remove_direct(name: string) is
704
_symbols.remove(name);
705
si
706
707
put_direct(name: string, symbol: Symbol) is
708
_symbols[name] = symbol;
709
si
710
711
declare(location: LOCATION, symbol: Symbol, symbol_definition_listener: SymbolDefinitionListener?) is
712
let name = symbol.name;
713
let existing = find_direct(name);
714
715
if existing? then
716
// Argument-count overloading: a Classy may join an
717
// existing Classy (or TYPE_GROUP) under the same name as
718
// long as no member already occupies its generic-argument
719
// count. `class Foo is` and `class Foo[T] is` form a
720
// TYPE_GROUP holding both.
721
let new_classy = cast Classy?(symbol);
722
723
if new_classy? then
724
let existing_group = cast TYPE_GROUP?(existing);
725
726
if existing_group? then
727
if existing_group.find_by_generic_arguments_count(new_classy.argument_names.count)? then
728
CONTAINER.instance.logger.error(location, "redefining symbol {symbol.name} originally defined at {existing.location}");
729
CONTAINER.instance.logger.error(existing.location, "symbol {symbol.name} is redefined at {location}");
730
731
return;
732
fi
733
734
existing_group.add(new_classy);
735
736
if symbol_definition_listener? then
737
symbol_definition_listener.add_symbol_definition(location, symbol);
738
fi
739
740
return;
741
fi
742
743
let existing_classy = cast Classy?(existing);
744
745
if existing_classy? /\ existing_classy.argument_names.count != new_classy.argument_names.count then
746
let group = TYPE_GROUP(existing.location, self, name);
747
748
group.add(existing_classy);
749
group.add(new_classy);
750
751
if symbol_definition_listener? then
752
symbol_definition_listener.add_symbol_definition(location, symbol);
753
fi
754
755
_symbols[name] = group;
756
757
return;
758
fi
759
fi
760
761
CONTAINER.instance.logger.error(location, "redefining symbol {symbol.name} originally defined at {existing.location}");
762
CONTAINER.instance.logger.error(existing.location, "symbol {symbol.name} is redefined at {location}");
763
764
return;
765
fi
766
767
if symbol_definition_listener? then
768
symbol_definition_listener.add_symbol_definition(location, symbol);
769
fi
770
771
_symbols[name] = symbol;
772
si
773
774
declare_undefined(location: LOCATION, kind: string, name: string) -> UNDEFINED is
775
CONTAINER.instance.logger.error(location, "cannot declare {kind} here");
776
777
return UNDEFINED(location, self, name);
778
si
779
780
declare_namespace(location: LOCATION, name: string, `namespace: NAMESPACE, symbol_definition_listener: SymbolDefinitionListener?) is
781
declare_undefined(location, "namespace", name);
782
si
783
784
declare_class(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
785
declare_undefined(location, "class", name);
786
787
declare_trait(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
788
declare_undefined(location, "trait", name);
789
790
declare_struct(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
791
declare_undefined(location, "struct", name);
792
793
declare_union(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
794
declare_undefined(location, "union", name);
795
796
declare_variant(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
797
declare_undefined(location, "variant", name);
798
799
declare_type(location: LOCATION, name: string, index: int, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
800
declare_undefined(location, "type", name);
801
802
declare_enum(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
803
declare_undefined(location, "enum", name);
804
805
declare_enum_member(location: LOCATION, name: string, value: string?, symbol_definition_listener: SymbolDefinitionListener?) is
806
declare_undefined(location, "enum member", name);
807
si
808
809
declare_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
810
declare_undefined(location, "closure", name);
811
812
declare_async_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
813
declare_undefined(location, "async closure", name);
814
815
declare_innate(location: LOCATION, name: string, innate_name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
816
declare_undefined(location, "innate", name);
817
818
declare_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
819
declare_undefined(location, "function", name);
820
821
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 =>
822
declare_undefined(location, "generator function", name);
823
824
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 =>
825
declare_undefined(location, "async function", name);
826
827
declare_variable(location: LOCATION, name: string, is_static: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
828
declare_undefined(location, "variable", name);
829
830
declare_property(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, is_assignable: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
831
declare_undefined(location, "property", name);
832
833
declare_label(location: LOCATION, name: string, symbol_definition_listener: SymbolDefinitionListener?) is
834
declare_undefined(location, "label", name);
835
si
836
837
declare_function_group(location: LOCATION, function: Function, symbol_definition_listener: SymbolDefinitionListener?) is
838
let name = function.name;
839
let existing = find_direct(name);
840
let function_group: Symbols.FUNCTION_GROUP mut;
841
842
if existing? then
843
if !isa Symbols.FUNCTION_GROUP(existing) then
844
CONTAINER.instance.logger.error(location, "redefining symbol {function.name} originally defined at {existing.location}");
845
CONTAINER.instance.logger.error(existing.location, "symbol {function.name} is redefined at {location}");
846
847
return;
848
fi
849
850
function_group = existing;
851
else
852
function_group = Symbols.FUNCTION_GROUP(location, self, name);
853
_symbols[name] = function_group;
854
fi
855
856
if symbol_definition_listener? then
857
symbol_definition_listener.add_symbol_definition(location, function);
858
fi
859
860
function_group.add(function);
861
si
862
863
add_member(member: Symbol) -> bool is
864
let name = member.name;
865
let journal = INHERITANCE_JOURNAL.current;
866
867
if _symbols.contains_key(name) then
868
869
let existing = _symbols[name]!;
870
871
if existing == member then
872
return true;
873
fi
874
875
if isa FUNCTION_GROUP(existing) then
876
if isa Function(member) then
877
existing.add(member);
878
879
if journal? then
880
journal.record(InheritanceOp.GROUP_MEMBER_ADDED(existing, member));
881
fi
882
elif !member.is_reflected \/ !existing.is_reflected then
883
throw Exception("cannot add function {member} over the top of non function member {existing}");
884
fi
885
886
return true;
887
elif isa Function(existing) then
888
if isa Function(member) then
889
let fg = FUNCTION_GROUP(location, self, name);
890
891
fg.add(existing);
892
fg.add(member);
893
894
_symbols[name] = fg;
895
896
if journal? then
897
journal.record(InheritanceOp.MEMBER_REPLACED(self, name, existing));
898
fi
899
elif !member.is_reflected \/ !existing.is_reflected then
900
throw Exception("cannot add function {member} over the top of non function member {existing}");
901
fi
902
903
return true;
904
elif isa TYPE_GROUP(existing) then
905
if isa Classy(member) /\ !existing.find_by_generic_arguments_count(member.argument_names.count)? then
906
existing.add(member);
907
908
if journal? then
909
journal.record(InheritanceOp.TYPE_GROUP_MEMBER_ADDED(existing, member));
910
fi
911
912
return true;
913
fi
914
915
return false;
916
elif isa Classy(existing) then
917
let new_classy = cast Classy?(member);
918
919
if new_classy? /\ existing.argument_names.count != new_classy.argument_names.count then
920
let group = TYPE_GROUP(location, self, name);
921
922
group.add(existing);
923
group.add(new_classy);
924
925
_symbols[name] = group;
926
927
if journal? then
928
journal.record(InheritanceOp.MEMBER_REPLACED(self, name, existing));
929
fi
930
931
return true;
932
fi
933
934
return false;
935
elif !member.is_reflected \/ !existing.is_reflected then
936
throw System.Exception("cannot add non-function {member} over the top of non-function member {existing}");
937
fi
938
939
// FIXME: specific error?
940
941
return false;
942
fi
943
944
if isa Function(member) then
945
let fg = FUNCTION_GROUP(location, self, name);
946
947
fg.add(member);
948
949
_symbols[name] = fg;
950
else
951
_symbols[name] = member;
952
fi
953
954
if journal? then
955
journal.record(InheritanceOp.MEMBER_ADDED(self, name));
956
fi
957
958
return true;
959
si
960
si
961
962
class NONE: Symbol is
963
_instance: NONE? static;
964
965
instance: NONE static is
966
if !_instance? then
967
_instance = NONE();
968
fi
969
970
return _instance;
971
si
972
973
init() is
974
super.init(LOCATION.internal, null, "!!!");
975
si
976
si
977
978
class UNDEFINED: Symbol, DeclarationContext, Types.Typed is
979
type: Type? => Types.ERROR();
980
981
describe(context: DESCRIBE_CONTEXT) -> SignaturePart =>
982
PARTS.literal("undefined");
983
984
init(location: LOCATION, owner: Scope, name: string) is
985
super.init(location, owner, name);
986
si
987
988
declare_undefined(location: LOCATION, kind: string, name: string) -> UNDEFINED is
989
CONTAINER.instance.logger.error(location, "cannot declare {kind} here");
990
991
return UNDEFINED(location, self, name);
992
si
993
994
declare_namespace(location: LOCATION, name: string, `namespace: NAMESPACE, symbol_definition_listener: SymbolDefinitionListener?) is
995
declare_undefined(location, "namespace", name);
996
si
997
998
declare_class(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
999
declare_undefined(location, "class", name);
1000
1001
declare_trait(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1002
declare_undefined(location, "trait", name);
1003
1004
declare_struct(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1005
declare_undefined(location, "struct", name);
1006
1007
declare_union(location: LOCATION, span: LOCATION, name: string, arguments: Collections.List[string], enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1008
declare_undefined(location, "union", name);
1009
1010
declare_variant(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1011
declare_undefined(location, "variant", name);
1012
1013
declare_type(location: LOCATION, name: string, index: int, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1014
declare_undefined(location, "type", name);
1015
1016
declare_enum(location: LOCATION, span: LOCATION, name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1017
declare_undefined(location, "enum", name);
1018
1019
declare_enum_member(location: LOCATION, name: string, value: string?, symbol_definition_listener: SymbolDefinitionListener?) is
1020
declare_undefined(location, "enum member", name);
1021
si
1022
1023
declare_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1024
declare_undefined(location, "closure", name);
1025
1026
declare_async_closure(location: LOCATION, name: string, owner: Scope, enclosing: Scope, is_recursive: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1027
declare_undefined(location, "async closure", name);
1028
1029
declare_innate(location: LOCATION, name: string, innate_name: string, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1030
declare_undefined(location, "innate", name);
1031
1032
declare_function(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, has_body: bool, enclosing: Scope, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1033
declare_undefined(location, "function", name);
1034
1035
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 =>
1036
declare_undefined(location, "generator function", name);
1037
1038
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 =>
1039
declare_undefined(location, "async function", name);
1040
1041
declare_variable(location: LOCATION, name: string, is_static: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1042
declare_undefined(location, "variable", name);
1043
1044
declare_property(location: LOCATION, span: LOCATION, name: string, is_static: bool, is_private: bool, is_assignable: bool, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol =>
1045
declare_undefined(location, "undefine", name);
1046
1047
declare_label(location: LOCATION, name: string, symbol_definition_listener: SymbolDefinitionListener?) is
1048
declare_undefined(location, "label", name);
1049
si
1050
si
1051
1052
class ScopedWithEnclosingScope: Scoped abstract is
1053
enclosing_scope: Scope?;
1054
1055
init(location: LOCATION, owner: Scope, name: string, enclosing_scope: Scope?) is
1056
super.init(location, owner, name);
1057
1058
self.enclosing_scope = enclosing_scope;
1059
si
1060
1061
find_enclosing_only(name: string) -> Symbol? is
1062
if enclosing_scope? then
1063
return enclosing_scope.find_enclosing(name);
1064
fi
1065
1066
return null;
1067
si
1068
1069
find_enclosing(name: string) -> Symbol? is
1070
let result = find_direct(name);
1071
1072
if result? then
1073
return result;
1074
else
1075
return find_enclosing_only(name);
1076
fi
1077
si
1078
1079
find_enclosing_only_matches(prefix: string, matches: Collections.MutableMap[string, Symbol]) is
1080
if enclosing_scope? then
1081
enclosing_scope.find_enclosing_matches(prefix, matches);
1082
fi
1083
si
1084
1085
find_enclosing_matches(prefix: string, matches: Collections.MutableMap[string, Symbol]) is
1086
find_direct_matches(prefix, matches);
1087
find_enclosing_only_matches(prefix, matches);
1088
si
1089
si
1090
si