diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/compact_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/compact_tags.txt deleted file mode 100644 index ec03984a7b..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/compact_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#compact keeps tainted status even if all elements are removed diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/delete_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/delete_tags.txt index 8af82dff10..e6af7e8972 100644 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/delete_tags.txt +++ b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/delete_tags.txt @@ -1,2 +1 @@ fails:Array#delete removes elements that are #== to object -fails:Array#delete may be given a block that is executed if no element matches object diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/fetch_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/fetch_tags.txt deleted file mode 100644 index 4c55ffa90d..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/fetch_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#fetch passes the original index argument object to the block, not the converted Integer diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/first_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/first_tags.txt deleted file mode 100644 index 51b296aaeb..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/first_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#first does not return subclass instance when passed count on Array subclasses diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/flatten_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/flatten_tags.txt deleted file mode 100644 index 4d65226be8..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/flatten_tags.txt +++ /dev/null @@ -1,2 +0,0 @@ -fails:Array#flatten does not call flatten on elements -fails:Array#flatten returns subclass instance for Array subclasses diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/last_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/last_tags.txt deleted file mode 100644 index a3781f1556..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/last_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#last does not return subclass instance on Array subclasses diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs index 2dac7c5800..f6a6fd8580 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs @@ -572,6 +572,8 @@ public static class IListOps { } } + allocateStorage.Context.TaintObjectBy(result, self); + return result; } @@ -620,7 +622,7 @@ public static class IListOps { public static object Delete(BinaryOpStorage/*!*/ equals, BlockParam block, IList/*!*/ self, object item) { bool removed = Remove(equals, self, item); - if (block != null) { + if (!removed && block != null) { object result; block.Yield(out result); return result; @@ -732,24 +734,37 @@ public static class IListOps { #region fetch [RubyMethod("fetch")] - public static object Fetch(RubyContext/*!*/ context, BlockParam outOfRangeValueProvider, IList/*!*/ list, [DefaultProtocol]int index, [Optional]object defaultValue) { - int oldIndex = index; - if (InRangeNormalized(list, ref index)) { - return list[index]; + public static object Fetch( + RespondToStorage/*!*/ respondToStorage, + CallSiteStorage>/*!*/ toIntStorage, + BlockParam outOfRangeValueProvider, + IList/*!*/ list, + object/*!*/ index, + [Optional]object defaultValue) { + + if (!Protocols.RespondTo(respondToStorage, index, "to_int")) { + throw RubyExceptions.CannotConvertTypeToTargetType(respondToStorage.Context, index, "Integer"); + } + + var toInt = toIntStorage.GetCallSite("to_int", 0); + int convertedIndex = toInt.Target(toInt, index); + + if (InRangeNormalized(list, ref convertedIndex)) { + return list[convertedIndex]; } if (outOfRangeValueProvider != null) { if (defaultValue != Missing.Value) { - context.ReportWarning("block supersedes default value argument"); + respondToStorage.Context.ReportWarning("block supersedes default value argument"); } object result; - outOfRangeValueProvider.Yield(oldIndex, out result); + outOfRangeValueProvider.Yield(index, out result); return result; } - + if (defaultValue == Missing.Value) { - throw RubyExceptions.CreateIndexError("index " + index + " out of array"); + throw RubyExceptions.CreateIndexError("index " + convertedIndex + " out of array"); } return defaultValue; } @@ -879,7 +894,7 @@ public static class IListOps { } count = count > self.Count ? self.Count : count; - return GetResultRange(allocateStorage, self, 0, count); + return RubyArray.Create(self as IList, 0, count); } [RubyMethod("last")] @@ -895,7 +910,7 @@ public static class IListOps { } count = count > self.Count ? self.Count : count; - return GetResultRange(allocateStorage, self, self.Count - count, count); + return RubyArray.Create(self as IList, self.Count - count, count); } #endregion @@ -906,12 +921,11 @@ public static class IListOps { private static RubyUtils.RecursionTracker _infiniteFlattenTracker = new RubyUtils.RecursionTracker(); public static bool TryFlattenArray( - CallSiteStorage>/*!*/ flattenStorage, + CallSiteStorage>/*!*/ allocateStorage, ConversionStorage/*!*/ tryToAry, IList list, out IList/*!*/ result) { - // TODO: create correct subclass of RubyArray rather than RubyArray directly - result = new RubyArray(); + result = CreateResultArray(allocateStorage, list); using (IDisposable handle = _infiniteFlattenTracker.TrackObject(list)) { if (handle == null) { @@ -922,14 +936,13 @@ public static class IListOps { IList item = Protocols.TryCastToArray(tryToAry, list[i]); if (item != null) { flattened = true; - var flatten = flattenStorage.GetCallSite("flatten", 0); + IList flattenedList; - object flattenedItem = flatten.Target(flatten, item); - IList flattenedList = Protocols.TryCastToArray(tryToAry, flattenedItem); + TryFlattenArray(allocateStorage, tryToAry, item, out flattenedList); if (flattenedList != null) { AddRange(result, flattenedList); } else { - result.Add(flattenedItem); + result.Add(item); } } else { result.Add(list[i]); @@ -941,21 +954,21 @@ public static class IListOps { [RubyMethod("flatten")] public static IList/*!*/ Flatten( - CallSiteStorage>/*!*/ flattenStorage, + CallSiteStorage>/*!*/ allocateStorage, ConversionStorage/*!*/ tryToAry, RubyContext/*!*/ context, IList/*!*/ self) { IList result; - TryFlattenArray(flattenStorage, tryToAry, self, out result); + TryFlattenArray(allocateStorage, tryToAry, self, out result); return result; } [RubyMethod("flatten!")] public static IList FlattenInPlace( - CallSiteStorage>/*!*/ flattenStorage, + CallSiteStorage>/*!*/ allocateStorage, ConversionStorage/*!*/ tryToAry, RubyContext/*!*/ context, IList/*!*/ self) { IList result; - if (!TryFlattenArray(flattenStorage, tryToAry, self, out result)) { + if (!TryFlattenArray(allocateStorage, tryToAry, self, out result)) { return null; } diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs index 3e17894dbc..213c2b2066 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs @@ -5071,7 +5071,7 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia ); module.DefineLibraryMethod("fetch", 0x51, - new System.Func(IronRuby.Builtins.IListOps.Fetch) + new System.Func>, IronRuby.Runtime.BlockParam, System.Collections.IList, System.Object, System.Object, System.Object>(IronRuby.Builtins.IListOps.Fetch) ); module.DefineLibraryMethod("fill", 0x51, @@ -5091,11 +5091,11 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia ); module.DefineLibraryMethod("flatten", 0x51, - new System.Func>, IronRuby.Runtime.ConversionStorage, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.Flatten) + new System.Func>, IronRuby.Runtime.ConversionStorage, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.Flatten) ); module.DefineLibraryMethod("flatten!", 0x51, - new System.Func>, IronRuby.Runtime.ConversionStorage, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.FlattenInPlace) + new System.Func>, IronRuby.Runtime.ConversionStorage, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.FlattenInPlace) ); module.DefineLibraryMethod("hash", 0x51,