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())); } } }
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)); }
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); }
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); }
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)); }
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(); }
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))); }
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); }
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)); }
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)); } }
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())); } }