summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/psych/nodes/node.rb12
-rw-r--r--lib/psych/tree_builder.rb48
-rw-r--r--test/psych/test_tree_builder.rb14
3 files changed, 70 insertions, 4 deletions
diff --git a/lib/psych/nodes/node.rb b/lib/psych/nodes/node.rb
index 1c76721..6d86669 100644
--- a/lib/psych/nodes/node.rb
+++ b/lib/psych/nodes/node.rb
@@ -17,6 +17,18 @@ module Psych
# An associated tag
attr_reader :tag
+ # The line number where this node start
+ attr_accessor :start_line
+
+ # The column number where this node start
+ attr_accessor :start_column
+
+ # The line number where this node ends
+ attr_accessor :end_line
+
+ # The column number where this node ends
+ attr_accessor :end_column
+
# Create a new Psych::Nodes::Node
def initialize
@children = []
diff --git a/lib/psych/tree_builder.rb b/lib/psych/tree_builder.rb
index b10fd5c..47a1695 100644
--- a/lib/psych/tree_builder.rb
+++ b/lib/psych/tree_builder.rb
@@ -23,6 +23,18 @@ module Psych
@stack = []
@last = nil
@root = nil
+
+ @start_line = nil
+ @start_column = nil
+ @end_line = nil
+ @end_column = nil
+ end
+
+ def event_location(start_line, start_column, end_line, end_column)
+ @start_line = start_line
+ @start_column = start_column
+ @end_line = end_line
+ @end_column = end_column
end
%w{
@@ -32,12 +44,15 @@ module Psych
class_eval %{
def start_#{node.downcase}(anchor, tag, implicit, style)
n = Nodes::#{node}.new(anchor, tag, implicit, style)
+ set_start_location(n)
@last.children << n
push n
end
def end_#{node.downcase}
- pop
+ n = pop
+ set_end_location(n)
+ n
end
}
end
@@ -49,6 +64,7 @@ module Psych
# See Psych::Handler#start_document
def start_document version, tag_directives, implicit
n = Nodes::Document.new version, tag_directives, implicit
+ set_start_location(n)
@last.children << n
push n
end
@@ -60,26 +76,35 @@ module Psych
# See Psych::Handler#start_document
def end_document implicit_end = !streaming?
@last.implicit_end = implicit_end
- pop
+ n = pop
+ set_end_location(n)
+ n
end
def start_stream encoding
@root = Nodes::Stream.new(encoding)
+ set_start_location(@root)
push @root
end
def end_stream
- pop
+ n = pop
+ set_end_location(n)
+ n
end
def scalar value, anchor, tag, plain, quoted, style
s = Nodes::Scalar.new(value,anchor,tag,plain,quoted,style)
+ set_location(s)
@last.children << s
s
end
def alias anchor
- @last.children << Nodes::Alias.new(anchor)
+ a = Nodes::Alias.new(anchor)
+ set_location(a)
+ @last.children << a
+ a
end
private
@@ -93,5 +118,20 @@ module Psych
@last = @stack.last
x
end
+
+ def set_location(node)
+ set_start_location(node)
+ set_end_location(node)
+ end
+
+ def set_start_location(node)
+ node.start_line = @start_line
+ node.start_column = @start_column
+ end
+
+ def set_end_location(node)
+ node.end_line = @end_line
+ node.end_column = @end_column
+ end
end
end
diff --git a/test/psych/test_tree_builder.rb b/test/psych/test_tree_builder.rb
index 3e35788..dfb5da9 100644
--- a/test/psych/test_tree_builder.rb
+++ b/test/psych/test_tree_builder.rb
@@ -21,6 +21,7 @@ module Psych
def test_stream
assert_instance_of Nodes::Stream, @tree
+ assert_location 0, 0, 8, 0, @tree
end
def test_documents
@@ -31,6 +32,7 @@ module Psych
assert_equal [1,1], doc.version
assert_equal [], doc.tag_directives
assert_equal false, doc.implicit
+ assert_location 0, 0, 8, 0, doc
end
def test_sequence
@@ -43,6 +45,7 @@ module Psych
assert_nil seq.tag
assert_equal true, seq.implicit
assert_equal Nodes::Sequence::BLOCK, seq.style
+ assert_location 2, 0, 8, 0, seq
end
def test_scalar
@@ -58,6 +61,7 @@ module Psych
assert_equal true, scalar.plain
assert_equal false, scalar.quoted
assert_equal Nodes::Scalar::PLAIN, scalar.style
+ assert_location 2, 2, 2, 5, scalar
end
def test_mapping
@@ -66,6 +70,7 @@ module Psych
map = seq.children[1]
assert_instance_of Nodes::Mapping, map
+ assert_location 3, 2, 6, 1, map
end
def test_alias
@@ -75,6 +80,15 @@ module Psych
al = seq.children[2]
assert_instance_of Nodes::Alias, al
assert_equal 'A', al.anchor
+ assert_location 7, 2, 7, 4, al
+ end
+
+ private
+ def assert_location(start_line, start_column, end_line, end_column, node)
+ assert_equal start_line, node.start_line
+ assert_equal start_column, node.start_column
+ assert_equal end_line, node.end_line
+ assert_equal end_column, node.end_column
end
end
end