@@ -68,26 +68,39 @@ public override void Initialize(AnalysisContext context)
6868 context . EnableConcurrentExecution ( ) ;
6969 context . ConfigureGeneratedCodeAnalysis ( GeneratedCodeAnalysisFlags . Analyze ) ;
7070
71- context . RegisterCodeBlockStartAction < SyntaxKind > ( ctxt =>
71+ context . RegisterCompilationStartAction ( compilationStartContext =>
7272 {
73- ctxt . RegisterSyntaxNodeAction ( Utils . DebuggableWrapper ( MethodAnalyzer . AnalyzeInvocation ) , SyntaxKind . InvocationExpression ) ;
74- ctxt . RegisterSyntaxNodeAction ( Utils . DebuggableWrapper ( MethodAnalyzer . AnalyzePropertyGetter ) , SyntaxKind . SimpleMemberAccessExpression ) ;
75- ctxt . RegisterSyntaxNodeAction ( Utils . DebuggableWrapper ( MethodAnalyzer . AnalyzeConditionalAccessExpression ) , SyntaxKind . ConditionalAccessExpression ) ;
73+ var excludedMethods = CommonInterest . ReadMethods ( compilationStartContext . Options , CommonInterest . FileNamePatternForSyncMethodsToExcludeFromVSTHRD103 , compilationStartContext . CancellationToken ) . ToImmutableArray ( ) ;
74+
75+ compilationStartContext . RegisterCodeBlockStartAction < SyntaxKind > ( ctxt =>
76+ {
77+ var methodAnalyzer = new MethodAnalyzer ( excludedMethods ) ;
78+ ctxt . RegisterSyntaxNodeAction ( Utils . DebuggableWrapper ( methodAnalyzer . AnalyzeInvocation ) , SyntaxKind . InvocationExpression ) ;
79+ ctxt . RegisterSyntaxNodeAction ( Utils . DebuggableWrapper ( methodAnalyzer . AnalyzePropertyGetter ) , SyntaxKind . SimpleMemberAccessExpression ) ;
80+ ctxt . RegisterSyntaxNodeAction ( Utils . DebuggableWrapper ( methodAnalyzer . AnalyzeConditionalAccessExpression ) , SyntaxKind . ConditionalAccessExpression ) ;
81+ } ) ;
7682 } ) ;
7783 }
7884
7985 private class MethodAnalyzer
8086 {
81- internal static void AnalyzePropertyGetter ( SyntaxNodeAnalysisContext context )
87+ private readonly ImmutableArray < CommonInterest . QualifiedMember > excludedMethods ;
88+
89+ public MethodAnalyzer ( ImmutableArray < CommonInterest . QualifiedMember > excludedMethods )
90+ {
91+ this . excludedMethods = excludedMethods ;
92+ }
93+
94+ internal void AnalyzePropertyGetter ( SyntaxNodeAnalysisContext context )
8295 {
8396 var memberAccessSyntax = ( MemberAccessExpressionSyntax ) context . Node ;
8497 if ( IsInTaskReturningMethodOrDelegate ( context ) )
8598 {
86- InspectMemberAccess ( context , memberAccessSyntax . Name , CommonInterest . SyncBlockingProperties ) ;
99+ this . InspectMemberAccess ( context , memberAccessSyntax . Name , CommonInterest . SyncBlockingProperties ) ;
87100 }
88101 }
89102
90- internal static void AnalyzeConditionalAccessExpression ( SyntaxNodeAnalysisContext context )
103+ internal void AnalyzeConditionalAccessExpression ( SyntaxNodeAnalysisContext context )
91104 {
92105 var conditionalAccessSyntax = ( ConditionalAccessExpressionSyntax ) context . Node ;
93106 if ( IsInTaskReturningMethodOrDelegate ( context ) )
@@ -97,17 +110,17 @@ internal static void AnalyzeConditionalAccessExpression(SyntaxNodeAnalysisContex
97110 MemberBindingExpressionSyntax bindingExpr => bindingExpr . Name ,
98111 _ => conditionalAccessSyntax . WhenNotNull ,
99112 } ;
100- InspectMemberAccess ( context , rightSide , CommonInterest . SyncBlockingProperties ) ;
113+ this . InspectMemberAccess ( context , rightSide , CommonInterest . SyncBlockingProperties ) ;
101114 }
102115 }
103116
104- internal static void AnalyzeInvocation ( SyntaxNodeAnalysisContext context )
117+ internal void AnalyzeInvocation ( SyntaxNodeAnalysisContext context )
105118 {
106119 if ( IsInTaskReturningMethodOrDelegate ( context ) )
107120 {
108121 var invocationExpressionSyntax = ( InvocationExpressionSyntax ) context . Node ;
109122 var memberAccessSyntax = invocationExpressionSyntax . Expression as MemberAccessExpressionSyntax ;
110- if ( memberAccessSyntax is not null && InspectMemberAccess ( context , memberAccessSyntax . Name , CommonInterest . SyncBlockingMethods ) )
123+ if ( memberAccessSyntax is not null && this . InspectMemberAccess ( context , memberAccessSyntax . Name , CommonInterest . SyncBlockingMethods ) )
111124 {
112125 // Don't return double-diagnostics.
113126 return ;
@@ -134,6 +147,12 @@ internal static void AnalyzeInvocation(SyntaxNodeAnalysisContext context)
134147 && m . Name != invocationDeclaringMethod ? . Identifier . Text
135148 && m . HasAsyncCompatibleReturnType ( ) )
136149 {
150+ // Check if this method is excluded from VSTHRD103 diagnostics
151+ if ( this . excludedMethods . Contains ( methodSymbol ) )
152+ {
153+ return ;
154+ }
155+
137156 // An async alternative exists.
138157 ImmutableDictionary < string , string ? > ? properties = ImmutableDictionary < string , string ? > . Empty
139158 . Add ( AsyncMethodKeyName , asyncMethodName ) ;
@@ -197,7 +216,7 @@ private static bool IsInTaskReturningMethodOrDelegate(SyntaxNodeAnalysisContext
197216 return methodSymbol ? . HasAsyncCompatibleReturnType ( ) is true ;
198217 }
199218
200- private static bool InspectMemberAccess ( SyntaxNodeAnalysisContext context , ExpressionSyntax memberName , IEnumerable < CommonInterest . SyncBlockingMethod > problematicMethods )
219+ private bool InspectMemberAccess ( SyntaxNodeAnalysisContext context , ExpressionSyntax memberName , IEnumerable < CommonInterest . SyncBlockingMethod > problematicMethods )
201220 {
202221 ISymbol ? memberSymbol = context . SemanticModel . GetSymbolInfo ( memberName , context . CancellationToken ) . Symbol ;
203222 if ( memberSymbol is object )
@@ -206,6 +225,12 @@ private static bool InspectMemberAccess(SyntaxNodeAnalysisContext context, Expre
206225 {
207226 if ( item . Method . IsMatch ( memberSymbol ) )
208227 {
228+ // Check if this method is excluded from VSTHRD103 diagnostics
229+ if ( this . excludedMethods . Contains ( memberSymbol ) )
230+ {
231+ return false ;
232+ }
233+
209234 Location ? location = memberName . GetLocation ( ) ;
210235 ImmutableDictionary < string , string ? > ? properties = ImmutableDictionary < string , string ? > . Empty
211236 . Add ( ExtensionMethodNamespaceKeyName , item . ExtensionMethodNamespace is object ? string . Join ( "." , item . ExtensionMethodNamespace ) : string . Empty ) ;
0 commit comments