Пример #1
0
        private static void CheckIfStatement(SyntaxNodeAnalysisContext context)
        {
            var ifStatement = (IfStatementSyntax)context.Node;

            if (ifStatement.Else == null ||
                ifStatement.Parent is ElseClauseSyntax)
            {
                return;
            }

            var whenTrue  = ExtractSingleStatement(ifStatement.Statement);
            var whenFalse = ExtractSingleStatement(ifStatement.Else.Statement);

            if (whenTrue == null ||
                whenFalse == null ||
                CSharpEquivalenceChecker.AreEquivalent(whenTrue, whenFalse))
            {
                /// Equivalence handled by S1871, <see cref="ConditionalStructureSameImplementation"/>
                return;
            }
            var possiblyNullCoalescing =
                TryGetExpressionComparedToNull(ifStatement.Condition, out var comparedToNull, out var comparedIsNullInTrue) &&
                ExpressionCanBeNull(comparedToNull, context.SemanticModel);

            if (CanBeSimplified(whenTrue, whenFalse,
                                possiblyNullCoalescing ? comparedToNull : null, context.SemanticModel,
                                comparedIsNullInTrue, out var isNullCoalescing))
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, ifStatement.IfKeyword.GetLocation(),
                                                                     ImmutableDictionary <string, string> .Empty.Add(IsNullCoalescingKey, isNullCoalescing.ToString()),
                                                                     isNullCoalescing ? "??" : "?:"));
            }
        }
        private static void CheckFollowingExpressions(SyntaxNodeAnalysisContext context, int currentExpressionIndex,
                                                      IList <ExpressionSyntax> expressionsInChain,
                                                      ExpressionSyntax expressionComparedToNull, BinaryExpressionSyntax comparisonToNull)
        {
            for (var j = currentExpressionIndex + 1; j < expressionsInChain.Count; j++)
            {
                var descendantNodes = expressionsInChain[j].DescendantNodes()
                                      .Where(descendant =>
                                             descendant.IsKind(expressionComparedToNull.Kind()) &&
                                             CSharpEquivalenceChecker.AreEquivalent(expressionComparedToNull, descendant))
                                      .Where(descendant =>
                                             (descendant.Parent is MemberAccessExpressionSyntax &&
                                              CSharpEquivalenceChecker.AreEquivalent(expressionComparedToNull,
                                                                                     ((MemberAccessExpressionSyntax)descendant.Parent).Expression)) ||
                                             (descendant.Parent is ElementAccessExpressionSyntax &&
                                              CSharpEquivalenceChecker.AreEquivalent(expressionComparedToNull,
                                                                                     ((ElementAccessExpressionSyntax)descendant.Parent).Expression)))
                                      .ToList();

                if (descendantNodes.Any())
                {
                    context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, comparisonToNull.GetLocation(),
                                                                         expressionComparedToNull.ToString()));
                }
            }
        }
Пример #3
0
        private static void CheckConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            var conditional = (ConditionalExpressionSyntax)context.Node;

            var condition = conditional.Condition.RemoveParentheses();
            var whenTrue  = conditional.WhenTrue.RemoveParentheses();
            var whenFalse = conditional.WhenFalse.RemoveParentheses();

            if (CSharpEquivalenceChecker.AreEquivalent(whenTrue, whenFalse))
            {
                /// handled by S2758, <see cref="TernaryOperatorPointless"/>
                return;
            }
            if (!TryGetExpressionComparedToNull(condition, out var comparedToNull, out var comparedIsNullInTrue) ||
                !ExpressionCanBeNull(comparedToNull, context.SemanticModel))
            {
                // expression not compared to null, or can't be null
                return;
            }

            if (CanExpressionBeNullCoalescing(whenTrue, whenFalse, comparedToNull, context.SemanticModel, comparedIsNullInTrue))
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, conditional.GetLocation(), "??"));
            }
        }
        private static ExpressionSyntax GetSimplifiedAssignment(ExpressionSyntax expression1, ExpressionSyntax expression2,
                                                                ExpressionSyntax condition, ExpressionSyntax compared, SemanticModel semanticModel, SyntaxAnnotation annotation,
                                                                bool isNullCoalescing)
        {
            var assignment1     = expression1 as AssignmentExpressionSyntax;
            var assignment2     = expression2 as AssignmentExpressionSyntax;
            var canBeSimplified =
                assignment1 != null &&
                assignment2 != null &&
                CSharpEquivalenceChecker.AreEquivalent(assignment1.Left, assignment2.Left) &&
                assignment1.Kind() == assignment2.Kind();

            if (!canBeSimplified)
            {
                return(null);
            }

            var createdExpression = isNullCoalescing
                ? GetNullCoalescing(assignment1.Right, assignment2.Right, compared, semanticModel, annotation)
                : GetConditionalExpression(condition, assignment1.Right, assignment2.Right, annotation);

            return(SyntaxFactory.AssignmentExpression(
                       assignment1.Kind(),
                       assignment1.Left,
                       createdExpression));
        }
