예제 #1
0
        private static bool CanRefactor(
            ExpressionStatementSyntax expressionStatement,
            IfStatementSyntax ifStatement,
            ExpressionSyntax expression,
            SyntaxNode parent)
        {
            ExpressionSyntax expression2 = expressionStatement.Expression;

            if (expression2?.IsKind(SyntaxKind.SimpleAssignmentExpression) == true)
            {
                var assignment = (AssignmentExpressionSyntax)expression2;

                ExpressionSyntax left = assignment.Left;

                if (left?.IsMissing == false)
                {
                    ExpressionSyntax right = assignment.Right;

                    return(right?.IsMissing == false &&
                           SyntaxComparer.AreEquivalent(expression, left) &&
                           !parent.ContainsDirectives(TextSpan.FromBounds(right.Span.End, ifStatement.Span.Start)));
                }
            }

            return(false);
        }
예제 #2
0
        private static IfRefactoring CreateIfToAssignment(
            IfStatementSyntax ifStatement,
            ExpressionSyntax left,
            ExpressionSyntax expression1,
            ExpressionSyntax expression2,
            NullCheckExpressionInfo nullCheck,
            IfAnalysisOptions options,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if ((nullCheck.Kind & NullCheckKind.ComparisonToNull) != 0 &&
                SyntaxComparer.AreEquivalent(nullCheck.Expression, expression1))
            {
                return(CreateIfToAssignment(ifStatement, left, expression1, expression2, options, isNullable: false));
            }

            expression1 = GetNullableOfTValueProperty(expression1, semanticModel, cancellationToken);

            if (SyntaxComparer.AreEquivalent(nullCheck.Expression, expression1))
            {
                return(CreateIfToAssignment(ifStatement, left, expression1, expression2, options, isNullable: true));
            }

            return(null);
        }
예제 #3
0
        private static IfRefactoring CreateIfToAssignmentWithWithCoalesceExpression(
            IfStatementSyntax ifStatement,
            ExpressionSyntax left,
            ExpressionSyntax expression1,
            ExpressionSyntax expression2,
            NullCheckExpression nullCheck,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (nullCheck.Kind == NullCheckKind.EqualsToNull ||
                nullCheck.Kind == NullCheckKind.NotEqualsToNull)
            {
                if (SyntaxComparer.AreEquivalent(nullCheck.Expression, expression1, requireNotNull: true))
                {
                    return(new IfElseToAssignmentWithCoalesceExpression(ifStatement, left, expression1, expression2));
                }
            }

            if (expression1.IsKind(SyntaxKind.SimpleMemberAccessExpression) &&
                SyntaxUtility.IsPropertyOfNullableOfT(expression1, "Value", semanticModel, cancellationToken))
            {
                expression1 = ((MemberAccessExpressionSyntax)expression1).Expression;

                if (SyntaxComparer.AreEquivalent(nullCheck.Expression, expression1, requireNotNull: true))
                {
                    return(new IfElseToAssignmentWithCoalesceExpression(ifStatement, left, expression1, expression2));
                }
            }

            return(null);
        }
