Skip to content

Commit a5cb7a7

Browse files
authored
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
1 parent e8bd9f2 commit a5cb7a7

File tree

3 files changed

+37
-23
lines changed

3 files changed

+37
-23
lines changed

src/Spring/Spring.Core/Expressions/MethodNode.cs

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#region License
1+
#region License
22

33
/*
4-
* Copyright © 2002-2011 the original author or authors.
4+
* Copyright © 2002-2011 the original author or authors.
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -170,14 +170,19 @@ protected override object Get(object context, EvaluationContext evalContext)
170170

171171
private int CalculateMethodHash(Type contextType, object[] argValues)
172172
{
173-
int hash = contextType.GetHashCode();
173+
HashCode hash = new HashCode();
174+
hash.Add(contextType.GetHashCode());
175+
174176
for (int i = 0; i < argValues.Length; i++)
175177
{
176178
object arg = argValues[i];
177179
if (arg != null)
178-
hash += s_primes[i] * arg.GetType().GetHashCode();
180+
{
181+
hash.Add(arg.GetType().GetHashCode());
182+
}
179183
}
180-
return hash;
184+
185+
return hash.ToHashCode();
181186
}
182187

183188
private void Initialize(string methodName, object[] argValues, object context)
@@ -272,23 +277,5 @@ private static IList<MethodInfo> GetCandidateMethods(Type type, string methodNam
272277

273278
return matches;
274279
}
275-
276-
// used to calculate signature hash while caring for arg positions
277-
private static readonly int[] s_primes =
278-
{
279-
17, 19, 23, 29
280-
, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71
281-
, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113
282-
, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173
283-
, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229
284-
, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281
285-
, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349
286-
, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409
287-
, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463
288-
, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541
289-
, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601
290-
, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659
291-
, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733
292-
};
293280
}
294281
}

src/Spring/Spring.Core/Spring.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
</ItemGroup>
2222
<ItemGroup>
2323
<PackageReference Include="Common.Logging" Version="$(CommonLoggingVersion)" />
24+
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
2425
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
2526
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
2627
<PackageReference Include="System.CodeDom" Version="4.7.0" />

test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
using System.EnterpriseServices;
2828
using System.Globalization;
2929
using System.IO;
30+
using System.Linq;
3031
using System.Reflection;
3132
using System.Runtime.Serialization;
3233
using System.Runtime.Serialization.Formatters.Binary;
@@ -2218,6 +2219,26 @@ public void TestMethodResolutionResolvesToExactMatchOfArgumentTypes()
22182219

22192220
Assert.AreEqual("ExactMatch", ExpressionEvaluator.GetValue(foo, "MethodWithSimilarArguments(1, #bars)", args));
22202221
}
2222+
2223+
/// <summary>
2224+
/// Test to show that a large number of parameters can be passed to methods
2225+
/// </summary>
2226+
[Test]
2227+
public void TestMethodResolutionWithLargeNumberOfParametersDoesNotThrow()
2228+
{
2229+
int expectedResult = 150;
2230+
int result = 0;
2231+
2232+
Foo foo = new Foo();
2233+
string expression = $"MethodWithParamArray({String.Join(", ", Enumerable.Range(0, expectedResult))})";
2234+
2235+
Assert.DoesNotThrow(() =>
2236+
{
2237+
result = (int)ExpressionEvaluator.GetValue(foo, expression);
2238+
});
2239+
2240+
Assert.AreEqual(expectedResult, result);
2241+
}
22212242

22222243
[Test]
22232244
public void TestIndexerResolutionResolvesToExactMatchOfArgumentTypes()
@@ -3057,6 +3078,11 @@ public string MethodWithParamArray(bool uppercase, params string[] values)
30573078
string ret = string.Join("|", values);
30583079
return (uppercase ? ret.ToUpper() : ret);
30593080
}
3081+
3082+
public int MethodWithParamArray(params int[] values)
3083+
{
3084+
return values.Length;
3085+
}
30603086
}
30613087

30623088
internal enum FooType

0 commit comments

Comments
 (0)