Browse Source

Merge pull request #4 from sebastienros/master

sync with  sebastienros master
fvaneijk 10 years ago
parent
commit
2a78cb9307

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

@@ -56,6 +56,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Runtime\Converters\NegateBoolConverter.cs" />
     <Compile Include="Runtime\Domain\A.cs" />
+    <Compile Include="Runtime\Domain\ArrayConverterTestClass.cs" />
     <Compile Include="Runtime\Domain\ClassWithField.cs" />
     <Compile Include="Runtime\Domain\ClassWithStaticFields.cs" />
     <Compile Include="Runtime\Domain\Colors.cs" />

+ 133 - 0
Jint.Tests/Runtime/Domain/ArrayConverterTestClass.cs

@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace Jint.Tests.Runtime.Domain
+{
+    public class ArrayConverterTestClass
+    {
+        public string MethodAcceptsArrayOfStrings(string[] arrayOfStrings)
+        {
+            return SerializeToString(arrayOfStrings);
+        }
+
+        public string MethodAcceptsArrayOfInt(int[] arrayOfInt)
+        {
+            return SerializeToString(arrayOfInt);
+        }
+
+        public string MethodAcceptsArrayOfBool(int[] arrayOfBool)
+        {
+            return SerializeToString(arrayOfBool);
+        }
+
+        private static string SerializeToString<T>(IEnumerable<T> array)
+        {
+            return String.Join(",", array);
+        }
+    }
+
+    public class ArrayConverterItem : IConvertible
+    {
+        private readonly int _value;
+
+        public ArrayConverterItem(int value)
+        {
+            _value = value;
+        }
+
+        public override string ToString()
+        {
+            return ToString(CultureInfo.InvariantCulture);
+        }
+
+        public string ToString(IFormatProvider provider)
+        {
+            return _value.ToString(provider);
+        }
+
+        public int ToInt32(IFormatProvider provider)
+        {
+            return Convert.ToInt32(_value, provider);
+        }
+
+        #region NotImplemented
+        public TypeCode GetTypeCode()
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool ToBoolean(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public char ToChar(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public sbyte ToSByte(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public byte ToByte(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public short ToInt16(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public ushort ToUInt16(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public uint ToUInt32(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public long ToInt64(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public ulong ToUInt64(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public float ToSingle(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public double ToDouble(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public decimal ToDecimal(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public DateTime ToDateTime(IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+
+        public object ToType(Type conversionType, IFormatProvider provider)
+        {
+            throw new NotImplementedException();
+        }
+        #endregion
+
+
+    }
+}

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

@@ -1060,6 +1060,7 @@ namespace Jint.Tests.Runtime
             RunTest(@"
                 assert(a.Call13('1','2','3') === '1,2,3');
                 assert(a.Call13('1') === '1');
+                assert(a.Call13(1) === '1');
                 assert(a.Call13() === '');
 
                 assert(a.Call14('a','1','2','3') === 'a:1,2,3');
@@ -1124,5 +1125,23 @@ namespace Jint.Tests.Runtime
                 assert(!ud.undefinedProperty);
             ");
         }
+
+        [Fact]
+        public void ShouldAutomaticallyConvertArraysToFindBestInteropResulution()
+        {
+            _engine.SetValue("a", new ArrayConverterTestClass());
+            _engine.SetValue("item1", new ArrayConverterItem(1));
+            _engine.SetValue("item2", new ArrayConverterItem(2));
+
+            RunTest(@"
+                assert(a.MethodAcceptsArrayOfInt([false, '1', 2]) === a.MethodAcceptsArrayOfInt([0, 1, 2]));
+                assert(a.MethodAcceptsArrayOfStrings(['1', 2]) === a.MethodAcceptsArrayOfStrings([1, 2]));
+                assert(a.MethodAcceptsArrayOfBool(['1', 0]) === a.MethodAcceptsArrayOfBool([true, false]));
+
+                assert(a.MethodAcceptsArrayOfStrings([item1, item2]) === a.MethodAcceptsArrayOfStrings(['1', '2']));
+                assert(a.MethodAcceptsArrayOfInt([item1, item2]) === a.MethodAcceptsArrayOfInt([1, 2]));
+            ");
+        }
+
     }
 }

+ 0 - 6
Jint/Native/JsValue.cs

@@ -18,7 +18,6 @@ using System.Runtime.InteropServices;
 
 namespace Jint.Native
 {
-    [StructLayout(LayoutKind.Explicit)]
     [DebuggerTypeProxy(typeof(JsValueDebugView))]
     public struct JsValue : IEquatable<JsValue>
     {
@@ -76,19 +75,14 @@ namespace Jint.Native
             _type = type;
         }
 
-        [FieldOffset(0)]
         private readonly bool _bool;
 
-        [FieldOffset(0)]
         private readonly double _double;
 
-        [FieldOffset(8)]
         private readonly ObjectInstance _object;
 
-        [FieldOffset(8)]
         private readonly string _string;
 
-        [FieldOffset(16)]
         private readonly Types _type;
 
         [Pure]

+ 1 - 2
Jint/Native/String/StringPrototype.cs

@@ -506,8 +506,7 @@ namespace Jint.Native.String
                     for (var k = 0; k < match.Groups.Count; k++)
                     {
                         var group = match.Groups[k];
-                        if (group.Success)
-                            args.Add(group.Value);
+                        args.Add(group.Value);
                     }
                     
                     args.Add(match.Index);

+ 13 - 0
Jint/Runtime/Interop/DefaultTypeConverter.cs

@@ -157,6 +157,19 @@ namespace Jint.Runtime.Interop
 
             }
 
+            if (type.IsArray)
+            {
+                var source = value as object[];
+                if (source == null)
+                    throw new ArgumentException(String.Format("Value of object[] type is expected, but actual type is {0}.", value.GetType()));
+
+                var targetElementType = type.GetElementType();
+                var itemsConverted = source.Select(o => Convert(o, targetElementType, formatProvider)).ToArray();
+                var result = Array.CreateInstance(targetElementType, source.Length);
+                itemsConverted.CopyTo(result, 0);
+                return result;
+            }
+
             return System.Convert.ChangeType(value, type, formatProvider);
         }
 

+ 4 - 2
Jint/Runtime/Interop/MethodInfoFunctionInstance.cs

@@ -91,8 +91,10 @@ namespace Jint.Runtime.Interop
                 if (argsToTransform.Count == 1 && argsToTransform.FirstOrDefault().IsArray())
                     continue;
 
-                var arrayInstance = ArrayConstructor.CreateArrayConstructor(Engine).Construct(argsToTransform.ToArray());
-                newArgumentsCollection.Add(new JsValue(arrayInstance));
+                var jsArray = Engine.Array.Construct(Arguments.Empty);
+                Engine.Array.PrototypeObject.Push(jsArray, argsToTransform.ToArray());
+
+                newArgumentsCollection.Add(new JsValue(jsArray));
                 return newArgumentsCollection.ToArray();
             }