Module: ActiverecordCallbackLens::Parser::AstWalker
- Defined in:
- lib/activerecord_callback_lens/parser/ast_walker.rb
Overview
Maps a Prism boolean AST (‘&&`, `||`, `!`, predicate calls) onto the ConditionTree node types. Shared by ConditionParser (lambda bodies) and MethodResolver (method bodies) so the two stay in lockstep.
The walker recognises the same boolean vocabulary the v0.1 ConditionParser established:
- StatementsNode -> the last statement is the effective return value
- ParenthesesNode -> transparent; walk the inner body
- AndNode/OrNode -> AndNode/OrNode combinators (nil operands dropped)
- CallNode `!` -> NotNode wrapping the negated receiver
- CallNode -> PredicateNode for the called method name
- anything else -> nil (unresolvable)
Class Method Summary collapse
-
.combinator(klass, node) ⇒ ConditionTree::Node
Builds an And/Or combinator from a binary Prism node, walking both sides and dropping any unresolved (nil) operand.
- .negate(node) ⇒ ConditionTree::NotNode?
-
.walk(node) ⇒ ConditionTree::Node?
Recursively maps a Prism boolean AST onto ConditionTree nodes.
Class Method Details
.combinator(klass, node) ⇒ ConditionTree::Node
Builds an And/Or combinator from a binary Prism node, walking both sides and dropping any unresolved (nil) operand.
46 47 48 |
# File 'lib/activerecord_callback_lens/parser/ast_walker.rb', line 46 def combinator(klass, node) klass.new(children: [walk(node.left), walk(node.right)].compact) end |
.negate(node) ⇒ ConditionTree::NotNode?
52 53 54 55 56 |
# File 'lib/activerecord_callback_lens/parser/ast_walker.rb', line 52 def negate(node) return nil if node.nil? ConditionTree::NotNode.new(child: node) end |
.walk(node) ⇒ ConditionTree::Node?
Recursively maps a Prism boolean AST onto ConditionTree nodes.
28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/activerecord_callback_lens/parser/ast_walker.rb', line 28 def walk(node) case node in Prism::StatementsNode then walk(node.body.last) in Prism::ParenthesesNode then walk(node.body) in Prism::AndNode then combinator(ConditionTree::AndNode, node) in Prism::OrNode then combinator(ConditionTree::OrNode, node) in Prism::CallNode if node.name == :! then negate(walk(node.receiver)) in Prism::CallNode then ConditionTree::PredicateNode.new(name: node.name.to_s) else nil end end |