Skip to content

Commit 861f3b5

Browse files
committed
In JavaScriptEngineSwitcher.ChakraCore fixed a error, that occurred during finding the suitable method overload, that receives numeric values and interfaces as parameters, of the host object
1 parent 14c22a9 commit 861f3b5

File tree

11 files changed

+187
-60
lines changed

11 files changed

+187
-60
lines changed

NuGet/JavaScriptEngineSwitcher.ChakraCore/JavaScriptEngineSwitcher.ChakraCore.nuspec

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ This package does not contain the native implementations of ChakraCore. Therefor
2020
* JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64
2121
* JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64</description>
2222
<summary>JavaScriptEngineSwitcher.ChakraCore contains adapter `ChakraCoreJsEngine` (wrapper for the ChakraCore).</summary>
23-
<releaseNotes>1. Now during the rethrowing of exceptions are preserved the full call stack trace;
24-
2. Reduced a number of delegate-wrappers.</releaseNotes>
23+
<releaseNotes>Fixed a error, that occurred during finding the suitable method overload, that receives numeric values and interfaces as parameters, of the host object.</releaseNotes>
2524
<copyright>Copyright (c) 2013-2017 Andrey Taritsyn - http://www.taritsyn.ru</copyright>
2625
<language>en-US</language>
2726
<tags>JavaScriptEngineSwitcher JavaScript ECMAScript ChakraCore</tags>

NuGet/JavaScriptEngineSwitcher.ChakraCore/readme.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@
3030
=============
3131
RELEASE NOTES
3232
=============
33-
1. Now during the rethrowing of exceptions are preserved the full call stack
34-
trace;
35-
2. Reduced a number of delegate-wrappers.
33+
Fixed a error, that occurred during finding the suitable method overload, that
34+
receives numeric values and interfaces as parameters, of the host object.
3635

3736
=============
3837
DOCUMENTATION

src/JavaScriptEngineSwitcher.ChakraCore/Helpers/ReflectionHelpers.cs

Lines changed: 65 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Reflection;
45