Пример #5
0
        internal static bool TryGetExpressionComparedToNull(ExpressionSyntax expression,
                                                            out ExpressionSyntax compared, out bool comparedIsNullInTrue)
        {
            compared             = null;
            comparedIsNullInTrue = false;
            if (!(expression is BinaryExpressionSyntax binary) ||
                !EqualsOrNotEquals.Contains(binary.Kind()))
            {
                return(false);
            }

            comparedIsNullInTrue = binary.IsKind(SyntaxKind.EqualsExpression);

            if (CSharpEquivalenceChecker.AreEquivalent(binary.Left, CSharpSyntaxHelper.NullLiteralExpression))
            {
                compared = binary.Right;
                return(true);
            }

            if (CSharpEquivalenceChecker.AreEquivalent(binary.Right, CSharpSyntaxHelper.NullLiteralExpression))
            {
                compared = binary.Left;
                return(true);
            }

            return(false);
        }
        private static void CheckLogicalExpression(SyntaxNodeAnalysisContext context)
        {
            var binaryExpression = (BinaryExpressionSyntax)context.Node;
            var left             = TryGetBinaryExpression(binaryExpression.Left);
            var right            = TryGetBinaryExpression(binaryExpression.Right);

            if (right == null || left == null)
            {
                return;
            }

            var eqRight = CSharpEquivalenceChecker.AreEquivalent(right.Right, left.Right);
            var eqLeft  = CSharpEquivalenceChecker.AreEquivalent(right.Left, left.Left);

            if (!eqRight || !eqLeft)
            {
                return;
            }

            var isEquality = IsIndirectEquality(binaryExpression, right, left, context);

            if (isEquality ||
                IsIndirectInequality(binaryExpression, right, left, context))
            {
                var messageEqualityPart = GetMessageEqualityPart(isEquality);

                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, binaryExpression.GetLocation(), messageEqualityPart));
            }
        }
        private static void CheckForBooleanConstant(BinaryExpressionSyntax binaryExpression, ExpressionSyntax booleanContantExpression,
                                                    ErrorLocation errorLocation, SyntaxNodeAnalysisContext context, bool leftSide)
        {
            var expression = leftSide
                ? binaryExpression.Left
                : binaryExpression.Right;

            if (!CSharpEquivalenceChecker.AreEquivalent(expression.RemoveParentheses(), booleanContantExpression))
            {
                return;
            }

            Location location;

            switch (errorLocation)
            {
            case ErrorLocation.Normal:
                location = expression.GetLocation();
                break;

            case ErrorLocation.Extended:
                location = CalculateExtendedLocation(binaryExpression, leftSide);
                break;

            case ErrorLocation.Inverted:
                location = CalculateExtendedLocation(binaryExpression, !leftSide);
                break;

            default:
                location = null;
                break;
            }

            context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, location));
        }
        private static bool CheckForNullabilityAndBooleanConstantsReport(BinaryExpressionSyntax binaryExpression,
                                                                         SyntaxNodeAnalysisContext context, bool reportOnTrue)
        {
            var typeLeft  = context.SemanticModel.GetTypeInfo(binaryExpression.Left).Type;
            var typeRight = context.SemanticModel.GetTypeInfo(binaryExpression.Right).Type;

            if (ShouldNotReport(typeLeft, typeRight))
            {
                return(true);
            }

            var binaryExpressionLeft  = binaryExpression.Left.RemoveParentheses();
            var binaryExpressionRight = binaryExpression.Right.RemoveParentheses();

            var leftIsTrue   = CSharpEquivalenceChecker.AreEquivalent(binaryExpressionLeft, CSharpSyntaxHelper.TrueLiteralExpression);
            var leftIsFalse  = CSharpEquivalenceChecker.AreEquivalent(binaryExpressionLeft, CSharpSyntaxHelper.FalseLiteralExpression);
            var rightIsTrue  = CSharpEquivalenceChecker.AreEquivalent(binaryExpressionRight, CSharpSyntaxHelper.TrueLiteralExpression);
            var rightIsFalse = CSharpEquivalenceChecker.AreEquivalent(binaryExpressionRight, CSharpSyntaxHelper.FalseLiteralExpression);

            var leftIsBoolean  = leftIsTrue || leftIsFalse;
            var rightIsBoolean = rightIsTrue || rightIsFalse;

            if (leftIsBoolean && rightIsBoolean)
            {
                var bothAreSame   = (leftIsTrue && rightIsTrue) || (leftIsFalse && rightIsFalse);
                var errorLocation = bothAreSame
                    ? CalculateExtendedLocation(binaryExpression, false)
                    : CalculateExtendedLocation(binaryExpression, reportOnTrue == leftIsTrue);

                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, errorLocation));
                return(true);
            }
            return(false);
        }
