|
1 | 1 | using System.Diagnostics.CodeAnalysis; |
2 | 2 | using System.Globalization; |
3 | 3 | using System.Reflection; |
| 4 | +using System.Runtime.CompilerServices; |
4 | 5 | using Jint.Extensions; |
5 | 6 | using Jint.Native; |
6 | 7 |
|
@@ -120,14 +121,59 @@ private static int CalculateMethodParameterScore(Engine engine, ParameterInfo pa |
120 | 121 | return 5; |
121 | 122 | } |
122 | 123 |
|
123 | | - if (paramType == typeof(int) && parameterValue.IsInteger()) |
| 124 | + const int ScoreForDifferentTypeButFittingNumberRange = 2; |
| 125 | + if (parameterValue.IsNumber()) |
124 | 126 | { |
125 | | - return 0; |
126 | | - } |
| 127 | + var num = (JsNumber) parameterValue; |
| 128 | + var numValue = num._value; |
127 | 129 |
|
128 | | - if (paramType == typeof(float) && objectValueType == typeof(double)) |
129 | | - { |
130 | | - return parameterValue.IsInteger() ? 1 : 2; |
| 130 | + if (paramType == typeof(double)) |
| 131 | + { |
| 132 | + return 0; |
| 133 | + } |
| 134 | + |
| 135 | + if (paramType == typeof(float) && numValue is <= float.MaxValue and >= float.MinValue) |
| 136 | + { |
| 137 | + return ScoreForDifferentTypeButFittingNumberRange; |
| 138 | + } |
| 139 | + |
| 140 | + var isInteger = num.IsInteger() || TypeConverter.IsIntegralNumber(num._value); |
| 141 | + |
| 142 | + // if value is integral number and within allowed range for the parameter type, we consider this perfect match |
| 143 | + if (isInteger) |
| 144 | + { |
| 145 | + if (paramType == typeof(int)) |
| 146 | + { |
| 147 | + return 0; |
| 148 | + } |
| 149 | + |
| 150 | + if (paramType == typeof(long)) |
| 151 | + { |
| 152 | + return ScoreForDifferentTypeButFittingNumberRange; |
| 153 | + } |
| 154 | + |
| 155 | + // check if we can narrow without exception throwing versions (CanChangeType) |
| 156 | + var integerValue = (int) num._value; |
| 157 | + if (paramType == typeof(short) && integerValue is <= short.MaxValue and >= short.MinValue) |
| 158 | + { |
| 159 | + return ScoreForDifferentTypeButFittingNumberRange; |
| 160 | + } |
| 161 | + |
| 162 | + if (paramType == typeof(ushort) && integerValue is <= ushort.MaxValue and >= ushort.MinValue) |
| 163 | + { |
| 164 | + return ScoreForDifferentTypeButFittingNumberRange; |
| 165 | + } |
| 166 | + |
| 167 | + if (paramType == typeof(byte) && integerValue is <= byte.MaxValue and >= byte.MinValue) |
| 168 | + { |
| 169 | + return ScoreForDifferentTypeButFittingNumberRange; |
| 170 | + } |
| 171 | + |
| 172 | + if (paramType == typeof(sbyte) && integerValue is <= sbyte.MaxValue and >= sbyte.MinValue) |
| 173 | + { |
| 174 | + return ScoreForDifferentTypeButFittingNumberRange; |
| 175 | + } |
| 176 | + } |
131 | 177 | } |
132 | 178 |
|
133 | 179 | if (paramType.IsEnum && |
|
0 commit comments