Skip to content
← Back

src/semantic/symbols/property.ghul

1
namespace Semantic.Symbols is
2
use System.Exception;
3
use System.Text.StringBuilder;
4
5
use Logging;
6
use Source;
7
8
use IR.Values.Value;
9
10
use Types.Type;
11
12
class Property: Symbol, Types.SettableTyped abstract is
13
_overriders: Collections.MutableList[Symbol]?;
14
_overridees: Collections.MutableList[Symbol]?;
15
16
span: LOCATION;
17
type: Type?;
18
19
// Incremental body re-walk override: also shift the declaration
20
// span when the retained interface symbol is relocated.
21
set_span(span_location: LOCATION) is
22
span = span_location;
23
si
24
25
set_type(value: Type) is type = value; si
26
27
short_description: string => "{name}: {if type? then type!.short_description else "?" fi}";
28
symbol_kind: SymbolKind => SymbolKind.PROPERTY;
29
completion_kind: CompletionKind => CompletionKind.PROPERTY;
30
is_private: bool;
31
is_assignable: bool public;
32
is_workspace_visible: bool => !name.starts_with('_');
33
34
read_function: Function? public;
35
read_function_il_name_override: string? public;
36
37
assign_function: Function? public;
38
assign_function_il_name_override: string? public;
39
40
overriders: Collections.Iterable[Symbol]? => _overriders;
41
overridees: Collections.Iterable[Symbol]? => _overridees;
42
43
has_overriders: bool => _overriders? /\ _overriders.count > 0;
44
45
// Prefixes the description's trailing kind comment when the
46
// getter is proven store-free — diagnostic surfacing only,
47
// deliberately inside the comment so it does not read as
48
// source syntax.
49
pure_prefix: string =>
50
if read_function? /\ read_function.is_store_free then
51
"pure "
52
else
53
""
54
fi;
55
56
// Shared body for the three concrete Property kinds. Delegates
57
// to Symbol._describe_typed so a narrowed property (path
58
// narrowing over a `T?` getter) surfaces the same
59
// `declared → narrowed` display a variable use gets.
60
_describe_property(context: DESCRIBE_CONTEXT) -> SignaturePart =>
61
_describe_typed(context, PARTS.name(self), type);
62
63
init(location: LOCATION, span: LOCATION, owner: Scope, name: string, is_assignable: bool, is_private: bool) is
64
super.init(location, owner, name);
65
66
self.span = span;
67
self.is_assignable = is_assignable;
68
self.is_private = is_private;
69
si
70
71
add_overrider(overrider: Symbol mut) is
72
let rsf = root_specialized_from;
73
if rsf != self then
74
rsf.add_overrider(overrider);
75
return;
76
fi
77
78
let overriders mut = _overriders;
79
80
if !overriders? then
81
overriders = Collections.LIST[Symbol]();
82
_overriders = overriders;
83
fi
84
85
overrider = overrider.root_specialized_from;
86
87
if overriders.contains(overrider) then
88
return;
89
fi
90
91
overriders.add(overrider);
92
93
if let journal = INHERITANCE_JOURNAL.current then
94
journal.record(InheritanceOp.PROPERTY_OVERRIDER_ADDED(self, overrider));
95
fi
96
si
97
98
remove_overrider(overrider: Symbol) is
99
let rsf = root_specialized_from;
100
if rsf != self then
101
rsf.remove_overrider(overrider);
102
return;
103
fi
104
105
let overriders = _overriders;
106
107
if overriders? then
108
overriders.remove(overrider.root_specialized_from);
109
fi
110
si
111
112
add_overridee(overridee: Symbol mut) is
113
let rsf = root_specialized_from;
114
if rsf != self then
115
rsf.add_overridee(overridee);
116
return;
117
fi
118
119
let overridees mut = _overridees;
120
121
if !overridees? then
122
overridees = Collections.LIST[Symbol]();
123
_overridees = overridees;
124
fi
125
126
overridee = overridee.root_specialized_from;
127
128
if overridees.contains(overridee) then
129
return;
130
fi
131
132
overridees.add(overridee);
133
134
if let journal = INHERITANCE_JOURNAL.current then
135
journal.record(InheritanceOp.PROPERTY_OVERRIDEE_ADDED(self, overridee));
136
fi
137
si
138
139
remove_overridee(overridee: Symbol) is
140
let rsf = root_specialized_from;
141
if rsf != self then
142
rsf.remove_overridee(overridee);
143
return;
144
fi
145
146
let overridees = _overridees;
147
148
if overridees? then
149
overridees.remove(overridee.root_specialized_from);
150
fi
151
si
152
153
specialize(type_map: Collections.Map[string,Type], owner: GENERIC) -> Symbol is
154
let result = cast Property?(self.memberwise_clone())!;
155
156
result.specialized_from = self;
157
158
if type? then
159
result.type = type.specialize(type_map);
160
fi
161
162
if read_function? then
163
result.read_function = read_function.specialize_function(type_map, owner);
164
fi
165
166
if assign_function? then
167
result.assign_function = assign_function.specialize_function(type_map, owner);
168
fi
169
170
// Attribute the specialized property to the constructed generic so
171
// its owner renders with the actual type arguments
172
// (`Iterator[char].current`, not `Iterator[T].current`), matching
173
// how fields and methods specialize.
174
result.owner = owner;
175
176
return result;
177
si
178
179
gen_reference(buffer: StringBuilder) => throw System.NotImplementedException("properties cannot be referenced directly");
180
gen_definition_header(buffer: StringBuilder) is
181
buffer.append(".property ");
182
183
gen_access(buffer);
184
185
gen_flags(buffer);
186
187
type!.gen_type(buffer);
188
189
gen_name(buffer);
190
191
buffer.append("() {{ ");
192
193
if let self.read_function? then
194
buffer.append(".get ");
195
read_function.gen_reference_for_property(buffer);
196
fi
197
198
buffer.append(' ');
199
200
if let self.assign_function? then
201
buffer.append(".set ");
202
assign_function.gen_reference_for_property(buffer);
203
fi
204
205
buffer.append('}');
206
si
207
208
gen_access(buffer: StringBuilder) is
209
si
210
211
gen_flags(buffer: StringBuilder) is
212
si
213
214
to_string() -> string is
215
let result = System.Text.StringBuilder();
216
217
try
218
result.append(IoC.CONTAINER.instance.name_display.name_for(self));
219
result.append(": ");
220
result.append(type);
221
222
return result.to_string();
223
catch ex: Exception
224
return "[garbled property: {result}]";
225
yrt
226
si
227
si
228
229
class INSTANCE_PROPERTY: Property is
230
describe(context: DESCRIBE_CONTEXT) -> SignaturePart =>
231
_describe_property(context);
232
233
describe_kind(context: DESCRIBE_CONTEXT) -> string? =>
234
"{pure_prefix}instance property";
235
236
is_instance: bool => true;
237
238
init(location: LOCATION, span: LOCATION, owner: Scope, name: string, is_assignable: bool, is_private: bool) is
239
super.init(location, span, owner, name, is_assignable, is_private);
240
si
241
242
load(location: LOCATION, from: Value?, loader: SYMBOL_LOADER) -> Value => loader.load_instance_property(location, from, self);
243
244
store(location: LOCATION, from: Value?, value: Value, loader: SYMBOL_LOADER, is_initialize: bool) -> Value => loader.store_instance_property(location, from, self, value);
245
246
gen_flags(buffer: StringBuilder) is
247
buffer.append("instance callconv(8) ");
248
si
249
si
250
251
class STATIC_PROPERTY: Property is
252
describe(context: DESCRIBE_CONTEXT) -> SignaturePart =>
253
_describe_property(context);
254
255
describe_kind(context: DESCRIBE_CONTEXT) -> string? =>
256
"{pure_prefix}class property";
257
258
init(location: LOCATION, span: LOCATION, owner: Scope, name: string, is_assignable: bool, is_private: bool) is
259
super.init(location, span, owner, name, is_assignable, is_private);
260
si
261
262
load(location: LOCATION, from: Value?, loader: SYMBOL_LOADER) -> Value => loader.load_static_property(location, self);
263
264
store(location: LOCATION, from: Value?, value: Value, loader: SYMBOL_LOADER, is_initialize: bool) -> Value => loader.store_static_property(location, self, value);
265
266
gen_flags(buffer: StringBuilder) is
267
buffer.append("callconv(8) ");
268
si
269
si
270
271
class GLOBAL_PROPERTY: Property is
272
describe(context: DESCRIBE_CONTEXT) -> SignaturePart =>
273
_describe_property(context);
274
275
describe_kind(context: DESCRIBE_CONTEXT) -> string? =>
276
"{pure_prefix}global property";
277
278
init(location: LOCATION, span: LOCATION, owner: Scope, name: string, is_assignable: bool) is
279
super.init(location, span, owner, name, is_assignable, false);
280
si
281
282
load(location: LOCATION, from: Value?, loader: SYMBOL_LOADER) -> Value => loader.load_global_property(location, self);
283
284
store(location: LOCATION, from: Value?, value: Value, loader: SYMBOL_LOADER, is_initialize: bool) -> Value => loader.store_global_property(location, self, value);
285
286
gen_flags(buffer: StringBuilder) is
287
buffer.append("callconv(8) ");
288
si
289
si
290
si