Skip to content
← Back

src/semantic/dotnet/type_wrapper.ghul

1
namespace Semantic.DotNet is
2
use IO.Std;
3
4
use TYPE = System.Type;
5
use Collections.LIST;
6
use Collections.List;
7
8
use Source.LOCATION;
9
10
use Types.Type;
11
12
class TYPE_WRAPPER: Types.NAMED is
13
_symbol_table: SYMBOL_TABLE;
14
_dotnet_type: TYPE;
15
16
symbol: Symbols.Symbol is
17
// _symbol is lazily materialized on first access
18
@suppress("presence-test-non-optional")
19
if !_symbol? then
20
materialize();
21
fi
22
23
return _symbol;
24
si
25
26
init(
27
symbol_table: SYMBOL_TABLE,
28
dotnet_type: TYPE
29
) is
30
super.init(null);
31
_symbol_table = symbol_table;
32
_dotnet_type = dotnet_type;
33
si
34
35
materialize() is
36
_symbol = _symbol_table.get_symbol(_dotnet_type)!;
37
si
38
si
39
40
class GENERIC_TYPE_WRAPPER: Types.GENERIC is
41
_symbol_table: SYMBOL_TABLE;
42
_type_mapper: TYPE_MAPPER;
43
_dotnet_type: TYPE;
44
45
symbol: Symbols.Symbol is
46
// _symbol is lazily materialized on first access
47
@suppress("presence-test-non-optional")
48
if !_symbol? then
49
materialize();
50
fi
51
52
return _symbol;
53
si
54
55
init(
56
symbol_table: SYMBOL_TABLE,
57
type_mapper: TYPE_MAPPER,
58
dotnet_type: TYPE
59
) is
60
_symbol_table = symbol_table;
61
_type_mapper = type_mapper;
62
_dotnet_type = dotnet_type;
63
si
64
65
materialize() is
66
let s = _symbol_table.get_symbol(_dotnet_type.get_generic_type_definition());
67
68
let unspecialized = cast Symbols.Classy?(s)!;
69
70
let arguments = LIST();
71
72
for a in _dotnet_type.get_generic_arguments() do
73
arguments.add(_type_mapper.get_type(a));
74
od
75
76
_symbol = create_symbol(unspecialized, arguments);
77
si
78
79
create_symbol(unspecialized: Symbols.Classy, arguments: List[Types.Type]) -> Symbols.GENERIC =>
80
Symbols.GENERIC(Source.LOCATION.internal, unspecialized, arguments);
81
si
82
83
// A reflected `System.Nullable[T]` — the same value-type optional
84
// a ghūl-written `T?` produces (Types.NULLABLE), so it must behave
85
// identically: optional, widening from T, and rendered with the
86
// `?` sugar. Mirrors FUNCTION_TYPE_WRAPPER / TUPLE_TYPE_WRAPPER,
87
// which likewise re-declare their behaviour and delegate to the
88
// eager type's statics / constructor.
89
class NULLABLE_TYPE_WRAPPER: GENERIC_TYPE_WRAPPER is
90
is_optional: bool => true;
91
92
optional_inner_type: Type? => arguments[0];
93
94
init(
95
symbol_table: SYMBOL_TABLE,
96
type_mapper: TYPE_MAPPER,
97
dotnet_type: TYPE
98
) is
99
super.init(symbol_table, type_mapper, dotnet_type);
100
si
101
102
compare(other: Type) -> Types.MATCH =>
103
Types.NULLABLE.compare_optional(self, other, super.compare(other));
104
105
create(
106
location: LOCATION,
107
symbol: Symbols.Classy,
108
arguments: Collections.List[Type]
109
) -> Types.GENERIC =>
110
Types.NULLABLE(location, symbol, arguments);
111
112
short_description: string => Types.NULLABLE.get_short_description(self);
113
114
to_string() -> string => "{arguments[0]}?";
115
si
116
117
// A reflected `Ghul.MAYBE[T]` — the runtime's unconstrained-T
118
// optional carrier. The Type-system flag is_maybe drives the
119
// implicit conversion to `T?` at slot boundaries; surfacing it as
120
// a wrapper subclass means recognition is `isa MAYBE_TYPE_WRAPPER`
121
// (no per-call symbol lookup, no behaviour on source-side MAYBE
122
// structs being newly compiled inside `ghul-runtime` itself).
123
class MAYBE_TYPE_WRAPPER: GENERIC_TYPE_WRAPPER is
124
is_maybe: bool => true;
125
126
is_optional: bool => true;
127
128
optional_inner_type: Type? => arguments[0];
129
130
init(
131
symbol_table: SYMBOL_TABLE,
132
type_mapper: TYPE_MAPPER,
133
dotnet_type: TYPE
134
) is
135
super.init(symbol_table, type_mapper, dotnet_type);
136
si
137
138
// Specialisation (`MAYBE[T]` → `MAYBE[CAT]`) hands off to the
139
// eager subclass so the is_maybe flag survives every rewrite —
140
// mirrors NULLABLE_TYPE_WRAPPER's hand-off to Types.NULLABLE.
141
create(
142
location: LOCATION,
143
symbol: Symbols.Classy,
144
arguments: Collections.List[Types.Type]
145
) -> Types.GENERIC =>
146
Types.MAYBE(location, symbol, arguments);
147
148
short_description: string => Types.MAYBE.get_short_description(self);
149
150
to_string() -> string => "{arguments[0]}?";
151
si
152
153
class HYBRID_GENERIC_TYPE_WRAPPER: Types.GENERIC is
154
_symbol_table: SYMBOL_TABLE;
155
_dotnet_type: TYPE;
156
_arguments: List[Type];
157
158
// _symbol: Symbols.GENERIC;
159
160
symbol: Symbols.Symbol is
161
// _symbol is lazily materialized on first access
162
@suppress("presence-test-non-optional")
163
if !_symbol? then
164
materialize();
165
fi
166
167
return _symbol;
168
si
169
170
init(
171
symbol_table: SYMBOL_TABLE,
172
dotnet_type: TYPE,
173
arguments: List[Type]
174
) is
175
assert arguments.count > 0 else "expected at least one type argument";
176
177
_symbol_table = symbol_table;
178
_dotnet_type = dotnet_type;
179
_arguments = arguments;
180
si
181
182
init(
183
symbol_table: SYMBOL_TABLE,
184
dotnet_type: TYPE,
185
argument: Type
186
) is
187
_symbol_table = symbol_table;
188
_dotnet_type = dotnet_type;
189
_arguments = LIST[Type]([argument]);
190
si
191
192
materialize() is
193
let s = _symbol_table.get_symbol(_dotnet_type);
194
195
let unspecialized = cast Symbols.Classy?(s)!;
196
197
_symbol = create_symbol(unspecialized, _arguments);
198
si
199
200
create_symbol(unspecialized: Symbols.Classy, arguments: List[Types.Type]) -> Symbols.GENERIC =>
201
Symbols.GENERIC(Source.LOCATION.internal, unspecialized, arguments);
202
si
203
204
class HYBRID_ARRAY_TYPE_WRAPPER: HYBRID_GENERIC_TYPE_WRAPPER is
205
short_description: string => Types.ARRAY.get_short_description(self);
206
207
init(
208
symbol_table: SYMBOL_TABLE,
209
dotnet_type: TYPE,
210
argument: Type
211
) is
212
super.init(
213
symbol_table,
214
dotnet_type,
215
argument
216
);
217
si
218
219
create(location: LOCATION, symbol: Symbols.Classy, arguments: Collections.List[Type]) -> Types.GENERIC =>
220
Types.ARRAY(location, symbol, arguments);
221
222
to_string() -> string => Types.ARRAY.get_short_description(self);
223
si
224
225
class HYBRID_REFERENCE_TYPE_WRAPPER: HYBRID_GENERIC_TYPE_WRAPPER is
226
short_description: string => Types.REFERENCE.get_short_description(self);
227
228
init(
229
symbol_table: SYMBOL_TABLE,
230
dotnet_type: TYPE,
231
argument: Type
232
) is
233
super.init(
234
symbol_table,
235
dotnet_type,
236
argument
237
);
238
si
239
240
create(location: LOCATION, symbol: Symbols.Classy, arguments: Collections.List[Type]) -> Types.GENERIC =>
241
Types.REFERENCE(location, symbol, arguments);
242
243
to_string() -> string => Types.REFERENCE.get_short_description(self);
244
si
245
246
class HYBRID_POINTER_TYPE_WRAPPER: HYBRID_GENERIC_TYPE_WRAPPER is
247
short_description: string => Types.POINTER.get_short_description(self);
248
249
init(
250
symbol_table: SYMBOL_TABLE,
251
dotnet_type: TYPE,
252
argument: Type
253
) is
254
super.init(
255
symbol_table,
256
dotnet_type,
257
argument
258
);
259
si
260
261
create(location: LOCATION, symbol: Symbols.Classy, arguments: Collections.List[Type]) -> Types.GENERIC =>
262
Types.POINTER(location, symbol, arguments);
263
264
to_string() -> string => Types.POINTER.get_short_description(self);
265
si
266
si