RuboCop AST
原理
虽然使用 parser
的 AST 表示相当容易(尤其是与 Ruby 内置 ripper
库的 AST 相比),但我们仍然认为有些地方可以改进。
-
处理 AST 节点的规范方法是像数组一样解构节点,这会导致代码难以阅读。
-
查找复杂的 AST 节点模式需要大量样板代码。
-
没有简单的方法来区分某些类型的 AST 节点 - 例如前缀与后缀条件语句。
-
没有简单的方法来获取某个节点的父节点。
rubocop-ast
应运而生,旨在解决这些问题。这个库作为 RuboCop 的一部分发展了多年,最终被剥离出来,希望它能对其他基于 parser
的项目有所帮助。
RuboCop::AST::Node
为 parser
的 Node
类提供了一个包装器(换句话说,RuboCop::AST::Node < Parser::AST::Node
)。除了提供许多方法来简化处理之外,包装器类还提供了一种检查节点 **父节点** 的方法,而 parser
节点不支持此功能。
以下是一些使用 parser
和 rubocop-ast
的示例。
|
|
|
|
|
|
示例用法
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) }
在 RuboCop AST 中,您可以指定 Prism 作为解析器引擎后端。
如果通过 Bundler 运行,请先将 gem 'prism'
添加到您的 Gemfile 中。
gem 'prism'
通过指定 parser_engine: :parser_prism
,可以使用 Prism 进行解析。
# Using the Parser gem with `parser_engine: parser_whitequark` is the default.
ProcessedSource.new(@options[:stdin], ruby_version, file, parser_engine: :parser_prism)
这是一个实验性功能。如果您在 Prism 和 Parser gem 之间遇到任何不兼容性,请查看以下 URL:https://github.com/ruby/prism/issues?q=is%3Aissue+is%3Aopen+label%3Arubocop