Browse Source

Fixing multi-generic types creation

Sebastien Ros 10 years ago
parent
commit
03c1cee683
2 changed files with 168 additions and 137 deletions
  1. 31 0
      Jint.Tests/Runtime/InteropTests.cs
  2. 137 137
      Jint/Runtime/Interop/NamespaceReference.cs

+ 31 - 0
Jint.Tests/Runtime/InteropTests.cs

@@ -274,6 +274,37 @@ namespace Jint.Tests.Runtime
             Assert.Equal("Donald Duck", dictionary[2]);
         }
 
+        [Fact]
+        public void CanUseGenericMethods()
+        {
+            var dictionary = new Dictionary<int, string>();
+            dictionary.Add(1, "Mickey Mouse");
+
+
+            _engine.SetValue("dictionary", dictionary);
+
+            RunTest(@"
+                dictionary.Add(2, 'Goofy');
+                assert(dictionary[2] === 'Goofy');
+            ");
+
+            Assert.Equal("Mickey Mouse", dictionary[1]);
+            Assert.Equal("Goofy", dictionary[2]);
+        }
+
+        [Fact]
+        public void CanUseMultiGenericTypes()
+        {
+            
+            RunTest(@"
+                var type = System.Collections.Generic.Dictionary(System.Int32, System.String);
+                var dictionary = new type();
+                dictionary.Add(1, 'Mickey Mouse');
+                dictionary.Add(2, 'Goofy');
+                assert(dictionary[2] === 'Goofy');
+            ");
+        }
+
         [Fact]
         public void CanUseIndexOnCollection()
         {

+ 137 - 137
Jint/Runtime/Interop/NamespaceReference.cs

@@ -1,124 +1,124 @@
 using System;
 using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using Jint.Native;
-using Jint.Native.Object;
-using Jint.Runtime.Descriptors;
-
-namespace Jint.Runtime.Interop
-{
-    /// <summary>
-    /// Any instance on this class represents a reference to a CLR namespace.
-    /// Accessing its properties will look for a class of the full name, or instantiate
-    /// a new <see cref="NamespaceReference"/> as it assumes that the property is a deeper
-    /// level of the current namespace
-    /// </summary>
-    public class NamespaceReference : ObjectInstance, ICallable
-    {
-        private readonly string _path;
-
-        public NamespaceReference(Engine engine, string path) : base(engine)
-        {
-            _path = path;
-        }
-
-        public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError)
-        {
-            if (throwOnError)
-            {
-                throw new JavaScriptException(Engine.TypeError, "Can't define a property of a NamespaceReference");
-            }
-
-            return false;
-        }
-
-        public override bool Delete(string propertyName, bool throwOnError)
-        {
-            if (throwOnError)
-            {
-                throw new JavaScriptException(Engine.TypeError, "Can't delete a property of a NamespaceReference");
-            }
-
-            return false;
-        }
-
-        public JsValue Call(JsValue thisObject, JsValue[] arguments)
-        {
-            // direct calls on a NamespaceReference constructor object is creating a generic type 
-            var genericTypes = new Type[arguments.Length];
-            for (int i = 0; i < arguments.Length; i++)
-            {
-                var genericTypeReference = arguments.At(i);
-                if (genericTypeReference == Undefined.Instance || !genericTypeReference.IsObject() || genericTypeReference.AsObject().Class != "TypeReference")
-                {
-                    throw new JavaScriptException(Engine.TypeError, "Invalid generic type parameter");
-                }
-
-                genericTypes[i] = arguments.At(0).As<TypeReference>().Type;
-            }
-
-            var typeReference = GetPath(_path + "`" + arguments.Length.ToString(CultureInfo.InvariantCulture)).As<TypeReference>();
-
-            if (typeReference == null)
-            {
-                return Undefined.Instance;
-            }
-
-            var genericType = typeReference.Type.MakeGenericType(genericTypes);
-
-            return TypeReference.CreateTypeReference(Engine, genericType);
-        }
-
-        public override JsValue Get(string propertyName)
-        {
-            var newPath = _path + "." + propertyName;
-
-            return GetPath(newPath);
-        }
-
-        public JsValue GetPath(string path)
-        {
-            Type type;
-
-            if (Engine.TypeCache.TryGetValue(path, out type))
-            {
-                if (type == null)
-                {
-                    return new NamespaceReference(Engine, path);
-                }
-
-                return TypeReference.CreateTypeReference(Engine, type);
-            }
-
-            // search for type in mscorlib
-            type = Type.GetType(path);
-            if (type != null)
-            {
-                Engine.TypeCache.Add(path, type);
-                return TypeReference.CreateTypeReference(Engine, type);
-            }
-
-            // search in loaded assemblies
-            foreach (var assembly in new[] { Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly() }.Distinct())
-            {
-                type = assembly.GetType(path);
-                if (type != null)
-                {
-                    Engine.TypeCache.Add(path, type);
-                    return TypeReference.CreateTypeReference(Engine, type);
-                }
-            }
-
-            // search in lookup assemblies
-            foreach (var assembly in Engine.Options.GetLookupAssemblies())
-            {
-                type = assembly.GetType(path);
-                if (type != null)
-                {
-                    Engine.TypeCache.Add(path, type);
-                    return TypeReference.CreateTypeReference(Engine, type);
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Jint.Native;
+using Jint.Native.Object;
+using Jint.Runtime.Descriptors;
+
+namespace Jint.Runtime.Interop
+{
+    /// <summary>
+    /// Any instance on this class represents a reference to a CLR namespace.
+    /// Accessing its properties will look for a class of the full name, or instantiate
+    /// a new <see cref="NamespaceReference"/> as it assumes that the property is a deeper
+    /// level of the current namespace
+    /// </summary>
+    public class NamespaceReference : ObjectInstance, ICallable
+    {
+        private readonly string _path;
+
+        public NamespaceReference(Engine engine, string path) : base(engine)
+        {
+            _path = path;
+        }
+
+        public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError)
+        {
+            if (throwOnError)
+            {
+                throw new JavaScriptException(Engine.TypeError, "Can't define a property of a NamespaceReference");
+            }
+
+            return false;
+        }
+
+        public override bool Delete(string propertyName, bool throwOnError)
+        {
+            if (throwOnError)
+            {
+                throw new JavaScriptException(Engine.TypeError, "Can't delete a property of a NamespaceReference");
+            }
+
+            return false;
+        }
+
+        public JsValue Call(JsValue thisObject, JsValue[] arguments)
+        {
+            // direct calls on a NamespaceReference constructor object is creating a generic type 
+            var genericTypes = new Type[arguments.Length];
+            for (int i = 0; i < arguments.Length; i++)
+            {
+                var genericTypeReference = arguments.At(i);
+                if (genericTypeReference == Undefined.Instance || !genericTypeReference.IsObject() || genericTypeReference.AsObject().Class != "TypeReference")
+                {
+                    throw new JavaScriptException(Engine.TypeError, "Invalid generic type parameter");
+                }
+
+                genericTypes[i] = arguments.At(i).As<TypeReference>().Type;
+            }
+
+            var typeReference = GetPath(_path + "`" + arguments.Length.ToString(CultureInfo.InvariantCulture)).As<TypeReference>();
+
+            if (typeReference == null)
+            {
+                return Undefined.Instance;
+            }
+
+            var genericType = typeReference.Type.MakeGenericType(genericTypes);
+
+            return TypeReference.CreateTypeReference(Engine, genericType);
+        }
+
+        public override JsValue Get(string propertyName)
+        {
+            var newPath = _path + "." + propertyName;
+
+            return GetPath(newPath);
+        }
+
+        public JsValue GetPath(string path)
+        {
+            Type type;
+
+            if (Engine.TypeCache.TryGetValue(path, out type))
+            {
+                if (type == null)
+                {
+                    return new NamespaceReference(Engine, path);
+                }
+
+                return TypeReference.CreateTypeReference(Engine, type);
+            }
+
+            // search for type in mscorlib
+            type = Type.GetType(path);
+            if (type != null)
+            {
+                Engine.TypeCache.Add(path, type);
+                return TypeReference.CreateTypeReference(Engine, type);
+            }
+
+            // search in loaded assemblies
+            foreach (var assembly in new[] { Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly() }.Distinct())
+            {
+                type = assembly.GetType(path);
+                if (type != null)
+                {
+                    Engine.TypeCache.Add(path, type);
+                    return TypeReference.CreateTypeReference(Engine, type);
+                }
+            }
+
+            // search in lookup assemblies
+            foreach (var assembly in Engine.Options.GetLookupAssemblies())
+            {
+                type = assembly.GetType(path);
+                if (type != null)
+                {
+                    Engine.TypeCache.Add(path, type);
+                    return TypeReference.CreateTypeReference(Engine, type);
                 }
 
                 var lastPeriodPos = path.LastIndexOf(".", StringComparison.Ordinal);
@@ -132,13 +132,13 @@ namespace Jint.Runtime.Interop
                       Engine.TypeCache.Add(path.Replace("+", "."), nType);
                       return TypeReference.CreateTypeReference(Engine, nType);
                     }
-                  }            
-            }
-
-            // the new path doesn't represent a known class, thus return a new namespace instance
-
-            Engine.TypeCache.Add(path, null);
-            return new NamespaceReference(Engine, path);
+                  }            
+            }
+
+            // the new path doesn't represent a known class, thus return a new namespace instance
+
+            Engine.TypeCache.Add(path, null);
+            return new NamespaceReference(Engine, path);
         }
 
         /// <summary>   Gets a type. </summary>
@@ -178,14 +178,14 @@ namespace Jint.Runtime.Interop
           }
         }
 
-      public override PropertyDescriptor GetOwnProperty(string propertyName)
-        {
-            return PropertyDescriptor.Undefined;
-        }
-
-        public override string ToString()
-        {
-            return "[Namespace: " + _path + "]";
-        }
-    }
-}
+      public override PropertyDescriptor GetOwnProperty(string propertyName)
+        {
+            return PropertyDescriptor.Undefined;
+        }
+
+        public override string ToString()
+        {
+            return "[Namespace: " + _path + "]";
+        }
+    }
+}