Skip to content

Commit 0f3c714

Browse files
committed
In JavaScriptEngineSwitcher.ChakraCore fixed a error, that occurred during finding a suitable method overload, that receives numeric parameters, of the host object
1 parent 35a88d4 commit 0f3c714

File tree

7 files changed

+97
-52
lines changed

7 files changed

+97
-52
lines changed

NuGet/JavaScriptEngineSwitcher.ChakraCore/JavaScriptEngineSwitcher.ChakraCore.nuspec

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ This package does not contain the native implementations of ChakraCore. Therefor
2020
* JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64
2121
* JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64</description>
2222
<summary>JavaScriptEngineSwitcher.ChakraCore contains adapter `ChakraCoreJsEngine` (wrapper for the ChakraCore).</summary>
23-
<releaseNotes>1. Added support of .NET Standard 2.0;
24-
2. ChakraCore was updated to version 1.7.3;
25-
3. JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64 package has been replaced by the JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64 package.</releaseNotes>
23+
<releaseNotes>Fixed a error, that occurred during finding a suitable method overload, that receives numeric parameters, of the host object.</releaseNotes>
2624
<copyright>Copyright (c) 2013-2017 Andrey Taritsyn - http://www.taritsyn.ru</copyright>
2725
<language>en-US</language>
2826
<tags>JavaScriptEngineSwitcher JavaScript ECMAScript ChakraCore</tags>

NuGet/JavaScriptEngineSwitcher.ChakraCore/readme.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@
3030
=============
3131
RELEASE NOTES
3232
=============
33-
1. Added support of .NET Standard 2.0;
34-
2. ChakraCore was updated to version 1.7.3;
35-
3. JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64 package has been
36-
replaced by the JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64 package.
33+
Fixed a error, that occurred during finding a suitable method overload, that
34+
receives numeric parameters, of the host object.
3735

3836
=============
3937
DOCUMENTATION

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"sdk": {
3-
"version": "2.0.2"
3+
"version": "2.0.3"
44
}
55
}

src/JavaScriptEngineSwitcher.ChakraCore/Helpers/ReflectionHelpers.cs

Lines changed: 58 additions & 30 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,10 +163,13 @@ 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)
167+
{
168+
compatibilityScore++;
169+
}
170+
else
159171
{
160-
if (!strictСompliance
161-
&& NumericHelpers.IsNumericType(argType) && NumericHelpers.IsNumericType(parameterType))
172+
if (NumericHelpers.IsNumericType(argType) && NumericHelpers.IsNumericType(parameterType))
162173
{
163174
object convertedArgValue;
164175

@@ -167,11 +178,6 @@ private static bool CompareParameterTypes(object[] argValues, Type[] argTypes, T
167178
return false;
168179
}
169180

170-
if (argValue != convertedArgValue)
171-
{
172-
return false;
173-
}
174-
175181
continue;
176182
}
177183

@@ -181,5 +187,27 @@ private static bool CompareParameterTypes(object[] argValues, Type[] argTypes, T
181187

182188
return true;
183189
}
190+
191+
192+
private sealed class MethodWithMetadata
193+
{
194+
public MethodBase Method
195+
{
196+
get;
197+
set;
198+
}
199+
200+
public Type[] ParameterTypes
201+
{
202+
get;
203+
set;
204+
}
205+
206+
public ushort CompatibilityScore
207+
{
208+
get;
209+
set;
210+
}
211+
}
184212
}
185213
}

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
}

test/JavaScriptEngineSwitcher.Tests/InteropTestsBase.cs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -302,25 +302,32 @@ public virtual void EmbeddingOfInstanceOfBuiltinReferenceTypeWithMethodIsCorrect
302302
}
303303

304304
[Fact]
305-
public virtual void EmbeddingOfInstanceOfCustomValueTypeWithMethodIsCorrect()
305+
public virtual void EmbeddingOfInstanceOfCustomValueTypeWithMethodsIsCorrect()
306306
{
307307
// Arrange
308308
var programmerDayDate = new Date(2015, 9, 13);
309309

310-
const string input = "programmerDay.GetDayOfYear()";
311-
const int targetOutput = 256;
310+
const string input1 = "programmerDay.GetDayOfYear()";
311+
const int targetOutput1 = 256;
312+
313+
const string input2 = @"var smileDay = programmerDay.AddDays(6);
314+
smileDay.GetDayOfYear();";
315+
const int targetOutput2 = 262;
312316

313317
// Act
314-
int output;
318+
int output1;
319+
int output2;
315320

316321
using (var jsEngine = CreateJsEngine())
317322
{
318323
jsEngine.EmbedHostObject("programmerDay", programmerDayDate);
319-
output = jsEngine.Evaluate<int>(input);
324+
output1 = jsEngine.Evaluate<int>(input1);
325+
output2 = jsEngine.Evaluate<int>(input2);
320326
}
321327

322328
// Assert
323-
Assert.Equal(targetOutput, output);
329+
Assert.Equal(targetOutput1, output1);
330+
Assert.Equal(targetOutput2, output2);
324331
}
325332

326333
[Fact]
@@ -849,25 +856,31 @@ public virtual void EmbeddingOfBuiltinValueTypeWithMethodIsCorrect()
849856
}
850857

851858
[Fact]
852-
public virtual void EmbeddingOfBuiltinReferenceTypeWithMethodIsCorrect()
859+
public virtual void EmbeddingOfBuiltinReferenceTypeWithMethodsIsCorrect()
853860
{
854861
// Arrange
855862
Type mathType = typeof(Math);
856863

857-
const string input = "Math2.Max(5.37, 5.56)";
858-
const double targetOutput = 5.56;
864+
const string input1 = "Math2.Max(5.37, 5.56)";
865+
const double targetOutput1 = 5.56;
866+
867+
const string input2 = "Math2.Log10(23)";
868+
const double targetOutput2 = 1.36172783601759;
859869

860870
// Act
861-
double output;
871+
double output1;
872+
double output2;
862873

863874
using (var jsEngine = CreateJsEngine())
864875
{
865876
jsEngine.EmbedHostType("Math2", mathType);
866-
output = jsEngine.Evaluate<double>(input);
877+
output1 = jsEngine.Evaluate<double>(input1);
878+
output2 = Math.Round(jsEngine.Evaluate<double>(input2), 14);
867879
}
868880

869881
// Assert
870-
Assert.Equal(targetOutput, output);
882+
Assert.Equal(targetOutput1, output1);
883+
Assert.Equal(targetOutput2, output2);
871884
}
872885

873886
[Fact]

test/JavaScriptEngineSwitcher.Tests/Vroom/InteropTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public override void EmbeddingOfBuiltinValueTypeWithFieldIsCorrect()
5454

5555
#region Types with methods
5656

57-
public override void EmbeddingOfBuiltinReferenceTypeWithMethodIsCorrect()
57+
public override void EmbeddingOfBuiltinReferenceTypeWithMethodsIsCorrect()
5858
{ }
5959

6060
#endregion

0 commit comments

Comments
 (0)