Skip to content

Commit 6ef28c0

Browse files
committed
Use GetNestedType.Match
1 parent 8621ce0 commit 6ef28c0

5 files changed

Lines changed: 70 additions & 45 deletions

File tree

ReflectionAnalyzers/Helpers/Reflection/Filters/Types.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ static bool ByNull(ISymbol? first, ISymbol? other, [NotNullWhen(true)] out ISymb
130130
return false;
131131
}
132132

133-
static ImmutableArray<IParameterSymbol> Parameters(ISymbol symbol)
133+
static ImmutableArray<IParameterSymbol> Parameters(ISymbol? symbol)
134134
{
135135
return symbol switch
136136
{
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
namespace ReflectionAnalyzers;
2+
3+
using System.Threading;
4+
using Gu.Roslyn.AnalyzerExtensions;
5+
using Microsoft.CodeAnalysis;
6+
using Microsoft.CodeAnalysis.CSharp.Syntax;
7+
8+
internal readonly struct GetNestedType
9+
{
10+
internal readonly InvocationExpressionSyntax Invocation;
11+
internal readonly IMethodSymbol Target;
12+
internal readonly ReflectedMember Member;
13+
internal readonly Name Name;
14+
internal readonly Flags Flags;
15+
16+
private GetNestedType(InvocationExpressionSyntax invocation, IMethodSymbol target, ReflectedMember member, Name name, Flags flags)
17+
{
18+
this.Invocation = invocation;
19+
this.Target = target;
20+
this.Member = member;
21+
this.Name = name;
22+
this.Flags = flags;
23+
}
24+
25+
internal INamedTypeSymbol? Single => this.Member.Match == FilterMatch.Single ? (INamedTypeSymbol)this.Member.Symbol! : null;
26+
27+
/// <summary>
28+
/// Check if <paramref name="candidate"/> is a call to Type.GetField.
29+
/// </summary>
30+
internal static GetNestedType? Match(ExpressionSyntax candidate, SemanticModel semanticModel, CancellationToken cancellationToken)
31+
{
32+
if (GetX.FindInvocation(candidate, semanticModel, cancellationToken) is { } invocation)
33+
{
34+
return Match(invocation, semanticModel, cancellationToken);
35+
}
36+
37+
return null;
38+
}
39+
40+
/// <summary>
41+
/// Check if <paramref name="candidate"/> is a call to Type.GetField.
42+
/// </summary>
43+
internal static GetNestedType? Match(InvocationExpressionSyntax candidate, SemanticModel semanticModel, CancellationToken cancellationToken)
44+
{
45+
if (candidate.TryGetTarget(KnownSymbol.Type.GetNestedType, semanticModel, cancellationToken, out var target))
46+
{
47+
if (ReflectedMember.TryGetType(candidate, semanticModel, cancellationToken, out var type, out var typeSource) &&
48+
Name.TryCreate(candidate, target, semanticModel, cancellationToken, out var name) &&
49+
Flags.TryCreate(candidate, target, semanticModel, cancellationToken, out var flags) &&
50+
ReflectedMember.TryCreate(target, candidate, type, typeSource, name, flags.Effective, Types.Any, semanticModel.Compilation, out var member))
51+
{
52+
return new GetNestedType(candidate, target, member, name, flags);
53+
}
54+
}
55+
56+
return null;
57+
}
58+
}

ReflectionAnalyzers/Helpers/Reflection/GetX.cs

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@
1313
/// </summary>
1414
internal static class GetX
1515
{
16-
/// <summary>
17-
/// Check if <paramref name="invocation"/> is a call to Type.GetNestedType.
18-
/// </summary>
19-
internal static bool TryMatchGetNestedType(InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken, out ReflectedMember member, out Name name, out Flags flags)
20-
{
21-
return TryMatchGetX(invocation, KnownSymbol.Type.GetNestedType, semanticModel, cancellationToken, out member, out name, out flags);
22-
}
23-
2416
internal static InvocationExpressionSyntax? FindInvocation(ExpressionSyntax candidate, SemanticModel semanticModel, CancellationToken cancellationToken)
2517
{
2618
return candidate switch
@@ -40,36 +32,5 @@ when semanticModel.TryGetSymbol(identifierName, cancellationToken, out ILocalSym
4032
_ => null,
4133
};
4234
}
43-
44-
/// <summary>
45-
/// Handles GetField, GetEvent, GetMember, GetMethod...
46-
/// </summary>
47-
private static bool TryMatchGetX(InvocationExpressionSyntax invocation, QualifiedMethod getXMethod, SemanticModel semanticModel, CancellationToken cancellationToken, out ReflectedMember member, out Name name, out Flags flags)
48-
{
49-
if (invocation.TryGetTarget(getXMethod, semanticModel, cancellationToken, out var getX))
50-
{
51-
if (ReflectedMember.TryGetType(invocation, semanticModel, cancellationToken, out var type, out var typeSource) &&
52-
Name.TryCreate(invocation, getX, semanticModel, cancellationToken, out name) &&
53-
Flags.TryCreate(invocation, getX, semanticModel, cancellationToken, out flags) &&
54-
ReflectedMember.TryCreate(getX, invocation, type, typeSource, name, flags.Effective, Types.Any, semanticModel.Compilation, out member))
55-
{
56-
return true;
57-
}
58-
59-
if (getXMethod.Name != "GetNestedType" &&
60-
Flags.TryCreate(invocation, getX, semanticModel, cancellationToken, out flags) &&
61-
flags.AreInSufficient)
62-
{
63-
_ = Name.TryCreate(invocation, getX, semanticModel, cancellationToken, out name);
64-
member = new ReflectedMember(type, typeSource, null, getX, invocation, FilterMatch.InSufficientFlags);
65-
return true;
66-
}
67-
}
68-
69-
member = default;
70-
name = default;
71-
flags = default;
72-
return false;
73-
}
7435
}
7536
}

ReflectionAnalyzers/Helpers/Reflection/Type.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,10 @@ when invocation.TryGetTarget(KnownSymbol.Type.GetGenericTypeDefinition, recursio
227227
return true;
228228

229229
case InvocationExpressionSyntax invocation
230-
when GetX.TryMatchGetNestedType(invocation, recursion.SemanticModel, recursion.CancellationToken, out var reflectedMember, out _, out _):
230+
when GetNestedType.Match(invocation, recursion.SemanticModel, recursion.CancellationToken) is { Single: { } type }:
231231
source = invocation;
232-
result = reflectedMember.Symbol as ITypeSymbol;
233-
return result != null && reflectedMember.Match == FilterMatch.Single;
232+
result = type;
233+
return true;
234234
case InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax memberAccess } invocation
235235
when invocation.TryGetTarget(KnownSymbol.Type.MakeGenericType, recursion.SemanticModel, recursion.CancellationToken, out _) &&
236236
TypeArguments.Find(invocation, recursion.SemanticModel, recursion.CancellationToken) is { } typeArguments &&

ReflectionAnalyzers/NodeAnalzers/GetXAnalyzer.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,14 @@ private static bool TryGetX(SyntaxNodeAnalysisContext context, out ReflectedMemb
301301
return true;
302302
}
303303

304-
types = default;
305-
return GetX.TryMatchGetNestedType(candidate, context.SemanticModel, context.CancellationToken, out member, out name, out flags);
304+
if (GetNestedType.Match(candidate, context.SemanticModel, context.CancellationToken) is { } getNestedType)
305+
{
306+
member = getNestedType.Member;
307+
name = getNestedType.Name;
308+
flags = getNestedType.Flags;
309+
types = default;
310+
return true;
311+
}
306312
}
307313

308314
member = default;

0 commit comments

Comments
 (0)