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