Skip to content

Commit

Permalink
Method with multiple generic params bug fix (#584)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonwoods-7 authored May 8, 2024
1 parent 991a4a2 commit cc5b0dd
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 14 deletions.
19 changes: 19 additions & 0 deletions AssemblyToProcess/InstanceClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ public MethodInfo GetStaticSetProperty()
static void MethodWithParams(string param1, int param2)
{
}

static void MethodWithSimpleGenericParams(string param1, List<int> param2)
{
}

static void MethodWithComplexGenericParams(string param1, Dictionary<int, string> param2)
{
}

// ReSharper restore UnusedParameter.Local

public MethodInfo GetMethodWithParams()
Expand All @@ -74,6 +83,16 @@ public MethodInfo GetMethodWithParamsTyped()
return Info.OfMethod<InstanceClass>(nameof(MethodWithParams), "String, Int32");
}

public MethodInfo GetMethodWithSimpleGenericParamsTyped()
{
return Info.OfMethod<InstanceClass>(nameof(MethodWithSimpleGenericParams), "String, System.Collections.Generic.List`1<System.Int32>");
}

public MethodInfo GetMethodWithComplexGenericParamsTyped()
{
return Info.OfMethod<InstanceClass>(nameof(MethodWithComplexGenericParams), "String, System.Collections.Generic.Dictionary`2<System.Int32, System.String>");
}

void InstanceMethod()
{
}
Expand Down
5 changes: 1 addition & 4 deletions InfoOf.Fody/OfConstructor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ void HandleOfConstructor(Instruction instruction, ILProcessor ilProcessor,
case 1:
case 3:
parametersInstruction = instruction.Previous;
parameters = GetLdString(parametersInstruction)
.Split([","], StringSplitOptions.RemoveEmptyEntries)
.Select(_ => _.Trim())
.ToList();
parameters = GetLdString(parametersInstruction).GetParameters();
typeNameInstruction = parametersInstruction.Previous;
break;
default:
Expand Down
5 changes: 1 addition & 4 deletions InfoOf.Fody/OfIndexerHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ void HandleOfIndexer(Instruction instruction, ILProcessor ilProcessor, MethodRef
Func<PropertyDefinition, MethodDefinition> func, Func<PropertyDefinition, List<string>, List<string>> getParameters)
{
var parametersInstruction = instruction.Previous;
var parameters = GetLdString(parametersInstruction)
.Split([","], StringSplitOptions.RemoveEmptyEntries)
.Select(_ => _.Trim())
.ToList();
var parameters = GetLdString(parametersInstruction).GetParameters();

const string propertyName = "Item";

Expand Down
5 changes: 1 addition & 4 deletions InfoOf.Fody/OfMethodHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ void HandleOfMethod(Instruction instruction, ILProcessor ilProcessor, MethodRefe
if (ofMethodReference.Parameters.Count is 2 or 4)
{
parametersInstruction = instruction.Previous;
parameters = GetLdString(parametersInstruction)
.Split([","], StringSplitOptions.RemoveEmptyEntries)
.Select(_ => _.Trim())
.ToList();
parameters = GetLdString(parametersInstruction).GetParameters();
methodNameInstruction = parametersInstruction.Previous;
}
else
Expand Down
20 changes: 20 additions & 0 deletions InfoOf.Fody/ParamChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,24 @@ public static bool HasSameParams(this MethodDefinition method, List<string> para
}
return true;
}

public static List<string> GetParameters(this string parameters) =>
parameters
.Aggregate(
(0, "", Array.Empty<string>()),
(acc, c) => (acc.Item1, c) switch
{
(0, ',') => (0, "", [.. acc.Item3, acc.Item2]),
(_, '<') => (acc.Item1 + 1, $"{acc.Item2}{c}", acc.Item3),
(_, '>') => (acc.Item1 - 1, $"{acc.Item2}{c}", acc.Item3),
(_, ' ') => acc,
(_, _) => (acc.Item1, $"{acc.Item2}{c}", acc.Item3)
},
acc => acc.Item2 switch
{
"" => acc.Item3,
_ => [.. acc.Item3, acc.Item2]
})
.Select(_ => _.Trim())
.ToList();
}
18 changes: 18 additions & 0 deletions Tests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,24 @@ public void InstanceMethodWithParamsTyped()
Assert.NotNull(methodInfo);
}

[Fact]
public void InstanceMethodWithSimpleGenericParamsTyped()
{
var type = assembly.GetType("InstanceClass");
var instance = (dynamic) Activator.CreateInstance(type);
MethodInfo methodInfo = instance.GetMethodWithSimpleGenericParamsTyped();
Assert.NotNull(methodInfo);
}

[Fact]
public void InstanceMethodWithComplexGenericParamsTyped()
{
var type = assembly.GetType("InstanceClass");
var instance = (dynamic) Activator.CreateInstance(type);
MethodInfo methodInfo = instance.GetMethodWithComplexGenericParamsTyped();
Assert.NotNull(methodInfo);
}

[Fact]
public void StaticMethod()
{
Expand Down
1 change: 0 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ var setIndexerTyped = methodof(MyClass.set_Item);
- Parameters are specified as comma separated list, e.g. `"System.String, System.Int32"`.
- For every parameter, the first namespace part can be omitted, so `"String, Int32"` works, too.
- Nested namespaces are not handled, only `"Regex"` won't work, but `"System.Text.RegularExpressions.Regex"` or `"Text.RegularExpressions.Regex"`.
- Generic types with more than one type param are not supported in method parameters. ```"System.Collections.Generic.List`1<System.Int32>"``` works, but ```"System.Collections.Generic.Dictionary`2<System.Int32, System.String>"``` does not. (see #583)

## Finding Generic Methods

Expand Down
1 change: 0 additions & 1 deletion readme.source.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ snippet: UsageCompiled
- Parameters are specified as comma separated list, e.g. `"System.String, System.Int32"`.
- For every parameter, the first namespace part can be omitted, so `"String, Int32"` works, too.
- Nested namespaces are not handled, only `"Regex"` won't work, but `"System.Text.RegularExpressions.Regex"` or `"Text.RegularExpressions.Regex"`.
- Generic types with more than one type param are not supported in method parameters. ```"System.Collections.Generic.List`1<System.Int32>"``` works, but ```"System.Collections.Generic.Dictionary`2<System.Int32, System.String>"``` does not. (see #583)

## Finding Generic Methods

Expand Down

0 comments on commit cc5b0dd

Please sign in to comment.