Skip to content

Commit 68917f1

Browse files
committed
Refactor: GetX.IsKnownSignature, allow Binder & ParameterModifier[] as long as they are null.
1 parent 517ee95 commit 68917f1

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

ReflectionAnalyzers/Helpers/GetX.cs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ namespace ReflectionAnalyzers
33
using System.Linq;
44
using Gu.Roslyn.AnalyzerExtensions;
55
using Microsoft.CodeAnalysis;
6+
using Microsoft.CodeAnalysis.CSharp;
67
using Microsoft.CodeAnalysis.CSharp.Syntax;
78
using Microsoft.CodeAnalysis.Diagnostics;
89

@@ -41,7 +42,7 @@ internal static class GetX
4142
if (invocation.ArgumentList != null &&
4243
invocation.TryGetTarget(KnownSymbol.Type.GetMethod, context.SemanticModel, context.CancellationToken, out var getX) &&
4344
TryGetTargetType(invocation, context, out targetType, out _) &&
44-
IsKnownSignature(getX) &&
45+
IsKnownSignature(getX, invocation) &&
4546
TryGetName(invocation, getX, context, out nameArg, out targetName) &&
4647
(TryGetFlags(invocation, getX, context, out flagsArg, out flags) ||
4748
TryGetDefaultFlags(KnownSymbol.Type.GetMethod, out flags)))
@@ -50,16 +51,6 @@ internal static class GetX
5051
}
5152

5253
return null;
53-
54-
bool IsKnownSignature(IMethodSymbol candidate)
55-
{
56-
// I don't know how binder works so limiting checks to what I know.
57-
return (candidate.Parameters.TrySingle(out var nameParameter) &&
58-
nameParameter.Type == KnownSymbol.String) ||
59-
(candidate.Parameters.Length == 2 &&
60-
candidate.Parameters.TrySingle(x => x.Type == KnownSymbol.String, out nameParameter) &&
61-
candidate.Parameters.TrySingle(x => x.Type == KnownSymbol.BindingFlags, out _));
62-
}
6354
}
6455

6556
/// <summary>
@@ -76,7 +67,7 @@ bool IsKnownSignature(IMethodSymbol candidate)
7667
if (invocation.ArgumentList != null &&
7768
invocation.TryGetTarget(KnownSymbol.Type.GetMember, context.SemanticModel, context.CancellationToken, out var getX) &&
7869
TryGetTargetType(invocation, context, out targetType, out _) &&
79-
IsKnownSignature(getX) &&
70+
IsKnownSignature(getX, invocation) &&
8071
TryGetName(invocation, getX, context, out nameArg, out targetName) &&
8172
(TryGetFlags(invocation, getX, context, out flagsArg, out flags) ||
8273
TryGetDefaultFlags(KnownSymbol.Type.GetMember, out flags)))
@@ -85,16 +76,6 @@ bool IsKnownSignature(IMethodSymbol candidate)
8576
}
8677

8778
return null;
88-
89-
bool IsKnownSignature(IMethodSymbol candidate)
90-
{
91-
// I don't know how binder works so limiting checks to what I know.
92-
return (candidate.Parameters.TrySingle(out var nameParameter) &&
93-
nameParameter.Type == KnownSymbol.String) ||
94-
(candidate.Parameters.Length == 2 &&
95-
candidate.Parameters.TrySingle(x => x.Type == KnownSymbol.String, out nameParameter) &&
96-
candidate.Parameters.TrySingle(x => x.Type == KnownSymbol.BindingFlags, out _));
97-
}
9879
}
9980

10081
/// <summary>
@@ -328,7 +309,7 @@ bool IsOverriding(ISymbol symbol, ISymbol candidateBase)
328309
return false;
329310
}
330311

331-
bool IsExplicitImplementation( out ISymbol result)
312+
bool IsExplicitImplementation(out ISymbol result)
332313
{
333314
foreach (var @interface in targetType.AllInterfaces)
334315
{
@@ -378,6 +359,33 @@ internal static bool TryGetDefaultFlags(QualifiedMethod getX, out BindingFlags d
378359
return false;
379360
}
380361

362+
/// <summary>
363+
/// Defensive check to only handle known cases. Don't know how the binder works.
364+
/// </summary>
365+
private static bool IsKnownSignature(IMethodSymbol candidate, InvocationExpressionSyntax invocation)
366+
{
367+
foreach (var parameter in candidate.Parameters)
368+
{
369+
if (!IsKnownArgument(parameter))
370+
{
371+
return false;
372+
}
373+
}
374+
375+
return true;
376+
bool IsKnownArgument(IParameterSymbol parameter)
377+
{
378+
if (parameter.Type == KnownSymbol.String ||
379+
parameter.Type == KnownSymbol.BindingFlags)
380+
{
381+
return true;
382+
}
383+
384+
return invocation.TryFindArgument(parameter, out var argument) &&
385+
argument.Expression?.IsKind(SyntaxKind.NullLiteralExpression) == true;
386+
}
387+
}
388+
381389
/// <summary>
382390
/// Handles GetField, GetEvent, GetMember, GetMethod...
383391
/// </summary>

ReflectionAnalyzers/Helpers/KnownSymbols/KnownSymbol.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ internal static class KnownSymbol
1212
internal static readonly AttributeType Attribute = new AttributeType();
1313
internal static readonly AssemblyType Assembly = new AssemblyType();
1414
internal static readonly QualifiedType BindingFlags = Create("System.Reflection.BindingFlags");
15+
internal static readonly QualifiedType Binder = Create("System.Reflection.Binder");
16+
internal static readonly QualifiedType ParameterModifier = Create("System.Reflection.ParameterModifier");
17+
internal static readonly QualifiedType CallingConventions = Create("System.Reflection.CallingConventions");
1518
internal static readonly ConstructorInfoType ConstructorInfo = new ConstructorInfoType();
1619
internal static readonly EventInfoType EventInfo = new EventInfoType();
1720
internal static readonly FieldInfoType FieldInfo = new FieldInfoType();

0 commit comments

Comments
 (0)