Module: Jade::Codegen::Transforms::SelfCall

Extended by:
SelfCall
Included in:
SelfCall
Defined in:
lib/jade/codegen/transforms/self_call.rb

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

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.

Returns:

  • (Boolean)


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.

Returns:

  • (Boolean)


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.

Returns:

  • (Boolean)


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