Skip to content
← Back

src/semantic/symbols/method_override_map.ghul

1
namespace Semantic is
2
use IO.Std;
3
4
use System.Text.StringBuilder;
5
6
use Collections.Iterable;
7
use Collections.Iterator;
8
9
use Collections.MAP;
10
use Collections.SET;
11
12
use Symbols.Symbol;
13
use Symbols.Function;
14
15
class METHOD_OVERRIDE_MAP(name: string): Iterable[METHOD_OVERRIDE_SET] is
16
_symbols: SET[SYMBOL_WRAPPER];
17
_symbols_list: Collections.LIST[Symbol]?;
18
19
methods: MAP[METHOD_OVERRIDE_CLASS,METHOD_OVERRIDE_SET];
20
21
// Read several times per class during override resolution, so the
22
// projected list is built once and reused; `add` resets it.
23
symbols: Iterable[Symbol] is
24
if _symbols_list? then
25
return _symbols_list;
26
fi
27
28
let list = Collections.LIST[Symbol]();
29
30
for w in _symbols do
31
list.add(w.symbol);
32
od
33
34
_symbols_list = list;
35
36
return list;
37
si
38
39
// Avoids building and piping `symbols` when only the first element
40
// is wanted.
41
first_symbol: Symbol? is
42
for w in _symbols do
43
return w.symbol;
44
od
45
46
return null;
47
si
48
49
iterator: Iterator[METHOD_OVERRIDE_SET] => methods.values.iterator;
50
51
contains_any_methods: bool => methods.count > 0;
52
contains_any_symbols: bool => _symbols.count > 0;
53
54
_empty: METHOD_OVERRIDE_MAP? static;
55
56
// Shared, read-only empty map for the common case where a class
57
// declares no member of a given name. Only ever read, never added to.
58
empty: METHOD_OVERRIDE_MAP static is
59
if _empty? then
60
return _empty;
61
fi
62
63
let empty = METHOD_OVERRIDE_MAP("");
64
65
_empty = empty;
66
67
return empty;
68
si
69
70
[method_class: METHOD_OVERRIDE_CLASS]: METHOD_OVERRIDE_SET? is
71
let result: METHOD_OVERRIDE_SET mut;
72
73
if methods.try_get_value(method_class, result ref) then
74
return result;
75
fi
76
77
return null;
78
si
79
80
init(..) is
81
methods = MAP();
82
_symbols = SET();
83
si
84
85
contains(override_class: METHOD_OVERRIDE_CLASS) -> bool => methods.contains_key(override_class);
86
87
add(symbol: Symbol) is
88
if isa Function(symbol) then
89
add(symbol);
90
91
return;
92
fi
93
94
let wrapper = SYMBOL_WRAPPER(symbol);
95
96
if !_symbols.contains(wrapper) then
97
_symbols.add(wrapper);
98
_symbols_list = null;
99
fi
100
si
101
102
add(group: Symbols.FUNCTION_GROUP) is
103
for f in group.functions do
104
add(f);
105
od
106
si
107
108
add(functions: Iterable[Function]) is
109
for f in functions do
110
add(f);
111
od
112
si
113
114
add(method: Function) is
115
let c = method.override_class;
116
117
let method_set: METHOD_OVERRIDE_SET mut;
118
119
if !methods.try_get_value(c, method_set ref) then
120
method_set = METHOD_OVERRIDE_SET(c);
121
methods[c] = method_set;
122
fi
123
124
assert method_set? else "no method set for {method.qualified_name}";
125
126
method_set.add(method);
127
si
128
129
to_string() -> string is
130
let result = StringBuilder();
131
132
for s in methods do
133
result.append("{name}: [{s.key}: {s.value}]");
134
od
135
136
result.append(" others: ").append(symbols|);
137
138
return result.to_string();
139
si
140
si
141
si