Пример #9
0
        private static bool AreCandidateAssignments(ExpressionSyntax expression1, ExpressionSyntax expression2,
                                                    ExpressionSyntax compared, SemanticModel semanticModel, bool comparedIsNullInTrue, out bool isNullCoalescing)
        {
            isNullCoalescing = false;
            var assignment1     = expression1 as AssignmentExpressionSyntax;
            var assignment2     = expression2 as AssignmentExpressionSyntax;
            var canBeSimplified =
                assignment1 != null &&
                assignment2 != null &&
                CSharpEquivalenceChecker.AreEquivalent(assignment1.Left, assignment2.Left) &&
                assignment1.Kind() == assignment2.Kind();

            if (!canBeSimplified)
            {
                return(false);
            }

            if (!AreTypesCompatible(assignment1.Right, assignment2.Right, semanticModel))
            {
                return(false);
            }

            if (compared != null &&
                CanExpressionBeNullCoalescing(assignment1.Right, assignment2.Right, compared, semanticModel, comparedIsNullInTrue))
            {
                isNullCoalescing = true;
            }

            return(true);
        }
Пример #10
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var equalsExpression = (BinaryExpressionSyntax)c.Node;

                var leftIsNull  = CSharpEquivalenceChecker.AreEquivalent(equalsExpression.Left, CSharpSyntaxHelper.NullLiteralExpression);
                var rightIsNull = CSharpEquivalenceChecker.AreEquivalent(equalsExpression.Right, CSharpSyntaxHelper.NullLiteralExpression);

                if (!(leftIsNull ^ rightIsNull))
                {
                    return;
                }

                var expressionToTypeCheck = leftIsNull ? equalsExpression.Right : equalsExpression.Left;
                if (c.SemanticModel.GetTypeInfo(expressionToTypeCheck).Type is ITypeParameterSymbol typeInfo &&
                    !typeInfo.HasReferenceTypeConstraint &&
                    !typeInfo.ConstraintTypes.OfType <IErrorTypeSymbol>().Any() &&
                    !typeInfo.ConstraintTypes.Any(typeSymbol =>
                                                  typeSymbol.IsReferenceType &&
                                                  typeSymbol.IsClass()))
                {
                    var expressionToReportOn = leftIsNull ? equalsExpression.Left : equalsExpression.Right;

                    c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, expressionToReportOn.GetLocation(),
                                                                   typeInfo.Name));
                }
            },
                SyntaxKind.EqualsExpression,
                SyntaxKind.NotEqualsExpression);
        }
        private static ExpressionSyntax GetNullCoalescing(ExpressionSyntax whenTrue, ExpressionSyntax whenFalse,
                                                          ExpressionSyntax compared, SemanticModel semanticModel, SyntaxAnnotation annotation)
        {
            if (CSharpEquivalenceChecker.AreEquivalent(whenTrue, compared))
            {
                var createdExpression = SyntaxFactory.BinaryExpression(
                    SyntaxKind.CoalesceExpression,
                    compared,
                    whenFalse)
                                        .WithAdditionalAnnotations(annotation);
                return(createdExpression);
            }

            if (CSharpEquivalenceChecker.AreEquivalent(whenFalse, compared))
            {
                var createdExpression = SyntaxFactory.BinaryExpression(
                    SyntaxKind.CoalesceExpression,
                    compared,
                    whenTrue)
                                        .WithAdditionalAnnotations(annotation);
                return(createdExpression);
            }

            return(GetSimplificationFromInvocations(whenTrue, whenFalse, null, compared, semanticModel, annotation,
                                                    isNullCoalescing: true));
        }