@@ -84,9 +85,8 @@ public static void FixArgumentTypes(ref object[] argValues, ParameterInfo[] para
8485

8586
public static MethodBase GetBestFitMethod(MethodBase[] methods, object[] argValues)
8687
{
87-
int argCount = argValues.Length;
88-
var methodCandidates = methods
89-
.Select(m => new
88+
MethodWithMetadata[] methodCandidates = methods
89+
.Select(m => new MethodWithMetadata
9090
{
9191
Method = m,
9292
ParameterTypes = m.GetParameters()
@@ -95,12 +95,14 @@ public static MethodBase GetBestFitMethod(MethodBase[] methods, object[] argValu
9595
})
9696
.ToArray()
9797
;
98-
99-
var methodsWithSameArity = methodCandidates
98+
int argCount = argValues.Length;
99+
MethodWithMetadata[] sameArityMethods = methodCandidates
100100
.Where(m => m.ParameterTypes.Length == argCount)
101101
.ToArray()
102102
;
103-
if (methodsWithSameArity.Length == 0)
103+
104+
int sameArityMethodCount = sameArityMethods.Length;
105+
if (sameArityMethodCount == 0)
104106
{
105107
return null;
106108
}
@@ -109,40 +111,46 @@ public static MethodBase GetBestFitMethod(MethodBase[] methods, object[] argValu
109111
.Select(a => a.GetType())
110112
.ToArray()
111113
;
112-
var weaklyCompatibleMethods = methodsWithSameArity
113-
.Where(m => CompareParameterTypes(argValues, argTypes, m.ParameterTypes, false))
114-
.ToArray()
115-
;
114+
var compatibleMethods = new List<MethodWithMetadata>();
116115

117-
int weaklyCompatibleMethodCount = weaklyCompatibleMethods.Length;
118-
if (weaklyCompatibleMethodCount > 0)
116+
for (int methodIndex = 0; methodIndex < sameArityMethodCount; methodIndex++)
119117
{
120-
if (weaklyCompatibleMethodCount == 1)
118+
MethodWithMetadata method = sameArityMethods[methodIndex];
119+
ushort compatibilityScore;
120+
121+
if (CompareParameterTypes(argValues, argTypes, method.ParameterTypes, out compatibilityScore))
121122
{
122-
return weaklyCompatibleMethods[0].Method;
123+
method.CompatibilityScore = compatibilityScore;
124+
compatibleMethods.Add(method);
123125
}
126+
}
124127

125-
var strictlyCompatibleMethods = weaklyCompatibleMethods
126-
.Where(m => CompareParameterTypes(argValues, argTypes, m.ParameterTypes, true))
127-
.ToArray()
128-
;
129-
if (strictlyCompatibleMethods.Length > 0)
128+
int compatibleMethodCount = compatibleMethods.Count;
129+
if (compatibleMethodCount > 0)
130+
{
131+
if (compatibleMethodCount == 1)
130132
{
131-
return strictlyCompatibleMethods[0].Method;
133+
return compatibleMethods[0].Method;
132134
}
133135

134-
return weaklyCompatibleMethods[0].Method;
136+
MethodWithMetadata bestFitMethod = compatibleMethods
137+
.OrderByDescending(m => m.CompatibilityScore)
138+
.First()
139+
;
140+
141+
return bestFitMethod.Method;
135142
}
136143

137144
return null;
138145
}
139146

140147
private static bool CompareParameterTypes(object[] argValues, Type[] argTypes, Type[] parameterTypes,
141-
bool strictСompliance)
148+
out ushort compatibilityScore)
142149
{
143150
int argValueCount = argValues.Length;
144151
int argTypeCount = argTypes.Length;
145152
int parameterCount = parameterTypes.Length;
153+
compatibilityScore = 0;
146154

147155
if (argValueCount != argTypeCount || argTypeCount != parameterCount)
148156
{
@@ -155,31 +163,49 @@ private static bool CompareParameterTypes(object[] argValues, Type[] argTypes, T
155163
Type argType = argTypes[argIndex];
156164
Type parameterType = parameterTypes[argIndex];
157165

158-
if (argType != parameterType)
166+
if (argType == parameterType)
159167
{
160-
if (!strictСompliance
161-
&& NumericHelpers.IsNumericType(argType) && NumericHelpers.IsNumericType(parameterType))
162-
{
163-
object convertedArgValue;
164-
165-
if (!TypeConverter.TryConvertToType(argValue, parameterType, out convertedArgValue))
166-
{
167-
return false;
168-
}
169-
170-
if (argValue != convertedArgValue)
171-
{
172-
return false;
173-
}
168+
compatibilityScore++;
169+
}
170+
else
171+
{
172+
// TODO: It is necessary to calculate the compatibility score based on length
173+
// of inheritance and interface implementation chains.
174+
object convertedArgValue;
174175

175-
continue;
176+
if (!TypeConverter.TryConvertToType(argValue, parameterType, out convertedArgValue))
177+
{
178+
return false;
176179
}
177180

178-
return false;
181+
continue;
179182
}
180183
}
181184

182185
return true;
183186
}
187+
188+
189+
private sealed class MethodWithMetadata
190+
{
191+
public MethodBase Method
192+
{
193+
get;
194+
set;
195+
}
196+
197+
public Type[] ParameterTypes
198+
{
199+
get;
200+
set;
201+
}
202+
203+
/// TODO: In future will need to change type to <code>double</code>
204+
public ushort CompatibilityScore
205+
{
206+
get;
207+
set;
208+
}
209+
}
184210
}
185211
}

test/JavaScriptEngineSwitcher.Tests.Net4/JavaScriptEngineSwitcher.Tests.Net40.csproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@
117117
<Compile Include="..\JavaScriptEngineSwitcher.Tests\InteropTestsBase.cs">
118118
<Link>InteropTestsBase.cs</Link>
119119
</Compile>
120+
<Compile Include="..\JavaScriptEngineSwitcher.Tests\Interop\Animals\AnimalTrainer.cs">
121+
<Link>Interop\Animals\AnimalTrainer.cs</Link>
122+
</Compile>
123+
<Compile Include="..\JavaScriptEngineSwitcher.Tests\Interop\Animals\Cat.cs">
124+
<Link>Interop\Animals\Cat.cs</Link>
125+
</Compile>
126+
<Compile Include="..\JavaScriptEngineSwitcher.Tests\Interop\Animals\Dog.cs">
127+
<Link>Interop\Animals\Dog.cs</Link>
128+
</Compile>
129+
<Compile Include="..\JavaScriptEngineSwitcher.Tests\Interop\Animals\IAnimal.cs">
130+
<Link>Interop\Animals\IAnimal.cs</Link>
131+
</Compile>
120132
<Compile Include="..\JavaScriptEngineSwitcher.Tests\Interop\Base64Encoder.cs">
121133
<Link>Interop\Base64Encoder.cs</Link>
122134
</Compile>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace JavaScriptEngineSwitcher.Tests.Interop.Animals
2+
{
3+
public sealed class AnimalTrainer
4+
{
5+
public string ExecuteVoiceCommand(IAnimal animal)
6+
{
7+
return animal.Cry();
8+
}
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace JavaScriptEngineSwitcher.Tests.Interop.Animals
2+
{
3+
public sealed class Cat : IAnimal
4+
{
5+
public string Cry()
6+
{
7+
return "Meow!";
8+
}
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace JavaScriptEngineSwitcher.Tests.Interop.Animals
2+
{
3+
public sealed class Dog : IAnimal
4+
{
5+
public string Cry()
6+
{
7+
return "Woof!";
8+
}
9+
}
10+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace JavaScriptEngineSwitcher.Tests.Interop.Animals
2+
{
3+
public interface IAnimal
4+
{
5+
string Cry();
6+
}
7+
}

test/JavaScriptEngineSwitcher.Tests/Interop/Date.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public static Date Today
1616
get
1717
{
1818
DateTime currentDateTime = DateTime.Today;
19-
Date currentDate = new Date(currentDateTime.Year, currentDateTime.Month, currentDateTime.Day);
19+
var currentDate = new Date(currentDateTime.Year, currentDateTime.Month, currentDateTime.Day);
2020

2121
return currentDate;
2222
}
@@ -43,5 +43,13 @@ public int GetDayOfYear()
4343
(Month > 2 && IsLeapYear(Year) ? 1 : 0)
4444
;
4545
}
46+
47+
public Date AddDays(double value)
48+
{
49+
var dateTime = new DateTime(Year, Month, Day);
50+
DateTime newDateTime = dateTime.AddDays(value);
51+
52+
return new Date(newDateTime.Year, newDateTime.Month, newDateTime.Day);
53+
}
4654
}
4755
}

0 commit comments

Comments
 (0)