From 722dd4d2dc233458a49f154b926ea666d2cdb324 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Sat, 18 Apr 2009 18:44:18 +0200 Subject: [PATCH] * IListOps.Difference now uses Object#hash and Object#eql? to check for object equality, this fixes the failing spec "Array#- acts as if using an intermediate hash to collect values" * Modified IListOps.RecursiveJoin to make it flag the resulting string as tainted if the given array, at least one of its elements or the separator string are tainted. * Changed IListOps.Repetition to return IList instances of the same type of the given self argument (this fixes also "Array#* with an integer returns subclass instance with Array subclasses") * Various changes to IListOps.Join to clear all of the remaining tags for the specs of Array#join. The tags marked as critical in join_tags.txt are not related to pending bugs for Array#join. * Added ArrayOps.ToAry as Array#to_a and Array#to_ary behave differently on subclasses of arrays. * Cleaning up tags removing expectations that do not fail anymore. * Changed one overload of IListOps.Equals to make it try to call #to_ary on the object argument of Array#== and use the resulting array as the actual argument for the equality check. * Changed IListOps.SetElement to make it try to invoke #to_ary on its argument for multi-element sets. * Changed IListOps.Reverse to return IList instances of the same type of the given self argument (this change also fixes the following failing spec: "Array#reverse returns subclass instance on Array subclasses") * Fixed IListOps.ReverseIndex as Array#rindex should not fail if elements are removed from the array during the iteration over its elements. * Slightly modified IListOps.UniqueSelf as suggested upon review. --- .../core/array/element_set_tags.txt | 1 - .../core/array/equal_value_tags.txt | 1 - .../core/array/intersection_tags.txt | 1 - .../ironruby-tags/core/array/join_tags.txt | 7 -- .../ironruby-tags/core/array/minus_tags.txt | 1 - .../core/array/multiply_tags.txt | 4 - .../ironruby-tags/core/array/new_tags.txt | 1 - .../ironruby-tags/core/array/reverse_tags.txt | 1 - .../ironruby-tags/core/array/rindex_tags.txt | 1 - .../ironruby-tags/core/array/union_tags.txt | 1 - .../ironruby-tags/core/array/uniq_tags.txt | 2 - .../mspec/ironruby-tags/critical_tags.txt | 4 - .../Builtins/ArrayOps.cs | 6 +- .../Extensions/IListOps.cs | 105 +++++++++++++----- .../Initializers.Generated.cs | 24 ++-- 15 files changed, 92 insertions(+), 68 deletions(-) delete mode 100644 Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/element_set_tags.txt delete mode 100644 Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/intersection_tags.txt delete mode 100644 Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/minus_tags.txt delete mode 100644 Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/reverse_tags.txt delete mode 100644 Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/rindex_tags.txt delete mode 100644 Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/union_tags.txt delete mode 100644 Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/uniq_tags.txt diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/element_set_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/element_set_tags.txt deleted file mode 100644 index ef7274c95f..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/element_set_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#[]= calls to_ary on its rhs argument for multi-element sets diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/equal_value_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/equal_value_tags.txt index b5d724ac30..3b032d009b 100644 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/equal_value_tags.txt +++ b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/equal_value_tags.txt @@ -1,2 +1 @@ fails:Array#== returns false if any element is not == to the corresponding element in the other the array -fails:Array#== calls to_ary on its argument diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/intersection_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/intersection_tags.txt deleted file mode 100644 index 77faa49cf6..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/intersection_tags.txt +++ /dev/null @@ -1 +0,0 @@ -critical:Array#& properly handles recursive arrays diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/join_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/join_tags.txt index 5ac63a91aa..b1c6b6caab 100644 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/join_tags.txt +++ b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/join_tags.txt @@ -1,12 +1,5 @@ critical:Array#join raises a NoMethodError if an element does not respond to #to_s critical:Array#join raises a NoMethodError if an element does not respond to #to_s -fails:Array#join tries to convert the passed seperator to a String using #to_str -fails:Array#join checks whether the passed seperator responds to #to_str -fails:Array#join handles recursive arrays -fails:Array#join does not consider taint of either the array or the separator when the array is empty -fails:Array#join returns a string which would be infected with taint of the array, its elements or the separator when the array is not empty -fails:Array#join does not process the separator if the array is empty -fails:Array#join raises a TypeError if the passed separator is not a string and does not respond to #to_str critical:Array#join raises a NoMethodError if an element does not respond to #to_s critical:Array#join raises a NoMethodError if an element does not respond to #to_s critical:Array#join raises a NoMethodError if an element does not respond to #to_s diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/minus_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/minus_tags.txt deleted file mode 100644 index 666ca276f7..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/minus_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#- acts as if using an intermediate hash to collect values diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/multiply_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/multiply_tags.txt index 8395a65c22..a4cbc90882 100644 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/multiply_tags.txt +++ b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/multiply_tags.txt @@ -1,8 +1,4 @@ -fails:Array#* with an integer returns subclass instance with Array subclasses -fails:Array#* with an integer copies the taint status of the original array even if the array is empty -fails:Array#* with an integer copies the taint status of the original array if the passed count is not 0 critical:Array#* with a string raises a NoMethodError if an element does not respond to #to_s -fails:Array#* with a string returns a string which would be infected with taint of the array, its elements or the separator when the array is not empty critical:Array#* with a string raises a NoMethodError if an element does not respond to #to_s critical:Array#* with a string raises a NoMethodError if an element does not respond to #to_s critical:Array#* with a string raises a NoMethodError if an element does not respond to #to_s diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/new_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/new_tags.txt index e523d385b0..30bd079468 100644 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/new_tags.txt +++ b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/new_tags.txt @@ -1,2 +1 @@ fails:Array.new with (size, object=nil) raises an ArgumentError if size is too large -fails:Array.new with (size, object=nil) uses the block value instead of using the default value diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/reverse_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/reverse_tags.txt deleted file mode 100644 index ec9e60dd48..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/reverse_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#reverse returns subclass instance on Array subclasses diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/rindex_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/rindex_tags.txt deleted file mode 100644 index 62445a0160..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/rindex_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Array#rindex does not fail when removing elements from block diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/union_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/union_tags.txt deleted file mode 100644 index 513d88c16a..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/union_tags.txt +++ /dev/null @@ -1 +0,0 @@ -critical:Array#| properly handles recursive arrays diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/uniq_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/uniq_tags.txt deleted file mode 100644 index 8cad6e155f..0000000000 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/uniq_tags.txt +++ /dev/null @@ -1,2 +0,0 @@ -critical:Array#uniq properly handles recursive arrays -critical:Array#uniq! properly handles recursive arrays diff --git a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/critical_tags.txt b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/critical_tags.txt index e71cabc35d..364868d8b1 100644 --- a/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/critical_tags.txt +++ b/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/critical_tags.txt @@ -16,12 +16,8 @@ core\argf\path_tags.txt:0:critical:ARGF.path it sets the $FILENAME global variab core\argf\rewind_tags.txt:0:critical:ARGF.rewind goes back to beginning of current file core\argf\to_i_tags.txt:0:critical:ARGF.to_i returns the current file number on each file core\argf\to_io_tags.txt:0:critical:ARGF.to_io returns the IO of the current file -core\array\intersection_tags.txt:0:critical:Array#& properly handles recursive arrays core\array\join_tags.txt:0:critical:Array#join raises a NoMethodError if an element does not respond to #to_s core\array\join_tags.txt:0:critical:Array#join does not separates elements when the passed separator is nil -core\array\union_tags.txt:0:critical:Array#| properly handles recursive arrays -core\array\uniq_tags.txt:0:critical:Array#uniq properly handles recursive arrays -core\array\uniq_tags.txt:0:critical:Array#uniq! properly handles recursive arrays core\kernel\sleep_tags.txt:3:critical:Kernel#sleep pauses execution indefinitely if not given a duration core\process\times_tags.txt:0:unstable:Process.times returns current cpu times core\string\process\wait_tags.txt:0:critical:Process.wait diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs index 8b72440cfa..6b379d32b4 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs @@ -171,11 +171,15 @@ public static class ArrayOps { #endregion [RubyMethod("to_a")] - [RubyMethod("to_ary")] public static RubyArray/*!*/ ToArray(RubyArray/*!*/ self) { return self is RubyArray.Subclass ? new RubyArray(self) : self; } + [RubyMethod("to_ary")] + public static RubyArray/*!*/ ToAry(RubyArray/*!*/ self) { + return self; + } + #region class FormatDirective is used by Array.pack and String.unpack internal struct FormatDirective { 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 36086fa849..b509fca7d1 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs @@ -186,14 +186,20 @@ public static class IListOps { #region *, +, concat [RubyMethod("*")] - public static RubyArray/*!*/ Repetition(IList/*!*/ self, int repeat) { + public static IList/*!*/ Repetition(CallSiteStorage>/*!*/ allocateStorage, IList/*!*/ self, int repeat) { if (repeat < 0) { throw RubyExceptions.CreateArgumentError("negative argument"); } - RubyArray result = new RubyArray(self.Count * repeat); + + IList result = CreateResultArray(allocateStorage, self); + if (result is RubyArray) { + (result as RubyArray).Capacity = self.Count * repeat; + } for (int i = 0; i < repeat; ++i) { AddRange(result, self); } + + allocateStorage.Context.TaintObjectBy(result, self); return result; } @@ -203,10 +209,10 @@ public static class IListOps { } [RubyMethod("*")] - public static object Repetition(ConversionStorage/*!*/ tosConversion, IList/*!*/ self, [DefaultProtocol]Union repeat) { + public static object Repetition(CallSiteStorage>/*!*/ allocateStorage, ConversionStorage/*!*/ tosConversion, IList/*!*/ self, [DefaultProtocol]Union repeat) { if (repeat.IsFixnum()) { - return Repetition(self, repeat.Fixnum()); + return Repetition(allocateStorage, self, repeat.Fixnum()); } else { return Repetition(tosConversion, self, repeat.String()); } @@ -230,13 +236,25 @@ public static class IListOps { } [RubyMethod("-")] - public static RubyArray/*!*/ Difference(BinaryOpStorage/*!*/ equals, IList/*!*/ self, [DefaultProtocol, NotNull]IList/*!*/ other) { + public static RubyArray/*!*/ Difference(RubyContext/*!*/ context, IList/*!*/ self, [DefaultProtocol, NotNull]IList/*!*/ other) { + // MRI follows hashing semantics here, so doesn't actually call eql?/hash for Fixnum/Symbol + IEqualityComparer comparer = context.EqualityComparer; RubyArray result = new RubyArray(); - + // TODO: optimize this - foreach (object element in self) { - if (!Include(equals, other, element)) { - result.Add(element); + foreach (object selfElement in self) { + bool found = false; + foreach (object otherElement in other) { + bool sameHashcode = comparer.GetHashCode(selfElement) == comparer.GetHashCode(otherElement); + bool isEql = comparer.Equals(selfElement, otherElement); + if (sameHashcode && isEql) { + found = true; + break; + } + } + + if (!found) { + result.Add(selfElement); } } @@ -248,8 +266,9 @@ public static class IListOps { #region ==, <=>, eql?, hash [RubyMethod("==")] - public static bool Equals(IList/*!*/ self, object other) { - return false; + public static bool Equals(ConversionStorage/*!*/ arrayTryCast, BinaryOpStorage/*!*/ equals, IList/*!*/ self, object other) { + IList otherAsArray = Protocols.TryCastToArray(arrayTryCast, other); + return otherAsArray != null ? Equals(equals, self, otherAsArray) : false; } [MultiRuntimeAware] @@ -409,8 +428,9 @@ public static class IListOps { } [RubyMethod("[]=")] - public static object SetElement(RubyContext/*!*/ context, IList/*!*/ self, [DefaultProtocol]int index, [DefaultProtocol]int length, object value) { - RubyUtils.RequiresNotFrozen(context, self); + public static object SetElement(ConversionStorage/*!*/ arrayTryCast, IList/*!*/ self, + [DefaultProtocol]int index, [DefaultProtocol]int length, object value) { + RubyUtils.RequiresNotFrozen(arrayTryCast.Context, self); if (length < 0) { throw RubyExceptions.CreateIndexError(String.Format("negative length ({0})", length)); @@ -422,12 +442,15 @@ public static class IListOps { } IList valueAsList = value as IList; + if (valueAsList == null) { + valueAsList = Protocols.TryCastToArray(arrayTryCast, value); + } if (value == null || (valueAsList != null && valueAsList.Count == 0)) { DeleteItems(self, index, length); } else { if (valueAsList == null) { - Insert(context, self, index, value); + Insert(arrayTryCast.Context, self, index, value); if (length > 0) { RemoveRange(self, index + 1, Math.Min(length, self.Count - index - 1)); @@ -459,7 +482,8 @@ public static class IListOps { } [RubyMethod("[]=")] - public static object SetElement(ConversionStorage/*!*/ fixnumCast, IList/*!*/ self, [NotNull]Range/*!*/ range, object value) { + public static object SetElement(ConversionStorage/*!*/ arrayTryCast, ConversionStorage/*!*/ fixnumCast, + IList/*!*/ self, [NotNull]Range/*!*/ range, object value) { RubyUtils.RequiresNotFrozen(fixnumCast.Context, self); int begin = Protocols.CastToFixnum(fixnumCast, range.Begin); @@ -473,7 +497,7 @@ public static class IListOps { end = end < 0 ? end + self.Count : end; int count = range.ExcludeEnd ? end - begin : end - begin + 1; - return SetElement(fixnumCast.Context, self, begin, Math.Max(count, 0), value); + return SetElement(arrayTryCast, self, begin, Math.Max(count, 0), value); } #endregion @@ -1010,10 +1034,13 @@ public static class IListOps { [RubyMethod("rindex")] public static object ReverseIndex(BinaryOpStorage/*!*/ equals, IList/*!*/ self, object item) { - for (int i = self.Count - 1; i >= 0; i--) { + for (int originalSize = self.Count, i = originalSize - 1; i >= 0; i--) { if (Protocols.IsEqual(equals, self[i], item)) { return i; } + if (self.Count < originalSize) { + i = originalSize - i - 1 + self.Count; + } } return null; } @@ -1083,6 +1110,7 @@ public static class IListOps { IList/*!*/ list, MutableString/*!*/ separator, MutableString/*!*/ result, Dictionary/*!*/ seen) { Assert.NotNull(list, separator, result, seen); + RubyContext context = tosConversion.Context; // TODO: can we get by only tracking List<> ? // (inspect needs to track everything) bool found; @@ -1109,6 +1137,12 @@ public static class IListOps { } } + if (!result.IsTainted){ + if (context.IsObjectTainted(list) || context.IsObjectTainted(item) || separator.IsTainted) { + result.IsTainted = true; + } + } + if (i < list.Count - 1) { result.Append(separator); } @@ -1124,9 +1158,16 @@ public static class IListOps { } [RubyMethod("join")] - public static MutableString/*!*/ Join(ConversionStorage/*!*/ tosConversion, IList/*!*/ self, MutableString separator) { + public static MutableString/*!*/ Join(ConversionStorage/*!*/ tosConversion, ConversionStorage/*!*/ tostrConversion, IList/*!*/ self, Object separator) { + if (self.Count == 0) { + return MutableString.Empty; + } + return Join(tosConversion, self, separator != null ? Protocols.CastToString(tostrConversion, separator) : MutableString.Empty); + } + + public static MutableString/*!*/ Join(ConversionStorage/*!*/ tosConversion, IList/*!*/ self, MutableString/*!*/ separator) { MutableString result = MutableString.CreateMutable(); - RecursiveJoin(tosConversion, self, separator ?? MutableString.Empty, result, + RecursiveJoin(tosConversion, self, separator ?? MutableString.Empty, result, new Dictionary(ReferenceEqualityComparer.Instance) ); return result; @@ -1270,12 +1311,12 @@ public static class IListOps { #region slice! [RubyMethod("slice!")] - public static object SliceInPlace(RubyContext/*!*/ context, IList/*!*/ self, [DefaultProtocol]int index) { - RubyUtils.RequiresNotFrozen(context, self); + public static object SliceInPlace(ConversionStorage/*!*/ arrayTryCast, IList/*!*/ self, [DefaultProtocol]int index) { + RubyUtils.RequiresNotFrozen(arrayTryCast.Context, self); index = index < 0 ? index + self.Count : index; if (index >= 0 && index < self.Count) { object result = self[index]; - SetElement(context, self, index, 1, null); + SetElement(arrayTryCast, self, index, 1, null); return result; } else { return null; @@ -1283,21 +1324,23 @@ public static class IListOps { } [RubyMethod("slice!")] - public static object SliceInPlace(ConversionStorage/*!*/ fixnumCast, + public static object SliceInPlace(ConversionStorage/*!*/ arrayTryCast, + ConversionStorage/*!*/ fixnumCast, CallSiteStorage>/*!*/ allocateStorage, IList/*!*/ self, [NotNull]Range/*!*/ range) { RubyUtils.RequiresNotFrozen(fixnumCast.Context, self); object result = GetElement(fixnumCast, allocateStorage, self, range); - SetElement(fixnumCast, self, range, null); + SetElement(arrayTryCast, fixnumCast, self, range, null); return result; } [RubyMethod("slice!")] - public static IList/*!*/ SliceInPlace(CallSiteStorage>/*!*/ allocateStorage, + public static IList/*!*/ SliceInPlace(ConversionStorage/*!*/ arrayTryCast, + CallSiteStorage>/*!*/ allocateStorage, IList/*!*/ self, [DefaultProtocol]int start, [DefaultProtocol]int length) { RubyUtils.RequiresNotFrozen(allocateStorage.Context, self); IList result = GetElements(allocateStorage, self, start, length); - SetElement(allocateStorage.Context, self, start, length, null); + SetElement(arrayTryCast, self, start, length, null); return result; } @@ -1342,8 +1385,11 @@ public static class IListOps { #region reverse, reverse!, transpose, uniq, uniq! [RubyMethod("reverse")] - public static RubyArray/*!*/ Reverse(IList/*!*/ self) { - RubyArray reversedList = new RubyArray(self.Count); + public static IList/*!*/ Reverse(CallSiteStorage>/*!*/ allocateStorage, IList/*!*/ self) { + IList reversedList = CreateResultArray(allocateStorage, self); + if (reversedList is RubyArray) { + (reversedList as RubyArray).Capacity = self.Count; + } for (int i = 0; i < self.Count; i++) { reversedList.Add(self[self.Count - i - 1]); } @@ -1411,7 +1457,6 @@ public static class IListOps { [RubyMethod("uniq!")] public static IList UniqueSelf(RubyContext/*!*/ context, IList/*!*/ self) { var seen = new Dictionary(context.EqualityComparer); - bool frozen = context.IsObjectFrozen(self); bool modified = false; int i = 0; while (i < self.Count) { @@ -1420,7 +1465,7 @@ public static class IListOps { seen.Add(key, true); i++; } else { - if (frozen) { + if (context.IsObjectFrozen(self)) { throw RubyExceptions.CreateTypeError("can't modify frozen array"); } self.RemoveAt(i); 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 a5c1938624..76d491afb8 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs @@ -439,7 +439,7 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia ); module.DefineLibraryMethod("to_ary", 0x51, - new System.Func(IronRuby.Builtins.ArrayOps.ToArray) + new System.Func(IronRuby.Builtins.ArrayOps.ToAry) ); } @@ -4989,7 +4989,7 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia private static void LoadSystem__Collections__IList_Instance(IronRuby.Builtins.RubyModule/*!*/ module) { module.DefineLibraryMethod("-", 0x51, - new System.Func(IronRuby.Builtins.IListOps.Difference) + new System.Func(IronRuby.Builtins.IListOps.Difference) ); module.DefineLibraryMethod("&", 0x51, @@ -4997,9 +4997,9 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia ); module.DefineLibraryMethod("*", 0x51, - new System.Func(IronRuby.Builtins.IListOps.Repetition), + new System.Func>, System.Collections.IList, System.Int32, System.Collections.IList>(IronRuby.Builtins.IListOps.Repetition), new System.Func, System.Collections.IList, IronRuby.Builtins.MutableString, IronRuby.Builtins.MutableString>(IronRuby.Builtins.IListOps.Repetition), - new System.Func, System.Collections.IList, IronRuby.Runtime.Union, System.Object>(IronRuby.Builtins.IListOps.Repetition) + new System.Func>, IronRuby.Runtime.ConversionStorage, System.Collections.IList, IronRuby.Runtime.Union, System.Object>(IronRuby.Builtins.IListOps.Repetition) ); module.DefineLibraryMethod("[]", 0x51, @@ -5010,8 +5010,8 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia module.DefineLibraryMethod("[]=", 0x51, new System.Func(IronRuby.Builtins.IListOps.SetElement), - new System.Func(IronRuby.Builtins.IListOps.SetElement), - new System.Func, System.Collections.IList, IronRuby.Builtins.Range, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement) + new System.Func, System.Collections.IList, System.Int32, System.Int32, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement), + new System.Func, IronRuby.Runtime.ConversionStorage, System.Collections.IList, IronRuby.Builtins.Range, System.Object, System.Object>(IronRuby.Builtins.IListOps.SetElement) ); module.DefineLibraryMethod("|", 0x51, @@ -5031,7 +5031,7 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia ); module.DefineLibraryMethod("==", 0x51, - new System.Func(IronRuby.Builtins.IListOps.Equals), + new System.Func, IronRuby.Runtime.BinaryOpStorage, System.Collections.IList, System.Object, System.Boolean>(IronRuby.Builtins.IListOps.Equals), new System.Func(IronRuby.Builtins.IListOps.Equals) ); @@ -5154,7 +5154,7 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia module.DefineLibraryMethod("join", 0x51, new System.Func, System.Collections.IList, IronRuby.Builtins.MutableString>(IronRuby.Builtins.IListOps.Join), - new System.Func, System.Collections.IList, IronRuby.Builtins.MutableString, IronRuby.Builtins.MutableString>(IronRuby.Builtins.IListOps.Join) + new System.Func, IronRuby.Runtime.ConversionStorage, System.Collections.IList, System.Object, IronRuby.Builtins.MutableString>(IronRuby.Builtins.IListOps.Join) ); module.DefineLibraryMethod("last", 0x51, @@ -5195,7 +5195,7 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia ); module.DefineLibraryMethod("reverse", 0x51, - new System.Func(IronRuby.Builtins.IListOps.Reverse) + new System.Func>, System.Collections.IList, System.Collections.IList>(IronRuby.Builtins.IListOps.Reverse) ); module.DefineLibraryMethod("reverse!", 0x51, @@ -5221,9 +5221,9 @@ public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitia ); module.DefineLibraryMethod("slice!", 0x51, - new System.Func(IronRuby.Builtins.IListOps.SliceInPlace), - new System.Func, IronRuby.Runtime.CallSiteStorage>, System.Collections.IList, IronRuby.Builtins.Range, System.Object>(IronRuby.Builtins.IListOps.SliceInPlace), - new System.Func>, System.Collections.IList, System.Int32, System.Int32, System.Collections.IList>(IronRuby.Builtins.IListOps.SliceInPlace) + new System.Func, System.Collections.IList, System.Int32, System.Object>(IronRuby.Builtins.IListOps.SliceInPlace), + new System.Func, IronRuby.Runtime.ConversionStorage, IronRuby.Runtime.CallSiteStorage>, System.Collections.IList, IronRuby.Builtins.Range, System.Object>(IronRuby.Builtins.IListOps.SliceInPlace), + new System.Func, IronRuby.Runtime.CallSiteStorage>, System.Collections.IList, System.Int32, System.Int32, System.Collections.IList>(IronRuby.Builtins.IListOps.SliceInPlace) ); module.DefineLibraryMethod("sort", 0x51,