Appearance
| 1 | namespace Semantic.Symbols is | |
| 2 | use IoC | |
| 3 | use Source | |
| 4 | use Ghul.Pipes | |
| 5 | ||
| 6 | use Types.Type | |
| 7 | ||
| 8 | // A type alias declared by `use NAME[T] = <type expression>;`. The | |
| 9 | // alias is transparent: it is never a type in its own right, and no | |
| 10 | // Type ever carries this symbol. Resolve-type-expressions looks one | |
| 11 | // up when a name resolves to it and hands back `target_type`, | |
| 12 | // substituting the arguments of a generic alias. The symbol is its | |
| 13 | // own scope so that its type parameters resolve while its target | |
| 14 | // type expression is being resolved. | |
| 15 | class TYPE_ALIAS: ScopedWithEnclosingScope is | |
| 16 | _arguments: Collections.LIST[GenericArgument] | |
| 17 | ||
| 18 | // Null until resolve-type-expressions has resolved the target | |
| 19 | // type expression, which happens on first use or when the walk | |
| 20 | // reaches the clause, whichever comes first. | |
| 21 | target_type: Type? | |
| 22 | ||
| 23 | // Set while the target is being resolved, so that an alias whose | |
| 24 | // target names the alias itself is reported rather than looping. | |
| 25 | is_resolving: bool public | |
| 26 | ||
| 27 | // The type the alias stands for, so that a name resolving to an | |
| 28 | // alias behaves as its target wherever a type is loaded rather | |
| 29 | // than written - constructing through the alias, most visibly. | |
| 30 | type: Type? => target_type | |
| 31 | ||
| 32 | is_type: bool => true | |
| 33 | ||
| 34 | type_parameters: Collections.List[GenericArgument] => _arguments | |
| 35 | argument_count: int => _arguments.count | |
| 36 | ||
| 37 | short_description: string => description | |
| 38 | ||
| 39 | symbol_kind: SymbolKind => SymbolKind.CLASS | |
| 40 | completion_kind: CompletionKind => CompletionKind.CLASS | |
| 41 | ||
| 42 | describe_kind(context: DESCRIBE_CONTEXT) -> string? => "type alias" | |
| 43 | ||
| 44 | describe(context: DESCRIBE_CONTEXT) -> SignaturePart is | |
| 45 | let parts = Collections.LIST[SignaturePart]() | |
| 46 | ||
| 47 | parts.add(PARTS.literal("use ")) | |
| 48 | parts.add(PARTS.name(self)) | |
| 49 | ||
| 50 | if _arguments.count > 0 then | |
| 51 | parts.add(PARTS.literal("[")) | |
| 52 | ||
| 53 | for i in 0.._arguments.count do | |
| 54 | if i > 0 then | |
| 55 | parts.add(PARTS.literal(", ")) | |
| 56 | fi | |
| 57 | ||
| 58 | parts.add(PARTS.literal(_arguments[i].name)) | |
| 59 | od | |
| 60 | ||
| 61 | parts.add(PARTS.literal("]")) | |
| 62 | fi | |
| 63 | ||
| 64 | parts.add(PARTS.literal(" = ")) | |
| 65 | ||
| 66 | if let t = target_type then | |
| 67 | parts.add(PARTS.literal(t.short_description)) | |
| 68 | fi | |
| 69 | ||
| 70 | return PARTS.sequence(parts |> collect_array()) | |
| 71 | si | |
| 72 | ||
| 73 | init(location: LOCATION, owner: Scope, name: string, enclosing_scope: Scope?) is | |
| 74 | super.init(location, owner, name, enclosing_scope) | |
| 75 | ||
| 76 | _arguments = Collections.LIST[GenericArgument]() | |
| 77 | si | |
| 78 | ||
| 79 | // Declares a type parameter, in declaration order. The parameters | |
| 80 | // of an alias never reach IL - every use of the alias substitutes | |
| 81 | // them away - so the class-level flavour is used throughout. | |
| 82 | declare_argument(location: LOCATION, name: string, symbol_definition_listener: SymbolDefinitionListener?) -> Symbol is | |
| 83 | let result = CLASSY_GENERIC_ARGUMENT(location, self, name, _arguments.count) | |
| 84 | ||
| 85 | declare(location, result, symbol_definition_listener) | |
| 86 | ||
| 87 | _arguments.add(result) | |
| 88 | ||
| 89 | return result | |
| 90 | si | |
| 91 | ||
| 92 | set_target_type(value: Type) is | |
| 93 | target_type = value | |
| 94 | si | |
| 95 | ||
| 96 | // The substitution taking this alias's own type parameters to the | |
| 97 | // arguments supplied at a use site. | |
| 98 | argument_map(supplied: Collections.List[Type]) -> Collections.Map[Symbol,Type] is | |
| 99 | let result = Collections.MAP[Symbol,Type]() | |
| 100 | ||
| 101 | for i in 0.._arguments.count do | |
| 102 | if i < supplied.count then | |
| 103 | result[_arguments[i]] = supplied[i] | |
| 104 | fi | |
| 105 | od | |
| 106 | ||
| 107 | return result | |
| 108 | si | |
| 109 | ||
| 110 | specialize(type_map: Collections.Map[string,Symbols.Symbol], owner: GENERIC) -> Symbol | |
| 111 | => self | |
| 112 | si | |
| 113 | si |