Bläddra i källkod

Fixing type resolution

Sebastien Ros 11 år sedan
förälder
incheckning
e811661b55

+ 4 - 0
Jint.Tests/Jint.Tests.csproj

@@ -54,6 +54,10 @@
   <ItemGroup>
     <Compile Include="Parser\JavascriptParserTests.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Runtime\Domain\A.cs" />
+    <Compile Include="Runtime\Domain\IPerson.cs" />
+    <Compile Include="Runtime\Domain\Person.cs" />
+    <Compile Include="Runtime\Domain\Shape.cs" />
     <Compile Include="Runtime\SamplesTests.cs" />
     <Compile Include="Runtime\InteropTests.cs" />
     <Compile Include="Runtime\EngineTests.cs" />

+ 49 - 0
Jint.Tests/Runtime/Domain/A.cs

@@ -0,0 +1,49 @@
+using System;
+using Jint.Native;
+
+namespace Jint.Tests.Runtime.Domain
+{
+    public class A
+    {
+        public int Call1()
+        {
+            return 0;
+        }
+
+        public int Call1(int x)
+        {
+            return x;
+        }
+
+        public string Call2(string x)
+        {
+            return x;
+        }
+
+        public string Call3(object x)
+        {
+            return x.ToString();
+        }
+
+        public string Call4(IPerson x)
+        {
+            return x.ToString();
+        }
+
+        public string Call5(Delegate callback)
+        {
+            var thisArg = JsValue.Undefined;
+            var arguments = new JsValue[] { 1, "foo" };
+
+            return callback.DynamicInvoke(thisArg, arguments).ToString();
+        }
+
+        public string Call6(Func<JsValue, JsValue[], JsValue> callback)
+        {
+            var thisArg = new JsValue("bar");
+            var arguments = new JsValue[] { 1, "foo" };
+
+            return callback(thisArg, arguments).ToString();
+        }
+    }
+}

+ 14 - 0
Jint.Tests/Runtime/Domain/IPerson.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jint.Tests.Runtime.Domain
+{
+    public interface IPerson
+    {
+        string Name { get; }
+    }
+
+}

+ 20 - 0
Jint.Tests/Runtime/Domain/Person.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jint.Tests.Runtime.Domain
+{
+    public class Person : IPerson
+    {
+        public string Name { get; set; }
+        public int Age { get; set; }
+
+        public override string ToString()
+        {
+            return Name;
+        }
+    }
+
+}

+ 32 - 0
Jint.Tests/Runtime/Domain/Shape.cs

@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Shapes
+{
+    public abstract class Shape
+    {
+        public abstract double Perimeter();
+    }
+
+    public class Circle : Shape
+    {
+        public Circle()
+        {
+        }
+
+        public Circle(double radius)
+        {
+            Radius = radius;
+        }
+
+        public double Radius { get; set; }
+
+        public override double Perimeter()
+        {
+            return Math.PI*Math.Pow(Radius, 2);
+        }
+    }
+}

+ 33 - 52
Jint.Tests/Runtime/InteropTests.cs

@@ -2,6 +2,8 @@
 using System.Collections.Generic;
 using Jint.Native;
 using Jint.Native.Object;
+using Jint.Tests.Runtime.Domain;
+using Shapes;
 using Xunit;
 
 namespace Jint.Tests.Runtime
@@ -12,7 +14,7 @@ namespace Jint.Tests.Runtime
 
         public InteropTests()
         {
-            _engine = new Engine()
+            _engine = new Engine(cfg => cfg.AllowClr(typeof(Shape).Assembly))
                 .SetValue("log", new Action<object>(Console.WriteLine))
                 .SetValue("assert", new Action<bool>(Assert.True))
                 ;
@@ -441,64 +443,43 @@ namespace Jint.Tests.Runtime
             ");
         }
 
