From 2f3998851148a1b95f9f4e5b6ccf48a9400c33cc Mon Sep 17 00:00:00 2001 From: tenderlove Date: Sun, 16 May 2010 23:50:23 +0000 Subject: * ext/psych/lib/psych/emitter.rb: removing unused file. * ext/psych/lib/psych/json/tree_builder.rb: moving tree builder to an event based external class. * ext/psych/lib/psych/tree_builder.rb: adding an end_stream event. * ext/psych/lib/psych/visitors/json_tree.rb: using event based AST builder. * ext/psych/lib/psych/visitors/yaml_tree.rb: using event based AST builder. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27855 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/psych/lib/psych.rb | 1 + ext/psych/lib/psych/emitter.rb | 4 - ext/psych/lib/psych/json/tree_builder.rb | 24 +++++ ext/psych/lib/psych/tree_builder.rb | 21 ++-- ext/psych/lib/psych/visitors/json_tree.rb | 32 ++---- ext/psych/lib/psych/visitors/yaml_tree.rb | 163 +++++++++++++----------------- 6 files changed, 118 insertions(+), 127 deletions(-) delete mode 100644 ext/psych/lib/psych/emitter.rb create mode 100644 ext/psych/lib/psych/json/tree_builder.rb diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb index 6c892c5393..464fae499e 100644 --- a/ext/psych/lib/psych.rb +++ b/ext/psych/lib/psych.rb @@ -3,6 +3,7 @@ require 'psych/nodes' require 'psych/visitors' require 'psych/handler' require 'psych/tree_builder' +require 'psych/json/tree_builder' require 'psych/parser' require 'psych/omap' require 'psych/set' diff --git a/ext/psych/lib/psych/emitter.rb b/ext/psych/lib/psych/emitter.rb deleted file mode 100644 index b06ad3ac49..0000000000 --- a/ext/psych/lib/psych/emitter.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Psych - class Emitter < Psych::Handler - end -end diff --git a/ext/psych/lib/psych/json/tree_builder.rb b/ext/psych/lib/psych/json/tree_builder.rb new file mode 100644 index 0000000000..91d7e6cad6 --- /dev/null +++ b/ext/psych/lib/psych/json/tree_builder.rb @@ -0,0 +1,24 @@ +module Psych + module JSON + ### + # Psych::JSON::TreeBuilder is an event based AST builder. Events are sent + # to an instance of Psych::JSON::TreeBuilder and a JSON AST is constructed. + class TreeBuilder < Psych::TreeBuilder + def start_document version, tag_directives, implicit + super(version, tag_directives, true) + end + + def end_document implicit_end + super(true) + end + + def start_mapping anchor, tag, implicit, style + super(anchor, tag, implicit, Nodes::Mapping::FLOW) + end + + def start_sequence anchor, tag, implicit, style + super(anchor, tag, implicit, Nodes::Sequence::FLOW) + end + end + end +end diff --git a/ext/psych/lib/psych/tree_builder.rb b/ext/psych/lib/psych/tree_builder.rb index 2b16290b8f..54d87a0b61 100644 --- a/ext/psych/lib/psych/tree_builder.rb +++ b/ext/psych/lib/psych/tree_builder.rb @@ -14,15 +14,14 @@ module Psych # See Psych::Handler for documentation on the event methods used in this # class. class TreeBuilder < Psych::Handler + # Returns the root node for the built tree + attr_reader :root + # Create a new TreeBuilder instance def initialize @stack = [] @last = nil - end - - # Returns the root node for the built tree - def root - @stack.first + @root = nil end %w{ @@ -48,7 +47,7 @@ module Psych # # See Psych::Handler#start_document def start_document version, tag_directives, implicit - n = Nodes::Document.new(version, tag_directives, implicit) + n = Nodes::Document.new version, tag_directives, implicit @last.children << n push n end @@ -64,7 +63,12 @@ module Psych end def start_stream encoding - push Nodes::Stream.new(encoding) + @root = Nodes::Stream.new(encoding) + push @root + end + + def end_stream + pop end def scalar value, anchor, tag, plain, quoted, style @@ -82,8 +86,9 @@ module Psych end def pop - @stack.pop + x = @stack.pop @last = @stack.last + x end end end diff --git a/ext/psych/lib/psych/visitors/json_tree.rb b/ext/psych/lib/psych/visitors/json_tree.rb index 774b043ba4..0ec1678a39 100644 --- a/ext/psych/lib/psych/visitors/json_tree.rb +++ b/ext/psych/lib/psych/visitors/json_tree.rb @@ -1,14 +1,16 @@ module Psych module Visitors class JSONTree < YAMLTree + def initialize options = {}, emitter = Psych::JSON::TreeBuilder.new + super + end + def visit_NilClass o - scalar = create_scalar( - 'null', nil, nil, true, false, Nodes::Scalar::PLAIN) - append scalar + @emitter.scalar 'null', nil, nil, true, false, Nodes::Scalar::PLAIN end def visit_Integer o - append create_scalar(o.to_s, nil, nil, true, false, Nodes::Scalar::PLAIN) + @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::PLAIN end def visit_Float o @@ -17,31 +19,11 @@ module Psych end def visit_String o - append create_scalar o.to_s + @emitter.scalar o.to_s, nil, nil, false, true, Nodes::Scalar::ANY end alias :visit_Symbol :visit_String private - def create_document - doc = super - doc.implicit = true - doc.implicit_end = true - doc - end - - def create_mapping - map = super - map.style = Nodes::Mapping::FLOW - map - end - - def create_scalar value, anchor = nil, tag = nil, plain = false, quoted = true, style = Nodes::Scalar::ANY - super - end - - def create_sequence anchor = nil, tag = nil, implicit = true, style = Nodes::Sequence::FLOW - super - end end end end diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index 608da6d1a0..4adb8d4c66 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -1,14 +1,20 @@ module Psych module Visitors + ### + # YAMLTree builds a YAML ast given a ruby object. For example: + # + # builder = Psych::Visitors::YAMLTree.new + # builder << { :foo => 'bar' } + # builder.tree # => # v } - @stack.pop + @emitter.end_sequence end def visit_Object o @@ -71,54 +79,48 @@ module Psych tag = ['!ruby/object', klass].compact.join(':') end - map = append create_mapping(nil, tag, false) + map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) register(o, map) - @stack.push map - dump_ivars(o, map) - @stack.pop + dump_ivars o + @emitter.end_mapping end def visit_Struct o tag = ['!ruby/struct', o.class.name].compact.join(':') - map = register(o, create_mapping(nil, tag, false)) - - @stack.push append map - + register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) o.members.each do |member| - map.children << create_scalar("#{member}") + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY accept o[member] end - dump_ivars(o, map) + dump_ivars o - @stack.pop + @emitter.end_mapping end def visit_Exception o tag = ['!ruby/exception', o.class.name].join ':' - map = append create_mapping(nil, tag, false) - - @stack.push map + @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK { 'message' => private_iv_get(o, 'mesg'), 'backtrace' => private_iv_get(o, 'backtrace'), }.each do |k,v| next unless v - map.children << create_scalar(k) + @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY accept v end - dump_ivars(o, map) + dump_ivars o - @stack.pop + @emitter.end_mapping end def visit_Regexp o - append create_scalar(o.inspect, nil, '!ruby/regexp', false) + @emitter.scalar o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY end def visit_Time o @@ -129,29 +131,34 @@ module Psych formatted += ".%06d %+.2d:00" % [o.usec, o.gmt_offset / 3600] end - append create_scalar formatted + @emitter.scalar formatted, nil, nil, true, false, Nodes::Scalar::ANY end def visit_Rational o - map = append create_mapping(nil, '!ruby/object:Rational', false) + @emitter.start_mapping(nil, '!ruby/object:Rational', false, Nodes::Mapping::BLOCK) + [ 'denominator', o.denominator.to_s, 'numerator', o.numerator.to_s ].each do |m| - map.children << create_scalar(m) + @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY end + + @emitter.end_mapping end def visit_Complex o - map = append create_mapping(nil, '!ruby/object:Complex', false) + @emitter.start_mapping(nil, '!ruby/object:Complex', false, Nodes::Mapping::BLOCK) ['real', o.real.to_s, 'image', o.imag.to_s].each do |m| - map.children << create_scalar(m) + @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY end + + @emitter.end_mapping end def visit_Integer o - append create_scalar o.to_s + @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY end alias :visit_TrueClass :visit_Integer alias :visit_FalseClass :visit_Integer @@ -159,11 +166,12 @@ module Psych def visit_Float o if o.nan? - append create_scalar '.nan' + @emitter.scalar '.nan', nil, nil, true, false, Nodes::Scalar::ANY elsif o.infinite? - append create_scalar(o.infinite? > 0 ? '.inf' : '-.inf') + @emitter.scalar((o.infinite? > 0 ? '.inf' : '-.inf'), + nil, nil, true, false, Nodes::Scalar::ANY) else - append create_scalar o.to_s + @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY end end @@ -186,19 +194,16 @@ module Psych ivars = find_ivars o - scalar = create_scalar str, nil, tag, plain, quote, style - if ivars.empty? - append scalar + @emitter.scalar str, nil, tag, plain, quote, style else - mapping = append create_mapping(nil, '!str', false) + @emitter.start_mapping nil, '!str', false, Nodes::Mapping::BLOCK + @emitter.scalar 'str', nil, nil, true, false, Nodes::Scalar::ANY + @emitter.scalar str, nil, tag, plain, quote, style - mapping.children << create_scalar('str') - mapping.children << scalar + dump_ivars o - @stack.push mapping - dump_ivars o, mapping - @stack.pop + @emitter.end_mapping end end @@ -207,47 +212,47 @@ module Psych end def visit_Range o - @stack.push append create_mapping(nil, '!ruby/range', false) + @emitter.start_mapping nil, '!ruby/range', false, Nodes::Mapping::BLOCK ['begin', o.begin, 'end', o.end, 'excl', o.exclude_end?].each do |m| accept m end - @stack.pop + @emitter.end_mapping end def visit_Hash o - @stack.push append register(o, create_mapping) + register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| accept k accept v end - @stack.pop + @emitter.end_mapping end def visit_Psych_Set o - @stack.push append register(o, create_mapping(nil, '!set', false)) + register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| accept k accept v end - @stack.pop + @emitter.end_mapping end def visit_Array o - @stack.push append register(o, create_sequence) + register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK) o.each { |c| accept c } - @stack.pop + @emitter.end_sequence end def visit_NilClass o - append create_scalar('', nil, 'tag:yaml.org,2002:null', false) + @emitter.scalar('', nil, 'tag:yaml.org,2002:null', false, false, Nodes::Scalar::ANY) end def visit_Symbol o - append create_scalar ":#{o}" + @emitter.scalar ":#{o}", nil, nil, true, false, Nodes::Scalar::ANY end private @@ -264,11 +269,6 @@ module Psych target.instance_variables end - def append o - @stack.last.children << o - o - end - def register target, yaml_obj @st[target.object_id] = yaml_obj yaml_obj @@ -289,48 +289,31 @@ module Psych def emit_coder c case c.type when :scalar - append create_scalar(c.scalar, nil, c.tag, c.tag.nil?) + @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, Nodes::Scalar::ANY when :seq - @stack.push append create_sequence(nil, c.tag, c.tag.nil?) + @emitter.start_sequence nil, c.tag, c.tag.nil?, Nodes::Sequence::BLOCK c.seq.each do |thing| accept thing end - @stack.pop + @emitter.end_sequence when :map - map = append create_mapping(nil, c.tag, c.implicit, c.style) - @stack.push map + @emitter.start_mapping nil, c.tag, c.implicit, c.style c.map.each do |k,v| - map.children << create_scalar(k) + @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY accept v end - @stack.pop + @emitter.end_mapping end end - def dump_ivars target, map + def dump_ivars target ivars = find_ivars target ivars.each do |iv| - map.children << create_scalar("#{iv.to_s.sub(/^@/, '')}") + @emitter.scalar("#{iv.to_s.sub(/^@/, '')}", nil, nil, true, false, Nodes::Scalar::ANY) accept target.instance_variable_get(iv) end end - - def create_document version = [], tag_directives = [], implicit = false - Nodes::Document.new version, tag_directives, implicit - end - - def create_mapping anchor = nil, tag = nil, implicit = true, style = Psych::Nodes::Mapping::BLOCK - Nodes::Mapping.new anchor, tag, implicit, style - end - - def create_scalar value, anchor = nil, tag = nil, plain = true, quoted = false, style = Nodes::Scalar::ANY - Nodes::Scalar.new(value, anchor, tag, plain, quoted, style) - end - - def create_sequence anchor = nil, tag = nil, implicit = true, style = Nodes::Sequence::BLOCK - Nodes::Sequence.new(anchor, tag, implicit, style) - end end end end -- cgit v1.2.3