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
// When true, each node keeps what its context pushed down and
37
// drops only what the walk produced (see Node.clear_outputs):
38
// the reset the compile-expressions retry loop makes between
39
// walks of one body. Implies preserving resolved types.
40
_outputs_only: bool
41
42
init() is
43
super.init()
44
_preserve_resolved_types = false
45
_outputs_only = false
46
si
47
48
init(preserve_resolved_types: bool) is
49
super.init()
50
_preserve_resolved_types = preserve_resolved_types
51
_outputs_only = false
52
si
53
54
init(preserve_resolved_types: bool, outputs_only: bool) is
55
super.init()
56
_preserve_resolved_types = preserve_resolved_types \/ outputs_only
57
_outputs_only = outputs_only
58
si
59
60
_clear(node: Trees.Node) is
61
if _outputs_only then
62
node.clear_outputs()
63
else
64
node.clear()
65
fi
66
si
67
68
apply(root: Trees.Node) is
69
root.walk(self)
70
si
71
72
_clear_type(type_expression: TypeExpressions.TypeExpression) is
73
if !_preserve_resolved_types then
74
type_expression.clear()
75
fi
76
si
77
78
// StrictVisitor.pre(STATEMENT) and pre(VAL_BLOCK) throw. Override
79
// here to allow normal recursion into the child body.
80
pre(statement: Trees.Expressions.STATEMENT) -> bool => false
81
pre(block: Trees.Expressions.VAL_BLOCK) -> bool => false
82
// Identifiers
83
visit(identifier: Identifiers.Identifier) is _clear(identifier); si
84
visit(identifier: Identifiers.QUALIFIED) is _clear(identifier); si
85
86
// Modifiers / pragmas
87
visit(modifier: Modifiers.Modifier) is _clear(modifier); si
88
visit(modifiers: Modifiers.LIST) is _clear(modifiers); si
89
visit(pragma: Pragmas.PRAGMA) is _clear(pragma); si
90
91
// Definitions
92
visit(definition: Definitions.Definition) is _clear(definition); si
93
// LIST has no per-build state of its own; the walk has already
94
// visited each child in `definitions` and called clear() on it.
95
visit(definitions: Definitions.LIST) is si
96
visit(pragma: Definitions.PRAGMA) is _clear(pragma); si
97
visit(`namespace: Definitions.NAMESPACE) is _clear(`namespace); si
98
visit(`use: Definitions.USE) is _clear(`use); si
99
visit(`class: Definitions.CLASS) is _clear(`class); si
100
visit(`partial: Definitions.PARTIAL) is _clear(`partial); si
101
visit(`impl: Definitions.IMPL) is _clear(`impl); si
102
visit(`trait: Definitions.TRAIT) is _clear(`trait); si
103
visit(`struct: Definitions.STRUCT) is _clear(`struct); si
104
visit(`union: Definitions.UNION) is _clear(`union); si
105
visit(variant: Definitions.VARIANT) is _clear(variant); si
106
visit(`enum: Definitions.ENUM) is _clear(`enum); si
107
visit(enum_member: Definitions.ENUM_MEMBER) is _clear(enum_member); si
108
visit(function: Definitions.FUNCTION) is _clear(function); si
109
visit(functions: Definitions.FUNCTION_GROUP) is _clear(functions); si
110
visit(property: Definitions.PROPERTY) is _clear(property); si
111
visit(indexer: Definitions.INDEXER) is _clear(indexer); si
112
113
// Variables (definition-side)
114
visit(variable: Variables.VARIABLE) is _clear(variable); si
115
visit(variables: Variables.LIST) is _clear(variables); si
116
visit(left: Trees.Variables.SIMPLE_VARIABLE_LEFT) is _clear(left); si
117
visit(destructure_left: Trees.Variables.DESTRUCTURING_VARIABLE_LEFT) is _clear(destructure_left); si
118
visit(literal_leaf: Trees.Variables.LITERAL_VARIABLE_LEFT) is _clear(literal_leaf); si
119
120
// Type expressions — clearing `type` here is skipped when
121
// preserving resolved types (see `_clear_type`).
122
visit(type_expression: TypeExpressions.TypeExpression) is _clear_type(type_expression); si
123
visit(type_expression: TypeExpressions.INFER) is _clear_type(type_expression); si
124
visit(structured: TypeExpressions.Structured) is _clear_type(structured); si
125
visit(array: TypeExpressions.ARRAY_) is _clear_type(array); si
126
visit(pointer: TypeExpressions.POINTER) is _clear_type(pointer); si
127
visit(optional: TypeExpressions.OPTIONAL) is _clear_type(optional); si
128
visit(reference: TypeExpressions.REFERENCE) is _clear_type(reference); si
129
visit(member: TypeExpressions.MEMBER) is _clear_type(member); si
130
visit(named: TypeExpressions.NAMED) is _clear_type(named); si
131
visit(types: TypeExpressions.LIST) is _clear(types); si
132
visit(generic: TypeExpressions.GENERIC) is _clear_type(generic); si
133
visit(function: TypeExpressions.FUNCTION) is _clear_type(function); si
134
visit(functions: TypeExpressions.FUNCTION_GROUP) is _clear_type(functions); si
135
visit(tuple: TypeExpressions.TUPLE) is _clear_type(tuple); si
136
visit(element: TypeExpressions.NAMED_TUPLE_ELEMENT) is _clear_type(element); si
137
visit(constraint: TypeExpressions.TYPE_PARAMETER_CONSTRAINT) is _clear_type(constraint); si
138
visit(element: TypeExpressions.UNDEFINED) is _clear_type(element); si
139
140
// Expressions
141
visit(expression: Expressions.Expression) is _clear(expression); si
142
visit(identifier: Expressions.IDENTIFIER) is _clear(identifier); si
143
visit(literal: Expressions.Literals.Literal) is _clear(literal); si
144
visit(`string: Expressions.Literals.STRING) is _clear(`string); si
145
visit(interpolation: Expressions.STRING_INTERPOLATION) is _clear(interpolation); si
146
visit(integer: Expressions.Literals.INTEGER) is _clear(integer); si
147
visit(float: Expressions.Literals.FLOAT) is _clear(float); si
148
visit(character: Expressions.Literals.CHARACTER) is _clear(character); si
149
visit(boolean: Expressions.Literals.BOOLEAN) is _clear(boolean); si
150
visit(variable: Expressions.VARIABLE) is _clear(variable); si
151
visit(variable: Expressions.TUPLE_ELEMENT) is _clear(variable); si
152
visit(none: Expressions.Literals.NONE) is _clear(none); si
153
visit(`null: Expressions.NULL) is _clear(`null); si
154
visit(`self: Expressions.SELF) is _clear(`self); si
155
visit(`super: Expressions.SUPER) is _clear(`super); si
156
visit(construct: Expressions.CONSTRUCT) is _clear(construct); si
157
// The reading of an ambiguous cast is a resolve-type-expressions
158
// result like any other, so it is cleared with them: a later
159
// walk decides again against whatever the scope says then.
160
visit(`cast: Expressions.CAST) is
161
`cast.set_reading(Expressions.CastReading.UNDECIDED)
162
_clear(`cast)
163
si
164
visit(`await: Expressions.AWAIT) is _clear(`await); si
165
visit(spill: Expressions.SPILL) is _clear(spill); si
166
visit(`isa: Expressions.ISA) is _clear(`isa); si
167
168
visit(field_equals: Expressions.FIELD_EQUALS) is _clear(field_equals); si
169
visit(hash_operand: Expressions.HASH_OPERAND) is _clear(hash_operand); si
170
visit(memberwise_equals: Expressions.MEMBERWISE_EQUALS) is _clear(memberwise_equals); si
171
visit(memberwise_hash: Expressions.MEMBERWISE_HASH) is _clear(memberwise_hash); si
172
visit(`isa: Expressions.TYPEOF) is _clear(`isa); si
173
visit(`default: Expressions.DEFAULT) is _clear(`default); si
174
visit(function: Expressions.FUNCTION) is _clear(function); si
175
visit(recurse: Expressions.RECURSE) is _clear(recurse); si
176
visit(tuple: Expressions.TUPLE) is _clear(tuple); si
177
visit(sequence: Expressions.SEQUENCE) is _clear(sequence); si
178
visit(list: Expressions.LIST) is _clear(list); si
179
visit(call: Expressions.CALL) is _clear(call); si
180
visit(member: Expressions.MEMBER) is _clear(member); si
181
visit(ambiguous_expression: Expressions.AMBIGUOUS_EXPRESSION) is _clear(ambiguous_expression); si
182
visit(ambiguous_expression: Expressions.GENERIC_APPLICATION) is _clear(ambiguous_expression); si
183
visit(index: Expressions.INDEX) is _clear(index); si
184
visit(has_value: Expressions.HAS_VALUE) is _clear(has_value); si
185
visit(unwrap: Expressions.UNWRAP) is _clear(unwrap); si
186
visit(reference: Expressions.REFERENCE) is _clear(reference); si
187
visit(unary: Expressions.UNARY) is _clear(unary); si
188
visit(binary: Expressions.BINARY) is _clear(binary); si
189
visit(statement: Expressions.STATEMENT) is _clear(statement); si
190
visit(statement: Expressions.LET_IN) is _clear(statement); si
191
visit(block: Expressions.VAL_BLOCK) is _clear(block); si
192
visit(assert_in: Expressions.ASSERT_IN) is _clear(assert_in); si
193
194
// Left-side expressions
195
visit(left: Trees.Expressions.SIMPLE_LEFT_EXPRESSION) is _clear(left); si
196
visit(destructure_left: Trees.Expressions.DESTRUCTURING_LEFT_EXPRESSION) is _clear(destructure_left); si
197
198
// Statements
199
visit(statement: Statements.Statement) is _clear(statement); si
200
visit(statements: Statements.LIST) is _clear(statements); si
201
visit(f: Statements.FUNCTION) is _clear(f); si
202
visit(l: Statements.LET) is _clear(l); si
203
visit(assign: Statements.ASSIGNMENT) is _clear(assign); si
204
visit(expression: Statements.EXPRESSION) is _clear(expression); si
205
visit(`return: Statements.RETURN) is _clear(`return); si
206
visit(`throw: Statements.THROW) is _clear(`throw); si
207
visit(`yield: Statements.YIELD) is _clear(`yield); si
208
visit(`yield: Statements.YIELD_ALL) is _clear(`yield); si
209
visit(assert__: Statements.ASSERT) is _clear(assert__); si
210
visit(`if: Statements.IF) is _clear(`if); si
211
visit(if_branch: Statements.IF_BRANCH) is _clear(if_branch); si
212
visit(rb: Statements.REFUTABLE_BINDING) is _clear(rb); si
213
visit(`case: Statements.CASE) is _clear(`case); si
214
visit(case_match: Statements.CASE_MATCH) is _clear(case_match); si
215
visit(`try: Statements.TRY) is _clear(`try); si
216
visit(`catch: Statements.CATCH) is _clear(`catch); si
217
visit(`do: Statements.DO) is _clear(`do); si
218
visit(`for: Statements.FOR) is _clear(`for); si
219
visit(labelled: Statements.LABELLED) is _clear(labelled); si
220
visit(`break: Statements.BREAK) is _clear(`break); si
221
visit(`continue: Statements.CONTINUE) is _clear(`continue); si
222
visit(pragma: Statements.PRAGMA) is _clear(pragma); si
223
224
// Bodies
225
visit(expression: Bodies.EXPRESSION) is _clear(expression); si
226
visit(block: Bodies.BLOCK) is _clear(block); si
227
visit(block: Bodies.NULL) is _clear(block); si
228
visit(block: Bodies.INNATE) is _clear(block); si
229
si
230
si