Пример #12
0
        public void AreEquivalent_Node_CS()
        {
            var result = CSharpEquivalenceChecker.AreEquivalent(methods_CS.Method1, methods_CS.Method2);

            result.Should().BeTrue();

            result = CSharpEquivalenceChecker.AreEquivalent(methods_CS.Method1, methods_CS.Method3);
            result.Should().BeFalse();
        }
Пример #13
0
        public void AreEquivalent_List_CS()
        {
            var result = CSharpEquivalenceChecker.AreEquivalent(methods_CS.Method1.Statements, methods_CS.Method2.Statements);

            result.Should().BeTrue();

            result = CSharpEquivalenceChecker.AreEquivalent(methods_CS.Method1.Statements, methods_CS.Method3.Statements);
            result.Should().BeFalse();
        }
 private static bool TwoSidesAreSameBooleans(BinaryExpressionSyntax binary)
 {
     return((
                CSharpEquivalenceChecker.AreEquivalent(binary.Left, CSharpSyntaxHelper.TrueLiteralExpression) &&
                CSharpEquivalenceChecker.AreEquivalent(binary.Right, CSharpSyntaxHelper.TrueLiteralExpression)) ||
            (
                CSharpEquivalenceChecker.AreEquivalent(binary.Left, CSharpSyntaxHelper.FalseLiteralExpression) &&
                CSharpEquivalenceChecker.AreEquivalent(binary.Right, CSharpSyntaxHelper.FalseLiteralExpression)));
 }
