Skip to content

Commit

Permalink
No longer crash when trying to match a generic method that'll violate…
Browse files Browse the repository at this point in the history
… the generic constraints (#274)

* No longer crash when trying to match a generic method with generic parameters that violate the generic constraints

* Clean up using statement.

* Update workflow to use .NET7 instead of .NET5
  • Loading branch information
metoule authored Feb 14, 2023
1 parent 86d57bd commit cd73460
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.x'
- name: Setup .NET Core 5.0
- name: Setup .NET 7.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '7.0.x'
- name: Setup gitversion
run: dotnet tool install --global GitVersion.Tool
- name: Calculate version
Expand All @@ -34,16 +34,16 @@ jobs:
run: dotnet build DynamicExpresso.sln --no-restore -c Release /p:Version=${{steps.calc_version.outputs.PROJECT_VERSION}}
- name: Test .net core 3.1
run: dotnet test DynamicExpresso.sln --no-build --no-restore -c Release --verbosity normal -f netcoreapp3.1
- name: Test .net core 5.0
run: dotnet test DynamicExpresso.sln --no-build --no-restore -c Release --verbosity normal -f netcoreapp5.0
- name: Test .net core 7.0
run: dotnet test DynamicExpresso.sln --no-build --no-restore -c Release --verbosity normal -f net7.0
test-win:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core 5.0
- name: Setup .NET 7.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '7.0.x'
- name: Restore packages
run: dotnet restore DynamicExpresso.sln
- name: Build
Expand Down
21 changes: 18 additions & 3 deletions src/DynamicExpresso.Core/Parsing/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Dynamic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using DynamicExpresso.Exceptions;
using DynamicExpresso.Resources;
Expand Down Expand Up @@ -2361,7 +2361,18 @@ private static MethodInfo MakeGenericMethod(MethodData method)
.Select(p => actualGenericArgs.TryGetValue(p.Name, out var typ) ? typ : typeof(object))
.ToArray();

return methodInfo.MakeGenericMethod(genericArgs);
MethodInfo genericMethod = null;
try
{
genericMethod = methodInfo.MakeGenericMethod(genericArgs);
}
catch (ArgumentException e) when (e.InnerException is VerificationException)
{
// this exception is thrown when a generic argument violates the generic constraints
return null;
}

return genericMethod;
}

private static Dictionary<string, Type> ExtractActualGenericArguments(
Expand Down Expand Up @@ -2398,8 +2409,12 @@ private static Dictionary<string, Type> ExtractActualGenericArguments(
}
else
{
var innerGenericTypes = ExtractActualGenericArguments(requestedType.GetGenericArguments(), actualType.GetGenericArguments());
var requestedInnerGenericArgs = requestedType.GetGenericArguments();
var actualInnerGenericArgs = actualType.GetGenericArguments();
if (requestedInnerGenericArgs.Length != actualInnerGenericArgs.Length)
continue;

var innerGenericTypes = ExtractActualGenericArguments(requestedInnerGenericArgs, actualInnerGenericArgs);
foreach (var innerGenericType in innerGenericTypes)
extractedGenericTypes[innerGenericType.Key] = innerGenericType.Value;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net5.0;netcoreapp3.1;net462</TargetFrameworks>
<TargetFrameworks>net7.0;net5.0;netcoreapp3.1;net462</TargetFrameworks>

<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
15 changes: 15 additions & 0 deletions test/DynamicExpresso.UnitTest/MemberInvocationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,18 @@ public void Method_with_generic_param()
Assert.AreEqual(x.MethodWithGenericParamAndDefault1Levels(y), target.Eval("x.MethodWithGenericParamAndDefault1Levels(y)", parameters));
Assert.AreEqual(x.MethodWithGenericParamAndDefault2Levels(y), target.Eval("x.MethodWithGenericParamAndDefault2Levels(y)", parameters));
Assert.AreEqual(x.MethodWithGenericParamAndDefault2Levels(y, w), target.Eval("x.MethodWithGenericParamAndDefault2Levels(y, w)", parameters));
}

[Test]
public void Method_with_generic_constraints()
{
var target = new Interpreter();

var x = new MyTestService();
target.SetVariable("x", x);

Assert.AreEqual("works", target.Eval("x.GenericMethodWithConstraint(\"works\")"));
Assert.Throws<NoApplicableMethodException>(() => target.Eval("x.GenericMethodWithConstraint(5)"), "This shouldn't throw a System.ArgumentException \"Violates the constraint of type 'T'\"");
}

[Test]
Expand Down Expand Up @@ -646,6 +656,11 @@ public long OverloadMethodWithParamsArray(params long[] paramsArray)
{
return paramsArray.Max();
}

public T GenericMethodWithConstraint<T>(T input) where T : class
{
return input;
}
}

private class MyTestServiceCaseInsensitive
Expand Down

0 comments on commit cd73460

Please sign in to comment.