Skip to content
← Back

src/syntax/process/clear_ast_state.ghul

1
namespace Syntax.Process is
2
use Trees;
3
4
// Walk an AST resetting per-build mutable state on each node.
5
//
6
// Each visit override calls `node.clear()` (non-recursive — Node.clear
7
// resets only its own state). Traversal is handled by the existing walk
8
// methods on each tree class, which already know how to recurse.
9
//
10
// Run between compile-expressions invocations on the same AST (analyser
11
// COMPILE-after-EDIT, multi-file rebuilds). See project_analysis_mode_workflow
12
// memory for why this is needed: ad-hoc resets in individual visit
13
// methods cover most state, but the constraint mechanism's narrowing-only
14
// upgrade can leave stale entries across `apply` calls. This visitor
15
// makes clearing structural rather than ad-hoc.
16
// Inherits from StrictVisitor (rather than Visitor) so that any AST
17
// node type added to the codebase later will throw NotImplementedException
18
// here until someone adds an override — forces us to consider whether
19
// the new node has clearable state. The default override per node type
20
// calls node.clear() which is itself a no-op unless the subclass adds
21
// state to clear, so the cost of adding a new node type is one trivial
22
// override here.
23
class CLEAR_STATE_VISITOR: StrictVisitor is
24
// When true, TypeExpression.type (resolve-type-expressions output)
25
// is left intact and only compile-expressions output is cleared.
26
// The recompile-dependents path uses this: a referencing file's
27
// bodies must re-compile to rebind to a reconciled symbol, but its
28
// interface type expressions are unchanged and re-resolving them
29
// against the retained interface symbols would set their types
30
// twice. Compile-expressions output lives in Expression/Statement
31
// compile state and the VariableLeft store, separate from
32
// TypeExpression.type, so clearing it without touching the resolved
33
// types is a clean split.
34
_preserve_resolved_types: bool;
35
36
init() is
37
super.init();
38
_preserve_resolved_types = false;
39
si
40
41
init(preserve_resolved_types: bool) is
42
super.init();
43
_preserve_resolved_types = preserve_resolved_types;
44
si
45
46
apply(root: Trees.Node) is
47
root.walk(self);
48
si
49
50
_clear_type(type_expression: TypeExpressions.TypeExpression) is
51
if !_preserve_resolved_types then
52
type_expression.clear();
53
fi
54
si
55
56
// StrictVisitor.pre(STATEMENT) and pre(VAL_BLOCK) throw. Override
57
// here to allow normal recursion into the child body.
58
pre(statement: Trees.Expressions.STATEMENT) -> bool => false;
59
pre(block: Trees.Expressions.VAL_BLOCK) -> bool => false;
60
// Identifiers
61
visit(identifier: Identifiers.Identifier) is identifier.clear(); si
62
visit(identifier: Identifiers.QUALIFIED) is identifier.clear(); si
63
64
// Modifiers / pragmas
65
visit(modifier: Modifiers.Modifier) is modifier.clear(); si
66
visit(modifiers: Modifiers.LIST) is modifiers.clear(); si
67
visit(pragma: Pragmas.PRAGMA) is pragma.clear(); si
68
69
// Definitions
70
visit(definition: Definitions.Definition) is definition.clear(); si
71
// LIST has no per-build state of its own; the walk has already
72
// visited each child in `definitions` and called clear() on it.
73
visit(definitions: Definitions.LIST) is si
74
visit(pragma: Definitions.PRAGMA) is pragma.clear(); si
75
visit(`namespace: Definitions.NAMESPACE) is `namespace.clear(); si
76
visit(`use: Definitions.USE) is `use.clear(); si
77
visit(`class: Definitions.CLASS) is `class.clear(); si
78
visit(`partial: Definitions.PARTIAL) is `partial.clear(); si
79
visit(`impl: Definitions.IMPL) is `impl.clear(); si
80
visit(`trait: Definitions.TRAIT) is `trait.clear(); si
81
visit(`struct: Definitions.STRUCT) is `struct.clear(); si
82
visit(`union: Definitions.UNION) is `union.clear(); si
83
visit(variant: Definitions.VARIANT) is variant.clear(); si
84
visit(`enum: Definitions.ENUM) is `enum.clear(); si
85
visit(enum_member: Definitions.ENUM_MEMBER) is enum_member.clear(); si
86
visit(function: Definitions.FUNCTION) is function.clear(); si
87
visit(functions: Definitions.FUNCTION_GROUP) is functions.clear(); si
88
visit(property: Definitions.PROPERTY) is property.clear(); si
89
visit(indexer: Definitions.INDEXER) is indexer.clear(); si
90
91
// Variables (definition-side)
92
visit(variable: Variables.VARIABLE) is variable.clear(); si
93
visit(variables: Variables.LIST) is variables.clear(); si
94
visit(left: Trees.Variables.SIMPLE_VARIABLE_LEFT) is left.clear(); si
95
visit(destructure_left: Trees.Variables.DESTRUCTURING_VARIABLE_LEFT) is destructure_left.clear(); si
96
visit(literal_leaf: Trees.Variables.LITERAL_VARIABLE_LEFT) is literal_leaf.clear(); si
97
98
// Type expressions — clearing `type` here is skipped when
99
// preserving resolved types (see `_clear_type`).
100
visit(type_expression: TypeExpressions.TypeExpression) is _clear_type(type_expression); si
101
visit(type_expression: TypeExpressions.INFER) is _clear_type(type_expression); si
102
visit(structured: TypeExpressions.Structured) is _clear_type(structured); si
103
visit(array: TypeExpressions.ARRAY_) is _clear_type(array); si
104
visit(pointer: TypeExpressions.POINTER) is _clear_type(pointer); si
105
visit(optional: TypeExpressions.OPTIONAL) is _clear_type(optional); si
106
visit(reference: TypeExpressions.REFERENCE) is _clear_type(reference); si
107
visit(member: TypeExpressions.MEMBER) is _clear_type(member); si
108
visit(named: TypeExpressions.NAMED) is _clear_type(named); si
109
visit(types: TypeExpressions.LIST) is types.clear(); si
110
visit(generic: TypeExpressions.GENERIC) is _clear_type(generic); si
111
visit(function: TypeExpressions.FUNCTION) is _clear_type(function); si
112
visit(functions: TypeExpressions.FUNCTION_GROUP) is _clear_type(functions); si
113
visit(tuple: TypeExpressions.TUPLE) is _clear_type(tuple); si
114
visit(element: TypeExpressions.NAMED_TUPLE_ELEMENT) is _clear_type(element); si
115
visit(constraint: TypeExpressions.TYPE_PARAMETER_CONSTRAINT) is _clear_type(constraint); si
116
visit(element: TypeExpressions.UNDEFINED) is _clear_type(element); si
117
118
// Expressions
119
visit(expression: Expressions.Expression) is expression.clear(); si
120
visit(identifier: Expressions.IDENTIFIER) is identifier.clear(); si
121
visit(literal: Expressions.Literals.Literal) is literal.clear(); si
122
visit(`string: Expressions.Literals.STRING) is `string.clear(); si
123
visit(interpolation: Expressions.STRING_INTERPOLATION) is interpolation.clear(); si
124
visit(integer: Expressions.Literals.INTEGER) is integer.clear(); si
125
visit(float: Expressions.Literals.FLOAT) is float.clear(); si
126
visit(character: Expressions.Literals.CHARACTER) is character.clear(); si
127
visit(boolean: Expressions.Literals.BOOLEAN) is boolean.clear(); si
128
visit(variable: Expressions.VARIABLE) is variable.clear(); si
129
visit(variable: Expressions.TUPLE_ELEMENT) is variable.clear(); si
130
visit(none: Expressions.Literals.NONE) is none.clear(); si
131
visit(`null: Expressions.NULL) is `null.clear(); si
132
visit(`self: Expressions.SELF) is `self.clear(); si
133
visit(`super: Expressions.SUPER) is `super.clear(); si
134
visit(`new: Expressions.NEW) is `new.clear(); si
135
visit(`cast: Expressions.CAST) is `cast.clear(); si
136
visit(`await: Expressions.AWAIT) is `await.clear(); si
137
visit(spill: Expressions.SPILL) is spill.clear(); si
138
visit(`isa: Expressions.ISA) is `isa.clear(); si
139
visit(`isa: Expressions.TYPEOF) is `isa.clear(); si
140
visit(`default: Expressions.DEFAULT) is `default.clear(); si
141
visit(function: Expressions.FUNCTION) is function.clear(); si
142
visit(recurse: Expressions.RECURSE) is recurse.clear(); si
143
visit(tuple: Expressions.TUPLE) is tuple.clear(); si
144
visit(sequence: Expressions.SEQUENCE) is sequence.clear(); si
145
visit(list: Expressions.LIST) is list.clear(); si
146
visit(call: Expressions.CALL) is call.clear(); si
147
visit(member: Expressions.MEMBER) is member.clear(); si
148
visit(member: Expressions.EXPLICIT_SPECIALIZATION) is member.clear(); si
149
visit(ambiguous_expression: Expressions.AMBIGUOUS_EXPRESSION) is ambiguous_expression.clear(); si
150
visit(ambiguous_expression: Expressions.GENERIC_APPLICATION) is ambiguous_expression.clear(); si
151
visit(index: Expressions.INDEX) is index.clear(); si
152
visit(has_value: Expressions.HAS_VALUE) is has_value.clear(); si
153
visit(unwrap: Expressions.UNWRAP) is unwrap.clear(); si
154
visit(reference: Expressions.REFERENCE) is reference.clear(); si
155
visit(unary: Expressions.UNARY) is unary.clear(); si
156
visit(binary: Expressions.BINARY) is binary.clear(); si
157
visit(statement: Expressions.STATEMENT) is statement.clear(); si
158
visit(statement: Expressions.LET_IN) is statement.clear(); si
159
visit(block: Expressions.VAL_BLOCK) is block.clear(); si
160
visit(assert_in: Expressions.ASSERT_IN) is assert_in.clear(); si
161
162
// Left-side expressions
163
visit(left: Trees.Expressions.SIMPLE_LEFT_EXPRESSION) is left.clear(); si
164
visit(destructure_left: Trees.Expressions.DESTRUCTURING_LEFT_EXPRESSION) is destructure_left.clear(); si
165
166
// Statements
167
visit(statement: Statements.Statement) is statement.clear(); si
168
visit(statements: Statements.LIST) is statements.clear(); si
169
visit(l: Statements.LET) is l.clear(); si
170
visit(assign: Statements.ASSIGNMENT) is assign.clear(); si
171
visit(expression: Statements.EXPRESSION) is expression.clear(); si
172
visit(`return: Statements.RETURN) is `return.clear(); si
173
visit(`throw: Statements.THROW) is `throw.clear(); si
174
visit(`yield: Statements.YIELD) is `yield.clear(); si
175
visit(assert__: Statements.ASSERT) is assert__.clear(); si
176
visit(`if: Statements.IF) is `if.clear(); si
177
visit(if_branch: Statements.IF_BRANCH) is if_branch.clear(); si
178
visit(rb: Statements.REFUTABLE_BINDING) is rb.clear(); si
179
visit(`case: Statements.CASE) is `case.clear(); si
180
visit(case_match: Statements.CASE_MATCH) is case_match.clear(); si
181
visit(`try: Statements.TRY) is `try.clear(); si
182
visit(`catch: Statements.CATCH) is `catch.clear(); si
183
visit(`do: Statements.DO) is `do.clear(); si
184
visit(`for: Statements.FOR) is `for.clear(); si
185
visit(labelled: Statements.LABELLED) is labelled.clear(); si
186
visit(`break: Statements.BREAK) is `break.clear(); si
187
visit(`continue: Statements.CONTINUE) is `continue.clear(); si
188
visit(pragma: Statements.PRAGMA) is pragma.clear(); si
189
190
// Bodies
191
visit(expression: Bodies.EXPRESSION) is expression.clear(); si
192
visit(block: Bodies.BLOCK) is block.clear(); si
193
visit(block: Bodies.NULL) is block.clear(); si
194
visit(block: Bodies.INNATE) is block.clear(); si
195
si
196
si