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:
Greg Jarzab
2021-04-13 00:08:36 -05:00
committed by GitHub
parent e8bd9f2290
commit a5cb7a7973
3 changed files with 37 additions and 23 deletions

View File

@@ -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
};
}
}

View File

@@ -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" />

View File

@@ -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