Skip to content

Implement `pattern` helper method for rubocop-parse

Peter Leitzen requested to merge pl-rubocop-parse-pattern into master

What does this MR do and why?

This MR adds the ability to compile and test RuboCop's node patterns interactively which is useful when implementing RuboCop cop rules.

To reduce the initial noise we no longer print the help on startup. It can be printed via help! command.

Refs

While testing !102765 (merged) I needed this functionality so I thought it'd be helpful to have it in rubocop-parse as well.

How to set up and validate locally

Interactive

$ scripts/rubocop-parse -i
Ruby version: 2.7

Type `help!` for instructions and examples.

>> help!

Use `ast(source_string, version: nil)` method to parse code and return its AST.
Use `pattern(string)` to compile RuboCop's node patterns.

See https://docs.rubocop.org/rubocop-ast/node_pattern.html.

Examples:
  node = ast('puts :hello')

  pat = pattern('`(sym :hello)')
  pat.match(node) # => true

=> nil
>> ast '<3'
Syntax error in `<3`.
=> nil
>> node = ast('puts :hello')
=>
s(:send, nil, :puts,
...
>> puts node
(send nil :puts
  (sym :hello))
=> nil
>> pat = pattern('`(sym :hello)')
=>
#<RuboCop::AST::NodePattern:0x00005600406e76c0 @pattern="`(sym :hello)", @ast=s(:descend,
...
>> pat.match(node)
=> true
>>

Eval

$ scripts/rubocop-parse -e 'puts "hello"'
(send nil :puts
  (str "hello"))

File

$ scripts/rubocop-parse app/models/project.rb | head
(begin
  (send nil :require
    (str "carrierwave/orm/activerecord"))
  (class
    (const nil :Project)
    (const nil :ApplicationRecord)
    (begin
      (send nil :include
        (const
          (const nil :Gitlab) :ConfigHelper))
 ...

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Peter Leitzen

Merge request reports