Skip to content
← Back

src/semantic/symbols/inheritance_journal.ghul

1
namespace Semantic.Symbols is
2
use Source.LOCATION;
3
4
// One reversible mutation made on behalf of a class's
5
// pull_down_super_symbols: members pulled into its store, override /
6
// implementor links registered on other symbols, and IL-name /
7
// assign-accessor state inherited onto its own members. Each op is
8
// self-contained; undo happens in strict reverse order, so an op's
9
// undo precondition is exactly the state its do-site left behind.
10
union InheritanceOp is
11
MEMBER_ADDED(scope: Scoped, name: string);
12
MEMBER_REPLACED(scope: Scoped, name: string, previous: Symbol);
13
GROUP_MEMBER_ADDED(group: FUNCTION_GROUP, function: Function);
14
TYPE_GROUP_MEMBER_ADDED(group: TYPE_GROUP, classy: Classy);
15
FUNCTION_OVERRIDER_ADDED(holder: Function, overrider: Symbol);
16
FUNCTION_OVERRIDEE_ADDED(holder: Function, overridee: Symbol);
17
PROPERTY_OVERRIDER_ADDED(holder: Property, overrider: Symbol);
18
PROPERTY_OVERRIDEE_ADDED(holder: Property, overridee: Symbol);
19
IMPLEMENTOR_ADDED(holder: Classy, implementor: Symbol);
20
IL_NAME_SET(symbol: Symbol);
21
PROPERTY_ASSIGN_INHERITED(property: Property);
22
si
23
24
// Journal of the mutations one class's pull_down_super_symbols made,
25
// so they can be undone exactly - the operation an incremental
26
// re-resolve needs before re-running resolve-overrides for a class
27
// against a retained symbol table. While a journal is on the stack,
28
// the pull-down mutation sites record into it; with the stack empty
29
// (batch import paths, reflected symbol construction) recording is a
30
// no-op and behaviour is unchanged.
31
//
32
// The stack nests because pull_down_super_symbols recurses into
33
// unresolved ancestors: each class's pull-down pushes its own journal,
34
// so every op lands on the class it belongs to.
35
class INHERITANCE_JOURNAL is
36
_stack: Collections.LIST[INHERITANCE_JOURNAL] static;
37
38
init() static is
39
_stack = Collections.LIST[INHERITANCE_JOURNAL]();
40
si
41
42
current: INHERITANCE_JOURNAL? static =>
43
if _stack.count > 0 then
44
_stack[_stack.count - 1]
45
else
46
null
47
fi;
48
49
push(journal: INHERITANCE_JOURNAL) static is
50
_stack.add(journal);
51
si
52
53
pop() static is
54
assert _stack.count > 0 else "inheritance journal stack is empty";
55
56
_stack.remove_at(_stack.count - 1);
57
si
58
59
for_class: Classy;
60
61
_ops: Collections.LIST[InheritanceOp];
62
63
init(for_class: Classy) is
64
self.for_class = for_class;
65
66
_ops = Collections.LIST[InheritanceOp]();
67
si
68
69
record(op: InheritanceOp) is
70
_ops.add(op);
71
si
72
73
// Reverse every recorded mutation, newest first.
74
undo() is
75
let i mut = _ops.count - 1;
76
77
while i >= 0 do
78
let op = _ops[i];
79
80
if let member_added: InheritanceOp.MEMBER_ADDED = op then
81
member_added.scope.remove_direct(member_added.name);
82
elif let member_replaced: InheritanceOp.MEMBER_REPLACED = op then
83
member_replaced.scope.put_direct(member_replaced.name, member_replaced.previous);
84
elif let group_member: InheritanceOp.GROUP_MEMBER_ADDED = op then
85
group_member.group.remove(group_member.function);
86
elif let type_group_member: InheritanceOp.TYPE_GROUP_MEMBER_ADDED = op then
87
type_group_member.group.remove(type_group_member.classy);
88
elif let function_overrider: InheritanceOp.FUNCTION_OVERRIDER_ADDED = op then
89
function_overrider.holder.remove_overrider(function_overrider.overrider);
90
elif let function_overridee: InheritanceOp.FUNCTION_OVERRIDEE_ADDED = op then
91
function_overridee.holder.remove_overridee(function_overridee.overridee);
92
elif let property_overrider: InheritanceOp.PROPERTY_OVERRIDER_ADDED = op then
93
property_overrider.holder.remove_overrider(property_overrider.overrider);
94
elif let property_overridee: InheritanceOp.PROPERTY_OVERRIDEE_ADDED = op then
95
property_overridee.holder.remove_overridee(property_overridee.overridee);
96
elif let implementor_added: InheritanceOp.IMPLEMENTOR_ADDED = op then
97
implementor_added.holder.remove_implementor(implementor_added.implementor);
98
elif let il_name_set: InheritanceOp.IL_NAME_SET = op then
99
il_name_set.symbol.il_name_override = null;
100
elif let assign_inherited: InheritanceOp.PROPERTY_ASSIGN_INHERITED = op then
101
assign_inherited.property.assign_function = null;
102
assign_inherited.property.is_assignable = false;
103
fi
104
105
i = i - 1;
106
od
107
108
_ops.clear();
109
si
110
si
111
si