Пример #15
0
        private static void CheckForLoopCondition(SyntaxNodeAnalysisContext context)
        {
            var forLoop = (ForStatementSyntax)context.Node;

            if (forLoop.Condition != null &&
                CSharpEquivalenceChecker.AreEquivalent(forLoop.Condition.RemoveParentheses(), CSharpSyntaxHelper.TrueLiteralExpression))
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, forLoop.Condition.GetLocation()));
            }
        }
        private static void CheckLogicalNot(SyntaxNodeAnalysisContext context)
        {
            var logicalNot = (PrefixUnaryExpressionSyntax)context.Node;

            var logicalNotOperand = logicalNot.Operand.RemoveParentheses();

            if (CSharpEquivalenceChecker.AreEquivalent(logicalNotOperand, CSharpSyntaxHelper.TrueLiteralExpression) ||
                CSharpEquivalenceChecker.AreEquivalent(logicalNotOperand, CSharpSyntaxHelper.FalseLiteralExpression))
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, logicalNot.Operand.GetLocation()));
            }
        }
        private static void ReportIfOperatorExpressionsMatch(SyntaxNodeAnalysisContext context, ExpressionSyntax left, ExpressionSyntax right,
                                                             SyntaxToken operatorToken)
        {
            if (CSharpEquivalenceChecker.AreEquivalent(left.RemoveParentheses(), right.RemoveParentheses()))
            {
                var message = string.Format(OperatorMessageFormat, operatorToken);

                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, right.GetLocation(),
                                                                     additionalLocations: new[] { left.GetLocation() },
                                                                     messageArgs: message));
            }
        }
        private static Document RewriteConditional(Document document, SyntaxNode root, SyntaxNode syntaxNode,
                                                   ConditionalExpressionSyntax conditional)
        {
            var whenTrue = conditional.WhenTrue.RemoveParentheses();

            if (whenTrue.Equals(syntaxNode) &&
                CSharpEquivalenceChecker.AreEquivalent(syntaxNode, CSharpSyntaxHelper.TrueLiteralExpression))
            {
                var newRoot = ReplaceExpressionWithBinary(conditional, root,
                                                          SyntaxKind.LogicalOrExpression,
                                                          conditional.Condition,
                                                          conditional.WhenFalse);

                return(document.WithSyntaxRoot(newRoot));
            }

            if (whenTrue.Equals(syntaxNode) &&
                CSharpEquivalenceChecker.AreEquivalent(syntaxNode, CSharpSyntaxHelper.FalseLiteralExpression))
            {
                var newRoot = ReplaceExpressionWithBinary(conditional, root,
                                                          SyntaxKind.LogicalAndExpression,
                                                          GetNegatedExpression(conditional.Condition),
                                                          conditional.WhenFalse);

                return(document.WithSyntaxRoot(newRoot));
            }

            var whenFalse = conditional.WhenFalse.RemoveParentheses();

            if (whenFalse.Equals(syntaxNode) &&
                CSharpEquivalenceChecker.AreEquivalent(syntaxNode, CSharpSyntaxHelper.TrueLiteralExpression))
            {
                var newRoot = ReplaceExpressionWithBinary(conditional, root,
                                                          SyntaxKind.LogicalOrExpression,
                                                          GetNegatedExpression(conditional.Condition),
                                                          conditional.WhenTrue);

                return(document.WithSyntaxRoot(newRoot));
            }

            if (whenFalse.Equals(syntaxNode) &&
                CSharpEquivalenceChecker.AreEquivalent(syntaxNode, CSharpSyntaxHelper.FalseLiteralExpression))
            {
                var newRoot = ReplaceExpressionWithBinary(conditional, root,
                                                          SyntaxKind.LogicalAndExpression,
                                                          conditional.Condition,
                                                          conditional.WhenTrue);

                return(document.WithSyntaxRoot(newRoot));
            }

            return(document);
        }
        public void AreEquivalent_List()
        {
            var result = CSharpEquivalenceChecker.AreEquivalent(
                this.methods.First(m => m.Identifier.ValueText == "Method1").Body.Statements,
                this.methods.First(m => m.Identifier.ValueText == "Method2").Body.Statements);

            result.Should().BeTrue();

            result = CSharpEquivalenceChecker.AreEquivalent(
                this.methods.First(m => m.Identifier.ValueText == "Method1").Body.Statements,
                this.methods.First(m => m.Identifier.ValueText == "Method3").Body.Statements);
            result.Should().BeFalse();
        }
        private static SyntaxNode FindNodeToKeep(BinaryExpressionSyntax binary)
        {
            #region logical and false, logical or true

            if (binary.IsKind(SyntaxKind.LogicalAndExpression) &&
                (CSharpEquivalenceChecker.AreEquivalent(binary.Left, CSharpSyntaxHelper.FalseLiteralExpression) ||
                 CSharpEquivalenceChecker.AreEquivalent(binary.Right, CSharpSyntaxHelper.FalseLiteralExpression)))
            {
                return(CSharpSyntaxHelper.FalseLiteralExpression);
            }
            if (binary.IsKind(SyntaxKind.LogicalOrExpression) &&
                (CSharpEquivalenceChecker.AreEquivalent(binary.Left, CSharpSyntaxHelper.TrueLiteralExpression) ||
                 CSharpEquivalenceChecker.AreEquivalent(binary.Right, CSharpSyntaxHelper.TrueLiteralExpression)))
            {
                return(CSharpSyntaxHelper.TrueLiteralExpression);
            }

            #endregion

            #region ==/!= both sides booleans

            if (binary.IsKind(SyntaxKind.EqualsExpression) &&
                TwoSidesAreDifferentBooleans(binary))
            {
                return(CSharpSyntaxHelper.FalseLiteralExpression);
            }
            if (binary.IsKind(SyntaxKind.EqualsExpression) &&
                TwoSidesAreSameBooleans(binary))
            {
                return(CSharpSyntaxHelper.TrueLiteralExpression);
            }
            if (binary.IsKind(SyntaxKind.NotEqualsExpression) &&
                TwoSidesAreSameBooleans(binary))
            {
                return(CSharpSyntaxHelper.FalseLiteralExpression);
            }
            if (binary.IsKind(SyntaxKind.NotEqualsExpression) &&
                TwoSidesAreDifferentBooleans(binary))
            {
                return(CSharpSyntaxHelper.TrueLiteralExpression);
            }

            #endregion

            if (CSharpEquivalenceChecker.AreEquivalent(binary.Left, CSharpSyntaxHelper.TrueLiteralExpression) ||
                CSharpEquivalenceChecker.AreEquivalent(binary.Left, CSharpSyntaxHelper.FalseLiteralExpression))
            {
                return(binary.Right);
            }
            return(binary.Left);
        }
 private static Document RemovePrefixUnary(Document document, SyntaxNode root,
                                           SyntaxNode literal)
 {
     if (CSharpEquivalenceChecker.AreEquivalent(literal, CSharpSyntaxHelper.TrueLiteralExpression))
     {
         var newRoot = root.ReplaceNode(literal.Parent, CSharpSyntaxHelper.FalseLiteralExpression);
         return(document.WithSyntaxRoot(newRoot));
     }
     else
     {
         var newRoot = root.ReplaceNode(literal.Parent, CSharpSyntaxHelper.TrueLiteralExpression);
         return(document.WithSyntaxRoot(newRoot));
     }
 }
        private static void CheckAsOperatorComparedToNull(ExpressionSyntax sideA, ExpressionSyntax sideB, Location location,
                                                          SyntaxNodeAnalysisContext context)
        {
            if (!CSharpEquivalenceChecker.AreEquivalent(sideA.RemoveParentheses(), CSharpSyntaxHelper.NullLiteralExpression))
            {
                return;
            }

            if (!sideB.RemoveParentheses().IsKind(SyntaxKind.AsExpression))
            {
                return;
            }

            context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, location, MessageIsOperator));
        }
 private static Document RemoveConditional(Document document, SyntaxNode root,
                                           ConditionalExpressionSyntax conditional)
 {
     if (CSharpEquivalenceChecker.AreEquivalent(conditional.WhenTrue, CSharpSyntaxHelper.TrueLiteralExpression))
     {
         var newRoot = root.ReplaceNode(conditional,
                                        conditional.Condition.WithAdditionalAnnotations(Formatter.Annotation));
         return(document.WithSyntaxRoot(newRoot));
     }
     else
     {
         var newRoot = root.ReplaceNode(conditional,
                                        GetNegatedExpression(conditional.Condition).WithAdditionalAnnotations(Formatter.Annotation));
         return(document.WithSyntaxRoot(newRoot));
     }
 }
        private static bool IsNullChecking(BinaryExpressionSyntax binaryExpression, string lambdaParameter)
        {
            if (CSharpEquivalenceChecker.AreEquivalent(CSharpSyntaxHelper.NullLiteralExpression, binaryExpression.Left.RemoveParentheses()) &&
                binaryExpression.Right.RemoveParentheses().ToString() == lambdaParameter)
            {
                return(true);
            }

            if (CSharpEquivalenceChecker.AreEquivalent(CSharpSyntaxHelper.NullLiteralExpression, binaryExpression.Right.RemoveParentheses()) &&
                binaryExpression.Left.RemoveParentheses().ToString() == lambdaParameter)
            {
                return(true);
            }

            return(false);
        }
