RuboCop AST
This gem introduces two core classes of RuboCop:
-
RuboCop::AST::Node
- this is an extension of theparser
gem’sNode
class, which adds a simpler and more powerful object-oriented API to make it easier to work with nodes. -
RuboCop::AST::NodePattern
- a regular expression-style method to traverse and match nodes in an Abstract Syntax Tree. See "Node Pattern" to get yourself familiar withNodePattern
's capabilities.
This gem may be used independently from the main RuboCop gem. It was extracted from RuboCop in version 0.84 and its only
dependency is the parser gem, which rubocop-ast extends.
|
Rationale
While working with parser
's AST representation is fairly easy (especially when compared to the AST of Ruby’s built-in ripper
library), there’s still areas we felt could be improved:
-
the canonical way to work with an AST node is to deconstruct the node in array-like fashion, which results in code that’s hard to read
-
looking for complex AST node patterns requires a lot of boilerplate code
-
there’s no easy way to tell apart AST nodes of certain types - e.g. prefix vs postfix conditionals
-
there’s no easy way to grab the parent node of some node
Enter rubocop-ast
, which aims to solve those problems. This library evolved for years as part of RuboCop and was eventually spun off in the hope that it might be useful
for other projects built on top of parser
.
RuboCop::AST::Node
provides a wrapper around parser
's Node
class (in other words, RuboCop::AST::Node < Parser::AST::Node
). In addition to a number of methods to make it easier to work with, the wrapper class also provides ways to inspect the parents of nodes, which the parser
nodes do not support.
Here are a few examples using parser
and rubocop-ast
:
|
|
|
|
|
|
Sample usage:
class MyRule < Parser::AST::Processor
include RuboCop::AST::Traversal
def on_sym(node)
puts "I found a symbol! #{node.value}"
end
end
source = RuboCop::AST::ProcessedSource.new(code, 2.7)
rule = MyRule.new
source.ast.each_node { |n| rule.process(n) }
In RuboCop AST, you can specify Prism as the parser engine backend.
If running through Bundler, please first add gem 'prism'
to your Gemfile:
gem 'prism'
By specifying parser_engine: :parser_prism
, parsing with Prism can be processed:
# Using the Parser gem with `parser_engine: parser_whitequark` is the default.
ProcessedSource.new(@options[:stdin], ruby_version, file, parser_engine: :parser_prism)
This is an experimental feature. If you encounter any incompatibilities between Prism and the Parser gem, please check the following URL: https://github.com/ruby/prism/issues?q=is%3Aissue+is%3Aopen+label%3Arubocop