Appearance
| 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 |