예제 #4
0
        private static ImmutableArray <IfRefactoring> Analyze(
            ExpressionStatementSyntax expressionStatement,
            IfStatementSyntax ifStatement,
            IfAnalysisOptions options)
        {
            SimpleAssignmentStatement assignment;

            if (SimpleAssignmentStatement.TryCreate(expressionStatement, out assignment))
            {
                ElseClauseSyntax elseClause = ifStatement.Else;

                if (elseClause?.Statement?.IsKind(SyntaxKind.IfStatement) == false)
                {
                    SimpleAssignmentStatement assignment1;
                    if (SimpleAssignmentStatement.TryCreate(ifStatement.GetSingleStatementOrDefault(), out assignment1))
                    {
                        SimpleAssignmentStatement assignment2;
                        if (SimpleAssignmentStatement.TryCreate(elseClause.GetSingleStatementOrDefault(), out assignment2) &&
                            SyntaxComparer.AreEquivalent(assignment1.Left, assignment2.Left, assignment.Left) &&
                            options.CheckSpanDirectives(ifStatement.Parent, TextSpan.FromBounds(expressionStatement.SpanStart, ifStatement.Span.End)))
                        {
                            return(new AssignmentAndIfElseToAssignmentWithConditionalExpression(expressionStatement, assignment.Right, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray());
                        }
                    }
                }
            }

            return(ImmutableArray <IfRefactoring> .Empty);
        }
예제 #5
0
        private static ImmutableArray<IfRefactoring> Analyze(
            ExpressionStatementSyntax expressionStatement,
            IfStatementSyntax ifStatement,
            IfAnalysisOptions options)
        {
            SimpleAssignmentStatementInfo assignment = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement);

            if (!assignment.Success)
                return Empty;

            ElseClauseSyntax elseClause = ifStatement.Else;

            if (elseClause?.Statement?.IsKind(SyntaxKind.IfStatement) != false)
                return Empty;

            SimpleAssignmentStatementInfo assignment1 = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.GetSingleStatementOrDefault());

            if (!assignment1.Success)
                return Empty;

            SimpleAssignmentStatementInfo assignment2 = SyntaxInfo.SimpleAssignmentStatementInfo(elseClause.GetSingleStatementOrDefault());

            if (!assignment2.Success)
                return Empty;

            if (!SyntaxComparer.AreEquivalent(assignment1.Left, assignment2.Left, assignment.Left))
                return Empty;

            if (!options.CheckSpanDirectives(ifStatement.Parent, TextSpan.FromBounds(expressionStatement.SpanStart, ifStatement.Span.End)))
                return Empty;

            return new AssignmentAndIfElseToAssignmentWithConditionalExpression(expressionStatement, assignment.Right, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray();
        }
        public static bool CanRefactor(AssignmentExpressionSyntax assignment)
        {
            if (assignment == null)
            {
                throw new ArgumentNullException(nameof(assignment));
            }

            if (assignment.IsKind(SyntaxKind.SimpleAssignmentExpression))
            {
                ExpressionSyntax left  = assignment.Left;
                ExpressionSyntax right = assignment.Right;

                if (left?.IsMissing == false &&
                    right?.IsMissing == false &&
                    !assignment.IsParentKind(SyntaxKind.ObjectInitializerExpression) &&
                    right.SupportsCompoundAssignment())
                {
                    var binaryExpression         = (BinaryExpressionSyntax)right;
                    ExpressionSyntax binaryLeft  = binaryExpression.Left;
                    ExpressionSyntax binaryRight = binaryExpression.Right;

                    return(binaryLeft?.IsMissing == false &&
                           binaryRight?.IsMissing == false &&
                           SyntaxComparer.AreEquivalent(left, binaryLeft) &&
                           (assignment
                            .DescendantTrivia(assignment.Span)
                            .All(f => f.IsWhitespaceOrEndOfLineTrivia())));
                }
            }

            return(false);
        }
예제 #7
0
 private static bool AreEquivalent(StatementSyntax statement, StatementSyntax statement2)
 {
     return(statement.Kind() == statement2.Kind() &&
            SyntaxComparer.AreEquivalent(statement, statement2) &&
            statement.DescendantTrivia().All(f => f.IsWhitespaceOrEndOfLineTrivia()) &&
            statement2.DescendantTrivia().All(f => f.IsWhitespaceOrEndOfLineTrivia()));
 }
        private static bool NullCheckExists(ExpressionSyntax expression, StatementSyntax statement)
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

            if (!statementsInfo.Success)
            {
                return(false);
            }

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            if (index >= statements.Count - 1)
            {
                return(false);
            }

            StatementSyntax nextStatement = statements[index + 1];

            if (!(nextStatement is IfStatementSyntax ifStatement))
            {
                return(false);
            }

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, NullCheckKind.NotEqualsToNull);

            if (!nullCheck.Success)
            {
                return(false);
            }

            return(SyntaxComparer.AreEquivalent(expression, nullCheck.Expression));
        }
예제 #9
0
        public void GetSequenceEdits4()
        {
            var edits = SyntaxComparer.GetSequenceEdits(
                ImmutableArray.Create(
                    SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                    SyntaxFactory.Token(SyntaxKind.StaticKeyword),
                    SyntaxFactory.Token(SyntaxKind.AsyncKeyword)
                    ),
                ImmutableArray.Create(
                    SyntaxFactory.Token(SyntaxKind.StaticKeyword),
                    SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                    SyntaxFactory.Token(SyntaxKind.AsyncKeyword)
                    )
                );

            AssertEx.Equal(
                new[]
            {
                new SequenceEdit(2, 2),
                new SequenceEdit(1, -1),
                new SequenceEdit(0, 1),
                new SequenceEdit(-1, 0),
            },
                edits,
                itemInspector: e => e.GetTestAccessor().GetDebuggerDisplay()
                );
        }
