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