edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/IronPython/Tests/test_peverify.py;C450364
File: test_peverify.py
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/IronPython/Tests/test_peverify.py;C450364 (server) 8/13/2008 7:15 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/IronPython/Tests/test_peverify.py;rubyclrinterop01
@@ -56,7 +56,7 @@
print "Error: ", output2
print
-if ret == 1 and "Error Verifying" in output1:
+if ret == 1 and ("Error Verifying" in output1 or "Error(s) Verifying" in output1):
print "caught verification failure: pass"
sys.exit(0)
else:
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Marshal.cs;C518603
File: Marshal.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Marshal.cs;C518603 (server) 8/8/2008 1:13 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Marshal.cs;rubyclrinterop01
@@ -300,7 +300,11 @@
RubyClass theClass = _rubyContext.GetClassOf(obj);
TestForAnonymous(theClass);
WriteSymbol(theClass.Name);
- WriteString(_DumpSite.Target(_DumpSite, _context, obj, _recursionLimit));
+ MutableString dumpResult = (_DumpSite.Target(_DumpSite, _context, obj, _recursionLimit) as MutableString);
+ if (dumpResult == null) {
+ throw RubyExceptions.CreateTypeError("_dump() must return string");
+ }
+ WriteString(dumpResult);
}
void WriteUsingMarshalDump(object/*!*/ obj) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RubyEncodingOps.cs;C525618
File: RubyEncodingOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RubyEncodingOps.cs;C525618 (server) 8/13/2008 8:53 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RubyEncodingOps.cs;rubyclrinterop01
@@ -42,7 +42,7 @@
[RubyMethod("inspect")]
public static MutableString/*!*/ Inspect(CodeContext/*!*/ context, RubyEncoding/*!*/ self) {
- // TODO: to_s overriden
+ // TODO: to_s overridden
MutableString result = MutableString.CreateMutable();
result.Append("#<");
result.Append(RubyUtils.GetClassName(context, self));
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C525618
File: Ruby.csproj
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C525618 (server) 8/4/2008 2:15 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;rubyclrinterop01
@@ -123,6 +123,7 @@
+
@@ -312,4 +313,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
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C518603
File: RubyClass.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C518603 (server) 8/6/2008 10:39 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;rubyclrinterop01
@@ -48,7 +48,7 @@
private readonly object _singletonClassOf;
// null for singletons:
- private readonly Type _underlyingSystemType;
+ private Type _underlyingSystemType;
private readonly bool _isRubyClass;
private GlobalScopeExtension _globalScope;
@@ -83,6 +83,10 @@
_globalScope = value;
}
+ protected override bool CanIncludeClrInterface {
+ get { return !IsSingletonClass && (_underlyingSystemType == null); }
+ }
+
#if FALSE
private Type _extensionType;
@@ -102,6 +106,10 @@
throw new InvalidOperationException("Singleton class doesn't have underlying system type.");
}
+ if (_underlyingSystemType == null) {
+ Interlocked.Exchange(ref _underlyingSystemType, RubyTypeBuilder.GetOrCreateType(_superClass.GetUnderlyingSystemType(), GetClrInterfaces()));
+ }
+
Debug.Assert(_underlyingSystemType != null);
return _underlyingSystemType;
}
@@ -118,16 +126,16 @@
// friend: RubyExecutionContext
// tracker: non-null => show members declared on the tracker
internal RubyClass(RubyExecutionContext/*!*/ context, SymbolId name, Type type, object singletonClassOf, Action initializer,
- RubyClass superClass, TypeTracker tracker, bool isRubyClass)
+ RubyClass superClass, TypeTracker tracker, bool isRubyClass, bool isSingletonClass)
: base(context, name, initializer, null, tracker) {
-
+
Debug.Assert((superClass == null) == (type == typeof(object)), "All classes have a superclass, except for Object");
Debug.Assert(!isRubyClass || tracker == null, "Ruby class cannot have a tracker");
- Debug.Assert(singletonClassOf != null || type != null, "Singleton classes don't have a type");
+ Debug.Assert(singletonClassOf != null || !isSingletonClass, "Singleton classes don't have a type");
_underlyingSystemType = type;
_superClass = superClass;
- _isSingletonClass = type == null;
+ _isSingletonClass = isSingletonClass;
_isRubyClass = isRubyClass;
_singletonClassOf = singletonClassOf;
@@ -157,10 +165,10 @@
// expect this type as "self" parameter (this is especially necessary for library types and types deriving from CLR types).
// - MRI duplicates Object class so that the result doesn't inherit from Object,
// which we don't do (we want our class hierarchy to be rooted).
- Type type = RubyTypeBuilder.GetOrCreateType(GetUnderlyingSystemType());
+ Type type = RubyTypeBuilder.GetOrCreateType(GetUnderlyingSystemType(), Type.EmptyTypes);
RubyClass result = ExecutionContext.CreateClass(SymbolId.Empty, type, null, null, null,
- _superClass ?? ExecutionContext.ObjectClass, null, true
+ _superClass ?? ExecutionContext.ObjectClass, null, true, false
);
result.InitializeFrom(this);
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C518603
File: RubyModule.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C518603 (server) 8/6/2008 12:56 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;rubyclrinterop01
@@ -61,7 +61,7 @@
// This is stored in the order that mixins are added, but
// in the reverse order from how methods/constants are searched
- private RubyModule[]/*!*/ _mixins;
+ private readonly List/*!*/ _mixins;
private SymbolId _name;
private State _state;
@@ -158,7 +158,7 @@
_executionContext = context;
_name = name;
_state = State.Uninitialized;
- _mixins = EmptyArray;
+ _mixins = new List();
_initializer = initializer;
_version = Interlocked.Increment(ref _globalVersion);
_clrConstants = clrConstants;
@@ -182,7 +182,7 @@
_methods = new Dictionary();
Debug.WriteLine(SymbolTable.IdToString(_name) ?? "", "INITED");
-
+
_state = State.Initializing;
try {
if (_initializer != null) {
@@ -196,7 +196,7 @@
internal virtual void EnsureInitialized() {
if (_state == State.Uninitialized) {
- for (int i = 0; i < _mixins.Length; i++) {
+ for (int i = 0; i < _mixins.Count; i++) {
_mixins[i].EnsureInitialized();
}
@@ -231,7 +231,7 @@
Debug.WriteLine(String.Format("{0,-50} {1,-30} affected={2,-5} total={3,-5}", Name, reason, affectedModules, counter), "UPDATED");
}
}
-
+
// TODO: optimize
internal int Updated(ref int affectedModules) {
_version = Interlocked.Increment(ref _globalVersion);
@@ -280,11 +280,12 @@
_methods = (module._methods != null) ? new Dictionary(module._methods) : null;
_classVariables = (module._classVariables != null) ? new Dictionary(module._classVariables) : null;
- _mixins = ArrayUtils.Copy(module._mixins);
+ _mixins.Clear();
+ AddMixins(module._mixins);
// dependentModules - skip
// tracker - skip, .NET members not copied
-
+
Updated("InitializeFrom");
}
@@ -307,8 +308,8 @@
public static RubyModule/*!*/ CreateAnonymousModule(CodeContext/*!*/ context, BlockParam block) {
// TODO:
throw new NotImplementedException();
- }
-
+ }
+
public RubyClass/*!*/ CreateSingletonClass() {
//^ ensures result.IsSingletonClass && !result.IsDummySingletonClass
@@ -332,7 +333,7 @@
return ForEachDeclaredAncestor(action);
}
}
-
+
protected virtual bool ForEachAncestor(Func/*!*/ action) {
return ForEachDeclaredAncestor(action);
}
@@ -356,7 +357,7 @@
public SymbolId MakeNestedModuleName(SymbolId nestedModuleSimpleName) {
return ReferenceEquals(this, _executionContext.ObjectClass) || nestedModuleSimpleName.IsEmpty ?
- nestedModuleSimpleName :
+ nestedModuleSimpleName :
SymbolTable.StringToId(_name + "::" + nestedModuleSimpleName);
}
@@ -364,7 +365,7 @@
ForEachAncestor(inherited, delegate(RubyModule/*!*/ module) {
// notification that we entered the module (it could have no constant):
if (action(module, SymbolId.Empty, Missing.Value)) return true;
-
+
return module.EnumerateConstants(action);
});
}
@@ -376,7 +377,7 @@
EnsureInitialized();
_constants[name] = value;
}
-
+
// TODO: we don't do dynamic constant lookup, so there is no need to update the class
// Updated("SetConstant");
}
@@ -434,10 +435,10 @@
}
EnsureInitialized();
-
+
if (_constants != null && _constants.TryGetValue(name, out value)) {
return true;
- }
+ }
if (_clrConstants != null && _clrConstants.TryGetValue(name, out value)) {
value = TrackerToModule(value);
@@ -453,7 +454,7 @@
if (typeGroup != null) {
return value;
}
-
+
// TypeTracker retrieved from namespace tracker should behave like a RubyClass/RubyModule:
TypeTracker typeTracker = value as TypeTracker;
if (typeTracker != null) {
@@ -505,7 +506,7 @@
// skip interfaces (methods declared on interfaces have already been looked for in the class);
// if 'this' is an interface, we want to visit all interface methods:
if (module.IsInterface && !this.IsInterface) return false;
-
+
// notification that we entered the module (it could have no method):
if (action(module, SymbolId.Empty, null)) return true;
@@ -530,24 +531,24 @@
// Update only if the current method overrides/redefines another one higher in the inheritance hierarchy.
// Method lookup failures are not cached in dynamic sites.
// Therefore a future invocation of the method will trigger resolution in binder that will find just added method.
- // If, on the other hand, a method is overriden there might be a dynamic site that caches a method call to that method.
+ // If, on the other hand, a method is overridden there might be a dynamic site that caches a method call to that method.
// In that case we need to update version to invalidate the site.
-
- RubyMemberInfo overridenMethod = ResolveMethodUsedInDynamicSite(name);
-
+
+ RubyMemberInfo overriddenMethod = ResolveMethodUsedInDynamicSite(name);
+
// TODO: cache this? (definition of method_missing could updated all subclasses):
- if (overridenMethod == null) {
- overridenMethod = ResolveMethodUsedInDynamicSite(Symbols.MethodMissing);
+ if (overriddenMethod == null) {
+ overriddenMethod = ResolveMethodUsedInDynamicSite(Symbols.MethodMissing);
// TODO: better check for builtin method
- if (overridenMethod != null && overridenMethod.DeclaringModule == ExecutionContext.KernelModule && overridenMethod is RubyMethodGroupInfo) {
- overridenMethod = null;
+ if (overriddenMethod != null && overriddenMethod.DeclaringModule == ExecutionContext.KernelModule && overriddenMethod is RubyMethodGroupInfo) {
+ overriddenMethod = null;
}
}
EnsureInitialized();
_methods[name] = method;
- if (overridenMethod != null) {
+ if (overriddenMethod != null) {
// TODO: stop updating if a module that defines a method of the same name is reached:
Updated("SetMethod: " + name);
}
@@ -584,7 +585,7 @@
_methods[name] = RubyMethodInfo.HiddenMethod;
Updated("HideMethod");
}
-
+
public void HideMethod(string/*!*/ name) {
HideMethod(SymbolTable.StringToId(name));
}
@@ -786,7 +787,7 @@
}
internal void SetMixins(IList/*!*/ modules) {
- Debug.Assert(_mixins.Length == 0);
+ Debug.Assert(_mixins.Count == 0);
Debug.Assert(modules != null && CollectionUtils.TrueForAll(modules, delegate(RubyModule m) { return m != null && !m.IsClass; }));
List allModules = new List();
@@ -794,7 +795,8 @@
SetDependency(modules);
// do not initialize modules:
- _mixins = allModules.ToArray();
+ _mixins.Clear();
+ AddMixins(allModules);
Updated("SetMixins");
}
@@ -804,11 +806,32 @@
// transitively include modules:
List allModules = new List();
- for (int i = 0; i < modules.Length; i++) {
- allModules.Add(modules[i]);
- GetMixinsRecursive(allModules, modules[i]._mixins);
+ foreach (RubyModule module in modules) {
+ allModules.Add(module);
+ GetMixinsRecursive(allModules, module._mixins);
}
+ foreach (RubyModule module in allModules) {
+ if (module.IsInterface) {
+ // Can't include generic interfaces
+ if (module.Tracker.Type.ContainsGenericParameters) {
+ throw RubyExceptions.CreateTypeError(String.Format(
+ "{0}: cannot extend with open generic instantiation {1}. Only closed instantiations are supported.",
+ Name, module.Name
+ ));
+ }
+
+ if (!CanIncludeClrInterface) {
+ if (CollectionUtils.TrueForAll(_mixins, delegate(RubyModule m) { return m != module; })) {
+ throw new InvalidOperationException(String.Format(
+ "Interface {0} cannot be included in class {1} because its underlying type has already been created.",
+ module.Name, Name
+ ));
+ }
+ }
+ }
+ }
+
SetDependency(allModules);
// initialize added modules:
@@ -818,19 +841,46 @@
}
}
- // new modules are inserted at the beginning so they come first in MRO
- _mixins = ArrayUtils.InsertAt(_mixins, 0, allModules.ToArray());
+ AddMixins(allModules);
Updated("IncludeModules");
}
- internal static void GetMixinsRecursive(List/*!*/ result, IList/*!*/ modules) {
- for (int i = 0; i < modules.Count; i++) {
- result.Add(modules[i]);
- GetMixinsRecursive(result, modules[i]._mixins);
+ private void AddMixins(IList allModules) {
+ // new modules are inserted at the beginning so they come first in MRO
+ if (_mixins.Capacity < _mixins.Count + allModules.Count) {
+ _mixins.Capacity = _mixins.Count + allModules.Count;
}
+ int position = 0;
+ foreach (RubyModule module in allModules) {
+ if (!_mixins.Contains(module)) {
+ _mixins.Insert(position++, module);
+ }
+ }
}
+ internal static void GetMixinsRecursive(List/*!*/ result, IList/*!*/ modules) {
+ foreach (RubyModule module in modules) {
+ result.Add(module);
+ GetMixinsRecursive(result, module._mixins);
+ }
+ }
+
+
+ protected virtual bool CanIncludeClrInterface {
+ get { return true; }
+ }
+
+ protected List GetClrInterfaces() {
+ List interfaces = new List();
+ foreach (RubyModule m in _mixins) {
+ if (m.IsInterface && !interfaces.Contains(m.Tracker.Type)) {
+ interfaces.Add(m.Tracker.Type);
+ }
+ }
+ return interfaces;
+ }
+
internal void IncludeTrait(Action/*!*/ trait) {
Assert.NotNull(trait);
@@ -848,7 +898,7 @@
internal void IncludeLibraryModule(Action instanceTrait, Action classTrait, RubyModule[]/*!*/ mixins) {
Assert.NotNull(mixins);
-
+
IncludeModules(mixins);
if (instanceTrait != null) {
@@ -865,7 +915,7 @@
internal void AddFullVersionTest(MetaObjectBuilder/*!*/ metaBuilder, MSA.Expression/*!*/ codeContextExpression) {
Assert.NotNull(metaBuilder);
EnsureInitialized(); // Initialization changes the version number, so ensure that the module is initialized
-
+
// TODO: runtime check could be a restriction
metaBuilder.AddCondition(AstFactory.OpCall("CheckVersionAndRuntime",
codeContextExpression,
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/RubyTypeBuilder.cs;C520315
File: RubyTypeBuilder.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/RubyTypeBuilder.cs;C520315 (server) 8/4/2008 2:20 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/RubyTypeBuilder.cs;rubyclrinterop01
@@ -19,7 +19,9 @@
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Serialization;
+using System.Text;
using System.Threading;
+using Microsoft.Scripting;
using Microsoft.Scripting.Generation;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;
@@ -28,61 +30,67 @@
namespace Ruby.Compiler.Generation {
internal sealed class RubyTypeBuilder {
- // base type that doesn't implement IRubyObject -> Ruby subtype that does
- private static readonly Dictionary/*!*/ _RubyTypes; // synchronized
+ private static readonly Publisher _newTypes;
static RubyTypeBuilder() {
- _RubyTypes = new Dictionary();
- _RubyTypes.Add(typeof(object), typeof(RubyObject));
- _RubyTypes.Add(typeof(MutableString), typeof(MutableString.Subclass));
- _RubyTypes.Add(typeof(Proc), typeof(Proc.Subclass));
+ _newTypes = new Publisher();
+
+ _newTypes.GetOrCreateValue(new TypeDescription(typeof(object)), delegate() { return typeof(RubyObject); });
+ _newTypes.GetOrCreateValue(new TypeDescription(typeof(MutableString)), delegate() { return typeof(MutableString.Subclass); });
+ _newTypes.GetOrCreateValue(new TypeDescription(typeof(Proc)), delegate() { return typeof(Proc.Subclass); });
}
+ [MultiRuntimeAware]
private static int _typeCounter;
- internal static Type/*!*/ GetOrCreateType(Type/*!*/ baseType) {
+ private readonly Type/*!*/ _baseType;
+ private readonly IEnumerable/*!*/ _interfaceTypes;
+ private TypeBuilder _tb;
+ private FieldBuilder _classField;
+ private FieldBuilder _instanceDataField;
+
+ internal static Type/*!*/ GetOrCreateType(Type/*!*/ baseType, IList/*!*/ interfaces) {
Assert.NotNull(baseType);
+ Assert.NotNull(interfaces);
- Type type;
- if (typeof(IRubyObject).IsAssignableFrom(baseType)) {
- type = baseType;
- } else {
- lock (_RubyTypes) {
- if (!_RubyTypes.TryGetValue(baseType, out type)) {
- type = CreateType(baseType);
- _RubyTypes.Add(baseType, type);
- }
- }
- }
+ TypeDescription typeInfo = new TypeDescription(baseType, interfaces);
+ Type type = _newTypes.GetOrCreateValue(typeInfo,
+ delegate() {
+ return new RubyTypeBuilder(typeInfo).CreateType();
+ });
Debug.Assert(typeof(IRubyObject).IsAssignableFrom(type));
return type;
}
- private static Type/*!*/ CreateType(Type/*!*/ baseType) {
- if (baseType.IsSealed) {
+ internal RubyTypeBuilder(TypeDescription /*!*/ typeInfo) {
+ _baseType = typeInfo.BaseType;
+ _interfaceTypes = typeInfo.InterfaceTypes;
+ }
+
+ private Type/*!*/ CreateType() {
+ if (_baseType.IsSealed) {
throw new NotSupportedException("Can't inherit from a sealed type.");
}
// make sure to generate a call to the base class constructor:
- int counter = Interlocked.Increment(ref _typeCounter);
- string typeName = "Ruby.Classes." + baseType.Name + counter;
- TypeBuilder tb = Snippets.Shared.DefinePublicType(typeName, baseType);
+ string typeName = GetName();
+ _tb = Snippets.Shared.DefinePublicType(typeName, _baseType);
Debug.WriteLine(typeName, "TYPE BUILDER");
// fields:
- FieldBuilder classField = tb.DefineField("_class", typeof(RubyClass), FieldAttributes.Private | FieldAttributes.InitOnly);
- FieldBuilder instanceDataField = tb.DefineField("_instanceData", typeof(RubyInstanceData), FieldAttributes.Private);
+ _classField = _tb.DefineField("_class", typeof(RubyClass), FieldAttributes.Private | FieldAttributes.InitOnly);
+ _instanceDataField = _tb.DefineField("_instanceData", typeof(RubyInstanceData), FieldAttributes.Private);
- DefineConstructors(tb, instanceDataField, classField);
- DefineRubyObjectImplementation(tb, instanceDataField, classField);
- DefineSerializer(tb, instanceDataField, classField);
+ DefineConstructors();
+ DefineRubyObjectImplementation();
+ DefineSerializer();
// TODO: use MetaObjects
- // DefineDynamicObjectImplementation(tb);
+ // DefineDynamicObjectImplementation();
+ ImplementInterfaces();
-
// we need to get the right execution context
#if OBSOLETE
// TODO: remove the need for these methods to be special cased
@@ -90,8 +98,18 @@
EmitOverrideGetHashCode(typeGen);
#endif
+ return _tb.CreateType();
+ }
- return tb.CreateType();
+ private string GetName() {
+ StringBuilder name = new StringBuilder("Ruby.Classes.");
+ name.Append(_baseType.Name);
+ name.Append(Interlocked.Increment(ref _typeCounter));
+ foreach (Type interfaceType in _interfaceTypes) {
+ name.Append("#");
+ name.Append(interfaceType.Name);
+ }
+ return name.ToString();
}
#if !SILVERLIGHT
@@ -101,32 +119,32 @@
return method != null && !method.IsPrivate && !method.IsFamilyAndAssembly;
}
- private static void DefineConstructors(TypeBuilder/*!*/ tb, FieldInfo/*!*/ instanceDataField, FieldInfo/*!*/ classField) {
+ private void DefineConstructors() {
BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
// ctor(RubyClass! class) : ... { this._class = class; }
- ConstructorBuilder ctor = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard,
+ ConstructorBuilder ctor = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard,
new Type[] { typeof(RubyClass) }
);
ILGen il = new ILGen(ctor.GetILGenerator());
ConstructorInfo baseCtor;
- if (IsAvailable(baseCtor = tb.BaseType.GetConstructor(bindingFlags, null, new Type[] { typeof(RubyClass) }, null))) {
+ if (IsAvailable(baseCtor = _tb.BaseType.GetConstructor(bindingFlags, null, new Type[] { typeof(RubyClass) }, null))) {
// : base(class)
il.EmitLoadArg(0);
il.EmitLoadArg(1);
il.Emit(OpCodes.Call, baseCtor);
- } else if (IsAvailable(baseCtor = tb.BaseType.GetConstructor(bindingFlags, null, Type.EmptyTypes, null))) {
+ } else if (IsAvailable(baseCtor = _tb.BaseType.GetConstructor(bindingFlags, null, Type.EmptyTypes, null))) {
// : base()
il.EmitLoadArg(0);
il.Emit(OpCodes.Call, baseCtor);
} else {
- throw new NotSupportedException("No compatible constructor found for class " + tb.BaseType.FullName);
+ throw new NotSupportedException("No compatible constructor found for class " + _tb.BaseType.FullName);
}
-
+
il.EmitLoadArg(0);
il.EmitLoadArg(1);
- il.EmitFieldSet(classField);
+ il.EmitFieldSet(_classField);
il.Emit(OpCodes.Ret);
#if !SILVERLIGHT
@@ -134,10 +152,10 @@
// RubyOps.DeserializeObject(out this._instanceData, out this._class, info);
// }
- ConstructorBuilder deserializer = tb.DefineConstructor(MethodAttributes.Family, CallingConventions.Standard, _deserializerSignature);
+ ConstructorBuilder deserializer = _tb.DefineConstructor(MethodAttributes.Family, CallingConventions.Standard, _deserializerSignature);
il = new ILGen(deserializer.GetILGenerator());
- ConstructorInfo baseDeserializer = tb.BaseType.GetConstructor(bindingFlags, null, _deserializerSignature, null);
+ ConstructorInfo baseDeserializer = _tb.BaseType.GetConstructor(bindingFlags, null, _deserializerSignature, null);
if (IsAvailable(baseDeserializer)) {
// : base(info, context) {
@@ -155,44 +173,44 @@
}
il.EmitLoadArg(0);
- il.EmitFieldAddress(instanceDataField);
+ il.EmitFieldAddress(_instanceDataField);
il.EmitLoadArg(0);
- il.EmitFieldAddress(classField);
+ il.EmitFieldAddress(_classField);
il.EmitLoadArg(1);
il.EmitCall(typeof(RubyOps).GetMethod("DeserializeObject"));
il.Emit(OpCodes.Ret);
#endif
}
- private static void DefineRubyObjectImplementation(TypeBuilder/*!*/ tb, FieldInfo/*!*/ instanceDataField, FieldInfo/*!*/ classField) {
- tb.AddInterfaceImplementation(typeof(IRubyObject));
+ private void DefineRubyObjectImplementation() {
+ _tb.AddInterfaceImplementation(typeof(IRubyObject));
ILGen il;
// RubyClass! IRubyObject.RubyClass { get { return this._class; } }
- il = DefineMethodOverride(tb, typeof(IRubyObject).GetProperty(RubyObject.ClassPropertyName).GetGetMethod());
+ il = DefineMethodOverride(_tb, typeof(IRubyObject).GetProperty(RubyObject.ClassPropertyName).GetGetMethod());
il.EmitLoadArg(0);
- il.EmitFieldGet(classField);
+ il.EmitFieldGet(_classField);
il.Emit(OpCodes.Ret);
// RubyInstanceData IRubyObject.TryGetInstanceData() { return this._instanceData; }
- il = DefineMethodOverride(tb, typeof(IRubyObject).GetMethod("TryGetInstanceData"));
+ il = DefineMethodOverride(_tb, typeof(IRubyObject).GetMethod("TryGetInstanceData"));
il.EmitLoadArg(0);
- il.EmitFieldGet(instanceDataField);
+ il.EmitFieldGet(_instanceDataField);
il.Emit(OpCodes.Ret);
// RubyInstanceData! IRubyObject.GetInstanceData() { return RubyOps.GetInstanceData(ref _instanceData); }
- il = DefineMethodOverride(tb, typeof(IRubyObject).GetMethod("GetInstanceData"));
+ il = DefineMethodOverride(_tb, typeof(IRubyObject).GetMethod("GetInstanceData"));
il.EmitLoadArg(0);
- il.EmitFieldAddress(instanceDataField);
+ il.EmitFieldAddress(_instanceDataField);
il.EmitCall(typeof(RubyOps).GetMethod("GetInstanceData"));
il.Emit(OpCodes.Ret);
}
- private static void DefineSerializer(TypeBuilder/*!*/ tb, FieldBuilder/*!*/ instanceDataField, FieldBuilder/*!*/ classField) {
+ private void DefineSerializer() {
#if !SILVERLIGHT
ILGen il;
- tb.AddInterfaceImplementation(typeof(ISerializable));
+ _tb.AddInterfaceImplementation(typeof(ISerializable));
// void ISerializable.GetObjectData(SerializationInfo! info, StreamingContext! context) {
// base.GetObjectData(info, context);
@@ -200,14 +218,14 @@
// }
MethodInfo baseSerializer;
- if (typeof(ISerializable).IsAssignableFrom(tb.BaseType)) {
- InterfaceMapping map = tb.BaseType.GetInterfaceMap(typeof(ISerializable));
+ if (typeof(ISerializable).IsAssignableFrom(_tb.BaseType)) {
+ InterfaceMapping map = _tb.BaseType.GetInterfaceMap(typeof(ISerializable));
baseSerializer = map.TargetMethods[0];
} else {
baseSerializer = null;
}
-
- il = DefineMethodOverride(tb, typeof(ISerializable).GetMethod("GetObjectData"));
+
+ il = DefineMethodOverride(_tb, typeof(ISerializable).GetMethod("GetObjectData"));
if (baseSerializer != null) {
il.EmitLoadArg(0);
il.EmitLoadArg(1);
@@ -216,9 +234,9 @@
}
il.EmitLoadArg(0);
- il.EmitFieldGet(instanceDataField);
+ il.EmitFieldGet(_instanceDataField);
il.EmitLoadArg(0);
- il.EmitFieldGet(classField);
+ il.EmitFieldGet(_classField);
il.EmitLoadArg(1);
il.EmitCall(typeof(RubyOps).GetMethod("SerializeObject"));
il.Emit(OpCodes.Ret);
@@ -280,16 +298,17 @@
cg.Finish();
}
+#endif
- private static void DefineDynamicObjectImplementation(TypeBuilder/*!*/ tb) {
- tb.AddInterfaceImplementation(typeof(IOldDynamicObject));
+ private void DefineDynamicObjectImplementation() {
+ _tb.AddInterfaceImplementation(typeof(IOldDynamicObject));
// MetaObjectBuilder! IOldDynamicObject.GetRule(OldDynamicAction! action, CodeContext! context, object[]! args) where T : class {
// return RubyOps.GetClassRule(action, context, args);
// }
MethodInfo decl = typeof(IOldDynamicObject).GetMethod("GetRule");
- MethodBuilder impl = tb.DefineMethod(
+ MethodBuilder impl = _tb.DefineMethod(
decl.Name,
decl.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.ReservedMask),
decl.ReturnType,
@@ -299,7 +318,7 @@
types[0].SetGenericParameterAttributes(GenericParameterAttributes.ReferenceTypeConstraint);
ILGen il = new ILGen(impl.GetILGenerator());
-
+
MethodInfo mi = typeof(RubyOps).GetMethod("GetClassRule").MakeGenericMethod(types);
il.EmitLoadArg(1);
il.EmitLoadArg(2);
@@ -307,9 +326,8 @@
il.EmitCall(mi);
il.Emit(OpCodes.Ret);
- tb.DefineMethodOverride(impl, decl);
+ _tb.DefineMethodOverride(impl, decl);
}
-#endif
private static ILGen/*!*/ DefineMethodOverride(TypeBuilder/*!*/ tb, MethodInfo/*!*/ decl) {
MethodBuilder impl;
@@ -327,5 +345,16 @@
tb.DefineMethodOverride(impl, decl);
return new ILGen(impl.GetILGenerator());
}
+
+ private void ImplementInterfaces() {
+ foreach (Type interfaceType in _interfaceTypes) {
+ ImplementInterface(interfaceType);
+ }
+ }
+
+ private void ImplementInterface(Type interfaceType) {
+ // TODO: Implement
+ // _tb.AddInterfaceImplementation(interfaceType);
+ }
}
}
===================================================================
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/TypeDescription.cs
File: TypeDescription.cs
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/TypeDescription.cs;rubyclrinterop01
@@ -1,0 +1,106 @@
+?/* ****************************************************************************
+ *
+ * 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
+ * dlr@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 Microsoft.Scripting.Utils;
+
+namespace Ruby.Compiler.Generation {
+
+ ///
+ /// TypeDescription captures the minimal information required by TypeBuilder to define a distinct CLS type
+ ///
+ internal class TypeDescription {
+ // The CLI base-type.
+ private readonly Type/*!*/ _baseType;
+
+ private readonly List/*!*/ _interfaceTypes;
+ protected Nullable _hash;
+
+ public TypeDescription(Type/*!*/ baseType)
+ : this(baseType, Type.EmptyTypes) {
+ }
+
+ public TypeDescription(Type/*!*/ baseType, IList/*!*/ interfaceTypes) {
+ _baseType = baseType;
+ _interfaceTypes = new List(interfaceTypes.Count);
+ foreach (Type t in interfaceTypes) {
+ AddInterface(t);
+ }
+ SortInterfaces();
+ }
+
+ public Type/*!*/ BaseType {
+ get { return _baseType; }
+ }
+
+ public IList/*!*/ InterfaceTypes {
+ get { return _interfaceTypes; }
+ }
+
+ protected void AddInterface(Type/*!*/ type) {
+ Assert.NotNull(type);
+ Assert.Equals(true, type.IsInterface && !type.ContainsGenericParameters);
+
+ for (int i = 0; i < _interfaceTypes.Count; i++) {
+ Type t = _interfaceTypes[i];
+ if (t == type || type.IsAssignableFrom(t)) {
+ // This interface is already included in the list
+ return;
+ }
+ if (t.IsAssignableFrom(type)) {
+ // We are going to supercede this interface
+ _interfaceTypes.RemoveAt(i--);
+ }
+ }
+ _interfaceTypes.Add(type);
+ _hash = null;
+ }
+
+ protected void SortInterfaces() {
+ _interfaceTypes.Sort(delegate(Type a, Type b) { return a.FullName.CompareTo(b.FullName); });
+ }
+
+ public override int GetHashCode() {
+ if (_hash == null) {
+ int hashCode = _baseType.GetHashCode();
+ for (int i = 0; i < _interfaceTypes.Count; i++) {
+ hashCode ^= _interfaceTypes[i].GetHashCode();
+ }
+ _hash = hashCode;
+ }
+
+ return _hash.Value;
+ }
+
+ public override bool Equals(object obj) {
+ TypeDescription other = obj as TypeDescription;
+ if (other == null) return false;
+
+ if (_baseType.Equals(other._baseType) &&
+ _interfaceTypes.Count == other._interfaceTypes.Count) {
+
+ for (int i = 0; i < _interfaceTypes.Count; i++) {
+ if (!_interfaceTypes[i].Equals(other._interfaceTypes[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+ }
+}
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;C518603
File: RubyExecutionContext.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;C518603 (server) 8/6/2008 10:39 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;rubyclrinterop01
@@ -57,7 +57,7 @@
/// $KCODE
///
private static KCode _kcode;
-
+
///
/// $/, $-O
///
@@ -183,7 +183,7 @@
);
}
- site.Target(site, context, obj, methodName);
+ site.Target(site, context, obj, methodName);
}
private void ClassInheritedEvent(RubyClass/*!*/ superClass, RubyClass/*!*/ subClass) {
@@ -201,8 +201,8 @@
#endregion
public Exception CurrentException {
- get { return _currentException; }
- set { _currentException = value; }
+ get { return _currentException; }
+ set { _currentException = value; }
}
public int CurrentSafeLevel {
@@ -235,7 +235,7 @@
public Proc TraceListener {
get { return _traceListener; }
- set { _traceListener = value; }
+ set { _traceListener = value; }
}
public IEnumerable>/*!*/ GlobalVariables {
@@ -255,8 +255,8 @@
}
public object ChildProcessExitStatus {
- get { return _childProcessExitStatus; }
- set { _childProcessExitStatus = value; }
+ get { return _childProcessExitStatus; }
+ set { _childProcessExitStatus = value; }
}
public Scope/*!*/ TopGlobalScope {
@@ -321,7 +321,7 @@
_stringSeparator = null;
_itemSeparator = null;
_kcode = KCode.Default;
-
+
_loader = new Loader(this, context.RubyOptions.SearchPaths);
if (!_loader.TryLoadBuiltins()) {
@@ -361,12 +361,12 @@
// $?
-
+
// $0
if (_context.RubyOptions.MainFile != null) {
DefineGlobalVariableNoLock(Symbols.CommandLineProgramPath, new GlobalVariableInfo(MutableString.Create(_context.RubyOptions.MainFile)));
}
-
+
DefineGlobalVariableNoLock(SymbolTable.StringToId("stdin"), new GlobalVariableInfo(StandardInput));
DefineGlobalVariableNoLock(SymbolTable.StringToId("stdout"), Runtime.GlobalVariables.OutputStream);
DefineGlobalVariableNoLock(SymbolTable.StringToId("stderr"), new GlobalVariableInfo(StandardErrorOutput));
@@ -427,7 +427,7 @@
_objectClass.SetConstant("RELEASE_DATE", releaseDate);
_objectClass.SetConstant("IRONRUBY_VERSION", MutableString.Create(RubyContext.IronRubyVersionString));
-
+
_objectClass.SetConstant("STDIN", StandardInput);
_objectClass.SetConstant("STDOUT", StandardOutput);
_objectClass.SetConstant("STDERR", StandardErrorOutput);
@@ -463,10 +463,10 @@
Action/*!*/ mainSingletonTrait,
Action/*!*/ kernelInstanceTrait,
- Action/*!*/ objectInstanceTrait,
- Action/*!*/ moduleInstanceTrait,
+ Action/*!*/ objectInstanceTrait,
+ Action/*!*/ moduleInstanceTrait,
Action/*!*/ classInstanceTrait,
-
+
Action/*!*/ kernelClassTrait,
Action/*!*/ objectClassTrait,
Action/*!*/ moduleClassTrait,
@@ -498,9 +498,9 @@
// we need to create object class before any other since constants are added in its dictionary:
_kernelModule = new RubyModule(this, Symbols.Kernel, kernelInstanceTrait, null, null);
- _objectClass = new RubyClass(this, Symbols.Object, objectTracker.Type, null, objectInstanceTrait, null, objectTracker, false);
- _moduleClass = new RubyClass(this, Symbols.Module, typeof(RubyModule), null, moduleInstanceTrait, _objectClass, null, false);
- _classClass = new RubyClass(this, Symbols.Class, typeof(RubyClass), null, classInstanceTrait, _moduleClass, null, false);
+ _objectClass = new RubyClass(this, Symbols.Object, objectTracker.Type, null, objectInstanceTrait, null, objectTracker, false, false);
+ _moduleClass = new RubyClass(this, Symbols.Module, typeof(RubyModule), null, moduleInstanceTrait, _objectClass, null, false, false);
+ _classClass = new RubyClass(this, Symbols.Class, typeof(RubyClass), null, classInstanceTrait, _moduleClass, null, false, false);
CreateDummySingletonClassFor(_kernelModule, _moduleClass, kernelClassTrait);
CreateDummySingletonClassFor(_objectClass, _classClass, objectClassTrait);
@@ -544,12 +544,12 @@
internal RubyModule/*!*/ GetOrCreateModule(NamespaceTracker/*!*/ tracker) {
Assert.NotNull(tracker);
-
+
lock (ModuleCacheSyncRoot) {
return GetOrCreateModuleNoLock(tracker);
}
}
-
+
internal bool TryGetModule(NamespaceTracker/*!*/ namespaceTracker, out RubyModule result) {
lock (NamespaceCacheSyncRoot) {
return _namespaceCache.TryGetValue(namespaceTracker, out result);
@@ -581,7 +581,7 @@
return false;
}
}
-
+
internal RubyClass/*!*/ GetOrCreateClass(Type/*!*/ type) {
Debug.Assert(type != null && !type.IsInterface);
@@ -589,10 +589,10 @@
return GetOrCreateClassNoLock(type);
}
}
-
+
private RubyModule/*!*/ GetOrCreateModuleNoLock(NamespaceTracker/*!*/ tracker) {
Assert.NotNull(tracker);
-
+
RubyModule result;
if (_namespaceCache.TryGetValue(tracker, out result)) {
return result;
@@ -616,7 +616,7 @@
_moduleCache[interfaceType] = result;
return result;
}
-
+
private RubyClass/*!*/ GetOrCreateClassNoLock(Type/*!*/ type) {
Debug.Assert(type != null && !type.IsInterface);
@@ -628,7 +628,7 @@
RubyClass baseClass = GetOrCreateClassNoLock(type.BaseType);
TypeTracker tracker = (TypeTracker)TypeTracker.FromMemberInfo(type);
- result = CreateClass(SymbolTable.StringToId(RubyUtils.GetQualifiedName(type)), type, null, null, null, baseClass, tracker, false);
+ result = CreateClass(SymbolTable.StringToId(RubyUtils.GetQualifiedName(type)), type, null, null, null, baseClass, tracker, false, false);
List interfaceMixins = GetDeclaredInterfaceModules(type);
if (interfaceMixins != null) {
@@ -657,17 +657,16 @@
#region Class and Module Factories
- internal RubyClass/*!*/ CreateClass(SymbolId name, Type type, object classSingletonOf, Action instanceTrait, Action classTrait,
- RubyClass/*!*/ superClass, TypeTracker tracker, bool isRubyClass) {
+ internal RubyClass/*!*/ CreateClass(SymbolId name, Type type, object classSingletonOf, Action instanceTrait, Action classTrait, RubyClass/*!*/ superClass, TypeTracker tracker, bool isRubyClass, bool isSingletonClass) {
Debug.Assert(superClass != null);
- RubyClass result = new RubyClass(this, name, type, classSingletonOf, instanceTrait, superClass, tracker, isRubyClass);
+ RubyClass result = new RubyClass(this, name, type, classSingletonOf, instanceTrait, superClass, tracker, isRubyClass, isSingletonClass);
CreateDummySingletonClassFor(result, superClass.SingletonClass, classTrait);
return result;
}
- internal RubyModule/*!*/ CreateModule(SymbolId name, Action instanceTrait, Action classTrait,
+ internal RubyModule/*!*/ CreateModule(SymbolId name, Action instanceTrait, Action classTrait,
NamespaceTracker namespaceTracker, TypeTracker typeTracker) {
RubyModule result = new RubyModule(this, name, instanceTrait, namespaceTracker, typeTracker);
CreateDummySingletonClassFor(result, _moduleClass, classTrait);
@@ -678,10 +677,10 @@
// Note that in MRI, member tables of dummy singleton are shared with the class the dummy is singleton for
// This is obviously an implementation detail leaking to the language and we don't support that for code clarity.
- // real class object and it's singleton share tyhe tracker:
+ // real class object and it's singleton share the tracker:
TypeTracker tracker = (module.IsSingletonClass) ? null : module.Tracker;
- RubyClass result = new RubyClass(this, SymbolId.Empty, null, module, trait, superClass, tracker, false);
+ RubyClass result = new RubyClass(this, SymbolId.Empty, null, module, trait, superClass, tracker, false, true);
result.SingletonClass = result;
module.SingletonClass = result;
#if DEBUG
@@ -736,7 +735,7 @@
RubyClass c = GetClassOf(obj, data);
- result = CreateClass(SymbolId.Empty, null, obj, instanceTrait, classTrait ?? _classSingletonTrait, c, null, true);
+ result = CreateClass(SymbolId.Empty, null, obj, instanceTrait, classTrait ?? _classSingletonTrait, c, null, true, true);
c.Updated("CreateInstanceSingleton");
SetInstanceSingletonOf(obj, ref data, result);
#if DEBUG
@@ -763,9 +762,15 @@
ContractUtils.RequiresNotNull(owner, "owner");
ContractUtils.RequiresNotNull(superClass, "superClass");
+ if (superClass.Tracker != null && superClass.Tracker.Type.ContainsGenericParameters) {
+ throw RubyExceptions.CreateTypeError(String.Format(
+ "{0}: cannot inherit from open generic instantiation {1}. Only closed instantiations are supported.",
+ SymbolTable.IdToString(name), superClass.Name
+ ));
+ }
+
SymbolId qualifiedName = owner.MakeNestedModuleName(name);
- Type type = RubyTypeBuilder.GetOrCreateType(superClass.GetUnderlyingSystemType());
- RubyClass result = CreateClass(qualifiedName, type, null, null, null, superClass, null, true);
+ RubyClass result = CreateClass(qualifiedName, null, null, null, null, superClass, null, true, false);
if (!name.IsEmpty) {
owner.SetConstant(name, result);
@@ -791,8 +796,8 @@
if (TryGetModuleNoLock(type, out module)) {
module.IncludeLibraryModule(instanceTrait, classTrait, mixins);
return module;
- }
-
+ }
+
if (name == null) {
name = RubyUtils.GetQualifiedName(type);
}
@@ -827,8 +832,8 @@
}
return result;
- }
-
+ }
+
if (name == null) {
name = RubyUtils.GetQualifiedName(type);
}
@@ -840,7 +845,7 @@
// setting tracker on the class makes CLR methods visible:
TypeTracker tracker = ReflectionCache.GetTypeTracker(type);
- result = CreateClass(SymbolTable.StringToId(name), type, null, instanceTrait, classTrait, super, tracker, false);
+ result = CreateClass(SymbolTable.StringToId(name), type, null, instanceTrait, classTrait, super, tracker, false, false);
result.SetMixins(mixins);
result.Factories = factories;
@@ -874,11 +879,11 @@
ContractUtils.Requires(!type.IsInterface);
return GetOrCreateClass(type);
}
-
+
///
/// Gets a class of the specified object (skips any singletons).
///
- public RubyClass/*!*/ GetClassOf(object obj)
+ public RubyClass/*!*/ GetClassOf(object obj)
//^ ensures !result.IsSingletonClass;
{
if (obj == null) {
@@ -905,7 +910,7 @@
if (module != null) {
return module.SingletonClass;
}
-
+
RubyInstanceData data;
RubyClass result = TryGetInstanceSingletonOf(obj, out data);
if (result != null) {
@@ -929,7 +934,7 @@
private void SetInstanceSingletonOf(object obj, ref RubyInstanceData data, RubyClass/*!*/ singleton) {
Debug.Assert(!(obj is RubyModule) && singleton != null);
-
+
if (data == null) {
data = GetInstanceData(obj);
}
@@ -1125,7 +1130,7 @@
TryGetGlobalVariable(null, SymbolTable.StringToId(name), out value);
return value;
}
-
+
public void DefineGlobalVariable(SymbolId name, object value) {
lock (_globalVariables) {
_globalVariables[name] = new GlobalVariableInfo(value);
@@ -1247,7 +1252,7 @@
public void SetKCode(MutableString encodingName) {
// TODO: Ruby 1.9 reports a warning:
-
+
// we allow nil as Ruby 1.9 does:
if (encodingName == null) {
_kcode = KCode.Default;
@@ -1269,7 +1274,7 @@
case 'u':
_kcode = KCode.Utf8;
break;
-
+
default:
_kcode = KCode.Binary;
break;
@@ -1353,10 +1358,10 @@
internal void MethodAdded(RubyModule/*!*/ module, SymbolId name) {
// not called on singleton classes:
if (!module.IsSingletonClass) {
- MethodEvent(ref _methodAddedCallbackSite, Symbols.MethodAdded,
+ MethodEvent(ref _methodAddedCallbackSite, Symbols.MethodAdded,
_context.EmptyContext, module, name);
} else {
- SingletonMethodEvent(ref _singletonMethodAddedCallbackSite, Symbols.SingletonMethodAdded,
+ SingletonMethodEvent(ref _singletonMethodAddedCallbackSite, Symbols.SingletonMethodAdded,
_context.EmptyContext, ((RubyClass)module).SingletonClassOf, name);
}
}
@@ -1364,7 +1369,7 @@
internal void MethodRemoved(RubyModule/*!*/ module, SymbolId name) {
// not called on singleton classes:
if (!module.IsSingletonClass) {
- MethodEvent(ref _methodRemovedCallbackSite, Symbols.MethodRemoved,
+ MethodEvent(ref _methodRemovedCallbackSite, Symbols.MethodRemoved,
_context.EmptyContext, module, name);
} else {
SingletonMethodEvent(ref _singletonMethodRemovedCallbackSite, Symbols.SingletonMethodRemoved,
@@ -1375,7 +1380,7 @@
internal void MethodUndefined(RubyModule/*!*/ module, SymbolId name) {
// not called on singleton classes:
if (!module.IsSingletonClass) {
- MethodEvent(ref _methodUndefinedCallbackSite, Symbols.MethodUndefined,
+ MethodEvent(ref _methodUndefinedCallbackSite, Symbols.MethodUndefined,
_context.EmptyContext, module, name);
} else {
SingletonMethodEvent(ref _singletonMethodUndefinedCallbackSite, Symbols.SingletonMethodUndefined,
@@ -1386,10 +1391,10 @@
internal void MethodCalled(RubyMethodScope/*!*/ scope, string fileName, int lineNumber) {
if (_traceListener != null && !_traceListenerSuspended) {
if (!_traceListenerCallbackSite.IsInitialized) {
- _traceListenerCallbackSite.EnsureInitialized(OldCallAction.Make(scope.LanguageContext.Binder,
+ _traceListenerCallbackSite.EnsureInitialized(OldCallAction.Make(scope.LanguageContext.Binder,
new CallSignature(ArgumentKind.List)));
}
-
+
try {
_traceListenerSuspended = true;
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/ProtocolConversionAction.cs;C520315
File: ProtocolConversionAction.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/ProtocolConversionAction.cs;C520315 (server) 8/13/2008 8:52 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/ProtocolConversionAction.cs;rubyclrinterop01
@@ -90,7 +90,7 @@
SymbolId toMethodName = ToMethodName;
string targetClassName = SymbolTable.IdToString(ec.GetClassOf(args.Target).Name);
- // Kernel#respond_to? method is not overriden => we could optimize
+ // Kernel#respond_to? method is not overridden => we could optimize
RubyMemberInfo respondToMethod = ec.ResolveMethodForSite(args.Target, Symbols.RespondTo);
if (respondToMethod == null ||
// the method is defined in library, hasn't been replaced by user defined method (TODO: maybe we should make this check better)
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/test_basic.rb;C503216
File: test_basic.rb
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/test_basic.rb;C503216 (server) 8/8/2008 12:14 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/test_basic.rb;rubyclrinterop01
@@ -228,6 +228,36 @@
assert_equal(type.is_assignable_from(type), true)
end
+def test_generics_give_type_error
+ assert_raise(TypeError) do
+ Class.new(System::Collections::Generic::List)
+ end
+ assert_raise(TypeError) do
+ Class.new do
+ include System::Collections::Generic::List
+ end
+ end
+end
+
+def test_include_interface_after_type_creation
+ c = Class.new do
+ include System::Collections::Generic::List[System::Int32]
+ end
+
+ # No object has been instantiated so we should be able to reopen the class and add a new interface
+ c.class_eval do
+ include System::IDisposable
+ end
+
+ # After instantiating the object, this will give us an error
+ tmp = c.new
+ assert_raise(TypeError) do
+ c.class_eval do
+ include System::IDisposable
+ end
+ end
+end
+
test_event
test_field
test_string
===================================================================