예제 #10
0
        internal static ExpressionSyntax FindExpressionThatCanBeConditionallyAccessed(ExpressionSyntax expressionToFind, ExpressionSyntax expression)
        {
            if (expression.IsKind(SyntaxKind.LogicalNotExpression))
            {
                expression = ((PrefixUnaryExpressionSyntax)expression).Operand;
            }

            SyntaxKind kind = expressionToFind.Kind();

            SyntaxToken firstToken = expression.GetFirstToken();

            int start = firstToken.SpanStart;

            SyntaxNode node = firstToken.Parent;

            while (node?.SpanStart == start)
            {
                if (kind == node.Kind() &&
                    node.IsParentKind(SyntaxKind.SimpleMemberAccessExpression, SyntaxKind.ElementAccessExpression) &&
                    SyntaxComparer.AreEquivalent(expressionToFind, node))
                {
                    return((ExpressionSyntax)node);
                }

                node = node.Parent;
            }

            return(null);
        }
예제 #11
0
        public void ComputeDistance3()
        {
            var distance = SyntaxComparer.ComputeDistance(
                new[] { SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword), SyntaxFactory.Token(SyntaxKind.AsyncKeyword) },
                new[] { SyntaxFactory.Token(SyntaxKind.StaticKeyword), SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.AsyncKeyword) });

            Assert.Equal(0.33, Math.Round(distance, 2));
        }
예제 #12
0
        public void ComputeDistance1()
        {
            var distance = SyntaxComparer.ComputeDistance(
                new[] { MakeLiteral(0), MakeLiteral(1), MakeLiteral(2) },
                new[] { MakeLiteral(1), MakeLiteral(3) });

            Assert.Equal(0.67, Math.Round(distance, 2));
        }
예제 #13
0
        public void ComputeDistance2()
        {
            var distance = SyntaxComparer.ComputeDistance(
                ImmutableArray.Create(MakeLiteral(0), MakeLiteral(1), MakeLiteral(2)),
                ImmutableArray.Create(MakeLiteral(1), MakeLiteral(3)));

            Assert.Equal(0.67, Math.Round(distance, 2));
        }
예제 #14
0
        public void ComputeDistance4()
        {
            var distance = SyntaxComparer.ComputeDistance(
                ImmutableArray.Create(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword), SyntaxFactory.Token(SyntaxKind.AsyncKeyword)),
                ImmutableArray.Create(SyntaxFactory.Token(SyntaxKind.StaticKeyword), SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.AsyncKeyword)));

            Assert.Equal(0.33, Math.Round(distance, 2));
        }
예제 #15
0
        public void ComputeDistance_Token()
        {
            var distance = SyntaxComparer.ComputeDistance(
                SyntaxFactory.Literal("abc", "abc"),
                SyntaxFactory.Literal("acb", "acb")
                );

            Assert.Equal(0.33, Math.Round(distance, 2));
        }
