Module: RubyVM::AbstractSyntaxTree
Overview
AbstractSyntaxTree provides methods to parse ::Ruby code into
abstract syntax trees. The nodes in the tree
are instances of Node.
This module is MRI specific as it exposes implementation details of the MRI abstract syntax tree.
This module is experimental and its API is not stable, therefore it might change without notice. As examples, the order of children nodes is not guaranteed, the number of children nodes might change, there is no way to access children nodes by name, etc.
Prism is the official ::Ruby API to parse ::Ruby code. It has a stable API
and is available on most ::Ruby implementations.
Therefore, it is the recommended replacement.
Using AbstractSyntaxTree is discouraged for new code for the reasons
above and because AbstractSyntaxTree might become deprecated in the future.
Class Method Summary
-
.node_id_for_backtrace_location(backtrace_location) ⇒ Integer
Returns the node id for the given backtrace location.
-
.of(proc, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) ⇒ AbstractSyntaxTree
Returns AST nodes of the given proc or method.
-
.parse(string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) ⇒ AbstractSyntaxTree
Parses the given string into an abstract syntax tree, returning the root node of that tree.
-
.parse_file(pathname, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) ⇒ AbstractSyntaxTree
Reads the file from pathname, then parses it like .parse, returning the root node of the abstract syntax tree.
Class Method Details
.node_id_for_backtrace_location(backtrace_location) ⇒ Integer
Returns the node id for the given backtrace location.
begin
raise
rescue => e
loc = e.backtrace_locations.first
RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc)
end # => 0
# File 'ast.rb', line 112
def self.node_id_for_backtrace_location backtrace_location Primitive.node_id_for_backtrace_location backtrace_location end
.of(proc, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) ⇒ AbstractSyntaxTree
.of(method, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) ⇒ AbstractSyntaxTree
AbstractSyntaxTree
.of(method, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) ⇒ AbstractSyntaxTree
Returns AST nodes of the given proc or method.
RubyVM::AbstractSyntaxTree.of(proc {1 + 2})
# => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:35-1:42>
def hello
puts "hello, world"
end
RubyVM::AbstractSyntaxTree.of(method(:hello))
# => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-3:3>
See .parse for explanation of keyword argument meaning and usage.
# File 'ast.rb', line 97
def self.of body, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false Primitive.ast_s_of body, keep_script_lines, error_tolerant, keep_tokens end
.parse(string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) ⇒ AbstractSyntaxTree
Parses the given string into an abstract syntax tree, returning the root node of that tree.
RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
# => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:9>
If keep_script_lines: true option is provided, the text of the parsed source is associated with nodes and is available via Node#script_lines.
If keep_tokens: true option is provided, Node#tokens are populated.
::SyntaxError is raised if the given string is invalid syntax. To overwrite this
behavior, error_tolerant: true can be provided. In this case, the parser
will produce a tree where expressions with syntax errors would be represented by
AbstractSyntaxTree::Node with type=:ERROR.
root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2")
# <internal:ast>:33:in `parse': syntax error, unexpected ';', expecting ')' (SyntaxError)
# x = 1; p(x; y=2
# ^
root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2", error_tolerant: true)
# (SCOPE@1:0-1:15
# tbl: [:x, :y]
# args: nil
# body: (BLOCK@1:0-1:15 (LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)) (ERROR@1:7-1:11) (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))))
root.children.last.children
# [(LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)),
# (ERROR@1:7-1:11),
# (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))]
Note that parsing continues even after the errored expression.
# File 'ast.rb', line 59
def self.parse string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false Primitive.ast_s_parse string, keep_script_lines, error_tolerant, keep_tokens end
.parse_file(pathname, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) ⇒ AbstractSyntaxTree
Reads the file from pathname, then parses it like .parse, returning the root node of the abstract syntax tree.
::SyntaxError is raised if pathname's contents are not
valid ::Ruby syntax.
RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb")
# => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
See .parse for explanation of keyword argument meaning and usage.
# File 'ast.rb', line 76
def self.parse_file pathname, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false Primitive.ast_s_parse_file pathname, keep_script_lines, error_tolerant, keep_tokens end