Skip to content
← Back

src/syntax/process/declare-members/declare_members.ghul

1
namespace Syntax.Process is
2
use Logging
3
use Source
4
use Trees
5
6
// Declares everything below type level: functions, properties, fields,
7
// enum members, and the block scopes, locals and closures inside
8
// bodies. Runs after resolve-uses - the declare-symbols pass declares
9
// only the type-level skeleton (namespaces, types, variants, type
10
// parameters), so by the time members are declared every import is
11
// bound and an impl/partial block's target name can be reached through
12
// a use import and declared anywhere.
13
//
14
// The inherited ScopedVisitor handlers enter the scopes declare-symbols
15
// associated with the type-level nodes; the overrides here declare the
16
// member-level symbols into them. impl and partial blocks are handled
17
// in place: the target resolves against the block's write site, and the
18
// block's members are declared into it through an injection scope.
19
class DECLARE_MEMBERS: ScopedVisitor is
20
_logger: Logger
21
_symbol_definition_listener: Semantic.SymbolDefinitionListener
22
23
// Labels seen since the last loop body scope was opened; the
24
// LABELLED pre pushes and the wrapped loop's pre declares into
25
// that scope (see declare_members_bodies.ghul).
26
_pending_labels: Collections.LIST[Trees.Identifiers.Identifier]
27
_symbol_use_locations: Semantic.SYMBOL_USE_LOCATIONS
28
_local_id_generator: IR.LOCAL_ID_GENERATOR
29
30
_anon_index: int
31
_pragma_scope_stack: PRAGMA_SCOPE_STACK
32
_generic_argument_declarer: GENERIC_ARGUMENT_DECLARER
33
34
init(
35
logger: Logger,
36
symbol_table: Semantic.SYMBOL_TABLE,
37
namespaces: Semantic.NAMESPACES,
38
symbol_definition_listener: Semantic.SymbolDefinitionListener,
39
symbol_use_locations: Semantic.SYMBOL_USE_LOCATIONS,
40
local_id_generator: IR.LOCAL_ID_GENERATOR
41
) is
42
super.init(logger, symbol_table, namespaces)
43
44
_logger = logger
45
_symbol_definition_listener = symbol_definition_listener
46
_symbol_use_locations = symbol_use_locations
47
_local_id_generator = local_id_generator
48
49
_pragma_scope_stack = PRAGMA_SCOPE_STACK()
50
_generic_argument_declarer = GENERIC_ARGUMENT_DECLARER(logger, symbol_table, symbol_definition_listener)
51
52
_pending_labels = Collections.LIST[Trees.Identifiers.Identifier]()
53
si
54
55
apply(node: Node) is
56
assert _pragma_scope_stack.is_balanced
57
58
node.walk(self)
59
60
assert _pragma_scope_stack.is_balanced
61
si
62
63
next_anon_name() -> string is
64
let result = "$anon_{_anon_index}"
65
_anon_index = _anon_index + 1
66
return result
67
si
68
69
// `_` is a discard placeholder: every occurrence
70
// gets its own unique slot so the redefinition check doesn't
71
// fire and there's no shared name for code to read from. Used
72
// in `let _ = expr`, tuple destructure (`let (_, _, z) = ...`),
73
// and lambda parameters.
74
next_discard_name() -> string is
75
let result = "$discard_{_anon_index}"
76
_anon_index = _anon_index + 1
77
return result
78
si
79
80
// Name of the single physical parameter slot backing a
81
// destructured formal argument - the parameter itself has no
82
// user-written name, only its leaves do.
83
next_argument_group_name() -> string is
84
let result = "$arg_{_anon_index}"
85
_anon_index = _anon_index + 1
86
return result
87
si
88
89
pre(pragma: Definitions.PRAGMA) -> bool is
90
_pragma_scope_stack.enter(pragma.pragma)
91
92
return false
93
si
94
95
visit(pragma: Definitions.PRAGMA) is
96
let p = pragma.pragma
97
98
let name = p.name.to_string()
99
100
let is_primitive = name =~ "IL.built_in_type"
101
102
if
103
is_primitive \/
104
name =~ "IL.name" \/
105
name =~ "IL.name.read" \/
106
name =~ "IL.name.assign"
107
then
108
if p.arguments.expressions.count != 1 then
109
_logger.error(p.arguments.location, "expected one argument")
110
return
111
fi
112
113
let argument = p.arguments.expressions[0]
114
115
if !isa Expressions.Literals.STRING(argument) then
116
_logger.error(p.arguments.location, "expected a string literal argument")
117
return
118
fi
119
120
let il_name = argument.value_string
121
122
// A name reaches metadata as written. Quoting was once
123
// how a name colliding with an IL keyword was spelled;
124
// now it would just become part of the name.
125
if il_name.index_of('\'') >= 0 then
126
_logger.error(
127
p.arguments.location, "an IL name cannot contain a quote")
128
129
return
130
fi
131
132
let definition mut = pragma.definition
133
134
while isa Definitions.PRAGMA(definition) do
135
definition = cast Definitions.PRAGMA(definition).definition
136
od
137
138
let symbol = symbol_for(definition)
139
140
if symbol? then
141
if isa Semantic.Symbols.Property(symbol) then
142
let property = symbol
143
144
if name =~ "IL.name.read" then
145
property.read_function_il_name_override = il_name
146
elif name =~ "IL.name.assign" then
147
property.assign_function_il_name_override = il_name
148
elif name =~ "IL.name" then
149
property.il_name_override = il_name
150
151
if !property.read_function_il_name_override? then
152
property.read_function_il_name_override = "get_{il_name}"
153
fi
154
155
if !property.assign_function_il_name_override? then
156
property.assign_function_il_name_override = "set_{il_name}"
157
fi
158
fi
159
160
return
161
fi
162
163
if is_primitive then
164
symbol.il_is_primitive_type = true
165
fi
166
167
symbol.il_name_override = il_name
168
fi
169
else
170
_pragma_scope_stack.leave(p)
171
fi
172
si
173
174
visit(`union: Definitions.UNION) is
175
// Pick the default variant now that every variant's fields
176
// have been declared: prefer one with the explicit-default
177
// flag; otherwise fall back to a sole variant whose own
178
// (non-inherited) field count is positive.
179
// Cross-assembly unions don't pass through here; they
180
// get `default_variant` set by
181
// `SYMBOL_FACTORY.materialize_variant` when it sees
182
// the `DEFAULT_VARIANT_ATTRIBUTE` marker on a reflected
183
// variant.
184
let union_symbol: Semantic.Symbols.UNION? mut = null
185
if isa Semantic.Symbols.UNION(current_scope) then
186
union_symbol = cast Semantic.Symbols.UNION(current_scope)
187
fi
188
189
if union_symbol? then
190
let explicit: Semantic.Symbols.VARIANT? mut = null
191
let explicit_count mut = 0
192
let sole_with_own_fields: Semantic.Symbols.VARIANT? mut = null
193
let with_own_fields_count mut = 0
194
195
for s in union_symbol.symbols do
196
if isa Semantic.Symbols.VARIANT(s) then
197
let v = cast Semantic.Symbols.VARIANT(s)
198
199
if v.is_default then
200
explicit = v
201
explicit_count = explicit_count + 1
202
fi
203
204
if v.own_field_count > 0 then
205
sole_with_own_fields = v
206
with_own_fields_count = with_own_fields_count + 1
207
fi
208
fi
209
od
210
211
if explicit_count == 1 then
212
union_symbol.default_variant = explicit
213
elif explicit_count == 0 /\ with_own_fields_count == 1 then
214
union_symbol.default_variant = sole_with_own_fields
215
fi
216
fi
217
218
leave_scope(`union)
219
si
220
221
pre(variant: Definitions.VARIANT) -> bool is
222
enter_scope(variant)
223
224
// Take charge of the walk so inherited-primary names and
225
// own-field declarations register on the variant scope
226
// interleaved in source position — positional destructure
227
// and field-description rendering both consult
228
// `_field_names` by index, so the order must match the
229
// synthesised init's argument order (which is taken from
230
// `variant.fields` in source order). Variables.VARIABLE.walk
231
// still skips inherited entries, so own fields go through
232
// the normal visit(VARIABLE) → declare_variable path and
233
// inherited entries are registered here directly.
234
let variant_scope: Semantic.Symbols.VARIANT? mut = null
235
if isa Semantic.Symbols.VARIANT(current_declaration_context) then
236
variant_scope = cast Semantic.Symbols.VARIANT?(current_declaration_context)!
237
fi
238
239
for f in variant.fields do
240
if f.is_inherited_primary then
241
if variant_scope? then
242
if let f.name?, field_name = name.name then
243
variant_scope.register_inherited_primary_field_name(field_name)
244
fi
245
fi
246
else
247
f.walk(self)
248
fi
249
od
250
251
variant.body.walk(self)
252
253
return true
254
si
255
256
// An impl/partial block declares its members into an
257
// already-declared target type. The target resolves here, at the
258
// block's write site - after resolve-uses, so the name can come
259
// through a use import and the target can be declared anywhere.
260
// The block gets an injection scope rather than the target's
261
// scope directly, so that names its members reference resolve at
262
// the write site while the target's members and type parameters
263
// stay visible first; the members are then declared by this
264
// visitor's ordinary member handlers.
265
pre(`partial: Definitions.PARTIAL) -> bool is
266
_enter_injection(
267
`partial,
268
"cannot find type {`partial.name.name} to add members to",
269
"cannot add members to imported type"
270
)
271
272
`partial.body.walk(self)
273
274
return true
275
si
276
277
pre(`impl: Definitions.IMPL) -> bool is
278
_enter_injection(
279
`impl,
280
"cannot find type {`impl.name.name} to implement an interface for",
281
"cannot implement an interface for imported type"
282
)
283
284
`impl.body.walk(self)
285
286
return true
287
si
288
289
_enter_injection(block: Definitions.Classy, cannot_find_message: string, imported_target_message: string) is
290
let target = cast Semantic.Symbols.Classy?(find_enclosing(block.name))
291
292
if !target? then
293
_logger.error(block.name.location, cannot_find_message)
294
associate_and_enter_scope(block, _rejecting_scope())
295
elif target.is_reflected then
296
// The CLR fixes a compiled type's members and interfaces at
297
// its definition, so only a type declared in this compilation
298
// can be reopened.
299
_logger.error(block.name.location, "{imported_target_message} {target.name}")
300
associate_and_enter_scope(block, _rejecting_scope())
301
else
302
// The target name is a reference to the target type, so
303
// record it: hover, rename and find-references all read
304
// these recorded uses.
305
_symbol_use_locations.add_symbol_use(block.name.right_location, cast Semantic.Symbols.Symbol(target))
306
307
if let block.name.qualifier? /\ isa Semantic.Symbols.Classy(target.owner) then
308
_symbol_use_locations.add_symbol_use(
309
qualifier.right_location,
310
cast Semantic.Symbols.Symbol(target.owner)
311
)
312
fi
313
314
associate_and_enter_scope(block, Semantic.INJECTION_SCOPE(target, current_scope))
315
fi
316
si
317
318
// When a block's target cannot be resolved to a same-assembly type,
319
// its members have nowhere valid to live. Route them into a scope
320
// that refuses them without another error each, since the target
321
// has already been reported, rather than cascading to "no scope
322
// found" downstream or declaring them as globals in the enclosing
323
// scope. A block scope
324
// still chains name lookups to the enclosing scope, so the block's
325
// own header references - an impl's interface name - resolve
326
// normally, as do the type names in each rejected member's own
327
// header.
328
_rejecting_scope() -> Semantic.Scope =>
329
Semantic.REJECTED_BLOCK_SCOPE(current_scope)
330
331
pre(enum_member: Definitions.ENUM_MEMBER) -> bool is
332
let value: string? mut = null
333
334
if enum_member.initializer? then
335
let i = enum_member.initializer
336
337
// Any other literal reaches metadata as a Constant row
338
// the enum's underlying type cannot hold, so it is
339
// rejected here rather than emitted. A NONE stands for
340
// an initializer the parser could not read, which it
341
// has already reported.
342
if isa Trees.Expressions.Literals.INTEGER(i) then
343
value = i.value_string
344
elif !isa Trees.Expressions.Literals.NONE(i) then
345
_logger.error(i.location, "enum member initializer must be an integer literal")
346
fi
347
fi
348
349
current_declaration_context.declare_enum_member(
350
enum_member.name.location,
351
enum_member.name.name,
352
value,
353
_symbol_definition_listener
354
)
355
return false
356
si
357
358
pre(function: Definitions.FUNCTION) -> bool is
359
// parse recovery can leave the declaration nameless;
360
// there is nothing to declare for it
361
let name = function.name
362
363
if !name? then
364
return true
365
fi
366
367
let is_innate = function.body? /\ isa Trees.Bodies.INNATE(function.body)
368
let is_static = function.modifiers.is_static
369
370
if is_static /\ name.name =~ "init" /\ function.arguments.count > 0 then
371
_logger.error(function.location, "a static constructor cannot take parameters")
372
fi
373
374
// An operator declared on a type takes its left operand as
375
// `self`, so its argument list holds the right operand alone.
376
// One declaring both operands type-checks where its name is
377
// in lexical scope, but the call it resolves to passes the
378
// right operand alone, so it can never be emitted. Declared
379
// undefined rather than as half an operator later passes
380
// would try to call.
381
let is_invalid_operator =
382
!is_static /\
383
current_instance_context? /\
384
Lexical.TOKENIZER.is_operator_name(name.name) /\
385
function.arguments.count > 1
386
387
if is_invalid_operator then
388
_logger.error(
389
function.location,
390
"an operator declared on a type takes one argument; its left operand is self",
391
function.location,
392
"help: declare it static to take both operands as arguments")
393
fi
394
395
let is_private = function.modifiers.is_private
396
397
// An underscore-prefixed method, or the accessor of an underscore-
398
// prefixed property (whose own $get_/$set_ name is not underscore-
399
// prefixed), is subject to the underscore access policy.
400
let is_underscore_method = name.name.starts_with('_') \/ function.is_underscore_scoped
401
402
let property: Semantic.Symbols.Property? mut = null
403
404
_local_id_generator.enter_function()
405
406
if function.for_property? then
407
let symbol = symbol_for(function.for_property)
408
409
assert symbol? else "function is accessor for property but no property found: {function.location}"
410
assert isa Semantic.Symbols.Property(symbol) else "function is accessor for property but associated symbol is not a property: {function.location}"
411
412
property = cast Semantic.Symbols.Property(symbol)
413
fi
414
415
if is_innate then
416
let `innate = cast Trees.Bodies.INNATE?(function.body)!
417
418
associate_and_enter_scope(
419
function,
420
current_declaration_context.declare_innate(
421
function.location,
422
name.name,
423
`innate.name.to_string(),
424
current_scope,_symbol_definition_listener
425
)
426
)
427
else
428
// Generator vs async detection. A body with `yield`
429
// (not inside a nested lambda) becomes a generator;
430
// a body with `await` (in this body, not in a nested
431
// lambda) becomes an async function.
432
//
433
// Either-or only — a body with both is diagnosed
434
// and falls back to generator classification.
435
let has_body = function.body? /\ !function.body.is_null
436
437
let body_has_yield =
438
has_body /\ YIELD_SCANNER().body_has_yield(function.body!)
439
440
let await_scanner = AWAIT_SCANNER()
441
if has_body then
442
await_scanner.scan(function.body!)
443
fi
444
445
let body_has_await = await_scanner.found
446
447
function.contains_let_await = body_has_await
448
function.is_void_async = body_has_await /\ !await_scanner.found_value_return
449
450
if body_has_yield /\ body_has_await then
451
_logger.error(
452
function.location,
453
"function cannot be both a generator and async"
454
)
455
fi
456
457
let is_generator = body_has_yield
458
let is_async = body_has_await /\ !is_generator
459
460
let symbol: Semantic.Symbols.Symbol mut
461
462
if is_invalid_operator then
463
// The rejecting scope below then keeps the header and
464
// body resolvable without leaving a callable operator
465
// for later passes to select. Built directly rather
466
// than through `declare_undefined`, whose own "cannot
467
// declare operator here" is not what is wrong here.
468
symbol = Semantic.Symbols.UNDEFINED(name.location, current_scope, name.name)
469
elif is_generator then
470
symbol = current_declaration_context.declare_generator_function(
471
name.location,
472
function.location,
473
name.name,
474
is_static,
475
is_private,
476
has_body,
477
current_scope,
478
_symbol_definition_listener)
479
elif is_async then
480
symbol = current_declaration_context.declare_async_function(
481
name.location,
482
function.location,
483
name.name,
484
is_static,
485
is_private,
486
has_body,
487
current_scope,
488
_symbol_definition_listener)
489
else
490
symbol = current_declaration_context.declare_function(
491
name.location,
492
function.location,
493
name.name,
494
is_static,
495
is_underscore_method,
496
has_body,
497
function.for_property?,
498
current_scope,
499
_symbol_definition_listener)
500
fi
501
502
// A rejected declaration has no function symbol to scope
503
// its arguments and body against. Entering it anyway makes
504
// every name in the header and body report as not found on
505
// top of the rejection; a rejecting scope keeps them
506
// resolvable.
507
if isa Semantic.Symbols.UNDEFINED(symbol) then
508
associate_and_enter_scope(function, _rejecting_scope())
509
else
510
associate_and_enter_scope(function, symbol)
511
fi
512
fi
513
514
let symbol = symbol_for(function)
515
516
if symbol? /\ isa Semantic.Symbols.Function(symbol) then
517
let function_symbol = symbol
518
519
let pure_owner = current_instance_context
520
521
if function.modifiers.is_pure then
522
function_symbol.mark_declared_pure()
523
elif
524
(!function.body? \/ function.body.is_null) /\
525
!function.modifiers.is_static /\
526
!function.is_assign_accessor /\
527
pure_owner? /\
528
pure_owner.is_pure
529
then
530
// A bodiless instance member of a pure type is a
531
// contract rather than an implementation, so it
532
// carries the declaration: implementors then inherit
533
// the obligation through the pure-override contract.
534
function_symbol.mark_declared_pure()
535
fi
536
537
if function.modifiers.is_stable then
538
if function.for_property? then
539
// The synthesized accessors copy the property's
540
// modifier list; only the read accessor carries
541
// the contract — the setter's copy is inert.
542
if function.arguments.variables.count == 0 then
543
function_symbol.mark_declared_stable()
544
fi
545
else
546
_logger.error(function.modifiers.location, "stable is only valid on a property")
547
fi
548
fi
549
550
if let operation = _pragma_scope_stack.intrinsic_operation then
551
function_symbol.intrinsic_operation = operation
552
fi
553
554
if function.is_top_level_entry then
555
function_symbol.is_top_level_entry = true
556
fi
557
558
// Record the primary constructor on its owning type so a
559
// hover on the declaration can show the primary parameters.
560
if
561
function.is_primary_constructor /\
562
isa Semantic.Symbols.Classy(function_symbol.owner)
563
then
564
(cast Semantic.Symbols.Classy?(function_symbol.owner)!).primary_constructor = function_symbol
565
fi
566
567
// Record on the owning type that it has its own
568
// zero-argument constructor — needed early (before
569
// constructor signatures are resolved) to check a
570
// `init` type-parameter constraint.
571
if
572
name.name =~ "init" /\
573
function.arguments.variables.count == 0 /\
574
isa Semantic.Symbols.Classy(function_symbol.owner)
575
then
576
(cast Semantic.Symbols.Classy?(function_symbol.owner)!).has_parameterless_constructor = true
577
fi
578
579
// A user-written body-less instance method on a class
580
// makes that class implicitly abstract — the user
581
// meant the method as a contract for subclasses to
582
// implement, and a bare instance would throw if the
583
// method were ever invoked. Skip property accessors,
584
// since a write-only property leaves the synthesised
585
// getter body-less without the user intending the
586
// class to be abstract; skip `init` (that's a
587
// separate concern handled by primary-ctor rewriting)
588
// and static methods (statics don't make instances
589
// abstract).
590
let body_is_null =
591
!function.body? \/ function.body.is_null
592
593
function_symbol.is_declared_without_body = body_is_null
594
595
if
596
body_is_null /\
597
!function.for_property? /\
598
!is_static /\
599
name.name !~ "init" /\
600
isa Semantic.Symbols.CLASS(function_symbol.owner)
601
then
602
(cast Semantic.Symbols.CLASS(function_symbol.owner)).mark_has_bodyless_method()
603
fi
604
605
if property? then
606
function_symbol.mark_synthesized()
607
608
if function.arguments.variables.count == 0 then
609
property.read_function = function_symbol
610
611
// an auto property's synthesized getter reads
612
// the backing field and nothing else, so it is
613
// store-free by construction
614
if function.for_property? /\ function.for_property.is_auto_property then
615
function_symbol.mark_backing_read()
616
fi
617
618
if property.read_function_il_name_override? then
619
function_symbol.il_name_override = property.read_function_il_name_override
620
fi
621
else
622
property.assign_function = function_symbol
623
624
if property.assign_function_il_name_override? then
625
function_symbol.il_name_override = property.assign_function_il_name_override
626
fi
627
fi
628
fi
629
630
if function.generic_arguments.count > 0 then
631
let generic_arguments = _generic_argument_declarer.declare_generic_arguments(function.generic_arguments)
632
633
function_symbol.generic_argument_names = generic_arguments.names
634
function_symbol.generic_arguments = generic_arguments.types
635
function_symbol.is_generic = true
636
fi
637
638
function_symbol.start_declaring_arguments()
639
function.arguments.walk(self)
640
function_symbol.end_declaring_arguments()
641
elif isa Semantic.BLOCK_SCOPE(current_declaration_context) then
642
// The declaration was rejected above, so there is no
643
// function symbol to open a declaring-arguments window
644
// against — but the parameters still need somewhere to
645
// resolve, or every reference downstream reports as
646
// missing on top of the rejection. Declare them into the
647
// rejecting scope entered above instead.
648
function.arguments.walk(self)
649
fi
650
651
if function.body? then
652
function.body.walk(self)
653
fi
654
655
return true
656
si
657
658
visit(function: Definitions.FUNCTION) is
659
_local_id_generator.leave_function()
660
661
leave_scope(function)
662
si
663
664
// Declare just a function's body — its block scopes, locals and
665
// closures — reusing the body-handling visit methods. The caller
666
// must already have the cursor positioned at the function's
667
// (retained) scope. Used by the incremental body re-walk, which
668
// keeps the interface symbols and re-declares only the edited
669
// bodies; the interface is never re-walked here, so the pass's
670
// non-idempotency on declarations is not exercised.
671
declare_body(function: Definitions.FUNCTION) is
672
if !function.body? then
673
return
674
fi
675
676
_local_id_generator.enter_function()
677
678
function.body!.walk(self)
679
680
_local_id_generator.leave_function()
681
si
682
683
pre(property: Definitions.PROPERTY) -> bool is
684
// parse recovery can leave the declaration nameless;
685
// there is nothing to declare for it
686
let name = property.name
687
688
if !name? then
689
return true
690
fi
691
692
let is_static = property.modifiers.is_static
693
let instance_context = current_instance_context
694
695
if property.modifiers.is_field then
696
// is_field implies the storage class modifier is present
697
if !instance_context? \/ instance_context.is_trait then
698
_logger.error(property.modifiers.storage_class!.location, "field is not valid here")
699
700
// Only a trait recovers as a property. Outside any type
701
// the declaration stays field-shaped and is declared as
702
// a variable below: accessor synthesis has already run
703
// and skipped it as a field, so clearing the storage
704
// class here would declare a property with no accessors
705
// and every read of it would fail with "does not have a
706
// read function" - a crash on top of the error already
707
// reported.
708
if instance_context? then
709
property.modifiers.clear_storage_class()
710
fi
711
elif property.read_body? \/ property.assign_body? \/ property.assign_argument? then
712
_logger.error(property.modifiers.storage_class!.location, "field cannot have a body")
713
fi
714
fi
715
716
if
717
property.modifiers.is_field \/ (
718
name.name.starts_with('_') /\
719
!property.read_body? /\
720
!property.assign_body?
721
)
722
then
723
if property.modifiers.is_stable then
724
_logger.error(property.modifiers.location, "stable is only valid on a property")
725
fi
726
727
let symbol = current_declaration_context.declare_variable(name.location, name.name, is_static, _symbol_definition_listener)
728
729
associate_node_with_scope(property, symbol)
730
731
else
732
let owner_is_trait = instance_context? /\ instance_context.is_trait
733
734
let is_assignable = !property.read_body? \/ property.assign_argument?
735
let is_private = !property.modifiers.is_public /\ !owner_is_trait
736
737
let symbol =
738
current_declaration_context
739
.declare_property(
740
name.location,
741
property.location,
742
name.name,
743
is_static,
744
is_private,
745
is_assignable,
746
_symbol_definition_listener
747
)
748
749
if property.read_body == null /\ property.assign_body == null then
750
current_declaration_context.declare_variable(
751
name.location,
752
"${name.name}",
753
is_static,
754
_symbol_definition_listener)
755
.mark_synthesized()
756
fi
757
758
// the rewriter that synthesized the accessors decided
759
// auto-ness before any body existed; carry its answer
760
// onto the symbol, where flow narrowing keys on it
761
if property.is_auto_property /\ isa Semantic.Symbols.Property(symbol) then
762
(cast Semantic.Symbols.Property(symbol)).is_auto = true
763
fi
764
765
// A property with a getter also marks the accessor in
766
// the function path; this mark is the only carrier for
767
// a body-less declaration (a trait requirement).
768
if property.modifiers.is_stable /\ isa Semantic.Symbols.Property(symbol) then
769
(cast Semantic.Symbols.Property(symbol)).mark_declared_stable()
770
fi
771
772
associate_node_with_scope(property, symbol)
773
fi
774
775
return true
776
si
777
778
pre(indexer: Definitions.INDEXER) -> bool is
779
// ???
780
781
return true
782
si
783
si
784
si