Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
RubyVM::InstructionSequence#syntax_tree
# File tmp/rubies/ruby-4.1.0-preview1/ast.rb, line 356
def syntax_tree
source_hash = self.source_hash
return nil unless source_hash
# When the source is kept in memory (RubyVM.keep_script_lines), use it
# instead of the file. This also works for eval'ed code.
if (lines = script_lines)
source = lines.join
else
path = absolute_path
return nil unless path && File.file?(path)
end
node_id = self.node_id
if Primitive.iseq_compiled_by_prism_p
# Ruby::Prism is the parser built into the interpreter, i.e., the very
# parser that parsed the source of this instruction sequence, so
# node_id always corresponds. The prism gem (if any) is not involved.
result = source ? Ruby::Prism.parse(source, version: "current") : Ruby::Prism.parse_file(path, version: "current")
return nil unless result.success?
# Hash exactly the bytes that prism parsed. The data section after an
# __END__ marker is not part of the code, so the hash covers the source
# only up to the end of the __END__ line.
code = result.source.source
if (data_loc = result.data_loc) && (eol = code.byteindex("\n", data_loc.start_offset))
code = code.byteslice(0, eol + 1)
end
return nil unless Primitive.source_hash_of(code) == source_hash
root = result.value
else
begin
root = source ? RubyVM::AbstractSyntaxTree.parse(source, keep_script_lines: true) :
RubyVM::AbstractSyntaxTree.parse_file(path, keep_script_lines: true)
rescue SyntaxError
# The source has been modified into invalid Ruby.
return nil
end
return nil unless Primitive.ast_node_source_hash(root) == source_hash
return Primitive.ast_node_find(root, node_id)
end
return root if root.node_id == node_id
queue = [root]
while (node = queue.shift)
node.compact_child_nodes.each do |child|
if child.node_id == node_id
# A block iseq refers to the block node itself. Return the outer
# node that owns the block (a CallNode, SuperNode, or
# ForwardingSuperNode) instead.
return child.type == :block_node ? node : child
end
queue << child
end
end
nil
end
Returns the AST node that this instruction sequence was compiled from, by re-parsing the source with the same parser that compiled it: a Ruby::Prism::Node if it was compiled by prism, or a RubyVM::AbstractSyntaxTree::Node if it was compiled by parse.y.
Returns nil whenever the node cannot be retrieved reliably. For example: the source is not available (such as eval’ed code without RubyVM.keep_script_lines enabled), or the source file has been modified since it was compiled.
The node is a Ruby::Prism::Node, not a node of the prism gem: Ruby::Prism is the parser built into the interpreter, so the returned tree always corresponds to the running code regardless of which version of the prism gem is installed.
This method is experimental and might change without notice.