-        public interface IPerson
+        [Fact]
+        public void ShouldUseSystemIO()
         {
-            string Name { get; }
+            RunTest(@"
+                var filename = System.IO.Path.GetTempFileName();
+                var sw = System.IO.File.CreateText(filename);
+                sw.Write('Hello World');
+                sw.Dispose();
+                
+                var content = System.IO.File.ReadAllText(filename);
+                System.Console.WriteLine(content);
+                
+                assert(content === 'Hello World');
+            ");
         }
 
-        public class Person : IPerson
+        [Fact]
+        public void ShouldImportNamespace()
         {
-            public string Name { get; set; }
-            public int Age { get; set; }
-            
-            public override string ToString()
-            {
-                return Name;
-            }
+            RunTest(@"
+                var Shapes = importNamespace('Shapes');
+                var circle = new Shapes.Circle();
+                assert(circle.Radius === 0);
+                assert(circle.Perimeter() === 0);
+            ");
         }
 
-        public class A
+        [Fact]
+        public void ShouldConstructWithParameters()
         {
-            public int Call1()
-            {
-                return 0;
-            }
-
-            public int Call1(int x)
-            {
-                return x;
-            }
-
-            public string Call2(string x)
-            {
-                return x;
-            }
-
-            public string Call3(object x)
-            {
-                return x.ToString();
-            }
-
-            public string Call4(IPerson x)
-            {
-                return x.ToString();
-            }
-
-            public string Call5(Delegate callback)
-            {
-                var thisArg = JsValue.Undefined;
-                var arguments = new JsValue[] { 1, "foo" };
-
-                return callback.DynamicInvoke(thisArg, arguments).ToString();
-            }
-
-            public string Call6(Func<JsValue, JsValue[], JsValue> callback)
-            {
-                var thisArg = new JsValue("bar");
-                var arguments = new JsValue[] { 1, "foo" };
-
-                return callback(thisArg, arguments).ToString();
-            }
+            RunTest(@"
+                var Shapes = importNamespace('Shapes');
+                var circle = new Shapes.Circle(1);
+                assert(circle.Radius === 1);
+                assert(circle.Perimeter() === Math.PI);
+            ");
         }
+
     }
 }

+ 17 - 3
Jint/Options.cs

@@ -1,4 +1,7 @@
-using System.Globalization;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
 using Jint.Runtime.Interop;
 
 namespace Jint
@@ -12,6 +15,7 @@ namespace Jint
         private ITypeConverter _typeConverter = new DefaultTypeConverter();
         private int _maxStatements;
         private CultureInfo _culture = CultureInfo.CurrentCulture;
+        private List<Assembly> _lookupAssemblies = new List<Assembly>(); 
 
         /// <summary>
         /// When called, doesn't initialize the global scope.
@@ -54,9 +58,14 @@ namespace Jint
             return this;
         }
 
-        public Options AllowClr(bool allowClr = true)
+        /// <summary>
+        /// Allows scripts to call CLR types directly like <example>System.IO.File</example>
+        /// </summary>
+        public Options AllowClr(params Assembly[] assemblies)
         {
-            _allowClr = allowClr;
+            _allowClr = true;
+            _lookupAssemblies.AddRange(assemblies);
+            _lookupAssemblies = _lookupAssemblies.Distinct().ToList();
             return this;
         }
 
@@ -91,6 +100,11 @@ namespace Jint
         {
             return _allowClr;
         }
+        
+        internal IList<Assembly> GetLookupAssemblies()
+        {
+            return _lookupAssemblies;
+        }
 
         internal ITypeConverter GetTypeConverter()
         {

+ 23 - 2
Jint/Runtime/Interop/NamespaceReference.cs

@@ -1,7 +1,6 @@
 using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
+using System.Reflection;
 using Jint.Native;
 using Jint.Native.Object;
 using Jint.Runtime.Descriptors;
@@ -46,12 +45,34 @@ namespace Jint.Runtime.Interop
         public override JsValue Get(string propertyName)
         {
             var newPath = _path + "." + propertyName;
+            
+            // search for type in mscorlib
             var type = Type.GetType(newPath);
             if (type != null)
             {
                 return TypeReference.CreateTypeReference(Engine, type);
             }
 
+            // search in loaded assemblies
+            foreach (var assembly in new [] { Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly() }.Distinct())
+            {
+                type = assembly.GetType(newPath);
+                if (type != null)
+                {
+                    return TypeReference.CreateTypeReference(Engine, type);
+                }
+            }
+
+            // search in lookup asemblies
+            foreach (var assembly in Engine.Options.GetLookupAssemblies())
+            {
+                type = assembly.GetType(newPath);
+                if (type != null)
+                {
+                    return TypeReference.CreateTypeReference(Engine, type);
+                }
+            }
+
             // the new path doesn't represent a known class, thus return a new namespace instance
 
             return new NamespaceReference(Engine, newPath);