Пример #25
0
        private static bool CanExpressionBeNullCoalescing(ExpressionSyntax whenTrue, ExpressionSyntax whenFalse,
                                                          ExpressionSyntax comparedToNull, SemanticModel semanticModel, bool comparedIsNullInTrue)
        {
            if (CSharpEquivalenceChecker.AreEquivalent(whenTrue, comparedToNull))
            {
                return(!comparedIsNullInTrue);
            }

            if (CSharpEquivalenceChecker.AreEquivalent(whenFalse, comparedToNull))
            {
                return(comparedIsNullInTrue);
            }

            return(AreCandidateInvocationsForNullCoalescing(whenTrue, whenFalse, comparedToNull,
                                                            semanticModel, comparedIsNullInTrue));
        }
Пример #26
0
        private static void CheckStatement(SyntaxNodeAnalysisContext context, StatementSyntax statement,
                                           IEnumerable <StatementSyntax> precedingStatements)
        {
            if (statement.ChildNodes().Count() < 2)
            {
                return;
            }

            var precedingStatement = precedingStatements
                                     .FirstOrDefault(preceding => CSharpEquivalenceChecker.AreEquivalent(statement, preceding));

            if (precedingStatement != null)
            {
                ReportSyntaxNode(context, statement, precedingStatement, "branch");
            }
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var expression = (ConditionalExpressionSyntax)c.Node;

                if (CSharpEquivalenceChecker.AreEquivalent(
                        expression.WhenTrue.RemoveParentheses(),
                        expression.WhenFalse.RemoveParentheses()))
                {
                    c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, expression.GetLocation()));
                }
            },
                SyntaxKind.ConditionalExpression);
        }
        private static void ReportOnObjectEqualsMatches(InvocationExpressionSyntax invocation,
                                                        SyntaxNodeAnalysisContext context)
        {
            var methodSymbol = context.SemanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

            var operands = GetOperands(invocation, methodSymbol);

            if (operands != null &&
                CSharpEquivalenceChecker.AreEquivalent(RemoveParantheses(operands.Item1), RemoveParantheses(operands.Item2)))
            {
                var message = string.Format(EqualsMessage, operands.Item2);

                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, operands.Item1.GetLocation(),
                                                                     additionalLocations: new[] { operands.Item2.GetLocation() },
                                                                     messageArgs: message));
            }
        }
