summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast.c12
-rw-r--r--ast.rb15
-rw-r--r--test/ruby/test_ast.rb13
3 files changed, 40 insertions, 0 deletions
diff --git a/ast.c b/ast.c
index c9d0b41fac..93c33a1f8d 100644
--- a/ast.c
+++ b/ast.c
@@ -196,6 +196,18 @@ script_lines(VALUE path)
}
static VALUE
+node_id_for_backtrace_location(rb_execution_context_t *ec, VALUE module, VALUE location)
+{
+ int node_id;
+ node_id = rb_get_node_id_from_frame_info(location);
+ if (node_id == -1) {
+ return Qnil;
+ }
+
+ return INT2NUM(node_id);
+}
+
+static VALUE
ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script_lines, VALUE error_tolerant)
{
VALUE node, lines = Qnil;
diff --git a/ast.rb b/ast.rb
index 24fd8e5526..1bc1168b80 100644
--- a/ast.rb
+++ b/ast.rb
@@ -67,6 +67,21 @@ module RubyVM::AbstractSyntaxTree
Primitive.ast_s_of body, keep_script_lines, error_tolerant
end
+ # call-seq:
+ # RubyVM::AbstractSyntaxTree.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
+ def self.node_id_for_backtrace_location backtrace_location
+ Primitive.node_id_for_backtrace_location backtrace_location
+ end
+
# RubyVM::AbstractSyntaxTree::Node instances are created by parse methods in
# RubyVM::AbstractSyntaxTree.
#
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index aaf626e801..0932e93d5a 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -186,6 +186,19 @@ class TestAst < Test::Unit::TestCase
end
end
+ def test_node_id_for_location
+ exception = begin
+ raise
+ rescue => e
+ e
+ end
+ loc = exception.backtrace_locations.first
+ node_id = RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc)
+ node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
+
+ assert_equal node.node_id, node_id
+ end
+
def test_of_proc_and_method
proc = Proc.new { 1 + 2 }
method = self.method(__method__)