Module: Jade::Codegen::Transforms::SelfCall
Overview
AST-walking primitives for recognizing self-recursive calls. A “self-call signature” is the pair ‘[self_sym, arity]`: a ValueRef carrying module_name + name, paired with the function’s user-declared arity (partial applications never qualify).
Constant Summary collapse
- METADATA_KEYS =
%i[ range symbol id leading_comments trailing_comments dangling_comments trailing_comma ].freeze
Instance Method Summary collapse
- #child_values(node) ⇒ Object
-
#contains_self_call?(node, sig, registry) ⇒ Boolean
Scope-aware: stops at Lambda boundaries.
-
#contains_self_call_anywhere?(node, sig, registry) ⇒ Boolean
Scope-blind: descends into Lambda bodies.
-
#self_call?(node, sig, registry) ⇒ Boolean
Defensive on ‘node` — anything that isn’t a FunctionCall returns false, so callers don’t need to type-check before calling.
Instance Method Details
#child_values(node) ⇒ Object
50 51 52 53 54 55 |
# File 'lib/jade/codegen/transforms/self_call.rb', line 50 def child_values(node) node .to_h .reject { |k, _| METADATA_KEYS.include?(k) } .values end |
#contains_self_call?(node, sig, registry) ⇒ Boolean
Scope-aware: stops at Lambda boundaries. A self-call inside a lambda body belongs to that lambda, not to the enclosing function.
33 34 35 36 37 38 39 |
# File 'lib/jade/codegen/transforms/self_call.rb', line 33 def contains_self_call?(node, sig, registry) return true if self_call?(node, sig, registry) return false if node.is_a?(AST::Lambda) child_descendants(node) .any? { contains_self_call?(it, sig, registry) } end |
#contains_self_call_anywhere?(node, sig, registry) ⇒ Boolean
Scope-blind: descends into Lambda bodies. For disqualifying any subtree that textually mentions a self-call at any depth.
43 44 45 46 47 48 |
# File 'lib/jade/codegen/transforms/self_call.rb', line 43 def contains_self_call_anywhere?(node, sig, registry) return true if self_call?(node, sig, registry) child_descendants(node) .any? { contains_self_call_anywhere?(it, sig, registry) } end |
#self_call?(node, sig, registry) ⇒ Boolean
Defensive on ‘node` — anything that isn’t a FunctionCall returns false, so callers don’t need to type-check before calling.
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/jade/codegen/transforms/self_call.rb', line 19 def self_call?(node, sig, registry) return false unless node.is_a?(AST::FunctionCall) self_sym, arity = sig resolved = resolve(node.callee.symbol, registry) resolved.is_a?(Symbol::Function) && resolved.module_name == self_sym.module_name && resolved.name == self_sym.name && node.args.size == arity end |