Skip to content

Commit

Permalink
Added support to YAML.quick_emit to be called on nested objects where…
Browse files Browse the repository at this point in the history
… the same emitter needs to be flowed through

Array.pack("a") was not dealing with nil input
yaml.rb should to "require stringio" like MRI does
Deleted a second copy of yaml.rb from the IronRuby.Libraries.Yaml folder
Added MutableString.Dump property to be able to inspect large strings in VS.
ir.exe -X:ExceptionDetail was not working in interactive mode because ir.exe catches the exception and does not call RubyExceptionData.SetCompiledTrace like a rescue block in Ruby code would do. Fixed this
  • Loading branch information
Shri Borde committed Mar 13, 2009
1 parent f45cbfc commit a5d2d23
Show file tree
Hide file tree
Showing 32 changed files with 461 additions and 60 deletions.
Expand Up @@ -62,6 +62,7 @@ public static class YamlObjectOps {
public static MutableString TagUri(RubyContext/*!*/ context, object self) {
MutableString str = MutableString.Create("!ruby/object:");
str.Append(RubyUtils.GetClassName(context, self));
str.Append(' ');
return str;
}
}
Expand Down
Expand Up @@ -18,7 +18,8 @@
namespace IronRuby.StandardLibrary.Yaml {
public sealed class YamlLibraryInitializer : IronRuby.Builtins.LibraryInitializer {
protected override void LoadModules() {
IronRuby.Builtins.RubyClass classRef0 = GetClass(typeof(IronRuby.Builtins.RubyObject));
IronRuby.Builtins.RubyClass classRef0 = GetClass(typeof(IronRuby.StandardLibrary.Yaml.Representer));
IronRuby.Builtins.RubyClass classRef1 = GetClass(typeof(IronRuby.Builtins.RubyObject));


ExtendModule(typeof(IronRuby.Builtins.FalseClass), LoadIronRuby__Builtins__FalseClass_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
Expand All @@ -36,15 +37,18 @@ public sealed class YamlLibraryInitializer : IronRuby.Builtins.LibraryInitialize
ExtendModule(typeof(Microsoft.Scripting.Math.BigInteger), LoadMicrosoft__Scripting__Math__BigInteger_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
ExtendModule(typeof(Microsoft.Scripting.Runtime.DynamicNull), LoadMicrosoft__Scripting__Runtime__DynamicNull_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
ExtendModule(typeof(Microsoft.Scripting.SymbolId), LoadMicrosoft__Scripting__SymbolId_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
DefineGlobalClass("Out", typeof(IronRuby.StandardLibrary.Yaml.RubyRepresenter), true, classRef0, LoadOut_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
ExtendModule(typeof(System.DateTime), LoadSystem__DateTime_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
ExtendModule(typeof(System.Double), LoadSystem__Double_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
ExtendModule(typeof(System.Exception), LoadSystem__Exception_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
ExtendClass(typeof(System.Object), LoadSystem__Object_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
IronRuby.Builtins.RubyModule def1 = DefineGlobalModule("YAML", typeof(IronRuby.StandardLibrary.Yaml.RubyYaml), true, null, LoadYAML_Class, null, IronRuby.Builtins.RubyModule.EmptyArray);
IronRuby.Builtins.RubyClass def2 = DefineClass("YAML::Stream", typeof(IronRuby.StandardLibrary.Yaml.RubyYaml.YamlStream), true, classRef0, LoadYAML__Stream_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray,
IronRuby.Builtins.RubyModule def2 = DefineModule("YAML::BaseNode", typeof(IronRuby.StandardLibrary.Yaml.RubyYaml.BaseNode), true, null, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
IronRuby.Builtins.RubyClass def3 = DefineClass("YAML::Stream", typeof(IronRuby.StandardLibrary.Yaml.RubyYaml.YamlStream), true, classRef1, LoadYAML__Stream_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray,
new System.Func<IronRuby.Builtins.RubyClass, IronRuby.Builtins.Hash, IronRuby.StandardLibrary.Yaml.RubyYaml.YamlStream>(IronRuby.StandardLibrary.Yaml.RubyYaml.YamlStream.CreateStream)
);
def1.SetConstant("Stream", def2);
def1.SetConstant("BaseNode", def2);
def1.SetConstant("Stream", def3);
}

private static void LoadIronRuby__Builtins__FalseClass_Instance(IronRuby.Builtins.RubyModule/*!*/ module) {
Expand Down Expand Up @@ -208,6 +212,13 @@ public sealed class YamlLibraryInitializer : IronRuby.Builtins.LibraryInitialize

}

private static void LoadOut_Instance(IronRuby.Builtins.RubyModule/*!*/ module) {
module.DefineLibraryMethod("map", 0x11,
new System.Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.StandardLibrary.Yaml.RubyRepresenter, IronRuby.Builtins.MutableString, System.Object, IronRuby.StandardLibrary.Yaml.Node>(IronRuby.StandardLibrary.Yaml.RubyRepresenter.Map)
);

}

private static void LoadSystem__DateTime_Instance(IronRuby.Builtins.RubyModule/*!*/ module) {
module.DefineLibraryMethod("taguri", 0x11,
new System.Func<System.DateTime, IronRuby.Builtins.MutableString>(IronRuby.StandardLibrary.Yaml.DateTimeOps.TagUri)
Expand Down Expand Up @@ -319,7 +330,7 @@ public sealed class YamlLibraryInitializer : IronRuby.Builtins.LibraryInitialize
);

module.DefineLibraryMethod("quick_emit", 0x21,
new System.Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyModule, System.Object, System.Object[], System.Object>(IronRuby.StandardLibrary.Yaml.RubyYaml.QuickEmit)
new System.Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyModule, System.Object, System.Object, System.Object>(IronRuby.StandardLibrary.Yaml.RubyYaml.QuickEmit)
);

module.DefineLibraryMethod("quick_emit_node", 0x21,
Expand Down
Expand Up @@ -25,6 +25,7 @@

namespace IronRuby.StandardLibrary.Yaml {

[RubyClass("Out")]
public class RubyRepresenter : Representer {
private readonly RubyContext/*!*/ _context;

Expand Down Expand Up @@ -125,14 +126,25 @@ public RubyRepresenter(RubyContext/*!*/ context, Serializer/*!*/ serializer, Yam
internal Node/*!*/ Map(object self, IDictionary/*!*/ map) {
MutableString taguri = GetTagUri(self);
object style = ToYamlStyle(self);
return Map(taguri, style, map);
}

internal Node/*!*/ Map(MutableString taguri, object to_yaml_style, IDictionary/*!*/ map) {
return Map(
taguri != null ? taguri.ConvertToString() : "",
taguri != null ? taguri.ConvertToString() : "tag:yaml.org,2002:map",
map,
RubyOps.IsTrue(style)
RubyOps.IsTrue(to_yaml_style)
);
}

[RubyMethod("map")]
public static Node/*!*/ Map(RubyContext/*!*/ context, [NotNull]BlockParam/*!*/ block, RubyRepresenter/*!*/ self, [DefaultProtocol]MutableString taguri, object to_yaml_style) {
var map = new Dictionary<object, object>();
object blockResult;
block.Yield(map, out blockResult);
return self.Map(taguri, to_yaml_style ?? false, map);
}

internal Node Sequence(object self, RubyArray seq) {
MutableString taguri = GetTagUri(self);
MutableString style = ToYamlStyle(self);
Expand Down
Expand Up @@ -27,6 +27,10 @@ namespace IronRuby.StandardLibrary.Yaml {

[RubyModule("YAML")]
public static partial class RubyYaml {

[RubyModule("BaseNode")]
public static class BaseNode { }

private const string _TaggedClasses = "tagged_classes";

// TODO: missing public singleton methods:
Expand Down Expand Up @@ -243,19 +247,26 @@ public static partial class RubyYaml {
}

[RubyMethod("quick_emit", RubyMethodAttributes.PublicSingleton)]
public static object QuickEmit(RubyContext/*!*/ context, BlockParam/*!*/ block, RubyModule/*!*/ self, object objectId, params object[] opts) {
if (block == null) {
throw RubyExceptions.NoBlockGiven();
}
MutableStringWriter writer = new MutableStringWriter();
//We currently don't support serialization options, so we just ignore opts argument
YamlOptions cfg = YamlOptions.DefaultOptions;
using (Serializer s = new Serializer(new Emitter(writer, cfg), cfg)) {
RubyRepresenter r = new RubyRepresenter(context, s, cfg);
public static object QuickEmit(RubyContext/*!*/ context, [NotNull]BlockParam/*!*/ block, RubyModule/*!*/ self, object objectId, [NotNull]object/*!*/ opts) {
if (opts is Hash) {
YamlOptions cfg = YamlOptions.DefaultOptions;
MutableStringWriter writer = new MutableStringWriter();
Emitter emitter = new Emitter(writer, cfg);

using (Serializer s = new Serializer(emitter, cfg)) {
RubyRepresenter r = new RubyRepresenter(context, s, cfg);
object result;
block.Yield(r, out result);
s.Serialize(result as Node);

return writer.String;
}
} else if (opts is RubyRepresenter) {
object result;
block.Yield(r, out result);
s.Serialize(result as Node);
return writer.String;
block.Yield(opts as RubyRepresenter, out result);
return result as Node;
} else {
throw RubyExceptions.CreateUnexpectedTypeError(context, opts, "Hash");
}
}

Expand Down

This file was deleted.

Expand Up @@ -5,7 +5,6 @@ fails:Array#pack just ignores unknown format
fails:Array#pack ignores white spaces
fails:Array#pack skips everything till the end of line (LF) string with ('#')
fails:Array#pack returns a tainted string when a pack argument is tainted
fails:Array#pack reuses last array element as often as needed to complete the string
fails:Array#pack with format 'B' returns packed bit-string descending order
fails:Array#pack with format 'B' accepts characters other than 0 or 1 for compatibility to perl
fails:Array#pack with format 'B' conversion edge case: all zeros
Expand Down
@@ -0,0 +1 @@
fails:YAML.each_node invokes block with a BaseNode
@@ -0,0 +1,2 @@
fails:YAML.emitter is of type Emitter
fails:YAML.emitter has a default level of 0
@@ -0,0 +1,5 @@
fails:YAML.quick_emit returns a BaseNode node if emitter level is non-zero
fails:YAML.quick_emit passes Out to block
fails:YAML.quick_emit accepts Emitter argument
fails:YAML.quick_emit requires opts parameter to be a Hash or Emitter
fails:YAML.quick_emit requires a block
Expand Up @@ -2,3 +2,5 @@ fails:Object#to_yaml returns the YAML representation of an Array object
fails:Object#to_yaml returns the YAML representation of a Date object
fails:Object#to_yaml returns the YAML representation of a Time object
fails:Object#to_yaml returns the YAML representation of numeric constants
fails:Object#to_yaml calls to_yaml on nested objects
fails:Object#to_yaml calls to_yaml on nested objects with Emitter
@@ -0,0 +1,2 @@
fails:Zlib::GzipWriter#flush raises BufError if called multiple times without writing data
fails:Zlib::GzipWriter#flush Zlib::FINISH closes the writer
Expand Up @@ -166,6 +166,11 @@ def self.format(count = nil)
["abc", "def"].pack(format('*')+format('*')).should == "abcdef"
end

it "handles nil" do
[nil].pack(format(0)).should == ""
[nil].pack(format('*')).should == ""
end

it "tries to convert the pack argument to a String using #to_str" do
obj = mock('to_str')
obj.should_receive(:to_str).and_return("abc")
Expand Down Expand Up @@ -227,6 +232,10 @@ def self.format(count = nil)
it "returns space padded string" do
['abcde'].pack('A7').should == 'abcde '
end

it "handles nil" do
[nil].pack(format('1')).should == " "
end
end

describe "Array#pack with format 'a'" do
Expand All @@ -235,6 +244,10 @@ def self.format(count = nil)
it "returns null padded string with ('a<count>')" do
['abcdef'].pack('a7').should == "abcdef\x0"
end

it "handles nil" do
[nil].pack(format('1')).should == "\000"
end
end

describe "Array#pack with format 'Z'" do
Expand All @@ -243,6 +256,10 @@ def self.format(count = nil)
it "returns null padded string with ('a<count>')" do
['abcdef'].pack('a7').should == "abcdef\x0"
end

it "handles nil" do
[nil].pack(format('1')).should == "\000"
end
end

describe "Array#pack with format 'B'" do
Expand Down
Expand Up @@ -112,9 +112,13 @@ def read size=2048

class StubReaderWithClose < StubReader
def close *args
end
end

class Undef_to_s
undef to_s
if self.methods.include?(:to_s) then
undef to_s
end
end

class InitializeMethod
Expand Down
@@ -1,2 +1,26 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require File.dirname(__FILE__) + '/fixtures/common'
require File.dirname(__FILE__) + '/fixtures/strings'

describe "YAML.each_node" do
it "invokes block with a BaseNode" do
node = nil
YAML.each_node(StringIO.new($test_yaml_string)) { |n| node = n }
node.should be_kind_of(YAML::BaseNode)
not_compliant_on :ironruby do
node.should be_kind_of(YAML::Syck::Map)
end
end

it "invokes block once for a simple string " do
i = 0
YAML.each_node(StringIO.new($test_yaml_string)) { |node| i = i + 1 }
i.should == 1
end

it "invokes block n times for a string with n documents" do
i = 0
YAML.each_node(StringIO.new($multidocument)) { |node| i = i + 1 }
i.should == 2
end
end
@@ -1,2 +1,15 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require File.dirname(__FILE__) + '/fixtures/common'

describe "YAML.emitter" do
it "is of type Emitter" do
(YAML.emitter.methods - Object.new.methods).sort.should == YamlSpecs::EmitterMethods
not_compliant_on :ironruby do
YAML.emitter.class.should == YAML::Syck::Emitter
end
end

it "has a default level of 0" do
YAML.emitter.level.should == 0
end
end
@@ -1,4 +1,75 @@
require 'yaml'
require File.dirname(__FILE__) + '/strings'

$test_file = tmp("yaml_test_file")
$test_parse_file = File.dirname(__FILE__) + "/test_yaml.yml"

module YamlSpecs
EmitterMethods = ["emit", "level", "level=", "node_export", "reset", "set_resolver"]
OutMethods = ["emitter", "emitter=", "map", "scalar", "seq"]

def self.get_a_node
io = StringIO.new($test_yaml_string)
YAML.each_node(io) { |node| return node }
end

def self.write_to_emitter out, h
out.map(nil, nil) do |map|
h.each_pair { |k, v| map.add(k, v) }
end
end

class Outer
def initialize
@outer1 = 1
@outer2 = Inner.new
end
end

class Inner
def initialize
@inner1 = 1
@inner2 = 2
end
end

class OuterToYaml
def initialize
@outer1 = 1
@outer2 = InnerToYaml.new
end

def inner
@outer2
end
end

class InnerToYaml
def initialize
@inner1 = 1
@inner2 = 2
end

def to_yaml emitter
if ScratchPad.recorded != nil then
ScratchPad.recorded[:emitter] = emitter
if emitter.respond_to? :level then
ScratchPad.recorded[:level] = emitter.level
end
end

node = YAML::quick_emit(nil, emitter) do |out|
out.map("tag:ruby.yaml.org,2002:object:YamlSpecs::InnerToYaml", to_yaml_style) do |map|
map.add("inner1", @inner1)
map.add("inner2", @inner2)
end
end

if ScratchPad.recorded != nil then
ScratchPad.recorded[:result] = node
end

node
end
end
end
Expand Up @@ -11,6 +11,12 @@
2001-08-14 ]
EOY

$test_yaml_string =
<<EOY
project:
name: RubySpec
EOY

$to_yaml_hash =
<<EOY
-
Expand Down

0 comments on commit a5d2d23

Please sign in to comment.