Skip to content
← Back

src/semantic/symbols/type_alias.ghul

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