edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C438696
File: RubyTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C438696 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;RubyBugFixesII
@@ -96,7 +96,10 @@
MethodUndefExpression,
Scenario_Assignment1,
SetterCallValue,
+ SimpleInplaceAsignmentToIndirectLeftValues1,
MemberAssignmentExpression1,
+ MemberAssignmentExpression2,
+ MemberAssignmentExpression3,
Scenario_ParallelAssignment1,
Scenario_ParallelAssignment2,
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/AssignmentTests.cs;C437359
File: AssignmentTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/AssignmentTests.cs;C437359 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/AssignmentTests.cs;RubyBugFixesII
@@ -266,6 +266,47 @@
");
}
+ ///
+ /// ArrayItemAccess and AttributeAccess read target ones in an in-place assignment.
+ ///
+ public void SimpleInplaceAsignmentToIndirectLeftValues1() {
+ AssertOutput(delegate {
+ CompilerTest(@"
+class Array
+ def x; 1; end
+ def x= value; puts 'x=' end
+end
+
+def foo
+ puts 'foo'
+ [0]
+end
+
+p foo[0] += 1
+p foo::x += 2
+p foo[0] &&= 3
+p foo::x &&= 4
+p foo[0] ||= 5
+p foo::x ||= 6
+");
+ }, @"
+foo
+1
+foo
+x=
+3
+foo
+3
+foo
+x=
+4
+foo
+0
+foo
+1
+");
+ }
+
public void SetterCallValue() {
AssertOutput(delegate {
CompilerTest(@"
@@ -296,5 +337,95 @@
nil");
}
+
+ private const string/*!*/ MemberAssignmentDefs = @"
+class String
+ def + other
+ puts ""#{self} + #{other}""
+ ""#{self}#{other}""
+ end
+end
+
+class C
+ def x= value
+ puts ""write: #{value}""
+ end
+
+ def x
+ puts ""read""
+ $result
+ end
+end
+
+def target
+ puts 'target'
+ C.new
+end
+
+def rhs
+ puts 'rhs'
+ '_rhs'
+end
+";
+
+ public void MemberAssignmentExpression1() {
+ AssertOutput(delegate {
+ CompilerTest(MemberAssignmentDefs + @"
+$result = 'result'
+puts(target.x += rhs)
+");
+ }, @"
+target
+read
+rhs
+result + _rhs
+write: result_rhs
+result_rhs
+");
+ }
+
+ public void MemberAssignmentExpression2() {
+ AssertOutput(delegate {
+ CompilerTest(MemberAssignmentDefs + @"
+$result = true
+puts(target.x &&= rhs)
+puts
+$result = false
+puts(target.x &&= rhs)
+");
+ }, @"
+target
+read
+rhs
+write: _rhs
+_rhs
+
+target
+read
+false
+");
+ }
+
+ public void MemberAssignmentExpression3() {
+ AssertOutput(delegate {
+ CompilerTest(MemberAssignmentDefs + @"
+$result = true
+puts(target.x ||= rhs)
+puts
+$result = false
+puts(target.x ||= rhs)
+");
+ }, @"
+target
+read
+true
+
+target
+read
+rhs
+write: _rhs
+_rhs
+");
+ }
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MethodTests.cs;C438696
File: MethodTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MethodTests.cs;C438696 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MethodTests.cs;RubyBugFixesII
@@ -85,38 +85,5 @@
}, @"123");
}
-
- public void MemberAssignmentExpression1() {
- AssertOutput(delegate {
- CompilerTest(@"
-class String
- def + other
- puts ""#{self} + #{other}""
- ""#{self}#{other}""
- end
-end
-
-class C
- def x= value
- puts ""write: #{value}""
- end
-
- def x
- puts ""read""
- 'result'
- end
-end
-
-z = C.new
-
-puts(z.x += '_rhs')
-");
- }, @"
-read
-result + _rhs
-write: result_rhs
-result_rhs
-");
- }
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;C438696
File: Initializer.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;C438696 (server) 5/15/2008 10:40 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;RubyBugFixesII
@@ -44,7 +44,7 @@
#endif
// Skipped primitive: Object
Ruby.Builtins.RubyModule def33 = DefineModule("System::Collections::Generic::IDictionary", typeof(System.Collections.Generic.IDictionary), new System.Action(LoadSystem__Collections__Generic__IDictionary_Instance), null, new Ruby.Builtins.RubyModule[] {def28, });
- DefineModule("System::Collections::IEnumerable", typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def28, });
+ Ruby.Builtins.RubyModule def47 = DefineModule("System::Collections::IEnumerable", typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def28, });
Ruby.Builtins.RubyModule def40 = DefineModule("System::Collections::IList", typeof(System.Collections.IList), new System.Action(LoadSystem__Collections__IList_Instance), null, new Ruby.Builtins.RubyModule[] {def28, });
DefineModule("System::IComparable", typeof(System.IComparable), new System.Action(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def38, });
DefineGlobalClass("Time", typeof(System.DateTime), typeof(Ruby.Builtins.TimeOps), new System.Action(LoadTime_Instance), new System.Action(LoadTime_Class), classRef1, new Ruby.Builtins.RubyModule[] {def38, }, new System.Delegate[] {
@@ -60,7 +60,7 @@
new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ArrayOps.CreateArray),
});
DefineGlobalClass("Binding", typeof(Ruby.Builtins.Binding), typeof(Ruby.Builtins.BindingOps), null, null, Context.ObjectClass, Ruby.Builtins.RubyModule.EmptyArray, null);
- DefineGlobalClass("ClrString", typeof(System.String), typeof(Ruby.Builtins.StringOps), new System.Action(LoadClrString_Instance), null, Context.ObjectClass, Ruby.Builtins.RubyModule.EmptyArray, null);
+ DefineGlobalClass("ClrString", typeof(System.String), typeof(Ruby.Builtins.StringOps), new System.Action(LoadClrString_Instance), null, Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def47, }, null);
Ruby.Builtins.RubyClass def13 = DefineClass("Digest::Class", typeof(Ruby.StandardLibrary.Digest.Class), null, null, new System.Action(LoadDigest__Class_Class), Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def14, }, null);
DefineGlobalClass("Dir", typeof(Ruby.Builtins.RubyDir), null, new System.Action(LoadDir_Instance), new System.Action(LoadDir_Class), Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def28, }, null);
Ruby.Builtins.RubyClass def39 = Context.ExceptionClass = DefineGlobalClass("Exception", typeof(System.Exception), typeof(Ruby.Builtins.ExceptionOps), new System.Action(LoadException_Instance), new System.Action(LoadException_Class), Context.ObjectClass, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] {
@@ -2049,6 +2049,10 @@
new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.MethodMissing),
});
+ module.DefineMethod("methods", 0x9, new System.Delegate[] {
+ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetMethods),
+ });
+
module.DefineMethod("nil?", 0x9, new System.Delegate[] {
new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.IsNil),
});
@@ -2101,7 +2105,6 @@
});
module.DefineMethod("singleton_methods", 0x9, new System.Delegate[] {
- new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetSingletonMethods),
new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetSingletonMethods),
});
@@ -3622,6 +3625,14 @@
new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Replace),
});
+ module.DefineMethod("reverse", 0x9, new System.Delegate[] {
+ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetReversed),
+ });
+
+ module.DefineMethod("reverse!", 0x9, new System.Delegate[] {
+ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Reverse),
+ });
+
module.DefineMethod("rindex", 0x9, new System.Delegate[] {
new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReverseIndex),
new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReverseIndex),
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Enumerable.cs;C415805
File: Enumerable.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Enumerable.cs;C415805 (server) 5/15/2008 1:17 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Enumerable.cs;RubyBugFixesII
@@ -13,23 +13,16 @@
*
* ***************************************************************************/
-using System;
using System.Collections;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
-using System.Text;
-using Microsoft.Scripting;
using Microsoft.Scripting.Actions;
using Microsoft.Scripting.Runtime;
-using Microsoft.Scripting.Utils;
-using Ruby.Extensions;
using Ruby.Runtime;
namespace Ruby.Builtins {
- using MSA = Microsoft.Scripting.Ast;
-
+
// TODO: All of these methods use RubySites.Each, which is not ideal (shared DynamicSite).
// We could have one DynamicSite per method, but what we really want is for the
// "each" site to be merged into the calling site (e.g. maybe use ActionOnCallable)
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C436555
File: Kernel.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C436555 (server) 5/15/2008 10:40 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;RubyBugFixesII
@@ -14,20 +14,17 @@
* ***************************************************************************/
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
+using System.Threading;
using Microsoft.Scripting;
using Microsoft.Scripting.Actions;
using Microsoft.Scripting.Ast;
+using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;
using Ruby.Runtime;
-using Microsoft.Scripting.Runtime;
-using Ruby.Compiler;
-using System.Threading;
using Ruby.Runtime.Calls;
-using System.Collections;
-using System.Diagnostics;
-using System.ComponentModel;
namespace Ruby.Builtins {
@@ -124,14 +121,14 @@
[RubyMethod("eval", RubyMethodAttributes.PrivateInstance)]
[RubyMethod("eval", RubyMethodAttributes.PublicSingleton)]
public static object Evaluate(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ code,
- [Optional]Binding binding, [Optional, NotNull]MutableString file, [Optional, DefaultValue(1)]int line) {
+ [Optional]Binding binding, [Optional, NotNull]MutableString file, [DefaultParameterValue(1)]int line) {
return RubyUtils.Evaluate(self, code, (binding != null) ? binding.LocalScope : RubyUtils.GetScope(context), file, line);
}
[RubyMethod("eval", RubyMethodAttributes.PrivateInstance)]
[RubyMethod("eval", RubyMethodAttributes.PublicSingleton)]
- public static object Evaluate(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ code,
- [NotNull]Proc/*!*/ procBinding, [Optional, NotNull]MutableString file, [Optional, DefaultValue(1)]int line) {
+ public static object Evaluate(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ code,
+ [NotNull]Proc/*!*/ procBinding, [Optional, NotNull]MutableString file, [DefaultParameterValue(1)]int line) {
return RubyUtils.Evaluate(self, code, procBinding.LocalScope, file, line);
}
@@ -767,13 +764,6 @@
return new RubyMethod(self, info, name);
}
- [RubyMethod("method")]
- public static RubyMethod/*!*/ GetMethod(CodeContext/*!*/ context, object self, object name) {
- return GetMethod(context, self, Protocols.CastToSymbol(context, name));
- }
-
- //methods
-
[RubyMethod("nil?")]
public static bool IsNil(object self) {
return self == null;
@@ -824,19 +814,31 @@
}
#endregion
- [RubyMethod("singleton_methods")]
- public static RubyArray/*!*/ GetSingletonMethods(CodeContext/*!*/ context, object self) {
- return GetSingletonMethods(context, self, true);
+ #region method, methods, singleton_methods
+
+ [RubyMethod("method")]
+ public static RubyMethod/*!*/ GetMethod(CodeContext/*!*/ context, object self, object name) {
+ return GetMethod(context, self, Protocols.CastToSymbol(context, name));
}
+ [RubyMethod("methods")]
+ public static RubyArray/*!*/ GetMethods(CodeContext/*!*/ context, object self, [DefaultParameterValue(true)]bool inherited) {
+ RubyClass immediateClass = RubyUtils.GetExecutionContext(context).GetImmediateClassOf(self);
+ return ModuleOps.GetMethods(immediateClass, inherited,
+ RubyMethodAttributes.Private | RubyMethodAttributes.Public | RubyMethodAttributes.Protected
+ );
+ }
+
[RubyMethod("singleton_methods")]
- public static RubyArray/*!*/ GetSingletonMethods(CodeContext/*!*/ context, object self, bool inherited) {
+ public static RubyArray/*!*/ GetSingletonMethods(CodeContext/*!*/ context, object self, [DefaultParameterValue(true)]bool inherited) {
RubyClass immediateClass = RubyUtils.GetExecutionContext(context).GetImmediateClassOf(self);
- return ModuleOps.GetInstanceMethods(immediateClass, inherited,
+ return ModuleOps.GetMethods(immediateClass, inherited,
RubyMethodAttributes.Public | RubyMethodAttributes.Protected | RubyMethodAttributes.Singleton
);
}
+ #endregion
+
///
/// Returns a string containing a human-readable representation of obj.
/// If not overridden, uses the to_s method to generate the string.
@@ -882,8 +884,7 @@
public static void RequiresNotFrozen(CodeContext/*!*/ context, object/*!*/ obj) {
if (Kernel.Frozen(context, obj)) {
- string typeName = RubyUtils.GetExecutionContext(context).GetClassOf(obj).Name.ToString().ToLower();
- throw RubyExceptions.CreateTypeError("can't modify frozen " + typeName);
+ throw RubyExceptions.CreateTypeError("can't modify frozen object");
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C438696
File: ModuleOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C438696 (server) 5/15/2008 10:59 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;RubyBugFixesII
@@ -15,18 +15,14 @@
using System;
using System.Collections.Generic;
+using System.Runtime.InteropServices;
using Microsoft.Scripting;
using Microsoft.Scripting.Actions;
+using Microsoft.Scripting.Ast;
+using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;
-using Microsoft.Scripting.Hosting;
using Ruby.Runtime;
using Ruby.Runtime.Calls;
-using Microsoft.Scripting.Runtime;
-using Ruby.Compiler;
-using System.Runtime.InteropServices;
-using System.ComponentModel;
-using System.Diagnostics;
-using Microsoft.Scripting.Ast;
namespace Ruby.Builtins {
@@ -521,8 +517,8 @@
[RubyMethod("module_eval")]
[RubyMethod("class_eval")]
- public static object Evaluate(CodeContext/*!*/ context, RubyModule/*!*/ self, BlockParam block, [NotNull]MutableString/*!*/ code,
- [Optional, NotNull]MutableString file, [Optional, DefaultValue(1)]int line) {
+ public static object Evaluate(CodeContext/*!*/ context, RubyModule/*!*/ self, BlockParam block, [NotNull]MutableString/*!*/ code,
+ [Optional, NotNull]MutableString file, [DefaultParameterValue(1)]int line) {
// TODO: binder should do this:
if (block != null) {
@@ -653,7 +649,7 @@
[RubyMethod("instance_methods")]
public static RubyArray/*!*/ GetInstanceMethods(RubyModule/*!*/ self, bool inherited) {
- return GetInstanceMethods(self, inherited, RubyMethodAttributes.PublicInstance);
+ return GetMethods(self, inherited, RubyMethodAttributes.PublicInstance);
}
[RubyMethod("private_instance_methods")]
@@ -663,7 +659,7 @@
[RubyMethod("private_instance_methods")]
public static RubyArray/*!*/ GetPrivateInstanceMethods(RubyModule/*!*/ self, bool inherited) {
- return GetInstanceMethods(self, inherited, RubyMethodAttributes.PrivateInstance);
+ return GetMethods(self, inherited, RubyMethodAttributes.PrivateInstance);
}
[RubyMethod("protected_instance_methods")]
@@ -673,7 +669,7 @@
[RubyMethod("protected_instance_methods")]
public static RubyArray/*!*/ GetProtectedInstanceMethods(RubyModule/*!*/ self, bool inherited) {
- return GetInstanceMethods(self, inherited, RubyMethodAttributes.ProtectedInstance);
+ return GetMethods(self, inherited, RubyMethodAttributes.ProtectedInstance);
}
[RubyMethod("public_instance_methods")]
@@ -683,7 +679,7 @@
[RubyMethod("public_instance_methods")]
public static RubyArray/*!*/ GetPublicInstanceMethods(RubyModule/*!*/ self, bool inherited) {
- return GetInstanceMethods(self, inherited, RubyMethodAttributes.PublicInstance);
+ return GetMethods(self, inherited, RubyMethodAttributes.PublicInstance);
}
///
@@ -693,18 +689,23 @@
/// inherited == false, attributes & Singleton != 0:
/// - get methods in the "self" module only
/// - do not visit mixins nor super classes
- /// inherited == true
+ /// inherited == true, attributes & Singleton != 0:
/// - walk all ancestors until a non-singleton is reached (include "self" module anyways)
+ /// inherited == true, attributes & (Singleton | Instance) == 0 :
+ /// - walk all ancestors until a an Object is reached
///
/// Methods are filtered by visibility specified in attributes (mutliple visibilities could be specified).
/// A name undefined in a module is not visible in that module and its ancestors.
/// Method names are not duplicated in the result.
///
- internal static RubyArray/*!*/ GetInstanceMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes) {
+ internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes) {
Dictionary visited = new Dictionary();
RubyArray result = new RubyArray();
+ // We can look for instance methods, singleton methods or all methods.
+ // The difference is when we stop searching.
bool instanceMethods = (attributes & RubyMethodAttributes.Instance) != 0;
+ bool singletonMethods = (attributes & RubyMethodAttributes.Singleton) != 0;
bool stop = false;
self.ForEachInstanceMethod(true, delegate(RubyModule/*!*/ module, SymbolId name, RubyMemberInfo method) {
@@ -718,8 +719,12 @@
if (instanceMethods) {
stop = !inherited && !module.IsSingletonClass;
- } else if ((!inherited || !module.IsSingletonClass) && module != self) {
- return true;
+ } else if (singletonMethods) {
+ if ((!inherited || !module.IsSingletonClass) && module != self) {
+ return true;
+ }
+ } else {
+ stop = !inherited;
}
} else if (method.IsUndefined) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C438696
File: MutableStringOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C438696 (server) 5/15/2008 10:40 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;RubyBugFixesII
@@ -3065,5 +3065,16 @@
}
#endregion
+
+ [RubyMethod("reverse")]
+ public static MutableString/*!*/ GetReversed(CodeContext/*!*/ context, MutableString/*!*/ self) {
+ return CreateSubClass(context, self, self).Reverse();
+ }
+
+ [RubyMethod("reverse!")]
+ public static MutableString/*!*/ Reverse(CodeContext/*!*/ context, MutableString/*!*/ self) {
+ Kernel.RequiresNotFrozen(context, self);
+ return self.Reverse();
+ }
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RangeOps.cs;C438696
File: RangeOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RangeOps.cs;C438696 (server) 5/15/2008 1:18 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RangeOps.cs;RubyBugFixesII
@@ -14,15 +14,11 @@
* ***************************************************************************/
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
-using System.Text;
using Microsoft.Scripting;
-using Microsoft.Scripting.Math;
using Microsoft.Scripting.Actions;
+using Microsoft.Scripting.Runtime;
using Ruby.Runtime;
-using Microsoft.Scripting.Runtime;
-using System.ComponentModel;
namespace Ruby.Builtins {
///
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C438696
File: Ruby.csproj
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C438696 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;RubyBugFixesII
@@ -258,6 +258,7 @@
+
@@ -288,4 +289,4 @@
mkdir "$(SolutionDir)..\..\Tools\Nessie\Nessie\bin\Debug"
copy /y "$(TargetPath)" "$(SolutionDir)..\..\Tools\Nessie\Nessie\bin\Debug"
-
+
\ No newline at end of file
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj.vspscc;C390406
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Utils.cs
File: Utils.cs
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Utils.cs;RubyBugFixesII
@@ -1,0 +1,40 @@
+?/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation.
+ *
+ * This source code is subject to terms and conditions of the Microsoft Public License. A
+ * copy of the license can be found in the License.html file at the root of this distribution. If
+ * you cannot locate the Microsoft Public License, please send an email to
+ * ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
+ * by the terms of the Microsoft Public License.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ *
+ * ***************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Scripting.Utils;
+using Ruby.Runtime;
+
+namespace Ruby {
+ public static class Utils {
+ public static class Array {
+ public static int IndexOf(/*this*/ string[]/*!*/ array, string/*!*/ value, StringComparer/*!*/ comparer) {
+ ContractUtils.RequiresNotNull(array, "array");
+ ContractUtils.RequiresNotNull(value, "value");
+ ContractUtils.RequiresNotNull(comparer, "comparer");
+
+ for (int i = 0; i < array.Length; i++) {
+ if (comparer.Equals(array[i], value)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+ }
+ }
+}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;C438696
File: MutableString.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;C438696 (server) 5/15/2008 10:40 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;RubyBugFixesII
@@ -662,7 +662,7 @@
#endregion
- #region Remove, Clear
+ #region Remove, Clear, Reverse
public MutableString/*!*/ Remove(int start, int count) {
RequiresArrayRange(start, count);
@@ -674,6 +674,29 @@
_content = _content.GetSlice(0, 0);
}
+ public MutableString/*!*/ Reverse() {
+ // TODO:
+ if (IsBinary) {
+ int length = Length;
+ for (int i = 0; i < length / 2; i++) {
+ byte a = GetByte(i);
+ byte b = GetByte(length - i - 1);
+ SetByte(i, b);
+ SetByte(length - i - 1, a);
+ }
+ } else {
+ int length = Length;
+ for (int i = 0; i < length / 2; i++) {
+ char a = GetChar(i);
+ char b = GetChar(length - i - 1);
+ SetChar(i, b);
+ SetChar(length - i - 1, a);
+ }
+ }
+
+ return this;
+ }
+
#endregion
#region Misc
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Assignments/MemberAssignmentExpression.cs;C437359
File: MemberAssignmentExpression.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Assignments/MemberAssignmentExpression.cs;C437359 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Assignments/MemberAssignmentExpression.cs;RubyBugFixesII
@@ -23,14 +23,14 @@
using MSA = Microsoft.Scripting.Ast;
using Ast = Microsoft.Scripting.Ast.Expression;
- // lhs.id op= rhs
+ // left.id op= rigth
public partial class MemberAssignmentExpression : AssignmentExpression {
- private readonly Expression/*!*/ _left;
+ private readonly Expression/*!*/ _leftTarget;
private readonly Expression/*!*/ _right;
private readonly SymbolId _memberName;
- public Expression/*!*/ Left {
- get { return _left; }
+ public Expression/*!*/ LeftTarget {
+ get { return _leftTarget; }
}
public Expression/*!*/ Right {
@@ -41,29 +41,45 @@
get { return _memberName; }
}
- public MemberAssignmentExpression(Expression/*!*/ left, SymbolId memberName, SymbolId operation, Expression/*!*/ right, SourceSpan location)
+ public MemberAssignmentExpression(Expression/*!*/ leftTarget, SymbolId memberName, SymbolId operation, Expression/*!*/ right, SourceSpan location)
: base(operation, location) {
- ContractUtils.RequiresNotNull(left, "left");
+ ContractUtils.RequiresNotNull(leftTarget, "leftTarget");
ContractUtils.RequiresNotNull(operation, "operation");
ContractUtils.RequiresNotNull(right, "right");
ContractUtils.Requires(!memberName.IsEmpty, "memberName");
ContractUtils.Requires(!operation.IsEmpty, "operation");
_memberName = memberName;
- _left = left;
+ _leftTarget = leftTarget;
_right = right;
}
internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
SymbolId setterName = SymbolTable.StringToId(SymbolTable.IdToString(_memberName) + "=");
- // left.member= left.member().op(right)
+ MSA.Expression transformedLeftTarget = _leftTarget.TransformRead(gen);
+ MSA.Expression transformedRight = _right.TransformRead(gen);
- MSA.Expression leftMemberRead = MethodCall.TransformRead(gen, _memberName, _left, null, null, null);
- MSA.Expression operationCall = MethodCall.TransformRead(gen, Operation, leftMemberRead, null, _right.TransformRead(gen), null);
- MSA.Expression assignment = MethodCall.TransformRead(gen, setterName, _left, null, null, operationCall);
+ MSA.Expression leftTemp = gen.CurrentCodeBlock.CreateTemporaryVariable(Symbols.None, transformedLeftTarget.Type);
- return assignment;
+ // lhs &&= rhs --> left.member && (left.member = rhs)
+ // lhs ||= rhs --> left.member || (left.member = rhs)
+ if (Operation == Symbols.And || Operation == Symbols.Or) {
+ MSA.Expression leftMemberRead = MethodCall.TransformRead(gen, _memberName, Ast.Assign(leftTemp, transformedLeftTarget), null, null, null);
+ MSA.Expression transformedWrite = MethodCall.TransformRead(gen, setterName, leftTemp, null, null, transformedRight);
+
+ if (Operation == Symbols.And) {
+ return AndExpression.TransformRead(gen, leftMemberRead, transformedWrite);
+ } else {
+ return OrExpression.TransformRead(gen, leftMemberRead, transformedWrite);
+ }
+ } else {
+ // left.member= left.member().op(right)
+ MSA.Expression leftMemberRead = MethodCall.TransformRead(gen, _memberName, leftTemp, null, null, null);
+ MSA.Expression operationCall = MethodCall.TransformRead(gen, Operation, leftMemberRead, null, transformedRight, null);
+ MSA.Expression transformedWrite = MethodCall.TransformRead(gen, setterName, Ast.Assign(leftTemp, transformedLeftTarget), null, null, operationCall);
+ return transformedWrite;
+ }
}
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Assignments/SimpleAssignmentExpression.cs;C437359
File: SimpleAssignmentExpression.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Assignments/SimpleAssignmentExpression.cs;C437359 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Assignments/SimpleAssignmentExpression.cs;RubyBugFixesII
@@ -51,22 +51,47 @@
}
internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
- MSA.Expression transformedRhs;
- if (_operation == Symbols.And) {
- // lhs &&= rhs
- transformedRhs = AndExpression.TransformRead(gen, _left, _right);
- } else if (_operation == Symbols.Or) {
- // lhs ||= rhs
- transformedRhs = OrExpression.TransformRead(gen, _left, _right);
- } else if (_operation != SymbolId.Empty) {
- // lhs op= rhs
- transformedRhs = MethodCall.TransformRead(gen, _operation, _left, null, _right.TransformRead(gen), null);
+ // first, read target into a temp:
+ MSA.Expression transformedLeftTarget = _left.TransformTargetRead(gen);
+ MSA.Expression leftTargetTemp;
+
+ if (transformedLeftTarget != null) {
+ leftTargetTemp = gen.CurrentCodeBlock.CreateTemporaryVariable(Symbols.None, transformedLeftTarget.Type);
} else {
- transformedRhs = _right.TransformRead(gen);
+ leftTargetTemp = null;
}
- return _left.TransformWrite(gen, transformedRhs);
+ MSA.Expression transformedRight = _right.TransformRead(gen);
+
+ // lhs &&= rhs --> lhs && (lhs = rhs)
+ // lhs ||= rhs --> lhs || (lhs = rhs)
+ if (_operation == Symbols.And || _operation == Symbols.Or) {
+ MSA.Expression transformedLeftRead = _left.TransformRead(gen,
+ (transformedLeftTarget != null) ? Ast.Assign(leftTargetTemp, transformedLeftTarget) : null,
+ true // tryRead
+ );
+
+ MSA.Expression transformedWrite = _left.TransformWrite(gen, leftTargetTemp, transformedRight);
+
+ if (_operation == Symbols.And) {
+ return AndExpression.TransformRead(gen, transformedLeftRead, transformedWrite);
+ } else {
+ return OrExpression.TransformRead(gen, transformedLeftRead, transformedWrite);
+ }
+ } else {
+ // lhs op= rhs --> lhs = lhs op rhs
+ if (_operation != SymbolId.Empty) {
+ MSA.Expression transformedLeftRead = _left.TransformRead(gen, leftTargetTemp, false);
+ transformedRight = MethodCall.TransformRead(gen, _operation, transformedLeftRead, null, transformedRight, null);
+ }
+
+ // transform lhs write assigning lhs-target temp:
+ return _left.TransformWrite(gen,
+ (transformedLeftTarget != null) ? Ast.Assign(leftTargetTemp, transformedLeftTarget) : null,
+ transformedRight
+ );
+ }
}
internal override string GetNodeName(AstGenerator gen) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/AndExpression.cs;C402444
File: AndExpression.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/AndExpression.cs;C402444 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/AndExpression.cs;RubyBugFixesII
@@ -49,14 +49,14 @@
}
internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
- return TransformRead(gen, _left, _right);
+ return TransformRead(gen, _left.TransformRead(gen), _right.TransformRead(gen));
}
- internal static MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, Expression/*!*/ left, Expression/*!*/ right) {
+ internal static MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, MSA.Expression/*!*/ left, MSA.Expression/*!*/ right) {
return Ast.CoalesceTrue(
gen.CurrentCodeBlock,
- Ast.ConvertHelper(left.TransformRead(gen), typeof(object)),
- Ast.ConvertHelper(right.TransformRead(gen), typeof(object)),
+ Ast.ConvertHelper(left, typeof(object)),
+ Ast.ConvertHelper(right, typeof(object)),
RubyOps.GetMethod("IsTrue")
);
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/MethodCall.cs;C437564
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/OrExpression.cs;C402444
File: OrExpression.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/OrExpression.cs;C402444 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/OrExpression.cs;RubyBugFixesII
@@ -47,14 +47,14 @@
}
internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
- return TransformRead(gen, _left, _right);
+ return TransformRead(gen, _left.TransformRead(gen), _right.TransformRead(gen));
}
- internal static MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, Expression/*!*/ left, Expression/*!*/ right) {
+ internal static MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, MSA.Expression/*!*/ left, MSA.Expression/*!*/ right) {
return Ast.CoalesceFalse(
gen.CurrentCodeBlock,
- Ast.ConvertHelper(left.TransformRead(gen), typeof(object)),
- Ast.ConvertHelper(right.TransformRead(gen), typeof(object)),
+ Ast.ConvertHelper(left, typeof(object)),
+ Ast.ConvertHelper(right, typeof(object)),
RubyOps.GetMethod("IsTrue")
);
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ArrayItemAccess.cs;C437359
File: ArrayItemAccess.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ArrayItemAccess.cs;C437359 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ArrayItemAccess.cs;RubyBugFixesII
@@ -16,6 +16,7 @@
using System;
using System.Collections.Generic;
using System.Text;
+using System.Diagnostics;
using Microsoft.Scripting;
using Microsoft.Scripting.Utils;
@@ -46,13 +47,19 @@
_array = array;
_arguments = arguments;
}
+
+ internal override MSA.Expression TransformTargetRead(AstGenerator/*!*/ gen) {
+ return _array.TransformRead(gen);
+ }
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
- return MethodCall.TransformRead(gen, Symbols.ArrayItemRead, _array, _arguments, null, null);
+ internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, MSA.Expression targetValue, bool tryRead) {
+ Assert.NotNull(gen, targetValue);
+ return MethodCall.TransformRead(gen, Symbols.ArrayItemRead, targetValue, _arguments, null, null);
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
- return MethodCall.TransformRead(gen, Symbols.ArrayItemWrite, _array, _arguments, null, rightValue);
+ internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression target, MSA.Expression/*!*/ rightValue) {
+ Assert.NotNull(target);
+ return MethodCall.TransformRead(gen, Symbols.ArrayItemWrite, target, _arguments, null, rightValue);
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/AttributeAccess.cs;C437359
File: AttributeAccess.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/AttributeAccess.cs;C437359 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/AttributeAccess.cs;RubyBugFixesII
@@ -47,10 +47,6 @@
_qualifier = qualifier;
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
- return MethodCall.TransformRead(gen, _name, _qualifier, null, null, rightValue);
- }
-
internal override string/*!*/ GetNodeName(AstGenerator/*!*/ gen) {
return "assignment";
}
@@ -59,8 +55,17 @@
return null;
}
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
- throw Assert.Unreachable;
+ internal override MSA.Expression TransformTargetRead(AstGenerator/*!*/ gen) {
+ return _qualifier.TransformRead(gen);
}
+
+ internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, MSA.Expression targetValue, bool tryRead) {
+ throw Assert.Unreachable;
+ }
+
+ internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ targetValue, MSA.Expression/*!*/ rightValue) {
+ Assert.NotNull(gen, targetValue, rightValue);
+ return MethodCall.TransformRead(gen, _name, targetValue, null, null, rightValue);
+ }
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ClassVariable.cs;C402444
File: ClassVariable.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ClassVariable.cs;C402444 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ClassVariable.cs;RubyBugFixesII
@@ -29,10 +29,6 @@
Debug.Assert(SymbolTable.IdToString(name).StartsWith("@@"));
}
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
- return TransformRead(gen, "Get");
- }
-
private MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, string/*!*/ opPrefix) {
// eval or in a non-singleton module/class declaration
// -> we find the right scope at runtime by walking the hierarchy
@@ -46,7 +42,11 @@
}
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
+ internal override MSA.Expression/*!*/ TransformReadVariable(AstGenerator/*!*/ gen, bool tryRead) {
+ return TransformRead(gen, tryRead ? "TryGet" : "Get");
+ }
+
+ internal override MSA.Expression/*!*/ TransformWriteVariable(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
if (gen.CompilerOptions.IsEval || gen.GetCurrentNonSingletonModule() != null) {
return AstFactory.OpCall("SetClassVariable", rightValue, Ast.CodeContext(), Ast.Constant(Name));
} else {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/CompoundLeftValue.cs;C437359
File: CompoundLeftValue.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/CompoundLeftValue.cs;C437359 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/CompoundLeftValue.cs;RubyBugFixesII
@@ -57,11 +57,16 @@
_unsplattedValue = unsplattedValue;
}
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
+ internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, MSA.Expression targetValue, bool tryRead) {
throw Assert.Unreachable;
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
+ internal override MSA.Expression TransformTargetRead(AstGenerator/*!*/ gen) {
+ return null;
+ }
+
+ internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression targetValue, MSA.Expression/*!*/ rightValue) {
+ Debug.Assert(targetValue == null);
return TransformWrite(gen, CollectionUtils.MakeList(rightValue), null);
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ConstantVariable.cs;C429806
File: ConstantVariable.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ConstantVariable.cs;C429806 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/ConstantVariable.cs;RubyBugFixesII
@@ -93,7 +93,7 @@
}
}
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
+ internal override MSA.Expression/*!*/ TransformReadVariable(AstGenerator/*!*/ gen, bool tryRead) {
return TransformRead(gen, "Get");
}
@@ -115,7 +115,7 @@
throw Assert.Unreachable;
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
+ internal override MSA.Expression/*!*/ TransformWriteVariable(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
MSA.Expression transformedName = TransformSymbolName(gen);
MSA.Expression transformedQualifier;
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/GlobalVariable.cs;C402444
File: GlobalVariable.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/GlobalVariable.cs;C402444 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/GlobalVariable.cs;RubyBugFixesII
@@ -31,11 +31,11 @@
Debug.Assert(name.ToString() == "$" || !name.ToString().StartsWith("$"));
}
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
+ internal override MSA.Expression/*!*/ TransformReadVariable(AstGenerator/*!*/ gen, bool tryRead) {
return AstFactory.OpCall("GetGlobalVariable", Ast.CodeContext(), TransformSymbolName(gen));
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
+ internal override MSA.Expression/*!*/ TransformWriteVariable(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
return AstFactory.OpCall("SetGlobalVariable", rightValue, Ast.CodeContext(), TransformSymbolName(gen));
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/InstanceVariable.cs;C402444
File: InstanceVariable.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/InstanceVariable.cs;C402444 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/InstanceVariable.cs;RubyBugFixesII
@@ -29,11 +29,11 @@
Debug.Assert(SymbolTable.IdToString(name).StartsWith("@"));
}
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
+ internal override MSA.Expression/*!*/ TransformReadVariable(AstGenerator/*!*/ gen, bool tryRead) {
return AstFactory.OpCall("GetInstanceVariable", Ast.CodeContext(), gen.CurrentSelfVariable, Ast.Constant(Name));
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
+ internal override MSA.Expression/*!*/ TransformWriteVariable(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
return AstFactory.OpCall("SetInstanceVariable", Ast.CodeContext(), gen.CurrentSelfVariable, Ast.Constant(Name), rightValue);
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/LeftValue.cs;C402444
File: LeftValue.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/LeftValue.cs;C402444 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/LeftValue.cs;RubyBugFixesII
@@ -29,8 +29,24 @@
: base(location) {
}
- internal abstract MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue);
+ // Gets an expression that evaluates to the part of the left value that represents a holder (target) of the left value;
+ // For example target.bar, target[key], ...
+ // This target is passed to the TransformWrite by assignment expressions.
+ // This is necessary to prevent redundant evaluation of the target expression in in-place assignment left op= right.
+ // Returns null if the left value doesn't have target expression.
+ internal abstract MSA.Expression TransformTargetRead(AstGenerator/*!*/ gen);
+
+ internal sealed override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
+ return TransformRead(gen, TransformTargetRead(gen), false);
+ }
+
+ internal MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
+ return TransformWrite(gen, TransformTargetRead(gen), rightValue);
+ }
+ internal abstract MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, MSA.Expression targetValue, bool tryRead);
+ internal abstract MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression targetValue, MSA.Expression/*!*/ rightValue);
+
internal virtual List/*!*/ ToList() {
List result = new List();
result.Add(this);
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/LocalVariable.cs;C420856
File: LocalVariable.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/LocalVariable.cs;C420856 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/LocalVariable.cs;RubyBugFixesII
@@ -34,7 +34,7 @@
_containingScope = containingScope;
}
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
+ internal override MSA.Expression/*!*/ TransformReadVariable(AstGenerator/*!*/ gen, bool tryRead) {
VariableInfo var = _containingScope.ResolveVariable(Name);
if (var.TransformedVariable != null) {
// static lookup:
@@ -45,7 +45,7 @@
}
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
+ internal override MSA.Expression/*!*/ TransformWriteVariable(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
VariableInfo var = _containingScope.ResolveVariable(Name);
if (var.TransformedVariable != null) {
// static lookup:
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/Placeholder.cs;C437359
File: Placeholder.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/Placeholder.cs;C437359 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/Placeholder.cs;RubyBugFixesII
@@ -27,18 +27,18 @@
/// Used as a null LHS without backing storage.
/// E.g. 'a, = 1' is represented as 'ParallelAssignment(CoumpoundLeftValue(Variable, Placeholder), CompoundRightValue(Constant))
///
- public partial class Placeholder : LeftValue {
+ public partial class Placeholder : Variable {
public static readonly Placeholder/*!*/ Singleton = new Placeholder();
private Placeholder()
- : base(SourceSpan.None) {
+ : base(SymbolId.Empty, SourceSpan.None) {
}
- internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
+ internal override MSA.Expression/*!*/ TransformReadVariable(AstGenerator/*!*/ gen, bool tryRead) {
throw Assert.Unreachable;
}
- internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
+ internal override MSA.Expression/*!*/ TransformWriteVariable(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue) {
Assert.NotNull(gen, rightValue);
// no-op
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/Variable.cs;C402444
File: Variable.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/Variable.cs;C402444 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/LeftValues/Variable.cs;RubyBugFixesII
@@ -40,5 +40,22 @@
internal MSA.Expression/*!*/ TransformSymbolName(AstGenerator/*!*/ gen) {
return Ast.Constant(_name);
}
+
+ internal sealed override MSA.Expression TransformTargetRead(AstGenerator/*!*/ gen) {
+ return null;
+ }
+
+ internal abstract MSA.Expression/*!*/ TransformReadVariable(AstGenerator/*!*/ gen, bool tryRead);
+ internal abstract MSA.Expression/*!*/ TransformWriteVariable(AstGenerator/*!*/ gen, MSA.Expression/*!*/ rightValue);
+
+ internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen, MSA.Expression targetValue, bool tryRead) {
+ Debug.Assert(targetValue == null);
+ return TransformReadVariable(gen, tryRead);
+ }
+
+ internal override MSA.Expression/*!*/ TransformWrite(AstGenerator/*!*/ gen, MSA.Expression targetValue, MSA.Expression/*!*/ rightValue) {
+ Debug.Assert(targetValue == null);
+ return TransformWriteVariable(gen, rightValue);
+ }
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Walkers/Walker.cs;C437359
File: Walker.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Walkers/Walker.cs;C437359 (server) 5/15/2008 10:00 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Walkers/Walker.cs;RubyBugFixesII
@@ -137,7 +137,7 @@
internal protected virtual void Walk(MemberAssignmentExpression/*!*/ node) {
if (Enter(node)) {
- node.Left.Walk(this);
+ node.LeftTarget.Walk(this);
node.Right.Walk(this);
}
Exit(node);
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Parser.cs;C438696
File: Parser.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Parser.cs;C438696 (server) 5/15/2008 11:36 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Parser.cs;RubyBugFixesII
@@ -293,10 +293,8 @@
}
private ArrayConstructor/*!*/ MakeVerbatimWords(List/*!*/ words, SourceSpan wordsLocation, SourceSpan location) {
-#if !SILVERLIGHT
- Debug.Assert(words.TrueForAll(delegate(Expression/*!*/ word) { return word is Literal && ((Literal)word).Value is string; }),
+ Debug.Assert(CollectionUtils.TrueForAll(words, delegate(Expression/*!*/ word) { return word is Literal && ((Literal)word).Value is string; }),
"all words are string literals");
-#endif
return new ArrayConstructor(new Arguments(words, null, null, null, wordsLocation), location);
}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;C436555
File: Loader.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;C436555 (server) 5/14/2008 7:51 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;RubyBugFixesII
@@ -15,25 +15,19 @@
using System;
using System.IO;
-using System.Text;
using System.Diagnostics;
-using System.Collections;
+using System.Reflection;
+using System.Text.RegularExpressions;
using System.Collections.Generic;
-using Assembly = System.Reflection.Assembly;
-using Microsoft.Scripting;
-using Microsoft.Scripting.Hosting;
-
-using Ruby.Runtime;
-using Ruby.Hosting;
using Ruby.Compiler;
using Ruby.Builtins;
+using Ruby.Runtime.Calls;
+
+using Microsoft.Scripting;
using Microsoft.Scripting.Utils;
using Microsoft.Scripting.Runtime;
-using System.Reflection;
-using System.Text.RegularExpressions;
using Microsoft.Scripting.Actions;
-using Ruby.Runtime.Calls;
namespace Ruby.Runtime {
[Flags]
@@ -62,6 +56,9 @@
// $"
private readonly RubyArray/*!*/ _loadedFiles;
+ // files that were required but their execution haven't completed yet:
+ private readonly Stack/*!*/ _unfinishedFiles;
+
///
/// TODO: Thread safety: the user of this object is responsible for locking it.
///
@@ -93,6 +90,7 @@
_loadPaths.Add(MutableString.Create("."));
_loadedFiles = new RubyArray();
+ _unfinishedFiles = new Stack();
}
///
@@ -117,7 +115,7 @@
}
}
- return LoadSourceFile(context, self, strPath, flags);
+ return LoadFromPath(context, self, strPath, flags);
}
public bool LoadAssembly(string/*!*/ assemblyName, string typeName, bool throwOnError) {
@@ -185,39 +183,74 @@
return false;
}
- private bool LoadSourceFile(CodeContext/*!*/ context, object self, string/*!*/ path, LoadFlags flags) {
+ private class ResolvedFile {
+ public readonly SourceUnit SourceUnit;
+ public readonly string/*!*/ Path;
+ public readonly string AppendedExtension;
+
+ public ResolvedFile(SourceUnit/*!*/ sourceUnit, string appendedExtension) {
+ SourceUnit = sourceUnit;
+ Path = sourceUnit.Path;
+ AppendedExtension = appendedExtension;
+ }
+
+ public ResolvedFile(string/*!*/ libraryPath, string appendedExtension) {
+ Assert.NotNull(libraryPath);
+ Path = libraryPath;
+ AppendedExtension = appendedExtension;
+ }
+ }
+
+ private bool LoadFromPath(CodeContext/*!*/ context, object self, string/*!*/ path, LoadFlags flags) {
Assert.NotNull(context, path);
- SourceUnit sourceUnit = FindSourceUnit(context, path, (flags & LoadFlags.AppendExtensions) != 0);
- if (sourceUnit == null) {
+ ResolvedFile file = FindFile(context, path, (flags & LoadFlags.AppendExtensions) != 0);
+ if (file == null) {
throw new LoadError(String.Format("no such file to load -- {0}", path));
}
MutableString pathWithExtension = MutableString.Create(path);
- if (Path.GetExtension(path).Length == 0) {
- pathWithExtension.Append(Path.GetExtension(sourceUnit.Path));
+ if (file.AppendedExtension != null) {
+ pathWithExtension.Append(file.AppendedExtension);
}
- if (AlreadyLoaded(context, pathWithExtension, flags)) {
+ if (AlreadyLoaded(context, pathWithExtension, flags) || _unfinishedFiles.Contains(pathWithExtension.ToString())) {
return false;
}
- RubyContext rubySource = sourceUnit.LanguageContext as RubyContext;
- if (rubySource != null) {
- RubyCompilerOptions options = new RubyCompilerOptions();
- options.IsIncluded = true;
- options.IsWrapped = (flags & LoadFlags.LoadIsolated) != 0;
- sourceUnit.Compile(options, _executionContext.RuntimeErrorSink).Run(context, false);
- } else {
- // TODO: publish scope?
- sourceUnit.Execute();
+ try {
+ // save path as is, no canonicalization nor combination with an extension or directory:
+ _unfinishedFiles.Push(pathWithExtension.ToString());
+
+ if (file.SourceUnit != null) {
+ RubyContext rubySource = file.SourceUnit.LanguageContext as RubyContext;
+ if (rubySource != null) {
+ RubyCompilerOptions options = new RubyCompilerOptions();
+ options.IsIncluded = true;
+ options.IsWrapped = (flags & LoadFlags.LoadIsolated) != 0;
+ file.SourceUnit.Compile(options, _executionContext.RuntimeErrorSink).Run(context, false);
+ } else {
+ // TODO: publish scope?
+ file.SourceUnit.Execute();
+ }
+ } else {
+ Debug.Assert(file.Path != null);
+ try {
+ DomainManager.LoadAssembly(Platform.LoadAssemblyFromPath(Platform.GetFullPath(file.Path)));
+ } catch (Exception e) {
+ throw new LoadError(e.Message, e);
+ }
+ }
+
+ AddLoadedFile(pathWithExtension);
+ } finally {
+ _unfinishedFiles.Pop();
}
- AddLoadedFile(pathWithExtension);
return true;
}
- private SourceUnit FindSourceUnit(CodeContext/*!*/ context, string/*!*/ path, bool appendExtensions) {
+ private ResolvedFile FindFile(CodeContext/*!*/ context, string/*!*/ path, bool appendExtensions) {
Assert.NotNull(path);
bool isAbsolutePath;
string extension;
@@ -229,9 +262,12 @@
throw new LoadError(e.Message, e);
}
+ string[] knownExtensions = DomainManager.GetRegisteredFileExtensions();
+ Array.Sort(knownExtensions, StringComparer.OrdinalIgnoreCase);
+
// absolute path -> LoadPaths not consulted:
if (isAbsolutePath) {
- return ResolveSourceUnit(path, extension, appendExtensions);
+ return ResolveFile(path, extension, appendExtensions, knownExtensions);
}
foreach (object dir in GetLoadPaths()) {
@@ -242,7 +278,7 @@
string strDir = _toStrSite.Invoke(context, dir).ConvertToString();
try {
- SourceUnit result = ResolveSourceUnit(Path.Combine(strDir, path), extension, appendExtensions);
+ ResolvedFile result = ResolveFile(Path.Combine(strDir, path), extension, appendExtensions, knownExtensions);
if (result != null) {
return result;
}
@@ -254,29 +290,43 @@
return null;
}
- private SourceUnit ResolveSourceUnit(string/*!*/ path, string/*!*/ extension, bool appendExtensions) {
+ private ResolvedFile ResolveFile(string/*!*/ path, string/*!*/ extension, bool appendExtensions, string[]/*!*/ knownExtensions) {
Debug.Assert(Path.GetExtension(path) == extension);
- // MRI doesn't load file w/o extension:
- if (extension.Length > 0) {
- if (Platform.FileExists(path)) {
- return GetSourceUnit(path, extension);
- }
- } else if (appendExtensions) {
- List matchingExtensions = GetExtensionsOfExistingFiles(path, DomainManager.GetRegisteredFileExtensions());
+ // MRI doesn't load file w/o .rb extension:
+ if (IsKnownExtension(extension, knownExtensions)) {
+ return GetSourceUnit(path, extension, false);
+ } else if (Utils.Array.IndexOf(_LibraryExtensions, extension, StringComparer.OrdinalIgnoreCase) != -1 && Platform.FileExists(path)) {
+ return new ResolvedFile(path, null);
+ }
+ if (appendExtensions) {
+ List matchingExtensions = GetExtensionsOfExistingFiles(path, knownExtensions);
+
if (matchingExtensions.Count == 1) {
- return GetSourceUnit(path + matchingExtensions[0], matchingExtensions[0]);
+ return GetSourceUnit(path + matchingExtensions[0], matchingExtensions[0], true);
} else if (matchingExtensions.Count > 1) {
Exception e = new AmbiguousFileNameException(path + matchingExtensions[0], path + matchingExtensions[1]);
throw new LoadError(e.Message, e);
}
+
+ foreach (string libExtension in _LibraryExtensions) {
+ if (Platform.FileExists(path + libExtension)) {
+ return new ResolvedFile(path + libExtension, libExtension);
+ }
+ }
}
return null;
}
- private SourceUnit GetSourceUnit(string/*!*/ path, string/*!*/ extension) {
+ private static readonly string[] _LibraryExtensions = new string[] { ".dll", ".so" };
+
+ private static bool IsKnownExtension(string/*!*/ extension, string[]/*!*/ knownExtensions) {
+ return extension.Length > 0 && Array.BinarySearch(knownExtensions, extension, StringComparer.OrdinalIgnoreCase) > 0;
+ }
+
+ private ResolvedFile GetSourceUnit(string/*!*/ path, string/*!*/ extension, bool extensionAppended) {
Assert.NotNull(path, extension);
LanguageContext language;
@@ -286,7 +336,8 @@
}
// TODO: default encoding:
- return DomainManager.Host.TryGetSourceFileUnit(language, path, StringUtils.DefaultEncoding, SourceCodeKind.File);
+ SourceUnit sourceUnit = DomainManager.Host.TryGetSourceFileUnit(language, path, StringUtils.DefaultEncoding, SourceCodeKind.File);
+ return (sourceUnit != null) ? new ResolvedFile(sourceUnit, extensionAppended ? extension : null) : null;
}
private List/*!*/ GetExtensionsOfExistingFiles(string/*!*/ path, IEnumerable/*!*/ extensions) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C438696
File: RubyOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C438696 (server) 5/15/2008 1:35 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;RubyBugFixesII
@@ -1135,6 +1135,21 @@
}
// emitted:
+ public static object TryGetObjectClassVariable(CodeContext/*!*/ context, SymbolId name) {
+ object value;
+ RubyUtils.GetExecutionContext(context).ObjectClass.TryGetClassVariable(name, out value);
+ return value;
+ }
+
+ // emitted:
+ public static object TryGetClassVariable(CodeContext/*!*/ context, SymbolId name) {
+ object value;
+ // owner is the first module in scope:
+ RubyUtils.GetExecutionContext(context).GetInnerMostModule(context, true).TryResolveClassVariable(name, out value);
+ return value;
+ }
+
+ // emitted:
public static bool IsDefinedObjectClassVariable(CodeContext/*!*/ context, SymbolId name) {
object value;
return RubyUtils.GetExecutionContext(context).ObjectClass.TryResolveClassVariable(name, out value) != null;
===================================================================