class Querly::Pattern::Expr::Send

Attributes

args[R]
block[R]
name[R]
receiver[R]

Public Class Methods

new(receiver:, name:, block:, args: Argument::AnySeq.new) click to toggle source
# File lib/querly/pattern/expr.rb, line 141
def initialize(receiver:, name:, block:, args: Argument::AnySeq.new)
  @name = Array(name)
  @receiver = receiver
  @args = args
  @block = block
end

Public Instance Methods

=~(pair) click to toggle source
# File lib/querly/pattern/expr.rb, line 148
def =~(pair)
  # Skip send node with block
  type = pair.node.type
  if (type == :send || type == :csend) && pair.parent
    if pair.parent.node.type == :block
      if pair.parent.node.children.first.equal? pair.node
        return false
      end
    end
  end

  test_node pair.node
end
hash_node_to_hash(node) click to toggle source
# File lib/querly/pattern/expr.rb, line 251
def hash_node_to_hash(node)
  node.children.each.with_object({}) do |pair, h|
    key = pair.children[0]
    value = pair.children[1]

    if key.type == :sym
      h[key.children[0]] = value
    end
  end
end
test_args(nodes, args) click to toggle source
# File lib/querly/pattern/expr.rb, line 199
def test_args(nodes, args)
  first_node = nodes.first

  case args
  when Argument::AnySeq
    case args.tail
    when Argument::KeyValue
      if first_node
        case
        when nodes.last.type == :kwsplat
          true
        when nodes.last.type == :hash && args.tail.is_a?(Argument::KeyValue)
          hash = hash_node_to_hash(nodes.last)
          test_hash_args(hash, args.tail)
        else
          test_hash_args({}, args.tail)
        end
      else
        test_hash_args({}, args.tail)
      end
    when Argument::Expr
      nodes.size.times.any? do |i|
        test_args(nodes.drop(i), args.tail)
      end
    else
      true
    end
  when Argument::Expr
    if first_node
      args.expr.test_node(nodes.first) && test_args(nodes.drop(1), args.tail)
    end
  when Argument::KeyValue
    if first_node
      types = nodes.map(&:type)
      if types == [:hash]
        hash = hash_node_to_hash(nodes.first)
        test_hash_args(hash, args)
      elsif types == [:hash, :kwsplat]
        true
      else
        args.negated
      end
    else
      test_hash_args({}, args)
    end
  when Argument::BlockPass
    first_node&.type == :block_pass && args.expr.test_node(first_node.children.first)
  when nil
    nodes.empty?
  end
end
test_hash_args(hash, args) click to toggle source
# File lib/querly/pattern/expr.rb, line 262
def test_hash_args(hash, args)
  while args
    if args.is_a?(Argument::KeyValue)
      node = hash[args.key]

      if !args.negated == !!(node && args.value.test_node(node))
        hash.delete args.key
      else
        return false
      end
    else
      break
    end

    args = args.tail
  end

  args.is_a?(Argument::AnySeq) || hash.empty?
end
test_name(node) click to toggle source
# File lib/querly/pattern/expr.rb, line 162
def test_name(node)
  name.map do |n|
    case n
    when String
      n.to_sym
    else
      n
    end
  end.any? {|n| n === node.children[1] }
end
test_node(node) click to toggle source
# File lib/querly/pattern/expr.rb, line 173
def test_node(node)
  return false if block == true && node.type != :block
  return false if block == false && node.type == :block

  node = node.children.first if node&.type == :block

  case node&.type
  when :send, :csend
    return false unless test_name(node)
    return false unless test_receiver(node.children[0])
    return false unless test_args(node.children.drop(2), args)
    true
  end
end
test_receiver(node) click to toggle source
# File lib/querly/pattern/expr.rb, line 188
def test_receiver(node)
  case receiver
  when Self
    !node || receiver.test_node(node)
  when nil
    true
  else
    receiver.test_node(node)
  end
end