Appearance
| 1 | namespace Syntax.Process is | |
| 2 | // Collects the names of variables written within a walked | |
| 3 | // subtree — by assignment (`=`, including destructuring) or by | |
| 4 | // being passed `ref`. Two consumers, each dropping a narrow on | |
| 5 | // a variable the walked subtree writes: the loop kill-set, where | |
| 6 | // a narrow cannot be assumed across the back-edge, and the entry | |
| 7 | // to a finally body, where a narrow proven before the try | |
| 8 | // survives what the try did not write. | |
| 9 | // | |
| 10 | // A `Visitor` whose default per-node visits are no-ops, so only | |
| 11 | // ASSIGNMENT and REFERENCE need overriding; default `pre` | |
| 12 | // returns false, so the framework descends through everything. | |
| 13 | class LOOP_ASSIGNMENT_COLLECTOR: Visitor is | |
| 14 | names: Collections.SET[string] public | |
| 15 | ||
| 16 | init() is | |
| 17 | super.init() | |
| 18 | names = Collections.SET[string]() | |
| 19 | si | |
| 20 | ||
| 21 | visit(assignment: Trees.Statements.ASSIGNMENT) is | |
| 22 | let targets = Collections.LIST[Trees.Expressions.Expression]() | |
| 23 | assignment.left.get_names_into(targets) | |
| 24 | ||
| 25 | for target in targets do | |
| 26 | _collect(target) | |
| 27 | od | |
| 28 | si | |
| 29 | ||
| 30 | visit(reference: Trees.Expressions.REFERENCE) is | |
| 31 | // `x ref` — a `ref` argument may be written by the callee. | |
| 32 | _collect(reference.left) | |
| 33 | si | |
| 34 | ||
| 35 | _collect(expr: Trees.Expressions.Expression) is | |
| 36 | if !isa Trees.Expressions.IDENTIFIER(expr) then | |
| 37 | return | |
| 38 | fi | |
| 39 | ||
| 40 | let identifier = expr | |
| 41 | ||
| 42 | names.add(identifier.identifier.name) | |
| 43 | si | |
| 44 | si | |
| 45 | si |