Skip to content

Commit

Permalink
Merge pull request #1058 from riganti/fix/extension-method-issues
Browse files Browse the repository at this point in the history
Fixed issues with extension methods
  • Loading branch information
acizmarik committed Jun 28, 2021
2 parents cfb8412 + 52e53d6 commit fd742af
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
49 changes: 49 additions & 0 deletions src/DotVVM.Framework.Tests/Binding/CustomExtensionMethodTests.cs
Expand Up @@ -88,12 +88,61 @@ public void Call_NotImportedExtensionMethodThrows()
// Not imported extension
CreateCall(notImportedTarget, Array.Empty<Expression>(), new[] { new NamespaceImport("DotVVM.Framework.Tests.Binding") });
}

[TestMethod]
public void Call_ExtensionMethodsWithOptionalArguments_UseDefaultValue()
{
var importedTarget = new MethodGroupExpression() {
MethodName = nameof(TestExtensions.ExtensionMethodWithOptionalArgument),
Target = Expression.Constant(11)
};

// Imported extension
var expression = CreateCall(importedTarget, Array.Empty<Expression>(), new[] { new NamespaceImport("DotVVM.Framework.Tests.Binding"), new NamespaceImport("DotVVM.Framework.Tests.Binding") });
var result = Expression.Lambda<Func<int>>(expression).Compile().Invoke();
Assert.AreEqual(321, result);
}

[TestMethod]
public void Call_ExtensionMethodsWithOptionalArguments_OverrideDefaultValue()
{
var importedTarget = new MethodGroupExpression() {
MethodName = nameof(TestExtensions.ExtensionMethodWithOptionalArgument),
Target = Expression.Constant(11)
};

// Imported extension
var expression = CreateCall(importedTarget, new[] { Expression.Constant(123) }, new[] { new NamespaceImport("DotVVM.Framework.Tests.Binding") });
var result = Expression.Lambda<Func<int>>(expression).Compile().Invoke();
Assert.AreEqual(123, result);
}

[TestMethod]
public void Call_ExtensionMethods_DuplicitImport_DoesNotThrow()
{
var importedTarget = new MethodGroupExpression() {
MethodName = nameof(TestExtensions.Increment),
Target = Expression.Constant(11)
};

// Imported extension
var expression = CreateCall(importedTarget, Array.Empty<Expression>(),
new[] {
new NamespaceImport("DotVVM.Framework.Tests.Binding"),
new NamespaceImport("DotVVM.Framework.Tests.Binding")
});
var result = Expression.Lambda<Func<int>>(expression).Compile().Invoke();
Assert.AreEqual(12, result);
}
}

public static class TestExtensions
{
public static int Increment(this int number)
=> ++number;

public static int ExtensionMethodWithOptionalArgument(this int number, int arg = 321)
=> arg;
}

namespace AmbiguousExtensions
Expand Down
Expand Up @@ -192,8 +192,7 @@ public Expression CallMethod(Expression target, BindingFlags flags, string name,
if (method.IsExtension)
{
// Change to a static call
var newArguments = new[] { target }.Concat(arguments);
return Expression.Call(method.Method, newArguments);
return Expression.Call(method.Method, method.Arguments);
}
return Expression.Call(target, method.Method, method.Arguments);
}
Expand Down Expand Up @@ -248,8 +247,8 @@ private MethodRecognitionResult FindValidMethodOveloads(Expression target, Type

private IEnumerable<MethodInfo> GetAllExtensionMethods()
{
foreach (var ns in importedNamespaces)
foreach (var method in extensionMethodsCache.GetExtensionsForNamespace(ns.Namespace))
foreach (var ns in importedNamespaces.Select(ns => ns.Namespace).Distinct())
foreach (var method in extensionMethodsCache.GetExtensionsForNamespace(ns))
yield return method;
}

Expand Down

0 comments on commit fd742af

Please sign in to comment.