Support for expressions involving method calls with more than 124 parameters (#203)
* Add test to demonstrate failure when more than 124 arguments are passed to a MethodNode. * Calculate method hash using HashCode instead of a using a fixed number of primes. * Add BOM and fix Copyright Sign
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <EFBFBD> 2002-2011 the original author or authors.
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -170,14 +170,19 @@ namespace Spring.Expressions
|
||||
|
||||
private int CalculateMethodHash(Type contextType, object[] argValues)
|
||||
{
|
||||
int hash = contextType.GetHashCode();
|
||||
HashCode hash = new HashCode();
|
||||
hash.Add(contextType.GetHashCode());
|
||||
|
||||
for (int i = 0; i < argValues.Length; i++)
|
||||
{
|
||||
object arg = argValues[i];
|
||||
if (arg != null)
|
||||
hash += s_primes[i] * arg.GetType().GetHashCode();
|
||||
{
|
||||
hash.Add(arg.GetType().GetHashCode());
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
|
||||
return hash.ToHashCode();
|
||||
}
|
||||
|
||||
private void Initialize(string methodName, object[] argValues, object context)
|
||||
@@ -272,23 +277,5 @@ namespace Spring.Expressions
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
// used to calculate signature hash while caring for arg positions
|
||||
private static readonly int[] s_primes =
|
||||
{
|
||||
17, 19, 23, 29
|
||||
, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71
|
||||
, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113
|
||||
, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173
|
||||
, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229
|
||||
, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281
|
||||
, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349
|
||||
, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409
|
||||
, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463
|
||||
, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541
|
||||
, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601
|
||||
, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659
|
||||
, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Common.Logging" Version="$(CommonLoggingVersion)" />
|
||||
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
|
||||
<PackageReference Include="System.CodeDom" Version="4.7.0" />
|
||||
|
||||
@@ -27,6 +27,7 @@ using System.Diagnostics;
|
||||
using System.EnterpriseServices;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
@@ -2218,6 +2219,26 @@ namespace Spring.Expressions
|
||||
|
||||
Assert.AreEqual("ExactMatch", ExpressionEvaluator.GetValue(foo, "MethodWithSimilarArguments(1, #bars)", args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to show that a large number of parameters can be passed to methods
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestMethodResolutionWithLargeNumberOfParametersDoesNotThrow()
|
||||
{
|
||||
int expectedResult = 150;
|
||||
int result = 0;
|
||||
|
||||
Foo foo = new Foo();
|
||||
string expression = $"MethodWithParamArray({String.Join(", ", Enumerable.Range(0, expectedResult))})";
|
||||
|
||||
Assert.DoesNotThrow(() =>
|
||||
{
|
||||
result = (int)ExpressionEvaluator.GetValue(foo, expression);
|
||||
});
|
||||
|
||||
Assert.AreEqual(expectedResult, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIndexerResolutionResolvesToExactMatchOfArgumentTypes()
|
||||
@@ -3057,6 +3078,11 @@ namespace Spring.Expressions
|
||||
string ret = string.Join("|", values);
|
||||
return (uppercase ? ret.ToUpper() : ret);
|
||||
}
|
||||
|
||||
public int MethodWithParamArray(params int[] values)
|
||||
{
|
||||
return values.Length;
|
||||
}
|
||||
}
|
||||
|
||||
internal enum FooType
|
||||
|
||||
Reference in New Issue
Block a user