예제 #16
0
        public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context)
        {
            var ifStatement = (IfStatementSyntax)context.Node;

            if (ifStatement.IsSimpleIf() &&
                !ifStatement.ContainsDiagnostics)
            {
                SyntaxList <StatementSyntax> statements;
                if (ifStatement.TryGetContainingList(out statements) &&
                    !IsPartOfLazyInitialization(ifStatement, statements))
                {
                    EqualsToNullExpression equalsToNull;
                    if (EqualsToNullExpression.TryCreate(ifStatement.Condition, out equalsToNull))
                    {
                        SimpleAssignmentStatement assignment;
                        if (SimpleAssignmentStatement.TryCreate(ifStatement.GetSingleStatementOrDefault(), out assignment) &&
                            SyntaxComparer.AreEquivalent(assignment.Left, equalsToNull.Left) &&
                            assignment.Right.IsSingleLine() &&
                            !ifStatement.SpanContainsDirectives())
                        {
                            int index = statements.IndexOf(ifStatement);

                            if (index > 0)
                            {
                                StatementSyntax previousStatement = statements[index - 1];

                                if (!previousStatement.ContainsDiagnostics &&
                                    CanRefactor(previousStatement, ifStatement, equalsToNull.Left, ifStatement.Parent))
                                {
                                    context.ReportDiagnostic(DiagnosticDescriptors.UseCoalesceExpression, previousStatement);
                                }
                            }

                            if (index < statements.Count - 1)
                            {
                                StatementSyntax nextStatement = statements[index + 1];

                                if (!nextStatement.ContainsDiagnostics)
                                {
                                    MemberInvocationStatement memberInvocation;
                                    if (MemberInvocationStatement.TryCreate(nextStatement, out memberInvocation) &&
                                        SyntaxComparer.AreEquivalent(equalsToNull.Left, memberInvocation.Expression) &&
                                        !ifStatement.Parent.ContainsDirectives(TextSpan.FromBounds(ifStatement.SpanStart, nextStatement.Span.End)))
                                    {
                                        context.ReportDiagnostic(DiagnosticDescriptors.InlineLazyInitialization, ifStatement);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #17
0
        private static bool CanRefactor(
            BinaryExpressionSyntax left,
            BinaryExpressionSyntax right,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (left.Right.IsKind(SyntaxKind.NullLiteralExpression))
            {
                ExpressionSyntax rightLeft = right.Left;

                ExpressionSyntax expression = left.Left;

                if (SyntaxComparer.AreEquivalent(expression, rightLeft))
                {
                    if (right.IsKind(SyntaxKind.EqualsExpression, SyntaxKind.NotEqualsExpression) &&
                        SymbolEquals(expression, rightLeft, semanticModel, cancellationToken) &&
                        CSharpUtility.IsEmptyString(right.Right, semanticModel, cancellationToken))
                    {
                        return(true);
                    }
                }
                else if (rightLeft.IsKind(SyntaxKind.SimpleMemberAccessExpression))
                {
                    var memberAccess = (MemberAccessExpressionSyntax)rightLeft;

                    if (string.Equals(memberAccess.Name.Identifier.ValueText, "Length", StringComparison.Ordinal) &&
                        right.Right.IsNumericLiteralExpression("0"))
                    {
                        ISymbol symbol = semanticModel.GetSymbol(memberAccess, cancellationToken);

                        if (symbol?.IsProperty() == true)
                        {
                            var propertySymbol = (IPropertySymbol)symbol;
                            if (!propertySymbol.IsIndexer &&
                                propertySymbol.IsPublic() &&
                                !propertySymbol.IsStatic &&
                                propertySymbol.Type.IsInt() &&
                                propertySymbol.ContainingType?.IsString() == true &&
                                string.Equals(propertySymbol.Name, "Length", StringComparison.Ordinal) &&
                                SyntaxComparer.AreEquivalent(expression, memberAccess.Expression) &&
                                SymbolEquals(expression, memberAccess.Expression, semanticModel, cancellationToken))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
예제 #18
0
        public void GetSequenceEdits2()
        {
            var edits = SyntaxComparer.GetSequenceEdits(
                ImmutableArray.Create(MakeLiteral(0), MakeLiteral(1), MakeLiteral(2)),
                ImmutableArray.Create(MakeLiteral(1), MakeLiteral(3)));

            AssertEx.Equal(new[]
            {
                new SequenceEdit(2, -1),
                new SequenceEdit(-1, 1),
                new SequenceEdit(1, 0),
                new SequenceEdit(0, -1),
            }, edits, itemInspector: e => e.GetTestAccessor().GetDebuggerDisplay());
        }
예제 #19
0
        public void GetSequenceEdits3()
        {
            var edits = SyntaxComparer.GetSequenceEdits(
                new[] { SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword), SyntaxFactory.Token(SyntaxKind.AsyncKeyword) },
                new[] { SyntaxFactory.Token(SyntaxKind.StaticKeyword), SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.AsyncKeyword) });

            AssertEx.Equal(new[]
            {
                new SequenceEdit(2, 2),
                new SequenceEdit(1, -1),
                new SequenceEdit(0, 1),
                new SequenceEdit(-1, 0),
            }, edits, itemInspector: e => e.GetDebuggerDisplay());
        }
        public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context)
        {
            var ifStatement = (IfStatementSyntax)context.Node;

            if (ifStatement.IsSimpleIf() &&
                !ifStatement.ContainsDiagnostics &&
                ifStatement.TryGetContainingList(out SyntaxList <StatementSyntax> statements) &&
                !IsPartOfLazyInitialization(ifStatement, statements))
            {
                NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, semanticModel: context.SemanticModel, cancellationToken: context.CancellationToken);
                if (nullCheck.Success)
                {
                    SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.GetSingleStatementOrDefault());
                    if (assignmentInfo.Success &&
                        SyntaxComparer.AreEquivalent(assignmentInfo.Left, nullCheck.Expression) &&
                        assignmentInfo.Right.IsSingleLine() &&
                        !ifStatement.SpanContainsDirectives())
                    {
                        int index = statements.IndexOf(ifStatement);

                        if (index > 0)
                        {
                            StatementSyntax previousStatement = statements[index - 1];

                            if (!previousStatement.ContainsDiagnostics &&
                                CanRefactor(previousStatement, ifStatement, nullCheck.Expression, ifStatement.Parent))
                            {
                                context.ReportDiagnostic(DiagnosticDescriptors.UseCoalesceExpression, previousStatement);
                            }
                        }

                        if (index < statements.Count - 1)
                        {
                            StatementSyntax nextStatement = statements[index + 1];

                            if (!nextStatement.ContainsDiagnostics)
                            {
                                MemberInvocationStatementInfo invocationInfo = SyntaxInfo.MemberInvocationStatementInfo(nextStatement);
                                if (invocationInfo.Success &&
                                    SyntaxComparer.AreEquivalent(nullCheck.Expression, invocationInfo.Expression) &&
                                    !ifStatement.Parent.ContainsDirectives(TextSpan.FromBounds(ifStatement.SpanStart, nextStatement.Span.End)))
                                {
                                    context.ReportDiagnostic(DiagnosticDescriptors.InlineLazyInitialization, ifStatement);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #21
0
        public void GetSequenceEdits1()
        {
            var edits = SyntaxComparer.GetSequenceEdits(
                new[] { MakeLiteral(0), MakeLiteral(1), MakeLiteral(2) },
                new[] { MakeLiteral(1), MakeLiteral(3) });

            AssertEx.Equal(new[]
            {
                new SequenceEdit(2, -1),
                new SequenceEdit(-1, 1),
                new SequenceEdit(1, 0),
                new SequenceEdit(0, -1),
            }, edits, itemInspector: e => e.GetTestAccessor().GetDebuggerDisplay());
        }
 private static void Analyze(
     SyntaxNodeAnalysisContext context,
     BinaryExpressionSyntax logicalAnd,
     ExpressionSyntax expression1,
     ExpressionSyntax expression2)
 {
     if (IsPropertyOfNullableOfT(expression2, "Value", context.SemanticModel, context.CancellationToken) &&
         SyntaxComparer.AreEquivalent(
             ((MemberAccessExpressionSyntax)expression1).Expression,
             ((MemberAccessExpressionSyntax)expression2).Expression,
             requireNotNull: true))
     {
         context.ReportDiagnostic(DiagnosticDescriptors.SimplifyBooleanExpression, logicalAnd);
     }
 }
예제 #23
0
        public static bool CanRefactor(
            IfStatementSyntax ifStatement,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (ifStatement.IsTopmostIf())
            {
                ElseClauseSyntax elseClause = ifStatement.Else;

                if (elseClause != null)
                {
                    ExpressionSyntax condition = ifStatement.Condition;

                    if (condition != null)
                    {
                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(condition, cancellationToken);

                        if (typeSymbol?.IsBoolean() == true)
                        {
                            AssignmentExpressionSyntax trueExpression = GetSimpleAssignmentExpression(ifStatement.GetSingleStatementOrDefault());

                            ExpressionSyntax trueRight = trueExpression?.Right;

                            if (trueRight?.Kind().IsBooleanLiteralExpression() == true)
                            {
                                AssignmentExpressionSyntax falseExpression = GetSimpleAssignmentExpression(elseClause.GetSingleStatementOrDefault());

                                ExpressionSyntax falseRight = falseExpression?.Right;

                                if (falseRight?.Kind().IsBooleanLiteralExpression() == true)
                                {
                                    var trueBooleanLiteral  = (LiteralExpressionSyntax)trueRight;
                                    var falseBooleanLiteral = (LiteralExpressionSyntax)falseRight;

                                    if (trueBooleanLiteral.IsKind(SyntaxKind.TrueLiteralExpression) != falseBooleanLiteral.IsKind(SyntaxKind.TrueLiteralExpression) &&
                                        SyntaxComparer.AreEquivalent(trueExpression.Left, falseExpression.Left, requireNotNull: true))
                                    {
                                        return(true);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
        private static bool AreStatementsEquivalent(List <StatementSyntax> first, List <StatementSyntax> second)
        {
            if (first.Count == second.Count)
            {
                for (int i = 0; i < first.Count; i++)
                {
                    if (!SyntaxComparer.AreEquivalent(first[i], second[i]))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            return(false);
        }
예제 #25
0
        private static bool NullCheckExists(ExpressionSyntax expression, StatementSyntax statement)
        {
            if (!statement.IsEmbedded())
            {
                StatementContainer container;
                if (StatementContainer.TryCreate(statement, out container))
                {
                    SyntaxList <StatementSyntax> statements = container.Statements;

                    int index = statements.IndexOf(statement);

                    if (index < statements.Count - 1)
                    {
                        StatementSyntax nextStatement = statements[index + 1];

                        if (nextStatement.IsKind(SyntaxKind.IfStatement))
                        {
                            var ifStatement = (IfStatementSyntax)nextStatement;

                            ExpressionSyntax condition = ifStatement.Condition;

                            if (condition?.IsKind(SyntaxKind.NotEqualsExpression) == true)
                            {
                                var notEqualsExpression = (BinaryExpressionSyntax)condition;

                                ExpressionSyntax left = notEqualsExpression.Left;

                                if (SyntaxComparer.AreEquivalent(left, expression, requireNotNull: true))
                                {
                                    ExpressionSyntax right = notEqualsExpression.Right;

                                    if (right?.IsKind(SyntaxKind.NullLiteralExpression) == true)
                                    {
                                        return(true);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
예제 #26
0
        public void ComputeDistance_Null()
        {
            double distance = SyntaxComparer.ComputeDistance(
                default(ImmutableArray <SyntaxToken>),
                ImmutableArray.Create(SyntaxFactory.Token(SyntaxKind.StaticKeyword)));

            Assert.Equal(1, Math.Round(distance, 2));

            distance = SyntaxComparer.ComputeDistance(
                default(ImmutableArray <SyntaxNode>),
                ImmutableArray.Create(MakeLiteral(0)));

            Assert.Equal(1, Math.Round(distance, 2));

            distance = SyntaxComparer.ComputeDistance(
                null,
                new SyntaxNode[0] {
            });

            Assert.Equal(0, Math.Round(distance, 2));

            distance = SyntaxComparer.ComputeDistance(
                new SyntaxNode[0] {
            },
                null);

            Assert.Equal(0, Math.Round(distance, 2));

            distance = SyntaxComparer.ComputeDistance(
                null,
                new SyntaxToken[0] {
            });

            Assert.Equal(0, Math.Round(distance, 2));

            distance = SyntaxComparer.ComputeDistance(
                new SyntaxToken[0] {
            },
                null);

            Assert.Equal(0, Math.Round(distance, 2));
        }
예제 #27
0
        public static void AnalyzeSimpleAssignmentExpression(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            var assignment = (AssignmentExpressionSyntax)context.Node;

            if (!assignment.IsParentKind(SyntaxKind.ObjectInitializerExpression))
            {
                ExpressionSyntax left  = assignment.Left;
                ExpressionSyntax right = assignment.Right;

                if (left?.IsMissing == false &&
                    right?.IsKind(SyntaxKind.AddExpression, SyntaxKind.SubtractExpression) == true)
                {
                    var binaryExpression = (BinaryExpressionSyntax)right;

                    ExpressionSyntax binaryLeft  = binaryExpression.Left;
                    ExpressionSyntax binaryRight = binaryExpression.Right;

                    if (binaryLeft?.IsMissing == false &&
                        binaryRight?.IsNumericLiteralExpression("1") == true)
                    {
                        ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(left, context.CancellationToken);

                        if (typeSymbol?.SupportsPrefixOrPostfixUnaryOperator() == true &&
                            SyntaxComparer.AreEquivalent(left, binaryLeft))
                        {
                            string operatorText = GetOperatorText(assignment);

                            ReportDiagnostic(context, assignment, operatorText);

                            context.ReportToken(DiagnosticDescriptors.UsePostfixUnaryOperatorInsteadOfAssignmentFadeOut, assignment.OperatorToken, operatorText);
                            context.ReportNode(DiagnosticDescriptors.UsePostfixUnaryOperatorInsteadOfAssignmentFadeOut, binaryLeft, operatorText);
                            context.ReportNode(DiagnosticDescriptors.UsePostfixUnaryOperatorInsteadOfAssignmentFadeOut, binaryRight, operatorText);
                        }
                    }
                }
            }
        }
        public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context, INamedTypeSymbol expressionType)
        {
            var ifStatement = (IfStatementSyntax)context.Node;

            if (ifStatement.IsSimpleIf() &&
                !ifStatement.ContainsDiagnostics)
            {
                NotEqualsToNullExpression notEqualsToNull;
                if (NotEqualsToNullExpression.TryCreate(ifStatement.Condition, out notEqualsToNull))
                {
                    MemberInvocationStatement memberInvocation;
                    if (MemberInvocationStatement.TryCreate(ifStatement.GetSingleStatementOrDefault(), out memberInvocation) &&
                        SyntaxComparer.AreEquivalent(notEqualsToNull.Left, memberInvocation.Expression) &&
                        !ifStatement.IsInExpressionTree(expressionType, context.SemanticModel, context.CancellationToken) &&
                        !ifStatement.SpanContainsDirectives())
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.UseConditionalAccess, ifStatement);
                    }
                }
            }
        }
예제 #29
0
        public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context, INamedTypeSymbol expressionType)
        {
            var ifStatement = (IfStatementSyntax)context.Node;

            if (ifStatement.IsSimpleIf() &&
                !ifStatement.ContainsDiagnostics)
            {
                NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, allowedKinds: NullCheckKind.NotEqualsToNull);
                if (nullCheck.Success)
                {
                    MemberInvocationStatementInfo invocationInfo = SyntaxInfo.MemberInvocationStatementInfo(ifStatement.GetSingleStatementOrDefault());
                    if (invocationInfo.Success &&
                        SyntaxComparer.AreEquivalent(nullCheck.Expression, invocationInfo.Expression) &&
                        !ifStatement.IsInExpressionTree(expressionType, context.SemanticModel, context.CancellationToken) &&
                        !ifStatement.SpanContainsDirectives())
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.UseConditionalAccess, ifStatement);
                    }
                }
            }
        }
예제 #30
0
        public static void ComputeRefactorings(RefactoringContext context, StatementContainerSelection selectedStatements)
        {
            using (IEnumerator <StatementSyntax> en = selectedStatements.GetEnumerator())
            {
                if (en.MoveNext() &&
                    en.Current.IsKind(SyntaxKind.ExpressionStatement))
                {
                    var statement = (ExpressionStatementSyntax)en.Current;

                    if (statement.Expression?.IsKind(SyntaxKind.SimpleAssignmentExpression) == true &&
                        en.MoveNext() &&
                        en.Current.IsKind(SyntaxKind.ReturnStatement))
                    {
                        var returnStatement = (ReturnStatementSyntax)en.Current;

                        if (returnStatement.Expression != null &&
                            !en.MoveNext())
                        {
                            var assignment = (AssignmentExpressionSyntax)statement.Expression;

                            if (assignment.Left?.IsMissing == false &&
                                assignment.Right?.IsMissing == false &&
                                SyntaxComparer.AreEquivalent(assignment.Left, returnStatement.Expression))
                            {
                                context.RegisterRefactoring(
                                    "Merge statements",
                                    cancellationToken =>
                                {
                                    return(RefactorAsync(
                                               context.Document,
                                               statement,
                                               returnStatement,
                                               cancellationToken));
                                });
                            }
                        }
                    }
                }
            }
        }