Пример #29
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var ifStatement = (IfStatementSyntax)c.Node;

                var precedingStatements = ifStatement
                                          .GetPrecedingStatementsInConditionChain()
                                          .ToList();

                CheckStatement(c, ifStatement.Statement, precedingStatements);

                if (ifStatement.Else == null)
                {
                    return;
                }

                precedingStatements.Add(ifStatement.Statement);
                CheckStatement(c, ifStatement.Else.Statement, precedingStatements);
            },
                SyntaxKind.IfStatement);

            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var switchSection = (SwitchSectionSyntax)c.Node;

                if (GetStatements(switchSection).Count(IsApprovedStatement) < 2)
                {
                    return;
                }

                var precedingSection = switchSection
                                       .GetPrecedingSections()
                                       .FirstOrDefault(
                    preceding => CSharpEquivalenceChecker.AreEquivalent(switchSection.Statements, preceding.Statements));

                if (precedingSection != null)
                {
                    ReportSyntaxNode(c, switchSection, precedingSection, "case");
                }
            },
                SyntaxKind.SwitchSection);
        }
        private static void CheckMatchingExpressionsInSucceedingStatements <T>(T statement,
                                                                               Func <T, ExpressionSyntax> expressionSelector, SyntaxNodeAnalysisContext context) where T : StatementSyntax
        {
            if (!(statement.GetPrecedingStatement() is T previousStatement))
            {
                return;
            }

            var currentExpression  = expressionSelector(statement);
            var previousExpression = expressionSelector(previousStatement);

            if (CSharpEquivalenceChecker.AreEquivalent(currentExpression, previousExpression) &&
                !ContainsPossibleUpdate(previousStatement, currentExpression, context.SemanticModel))
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, currentExpression.GetLocation(),
                                                                     previousExpression.GetLineNumberToReport()));
            }
        }