/// <summary> /// Check to see if we have an expression comparing the result of /// <see cref="System.Linq.Enumerable.Count{TSource}(System.Collections.Generic.IEnumerable{TSource})"/> or /// <see cref="System.Linq.Enumerable.Count{TSource}(System.Collections.Generic.IEnumerable{TSource}, Func{TSource, bool})"/> /// using operators. /// </summary> private static void AnalyzeBinaryExpression(IBinaryOperation binaryOperation, INamedTypeSymbol enumerableType, Action <Diagnostic> reportDiagnostic) { if (binaryOperation.IsComparisonOperator() && (IsLeftCountComparison(binaryOperation, enumerableType) || IsRightCountComparison(binaryOperation, enumerableType))) { reportDiagnostic(binaryOperation.Syntax.CreateDiagnostic(s_rule)); } }
protected override PredicateValueKind SetValueForEqualsOrNotEqualsComparisonOperator(IBinaryOperation operation, StringContentAnalysisData negatedCurrentAnalysisData, bool equals) { Debug.Assert(operation.IsComparisonOperator()); var predicateValueKind = PredicateValueKind.Unknown; // Handle 'a == "SomeString"' and 'a != "SomeString"' SetValueForComparisonOperator(operation.LeftOperand, operation.RightOperand, negatedCurrentAnalysisData, equals, ref predicateValueKind); // Handle '"SomeString" == a' and '"SomeString" != a' SetValueForComparisonOperator(operation.RightOperand, operation.LeftOperand, negatedCurrentAnalysisData, equals, ref predicateValueKind); return(predicateValueKind); }
protected override PredicateValueKind SetValueForEqualsOrNotEqualsComparisonOperator(IBinaryOperation operation, CopyAnalysisData negatedCurrentAnalysisData, bool equals) { Debug.Assert(operation.IsComparisonOperator()); if (GetCopyAbstractValue(operation.LeftOperand).Kind != CopyAbstractValueKind.Unknown && GetCopyAbstractValue(operation.RightOperand).Kind != CopyAbstractValueKind.Unknown && AnalysisEntityFactory.TryCreate(operation.LeftOperand, out AnalysisEntity leftEntity) && AnalysisEntityFactory.TryCreate(operation.RightOperand, out AnalysisEntity rightEntity)) { var predicateKind = PredicateValueKind.Unknown; if (!CurrentAnalysisData.TryGetValue(rightEntity, out CopyAbstractValue rightValue)) { rightValue = new CopyAbstractValue(rightEntity); } else if (rightValue.AnalysisEntities.Contains(leftEntity)) { // We have "a == b && a == b" or "a == b && a != b" // For both cases, condition on right is always true or always false and redundant. predicateKind = equals ? PredicateValueKind.AlwaysTrue : PredicateValueKind.AlwaysFalse; } else if (negatedCurrentAnalysisData.TryGetValue(rightEntity, out var negatedRightValue) && negatedRightValue.AnalysisEntities.Contains(leftEntity)) { // We have "a == b || a == b" or "a == b || a != b" // For both cases, condition on right is always true or always false and redundant. predicateKind = equals ? PredicateValueKind.AlwaysFalse : PredicateValueKind.AlwaysTrue; } if (predicateKind != PredicateValueKind.Unknown) { if (!equals) { // "a == b && a != b" or "a == b || a != b" // CurrentAnalysisData and negatedCurrentAnalysisData are both unknown values. foreach (var entity in rightValue.AnalysisEntities) { SetAbstractValue(CurrentAnalysisData, entity, CopyAbstractValue.Invalid, fromPredicate: true); SetAbstractValue(negatedCurrentAnalysisData, entity, CopyAbstractValue.Invalid, fromPredicate: true); } } return(predicateKind); } var analysisData = equals ? CurrentAnalysisData : negatedCurrentAnalysisData; SetAbstractValue(analysisData, leftEntity, rightValue, fromPredicate: true); } return(PredicateValueKind.Unknown); }
protected override PredicateValueKind SetValueForEqualsOrNotEqualsComparisonOperator(IBinaryOperation operation, NullAnalysisData negatedCurrentAnalysisData, bool equals) { Debug.Assert(operation.IsComparisonOperator()); var predicateValueKind = PredicateValueKind.Unknown; // Handle "a == null" and "a != null" if (SetValueForComparisonOperator(operation.LeftOperand, operation.RightOperand, negatedCurrentAnalysisData, equals, ref predicateValueKind)) { return(predicateValueKind); } // Otherwise, handle "null == a" and "null != a" SetValueForComparisonOperator(operation.RightOperand, operation.LeftOperand, negatedCurrentAnalysisData, equals, ref predicateValueKind); return(predicateValueKind); }