@@ -95,6 +95,7 @@ private static ImmutableArray<Func<IMethodSymbol, bool>> BuildExclusions(Compila
9595 {
9696 exclusions . Add ( x => x . IsAny ( KnownType . Microsoft_EntityFrameworkCore_DbSet_TEntity , ExcludedMethodNames ) ) ; // https://github.com/SonarSource/sonar-dotnet/issues/9269
9797 exclusions . Add ( x => x . IsAny ( KnownType . Microsoft_EntityFrameworkCore_DbContext , ExcludedMethodNames ) ) ; // https://github.com/SonarSource/sonar-dotnet/issues/9269
98+ exclusions . Add ( x => x . IsImplementingInterfaceMember ( KnownType . Microsoft_EntityFrameworkCore_IDbContextFactory_TContext , "CreateDbContext" ) ) ;
9899 }
99100 if ( compilation . GetTypeByMetadataName ( KnownType . FluentValidation_IValidator ) is not null )
100101 {
@@ -109,25 +110,25 @@ private static ImmutableArray<Func<IMethodSymbol, bool>> BuildExclusions(Compila
109110 }
110111
111112 private static ImmutableArray < ISymbol > FindAwaitableAlternatives ( WellKnownExtensionMethodContainer wellKnownExtensionMethodContainer , ImmutableArray < Func < IMethodSymbol , bool > > exclusions ,
112- InvocationExpressionSyntax invocationExpression , SemanticModel semanticModel , ISymbol containingSymbol , CancellationToken cancel )
113+ InvocationExpressionSyntax invocationExpression , SemanticModel model , ISymbol containingSymbol , CancellationToken cancel )
113114 {
114115 var awaitableRoot = GetAwaitableRootOfInvocation ( invocationExpression ) ;
115116 if ( awaitableRoot is not { Parent : AwaitExpressionSyntax } // Invocation result is already awaited.
116117 && invocationExpression . EnclosingScope ( ) is { } scope
117118 && IsAsyncCodeBlock ( scope )
118- && semanticModel . GetSymbolInfo ( invocationExpression , cancel ) . Symbol is IMethodSymbol { MethodKind : not MethodKind . DelegateInvoke } methodSymbol
119+ && model . GetSymbolInfo ( invocationExpression , cancel ) . Symbol is IMethodSymbol { MethodKind : not MethodKind . DelegateInvoke } methodSymbol
119120 && ! ( methodSymbol . IsAwaitableNonDynamic ( ) // The invoked method returns something awaitable (but it isn't awaited).
120121 || methodSymbol . ContainingType . DerivesFromAny ( ExcludedTypes ) )
121122 && ! exclusions . Any ( x => x ( methodSymbol ) ) )
122123 {
123124 // Perf: Before doing (expensive) speculative re-binding in SpeculativeBindCandidates, we check if there is an "..Async()" alternative in scope.
124- var invokedType = invocationExpression . Expression . GetLeftOfDot ( ) is { } expression && semanticModel . GetTypeInfo ( expression ) is { Type : { } type }
125+ var invokedType = invocationExpression . Expression . GetLeftOfDot ( ) is { } expression && model . GetTypeInfo ( expression ) is { Type : { } type }
125126 ? type // A dotted expression: Lookup the type, left of the dot (this may be different from methodSymbol.ContainingType)
126127 : containingSymbol . ContainingType ; // If not dotted, than the scope is the current type. Local function support is missing here.
127128 var members = GetMethodSymbolsInScope ( $ "{ methodSymbol . Name } Async", wellKnownExtensionMethodContainer , invokedType , methodSymbol . ContainingType ) ;
128129 var awaitableCandidates = members . Where ( x => x . IsAwaitableNonDynamic ( ) ) ;
129130 // Get the method alternatives and exclude candidates that would resolve to the containing method (endless loop)
130- var awaitableAlternatives = SpeculativeBindCandidates ( semanticModel , awaitableRoot , invocationExpression , awaitableCandidates )
131+ var awaitableAlternatives = SpeculativeBindCandidates ( model , awaitableRoot , invocationExpression , awaitableCandidates )
131132 . Where ( x => ! containingSymbol . Equals ( x ) )
132133 . ToImmutableArray ( ) ;
133134 return awaitableAlternatives ;
@@ -148,15 +149,15 @@ private static IEnumerable<INamedTypeSymbol> WellKnownExtensionMethodContainer(W
148149 ? extensionMethodContainer
149150 : [ ] ;
150151
151- private static IEnumerable < ISymbol > SpeculativeBindCandidates ( SemanticModel semanticModel , SyntaxNode awaitableRoot ,
152+ private static IEnumerable < ISymbol > SpeculativeBindCandidates ( SemanticModel model , SyntaxNode awaitableRoot ,
152153 InvocationExpressionSyntax invocationExpression , IEnumerable < IMethodSymbol > awaitableCandidates ) =>
153154 awaitableCandidates
154155 . Select ( x => x . Name )
155156 . Distinct ( )
156- . Select ( x => SpeculativeBindCandidate ( semanticModel , x , awaitableRoot , invocationExpression ) )
157+ . Select ( x => SpeculativeBindCandidate ( model , x , awaitableRoot , invocationExpression ) )
157158 . WhereNotNull ( ) ;
158159
159- private static IMethodSymbol SpeculativeBindCandidate ( SemanticModel semanticModel , string candidateName , SyntaxNode awaitableRoot ,
160+ private static IMethodSymbol SpeculativeBindCandidate ( SemanticModel model , string candidateName , SyntaxNode awaitableRoot ,
160161 InvocationExpressionSyntax invocationExpression )
161162 {
162163 var invocationIdentifierName = invocationExpression . GetMethodCallIdentifier ( ) ? . Parent ;
@@ -165,7 +166,7 @@ private static IMethodSymbol SpeculativeBindCandidate(SemanticModel semanticMode
165166 return null ;
166167 }
167168 var invocationReplaced = ReplaceInvocation ( awaitableRoot , invocationExpression , invocationIdentifierName , candidateName ) ;
168- var speculativeSymbolInfo = semanticModel . GetSpeculativeSymbolInfo ( invocationReplaced . SpanStart , invocationReplaced , SpeculativeBindingOption . BindAsExpression ) ;
169+ var speculativeSymbolInfo = model . GetSpeculativeSymbolInfo ( invocationReplaced . SpanStart , invocationReplaced , SpeculativeBindingOption . BindAsExpression ) ;
169170 var speculativeSymbol = speculativeSymbolInfo . Symbol as IMethodSymbol ;
170171 return speculativeSymbol ;
171172 }
0 commit comments