class Kenma::PatternCapture

Public Class Methods

new(pat_node) click to toggle source
# File lib/kenma/macro/macro_pattern.rb, line 10
def initialize(pat_node)
  self.pat_node = pat_node
end

Public Instance Methods

===(node)
Alias for: match
match(node) click to toggle source
# File lib/kenma/macro/macro_pattern.rb, line 14
def match(node)
  _match(node, pat_node)
end
Also aliased as: ===

Private Instance Methods

_match(node, pat) click to toggle source
# File lib/kenma/macro/macro_pattern.rb, line 21
def _match(node, pat)
  return {} if node == pat
  return nil if node.nil? || pat.nil?
  return nil if !node.node? || !pat.node?

  if pat.type == :GASGN && node.type.to_s =~ /ASGN|CDECL/
    match_result = _match(node.children.last, pat.children.last)
    if match_result
      tag = pat.children.first.to_s.delete_prefix("$").to_sym
      { tag => node.children.first }.merge(_match(node.children.last, pat.children.last))
    else
      nil
    end
  elsif pat.type == :GVAR
    tag = pat.children.first.to_s.delete_prefix("$").to_sym
    { tag => node }
  # Add Support: pat { [*$node] } === ast { [a, b, c] } # => { node: [a, b, c] }
  # Not Support: pat { [$first, *$node] } === ast { [a, b, c] } # => nil
  elsif pat.type === :SPLAT && pat.children.first.type == :GVAR
    tag = pat.children.first.children.first.to_s.delete_prefix("$").to_sym
    { tag => node }
  elsif node.type == pat.type && node.children.size == pat.children.size
    node.children.zip(pat.children).inject({}) { |result, (src, pat)|
      if match_result = _match(src, pat)
        result.merge(match_result)
      else
        break nil
      end
    }
  else
    nil
  end
end