123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
RuboCop::AST::NodePattern::Compiler::Debug::NodePatternSubcompiler
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Subcompiler
Instance Chain:
self, Subcompiler
Inherits: RuboCop::AST::NodePattern::Compiler::Subcompiler
Defined in: lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb

Overview

Compiles code that evalues to true or false for a given value var (typically a RuboCop::AST::Node) or it’s node.type if #seq_head is true

Doc on how this fits in the compiling process: /docs/modules/ROOT/pages/node_pattern.adoc

Class Attribute Summary

Subcompiler - Inherited

Class Method Summary

Instance Attribute Summary

Subcompiler - Inherited

Instance Method Summary

Constructor Details

.new(compiler, var: nil, access: var, seq_head: false) ⇒ NodePatternSubcompiler

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 16

def initialize(compiler, var: nil, access: var, seq_head: false)
  super(compiler)
  @var = var
  @access = access
  @seq_head = seq_head
end

Instance Attribute Details

#access (readonly)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 14

attr_reader :access, :seq_head

#seq_head (readonly)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 14

attr_reader :access, :seq_head

Instance Method Details

#access_element (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 119

def access_element
  seq_head ? "#{access}.type" : access
end

#access_node (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 123

def access_node
  return access if seq_head

  "#{compile_guard_clause} && #{access}"
end

#compile_args(arg_list, first: nil) ⇒ String? (private)

Parameters:

  • (Array<Node>, nil)
[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 113

def compile_args(arg_list, first: nil)
  args = arg_list&.map { |arg| compiler.compile_as_atom(arg) }
  args = [first, *args] if first
  "(#{args.join(', ')})" if args
end

#compile_guard_clause (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 129

def compile_guard_clause
  "#{access}.is_a?(::RuboCop::AST::Node)"
end

#compile_value_match(value) (private)

Compiling helpers

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 107

def compile_value_match(value)
  "#{value} === #{access_element}"
end

#multiple_access(kind) (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 133

def multiple_access(kind)
  return yield @var if @var

  compiler.with_temp_variables(kind) do |var|
    memo = "#{var} = #{access}"
    @var = @access = var
    "(#{memo}; #{yield @var})"
  end
end

#visit_ascend (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 30

def visit_ascend
  compiler.with_temp_variables do |ascend|
    expr = compiler.compile_as_node_pattern(node.child, var: ascend)
    "(#{ascend} = #{access_node}) && (#{ascend} = #{ascend}.parent) && #{expr}"
  end
end

#visit_capture (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 58

def visit_capture
  "(#{compiler.next_capture} = #{access_element}; #{compile(node.child)})"
end

#visit_descend (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 37

def visit_descend
  compiler.with_temp_variables { |descendant| <<~RUBY.chomp }
    ::RuboCop::AST::NodePattern.descend(#{access}).any? do |#{descendant}|
      #{compiler.compile_as_node_pattern(node.child, var: descendant)}
    end
  RUBY
end

#visit_function_call (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 84

def visit_function_call
  "#{node.method_name}#{compile_args(node.arg_list, first: access_element)}"
end

#visit_intersection (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 73

def visit_intersection
  multiple_access(:intersection) do
    node.children.map { |child| compile(child) }
        .join(' && ')
  end
end

#visit_negation (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 25

def visit_negation
  expr = compile(node.child)
  "!(#{expr})"
end

#visit_node_type (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 88

def visit_node_type
  "#{access_node}.#{node.child.to_s.tr('-', '_')}_type?"
end

#visit_other_type (private)

Assumes other types are atoms.

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 100

def visit_other_type
  value = compiler.compile_as_atom(node)
  compile_value_match(value)
end

#visit_predicate (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 80

def visit_predicate
  "#{access_element}.#{node.method_name}#{compile_args(node.arg_list)}"
end

#visit_sequence (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 92

def visit_sequence
  multiple_access(:sequence) do |var|
    term = compiler.compile_sequence(node, var: var)
    "#{compile_guard_clause} && #{term}"
  end
end

#visit_unify (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 49

def visit_unify
  name = compiler.bind(node.child) do |unify_name|
    # double assign to avoid "assigned but unused variable"
    return "(#{unify_name} = #{access_element}; #{unify_name} = #{unify_name}; true)"
  end

  compile_value_match(name)
end

#visit_union (private)

Lists

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 64

def visit_union
  multiple_access(:union) do
    terms = compiler.each_union(node.children)
                    .map { |child| compile(child) }

    "(#{terms.join(' || ')})"
  end
end

#visit_wildcard (private)

[ GitHub ]

  
# File 'lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb', line 45

def visit_wildcard
  'true'
end