module RuboCop::AST::NodePattern::MethodDefiner

Functionality to turn `match_code` into methods/lambda

Public Instance Methods

as_lambda() click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 37
def as_lambda
  eval(compile_as_lambda) # rubocop:disable Security/Eval
end
compile_as_lambda() click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 27
        def compile_as_lambda
          <<~RUBY
            ->(#{emit_params('param0')}, block: nil) do
              #{VAR} = param0
              #{compile_init}
              #{emit_lambda_code}
            end
          RUBY
        end
def_node_matcher(base, method_name, **defaults) click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 8
        def def_node_matcher(base, method_name, **defaults)
          def_helper(base, method_name, **defaults) do |name|
            params = emit_params('param0 = self')
            <<~RUBY
              def #{name}(#{params})
                #{VAR} = param0
                #{compile_init}
                #{emit_method_code}
              end
            RUBY
          end
        end

Private Instance Methods

compile_init() click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 139
def compile_init
  "captures = Array.new(#{captures})" if captures.positive?
end
def_helper(base, method_name, **defaults) { |method_name| ... } click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 50
def def_helper(base, method_name, **defaults)
  location = caller_locations(3, 1).first
  unless defaults.empty?
    call = :"without_defaults_#{method_name}"
    base.send :define_method, method_name, &wrapping_block(call, **defaults)
    method_name = call
  end
  src = yield method_name
  base.class_eval(src, location.path, location.lineno)

  method_name
end
emit_keyword_list(forwarding: false) click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 114
def emit_keyword_list(forwarding: false)
  pattern = "%<keyword>s: #{'%<keyword>s' if forwarding}"
  named_parameters.map { |k| format(pattern, keyword: k) }.join(',')
end
emit_lambda_code() click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 132
        def emit_lambda_code
          <<~RUBY
            return unless #{match_code}
            block ? #{emit_yield_capture(yield_with: 'block.call')} : (return #{emit_retval})
          RUBY
        end
emit_method_code() click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 125
        def emit_method_code
          <<~RUBY
            return unless #{match_code}
            block_given? ? #{emit_yield_capture} : (return #{emit_retval})
          RUBY
        end
emit_node_search_body(method_name, prelude:, on_match:) click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 74
        def emit_node_search_body(method_name, prelude:, on_match:)
          <<~RUBY
            def #{method_name}(#{emit_params('param0')})
              #{compile_init}
              #{prelude}
              param0.each_node do |#{VAR}|
                if #{match_code}
                  #{on_match}
                end
              end
              nil
            end
          RUBY
        end
emit_param_list() click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 110
def emit_param_list
  (1..positional_parameters).map { |n| "param#{n}" }.join(',')
end
emit_params(*first, forwarding: false) click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 119
def emit_params(*first, forwarding: false)
  params = emit_param_list
  keywords = emit_keyword_list(forwarding: forwarding)
  [*first, params, keywords].reject(&:empty?).join(',')
end
emit_retval() click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 100
def emit_retval
  if captures.zero?
    'true'
  elsif captures == 1
    'captures[0]'
  else
    'captures'
  end
end
emit_yield_capture(when_no_capture = '', yield_with: 'yield') click to toggle source
# File lib/rubocop/ast/node_pattern/method_definer.rb, line 89
def emit_yield_capture(when_no_capture = '', yield_with: 'yield')
  yield_val = if captures.zero?
                when_no_capture
              elsif captures == 1
                'captures[0]' # Circumvent https://github.com/jruby/jruby/issues/5710
              else
                '*captures'
              end
  "#{yield_with}(#{yield_val})"
end
wrapping_block(method_name, **defaults) click to toggle source

This method minimizes the closure for our method

# File lib/rubocop/ast/node_pattern/method_definer.rb, line 44
def wrapping_block(method_name, **defaults)
  proc do |*args, **values|
    send method_name, *args, **defaults, **values
  end
end