Skip to content
← Back

src/semantic/symbols/function_group.ghul

1
namespace Semantic.Symbols is
2
use System.NotImplementedException;
3
4
use IoC;
5
use Logging;
6
use Source;
7
8
use IR.Values.Value;
9
10
use Types.Type;
11
12
use Ghul.Pipes;
13
14
class FUNCTION_GROUP: Symbol, Types.Typed is
15
_functions: Collections.LIST[Function];
16
17
count: int => _functions.count;
18
is_empty: bool => _functions.count == 0;
19
20
short_description: string => "{name}(...)";
21
22
describe(context: DESCRIBE_CONTEXT) -> SignaturePart =>
23
PARTS.sequence([
24
PARTS.name(self),
25
PARTS.literal("(...)")
26
]);
27
28
describe_kind(context: DESCRIBE_CONTEXT) -> string? => "function group";
29
symbol_kind: SymbolKind => SymbolKind.FUNCTION;
30
completion_kind: CompletionKind => CompletionKind.FUNCTION;
31
32
is_function_group: bool => true;
33
34
type: Type;
35
36
set_type(value: Type) is type = value; si
37
38
functions: Collections.List[Function] => _functions;
39
40
init(location: LOCATION, owner: Scope, name: string) is
41
super.init(location, owner, name);
42
43
type = Types.FUNCTION_GROUP(name, self);
44
_functions = Collections.LIST[Function]();
45
si
46
47
specialize_function_group(type_map: Collections.Map[string,Type], owner: GENERIC) -> FUNCTION_GROUP is
48
let result = cast FUNCTION_GROUP?(memberwise_clone())!;
49
50
result.specialized_from = self;
51
52
result.type = Types.FUNCTION_GROUP(
53
name,
54
result
55
);
56
57
// Pre-sized empty, filled by add: a LIST(_functions) copy would
58
// duplicate every element only for the loop to overwrite them all.
59
result._functions = Collections.LIST[Function](_functions.count);
60
61
for i in 0.._functions.count do
62
result._functions.add(_functions[i].specialize_function(type_map, owner));
63
od
64
65
return result;
66
si
67
68
specialize(type_map: Collections.Map[string,Type], owner: GENERIC) -> Symbol =>
69
specialize_function_group(type_map, owner);
70
71
try_specialize(
72
location: LOCATION,
73
logger: Logger,
74
actual_type_arguments: Collections.List[Type]
75
) -> Symbol?
76
is
77
let result_functions = Collections.LIST[Symbol]();
78
let result = FUNCTION_GROUP(location, owner!, name);
79
80
let expected_argument_counts = Collections.LIST[int]();
81
82
for f in _functions do
83
if f.is_generic then
84
if f.generic_arguments.count == actual_type_arguments.count then
85
GENERIC_CONSTRAINT_CHECKER().check_arguments(
86
location,
87
logger,
88
f,
89
f.generic_argument_names,
90
actual_type_arguments
91
);
92
93
let sf = f.specialize(actual_type_arguments);
94
95
result.add(cast Function?(sf)!);
96
else
97
expected_argument_counts.add(f.generic_arguments.count);
98
fi
99
fi
100
od
101
102
if result.is_empty then
103
if expected_argument_counts.count > 0 then
104
let counts_string mut = expected_argument_counts |> sort() |> join(", ");
105
let last_comma_index = counts_string.last_index_of(", ");
106
107
if last_comma_index >= 0 then
108
counts_string = counts_string.remove(last_comma_index, 2).insert(last_comma_index, " or ");
109
fi
110
111
logger.error(location, "expected {counts_string} type arguments but found {actual_type_arguments.count}");
112
else
113
logger.error(location, "cannot supply type arguments here");
114
fi
115
116
return null;
117
fi
118
119
return result;
120
si
121
122
remove(function: Function) is
123
_functions.remove(function);
124
si
125
126
add(function: Function) is
127
_functions.add(function);
128
si
129
130
// Combine this group with a same-named group from an enclosing
131
// scope: all of this group's functions are kept, and an outer
132
// function only joins the overload set when no function here
133
// already covers its override class.
134
merged_over(outer: FUNCTION_GROUP) -> FUNCTION_GROUP is
135
let combined = FUNCTION_GROUP(location, owner!, name);
136
137
let seen = Collections.SET[METHOD_OVERRIDE_CLASS]();
138
139
for f in _functions do
140
seen.add(f.override_class);
141
combined.add(f);
142
od
143
144
for f in outer.functions do
145
if !seen.contains(f.override_class) then
146
combined.add(f);
147
fi
148
od
149
150
return combined;
151
si
152
153
add(fg: FUNCTION_GROUP) is
154
_functions.add_range(fg.functions);
155
si
156
157
load(location: LOCATION, from: Value?, loader: SYMBOL_LOADER) -> Value =>
158
loader.load_function_group(from, self);
159
160
call(location: Source.LOCATION, from: Value?, arguments: Collections.List[Value], type: Type?, caller: FUNCTION_CALLER) -> IR.Values.Value => throw NotImplementedException("cannot call unresolved function overload group: {self}");
161
collapse_group_if_single_member() -> Symbols.Symbol =>
162
if _functions.count == 1 then
163
_functions[0];
164
else
165
self;
166
fi;
167
168
to_string() -> string =>
169
"{description} [{_functions|}]";
170
si
171
si