1- #nullable enable
2-
3- using System . Collections . Immutable ;
4- using System . Linq ;
5- using Microsoft . CodeAnalysis ;
6- using Microsoft . CodeAnalysis . CSharp ;
7- using Microsoft . CodeAnalysis . CSharp . Syntax ;
8- using Microsoft . CodeAnalysis . Diagnostics ;
9-
101namespace GraphQL . EntityFramework . Analyzers ;
112
123[ DiagnosticAnalyzer ( LanguageNames . CSharp ) ]
134public class FieldBuilderResolveAnalyzer : DiagnosticAnalyzer
145{
156 public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics { get ; } =
16- ImmutableArray . Create ( DiagnosticDescriptors . GQLEF002 ) ;
7+ [ DiagnosticDescriptors . GQLEF002 ] ;
178
189 public override void Initialize ( AnalysisContext context )
1910 {
@@ -22,7 +13,7 @@ public override void Initialize(AnalysisContext context)
2213 context . RegisterSyntaxNodeAction ( AnalyzeInvocation , SyntaxKind . InvocationExpression ) ;
2314 }
2415
25- void AnalyzeInvocation ( SyntaxNodeAnalysisContext context )
16+ static void AnalyzeInvocation ( SyntaxNodeAnalysisContext context )
2617 {
2718 var invocation = ( InvocationExpressionSyntax ) context . Node ;
2819
@@ -54,16 +45,15 @@ void AnalyzeInvocation(SyntaxNodeAnalysisContext context)
5445 }
5546 }
5647
57- bool IsFieldBuilderResolveCall (
48+ static bool IsFieldBuilderResolveCall (
5849 InvocationExpressionSyntax invocation ,
5950 SemanticModel semanticModel ,
6051 out LambdaExpressionSyntax ? lambdaExpression )
6152 {
6253 lambdaExpression = null ;
6354
6455 // Check method name is Resolve, ResolveAsync, ResolveList, or ResolveListAsync
65- var memberAccess = invocation . Expression as MemberAccessExpressionSyntax ;
66- if ( memberAccess == null )
56+ if ( invocation . Expression is not MemberAccessExpressionSyntax memberAccess )
6757 {
6858 return false ;
6959 }
@@ -114,7 +104,7 @@ bool IsFieldBuilderResolveCall(
114104 return false ;
115105 }
116106
117- bool IsProjectionBasedResolve ( InvocationExpressionSyntax invocation , SemanticModel semanticModel )
107+ static bool IsProjectionBasedResolve ( InvocationExpressionSyntax invocation , SemanticModel semanticModel )
118108 {
119109 var symbolInfo = semanticModel . GetSymbolInfo ( invocation ) ;
120110 if ( symbolInfo . Symbol is not IMethodSymbol methodSymbol )
@@ -128,7 +118,7 @@ bool IsProjectionBasedResolve(InvocationExpressionSyntax invocation, SemanticMod
128118 methodSymbol . ContainingNamespace ? . ToString ( ) == "GraphQL.EntityFramework" ;
129119 }
130120
131- bool IsInEfGraphType ( SyntaxNode node , SemanticModel semanticModel )
121+ static bool IsInEfGraphType ( SyntaxNode node , SemanticModel semanticModel )
132122 {
133123 var classDeclaration = node . FirstAncestorOrSelf < ClassDeclarationSyntax > ( ) ;
134124 if ( classDeclaration == null )
@@ -147,9 +137,7 @@ bool IsInEfGraphType(SyntaxNode node, SemanticModel semanticModel)
147137 while ( baseType != null )
148138 {
149139 var typeName = baseType . Name ;
150- if ( ( typeName == "EfObjectGraphType" ||
151- typeName == "EfInterfaceGraphType" ||
152- typeName == "QueryGraphType" ) &&
140+ if ( typeName is "EfObjectGraphType" or "EfInterfaceGraphType" or "QueryGraphType" &&
153141 baseType . ContainingNamespace ? . ToString ( ) == "GraphQL.EntityFramework" )
154142 {
155143 return true ;
@@ -161,7 +149,7 @@ bool IsInEfGraphType(SyntaxNode node, SemanticModel semanticModel)
161149 return false ;
162150 }
163151
164- bool AccessesNavigationProperties ( LambdaExpressionSyntax lambda , SemanticModel semanticModel )
152+ static bool AccessesNavigationProperties ( LambdaExpressionSyntax lambda , SemanticModel semanticModel )
165153 {
166154 var body = lambda . Body ;
167155
@@ -196,7 +184,7 @@ bool AccessesNavigationProperties(LambdaExpressionSyntax lambda, SemanticModel s
196184 return false ;
197185 }
198186
199- bool IsContextSourceAccess ( MemberAccessExpressionSyntax memberAccess , out MemberAccessExpressionSyntax ? propertyAccess )
187+ static bool IsContextSourceAccess ( MemberAccessExpressionSyntax memberAccess , out MemberAccessExpressionSyntax ? propertyAccess )
200188 {
201189 propertyAccess = null ;
202190
@@ -207,8 +195,15 @@ bool IsContextSourceAccess(MemberAccessExpressionSyntax memberAccess, out Member
207195 // Walk up the chain to find context.Source
208196 while ( true )
209197 {
210- if ( current . Expression is MemberAccessExpressionSyntax { Name . Identifier . Text : "Source" , Expression : IdentifierNameSyntax identifier } &&
211- ( identifier . Identifier . Text == "context" || identifier . Identifier . Text == "ctx" ) )
198+ if ( current . Expression is
199+ MemberAccessExpressionSyntax
200+ {
201+ Name . Identifier . Text : "Source" ,
202+ Expression : IdentifierNameSyntax
203+ {
204+ Identifier . Text : "context" or "ctx"
205+ }
206+ } )
212207 {
213208 sourceAccess = current ;
214209 break ;
@@ -240,21 +235,24 @@ bool IsContextSourceAccess(MemberAccessExpressionSyntax memberAccess, out Member
240235
241236 // Also check for direct access like: context.Source (without further property access)
242237 if ( memberAccess . Name . Identifier . Text == "Source" &&
243- memberAccess . Expression is IdentifierNameSyntax ctxId &&
244- ( ctxId . Identifier . Text == "context" || ctxId . Identifier . Text == "ctx" ) )
245- {
246- // This is just context.Source itself, check parent node
247- if ( memberAccess . Parent is MemberAccessExpressionSyntax parentMember )
238+ memberAccess is
248239 {
249- propertyAccess = parentMember ;
250- return true ;
251- }
240+ Expression : IdentifierNameSyntax
241+ {
242+ Identifier . Text : "context" or "ctx"
243+ } ,
244+ Parent : MemberAccessExpressionSyntax parentMember
245+ } )
246+ // This is just context.Source itself, check parent node
247+ {
248+ propertyAccess = parentMember ;
249+ return true ;
252250 }
253251
254252 return false ;
255253 }
256254
257- bool IsSafeProperty ( IPropertySymbol propertySymbol )
255+ static bool IsSafeProperty ( IPropertySymbol propertySymbol )
258256 {
259257 // Only primary keys and foreign keys are safe to access
260258 // because they are always included in EF projections
@@ -344,5 +342,4 @@ static bool IsForeignKeyProperty(IPropertySymbol propertySymbol)
344342 var typeName = underlyingType . ToString ( ) ;
345343 return typeName == "System.Guid" ;
346344 }
347-
348345}
0 commit comments