@@ -46,26 +46,43 @@ public sealed override void Initialize(AnalysisContext context)
4646 context . EnableConcurrentExecution ( ) ;
4747 context . ConfigureGeneratedCodeAnalysis ( GeneratedCodeAnalysisFlags . None ) ;
4848
49- context . RegisterOperationAction (
50- operationAnalysisContext => AnalyzeInvocationExpression ( ( IInvocationOperation ) operationAnalysisContext . Operation , operationAnalysisContext . ReportDiagnostic ) ,
51- OperationKind . Invocation ) ;
52-
53- context . RegisterOperationAction (
54- operationAnalysisContext => AnalyzeBinaryExpression ( ( IBinaryOperation ) operationAnalysisContext . Operation , operationAnalysisContext . ReportDiagnostic ) ,
55- OperationKind . BinaryOperator ) ;
49+ context . RegisterCompilationStartAction ( context =>
50+ {
51+ var linqExpressionType = context . Compilation . GetOrCreateTypeByMetadataName ( WellKnownTypeNames . SystemLinqExpressionsExpression1 ) ;
52+
53+ context . RegisterOperationAction (
54+ operationAnalysisContext => AnalyzeInvocationExpression (
55+ ( IInvocationOperation ) operationAnalysisContext . Operation , linqExpressionType ,
56+ operationAnalysisContext . ReportDiagnostic ) ,
57+ OperationKind . Invocation ) ;
58+
59+ context . RegisterOperationAction (
60+ operationAnalysisContext => AnalyzeBinaryExpression (
61+ ( IBinaryOperation ) operationAnalysisContext . Operation , linqExpressionType ,
62+ operationAnalysisContext . ReportDiagnostic ) ,
63+ OperationKind . BinaryOperator ) ;
64+ } ) ;
5665 }
5766
5867 /// <summary>
5968 /// Check to see if we have an invocation to string.Equals that has an empty string as an argument.
6069 /// </summary>
61- private static void AnalyzeInvocationExpression ( IInvocationOperation invocationOperation , Action < Diagnostic > reportDiagnostic )
70+ private static void AnalyzeInvocationExpression ( IInvocationOperation invocationOperation ,
71+ INamedTypeSymbol ? linqExpressionTreeType , Action < Diagnostic > reportDiagnostic )
6272 {
6373 if ( ! invocationOperation . Arguments . IsEmpty )
6474 {
6575 IMethodSymbol methodSymbol = invocationOperation . TargetMethod ;
66- if ( methodSymbol != null &&
67- IsStringEqualsMethod ( methodSymbol ) &&
68- HasAnEmptyStringArgument ( invocationOperation ) )
76+ if ( methodSymbol == null
77+ || ! IsStringEqualsMethod ( methodSymbol )
78+ || ! HasAnEmptyStringArgument ( invocationOperation ) )
79+ {
80+ return ;
81+ }
82+
83+ // Check if we are in a Expression<Func<T...>> context, in which case it is possible
84+ // that the underlying call doesn't have the helper so we want to bail-out.
85+ if ( ! invocationOperation . IsWithinExpressionTree ( linqExpressionTreeType ) )
6986 {
7087 reportDiagnostic ( invocationOperation . Syntax . CreateDiagnostic ( s_rule ) ) ;
7188 }
@@ -76,7 +93,8 @@ private static void AnalyzeInvocationExpression(IInvocationOperation invocationO
7693 /// Check to see if we have a equals or not equals expression where an empty string is being
7794 /// compared.
7895 /// </summary>
79- private static void AnalyzeBinaryExpression ( IBinaryOperation binaryOperation , Action < Diagnostic > reportDiagnostic )
96+ private static void AnalyzeBinaryExpression ( IBinaryOperation binaryOperation ,
97+ INamedTypeSymbol ? linqExpressionTreeType , Action < Diagnostic > reportDiagnostic )
8098 {
8199 if ( binaryOperation . OperatorKind is not BinaryOperatorKind . Equals and
82100 not BinaryOperatorKind . NotEquals )
@@ -90,7 +108,15 @@ private static void AnalyzeBinaryExpression(IBinaryOperation binaryOperation, Ac
90108 return ;
91109 }
92110
93- if ( IsEmptyString ( binaryOperation . LeftOperand ) || IsEmptyString ( binaryOperation . RightOperand ) )
111+ if ( ! IsEmptyString ( binaryOperation . LeftOperand )
112+ && ! IsEmptyString ( binaryOperation . RightOperand ) )
113+ {
114+ return ;
115+ }
116+
117+ // Check if we are in a Expression<Func<T...>> context, in which case it is possible
118+ // that the underlying call doesn't have the helper so we want to bail-out.
119+ if ( ! binaryOperation . IsWithinExpressionTree ( linqExpressionTreeType ) )
94120 {
95121 reportDiagnostic ( binaryOperation . Syntax . CreateDiagnostic ( s_rule ) ) ;
96122 }
0 commit comments