class Rbr::Matchers

methods for determining if a node matches given conditions

Public Class Methods

ar_update(node, name) click to toggle source

Updating an ActiveRecord model attribute

# File lib/rbr/matchers.rb, line 16
def self.ar_update(node, name)
  name &&
    (
      ar_update_hash(node, name) ||
      ar_update_positional(node, name) ||
      ar_update_dynamic_method(node, name) ||
      ar_update_attributes(node, name) ||
      ar_update_hash_element(node, name)
    )
end
assignment(node, name) click to toggle source

Assignment to a specified lvalue

# File lib/rbr/matchers.rb, line 28
def self.assignment(node, name)
  name &&
    node.assignment? &&
    node.value == name
end
const(node, name) click to toggle source

Node is a Ruby constant

# File lib/rbr/matchers.rb, line 47
def self.const(node, name)
  name &&
    node.const? &&
    node.children.last == name
end
literal(node, value) click to toggle source

Node is a literal int, float, or string

# File lib/rbr/matchers.rb, line 35
def self.literal(node, value)
  number(node, value) || string(node, value)
end
match(node, matcher, condition) click to toggle source
# File lib/rbr/matchers.rb, line 6
def self.match(node, matcher, condition)
  send(matcher, node, condition)
end
method_call(node, name) click to toggle source

Method call

# File lib/rbr/matchers.rb, line 11
def self.method_call(node, name)
  name && node.method_call?(name)
end
number(node, value) click to toggle source

Node is a literal int or float

# File lib/rbr/matchers.rb, line 40
def self.number(node, value)
  value &&
    node.number? &&
    node.value.to_s == value
end
string(node, pattern) click to toggle source

Node is a string

# File lib/rbr/matchers.rb, line 54
def self.string(node, pattern)
  pattern &&
    node.str? &&
    node.any_descendant_matches?(
      ->(n) { n.is_a?(String) && n.match?(pattern) }
    )
end

Private Class Methods

ar_update_attributes(node, name) click to toggle source
# File lib/rbr/matchers.rb, line 96
                     def self.ar_update_attributes(node, name)
  node.method_call?(:attributes=) &&
  node.children.last.type == :hash &&
  node.children.last.children.any? do |child|
    child.is_a?(Node) && child.children[0].value == name
  end
end
ar_update_dynamic_method(node, name) click to toggle source
# File lib/rbr/matchers.rb, line 92
                     def self.ar_update_dynamic_method(node, name)
  node.method_call?("#{name}=".to_sym)
end
ar_update_hash(node, name) click to toggle source
# File lib/rbr/matchers.rb, line 64
                     def self.ar_update_hash(node, name)
  return false unless node.method_call?(
    %i[update update! assign_attributes update_attributes update_attributes!
       update_columns update_all upsert upsert_all insert insert! insert_all
       insert_all!]
  )

  hash_arg = if node.children[3]&.type == :hash
               node.children[3]
             else
               node.children[2]
             end

  return false unless hash_arg.is_a?(Node)

  hash_arg.children.any? do |child|
    child.is_a?(Node) && child.type == :pair && child.children[0].value == name
  end
end
ar_update_hash_element(node, name) click to toggle source
# File lib/rbr/matchers.rb, line 104
                     def self.ar_update_hash_element(node, name)
  node.method_call?(:[]=) && node.children[-2].is_a?(Node) && node.children[-2].value == name
end
ar_update_positional(node, name) click to toggle source
# File lib/rbr/matchers.rb, line 84
                     def self.ar_update_positional(node, name)
  return false unless node.method_call?(
    %i[write_attribute update_attribute update_column]
  )

  node.children[2].value == name
end