コード例 #1
0
        private static bool CanRefactor(
            SimpleAssignmentStatementInfo assignmentInfo,
            ExpressionSyntax expression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (!assignmentInfo.Success)
            {
                return(false);
            }

            if (assignmentInfo.Right.IsKind(SyntaxKind.NullLiteralExpression, SyntaxKind.DefaultExpression))
            {
                return(false);
            }

            if (CannotBeEqualToNull(assignmentInfo.Right))
            {
                return(false);
            }

            if (NullCheckExists(expression, assignmentInfo.Statement))
            {
                return(false);
            }

            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken);

            if (typeSymbol == null)
            {
                return(false);
            }

            return(typeSymbol.IsReferenceTypeOrNullableType());
        }
コード例 #2
0
        public static bool IsValidAssignmentStatement(
            StatementSyntax statement,
            ISymbol symbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            SimpleAssignmentStatementInfo simpleAssignment = SyntaxInfo.SimpleAssignmentStatementInfo(statement);

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

            ExpressionSyntax left = simpleAssignment.Left;

            if (left.Kind() != SyntaxKind.SimpleMemberAccessExpression)
            {
                return(false);
            }

            var memberAccess = (MemberAccessExpressionSyntax)left;

            ISymbol expressionSymbol = semanticModel.GetSymbol(memberAccess.Expression, cancellationToken);

            if (!symbol.Equals(expressionSymbol))
            {
                return(false);
            }

            return(semanticModel.GetSymbol(left, cancellationToken)?.Kind == SymbolKind.Property);
        }
コード例 #3
0
        private static bool IsSymbolAssignedInStatement(ISymbol symbol, StatementSyntax statement, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(statement);

            return(assignmentInfo.Success &&
                   symbol.Equals(semanticModel.GetSymbol(assignmentInfo.Left, cancellationToken)));
        }
コード例 #4
0
        public static void ComputeRefactorings(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count != 2)
            {
                return;
            }

            SimpleAssignmentStatementInfo simpleAssignment = SyntaxInfo.SimpleAssignmentStatementInfo(selectedStatements.First());

            if (!simpleAssignment.Success)
            {
                return;
            }

            if (!(selectedStatements.Last() is ReturnStatementSyntax returnStatement))
            {
                return;
            }

            if (returnStatement.Expression == null)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(simpleAssignment.Left, returnStatement.Expression))
            {
                return;
            }

            context.RegisterRefactoring(
                "Merge statements",
                ct => RefactorAsync(context.Document, simpleAssignment.Statement, returnStatement, ct),
                RefactoringIdentifiers.MergeAssignmentExpressionWithReturnStatement);
        }
コード例 #5
0
ファイル: IfRefactoring.cs プロジェクト: szKarlen/Roslynator
        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();
        }
コード例 #6
0
        public static void ComputeRefactorings(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count != 2)
            {
                return;
            }

            SimpleAssignmentStatementInfo simpleAssignment = SyntaxInfo.SimpleAssignmentStatementInfo(selectedStatements.First());

            if (!simpleAssignment.Success)
            {
                return;
            }

            if (selectedStatements.Last() is not ReturnStatementSyntax returnStatement)
            {
                return;
            }

            if (returnStatement.Expression == null)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(simpleAssignment.Left, returnStatement.Expression))
            {
                return;
            }

            context.RegisterRefactoring(
                "Remove unnecessary assignment",
                ct => RefactorAsync(context.Document, simpleAssignment.Statement, returnStatement, ct),
                RefactoringDescriptors.RemoveUnnecessaryAssignment);
        }
コード例 #7
0
        private static bool CanUseCoalesceExpression(StatementSyntax statement, ExpressionSyntax expression)
        {
            SyntaxKind kind = statement.Kind();

            if (kind == SyntaxKind.LocalDeclarationStatement)
            {
                SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)statement);

                return(localInfo.Success &&
                       !localInfo.Type.IsKind(SyntaxKind.RefType) &&
                       expression.IsKind(SyntaxKind.IdentifierName) &&
                       string.Equals(localInfo.IdentifierText, ((IdentifierNameSyntax)expression).Identifier.ValueText, StringComparison.Ordinal) &&
                       !localInfo.Value.GetTrailingTrivia().Any(f => f.IsDirective) &&
                       !localInfo.SemicolonToken.ContainsDirectives);
            }
            else if (kind == SyntaxKind.ExpressionStatement)
            {
                var expressionStatement = (ExpressionStatementSyntax)statement;

                SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement);

                return(assignmentInfo.Success &&
                       CSharpFactory.AreEquivalent(expression, assignmentInfo.Left) &&
                       !assignmentInfo.Right.GetTrailingTrivia().Any(f => f.IsDirective) &&
                       !expressionStatement.SemicolonToken.ContainsDirectives);
            }

            return(false);
        }
コード例 #8
0
        private static bool CanUseCoalesceExpression(StatementSyntax statement, ExpressionSyntax expression)
        {
            SyntaxKind kind = statement.Kind();

            if (kind == SyntaxKind.LocalDeclarationStatement)
            {
                var localDeclarationStatement = (LocalDeclarationStatementSyntax)statement;

                VariableDeclaratorSyntax declarator = localDeclarationStatement.Declaration?
                                                      .Variables
                                                      .SingleOrDefault(shouldThrow: false);

                ExpressionSyntax value = declarator?.Initializer?.Value;

                return(value != null &&
                       expression.IsKind(SyntaxKind.IdentifierName) &&
                       string.Equals(declarator.Identifier.ValueText, ((IdentifierNameSyntax)expression).Identifier.ValueText, StringComparison.Ordinal) &&
                       !value.GetTrailingTrivia().Any(f => f.IsDirective) &&
                       !localDeclarationStatement.SemicolonToken.ContainsDirectives);
            }
            else if (kind == SyntaxKind.ExpressionStatement)
            {
                var expressionStatement = (ExpressionStatementSyntax)statement;

                SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement);

                return(assignmentInfo.Success &&
                       CSharpFactory.AreEquivalent(expression, assignmentInfo.Left) &&
                       !assignmentInfo.Right.GetTrailingTrivia().Any(f => f.IsDirective) &&
                       !expressionStatement.SemicolonToken.ContainsDirectives);
            }

            return(false);
        }
コード例 #9
0
ファイル: IfAnalysis.cs プロジェクト: peteri/Roslynator
        private static ImmutableArray <IfAnalysis> Analyze(
            ExpressionStatementSyntax expressionStatement,
            IfStatementSyntax ifStatement,
            IfAnalysisOptions options,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            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.SingleNonBlockStatementOrDefault());

            if (!assignment1.Success)
            {
                return(Empty);
            }

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

            if (!assignment2.Success)
            {
                return(Empty);
            }

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

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

            if (IsNullLiteralConvertedToNullableOfT(assignment1.Right, semanticModel, cancellationToken) ||
                IsNullLiteralConvertedToNullableOfT(assignment2.Right, semanticModel, cancellationToken))
            {
                return(Empty);
            }

            return(new AssignmentAndIfElseToAssignmentWithConditionalExpressionAnalysis(expressionStatement, assignment.Right, ifStatement, assignment1.Right, assignment2.Right, semanticModel).ToImmutableArray());
        }
コード例 #10
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, InitializerExpressionSyntax initializer)
        {
            if (!initializer.IsKind(
                    SyntaxKind.ObjectInitializerExpression,
                    SyntaxKind.CollectionInitializerExpression))
            {
                return;
            }

            if (!initializer.Expressions.Any())
            {
                return;
            }

            SyntaxNode parent = initializer.Parent;

            if (parent?.Kind() != SyntaxKind.ObjectCreationExpression)
            {
                return;
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            if (!CanExpand(initializer, semanticModel, context.CancellationToken))
            {
                return;
            }

            if (parent.IsParentKind(SyntaxKind.SimpleAssignmentExpression))
            {
                SimpleAssignmentStatementInfo simpleAssignment = SyntaxInfo.SimpleAssignmentStatementInfo((AssignmentExpressionSyntax)parent.Parent);

                if (simpleAssignment.Success)
                {
                    RegisterRefactoring(context, simpleAssignment.Statement, initializer, simpleAssignment.Left);
                }
            }
            else
            {
                LocalDeclarationStatementInfo localInfo = SyntaxInfo.LocalDeclarationStatementInfo((ExpressionSyntax)parent);

                if (localInfo.Success)
                {
                    var declarator = (VariableDeclaratorSyntax)parent.Parent.Parent;

                    RegisterRefactoring(
                        context,
                        localInfo.Statement,
                        initializer,
                        IdentifierName(declarator.Identifier.ValueText));
                }
            }
        }
コード例 #11
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, ExpressionSyntax expression)
        {
            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(expression.Parent.Parent);

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            if (!CanRefactor(assignmentInfo, expression, semanticModel, context.CancellationToken))
            {
                return;
            }

            RegisterRefactoring(context, expression, assignmentInfo.Statement);
        }
コード例 #12
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #13
0
ファイル: IfRefactoring.cs プロジェクト: szKarlen/Roslynator
        private static ImmutableArray<IfRefactoring> Analyze(
            LocalDeclarationStatementSyntax localDeclarationStatement,
            IfStatementSyntax ifStatement,
            IfAnalysisOptions options)
        {
            VariableDeclaratorSyntax declarator = localDeclarationStatement
                .Declaration?
                .Variables
                .SingleOrDefault(shouldthrow: false);

            if (declarator == null)
                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 (!assignment1.Left.IsKind(SyntaxKind.IdentifierName))
                return Empty;

            if (!assignment2.Left.IsKind(SyntaxKind.IdentifierName))
                return Empty;

            string identifier1 = ((IdentifierNameSyntax)assignment1.Left).Identifier.ValueText;
            string identifier2 = ((IdentifierNameSyntax)assignment2.Left).Identifier.ValueText;

            if (!string.Equals(identifier1, identifier2, StringComparison.Ordinal))
                return Empty;

            if (!string.Equals(identifier1, declarator.Identifier.ValueText, StringComparison.Ordinal))
                return Empty;

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

            return new LocalDeclarationAndIfElseAssignmentWithConditionalExpression(localDeclarationStatement, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray();
        }
コード例 #14
0
        internal static async Task ComputeRefactoringAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count <= 1)
            {
                return;
            }

            StatementSyntax statement = selectedStatements.First();

            SyntaxKind kind = statement.Kind();

            if (kind == SyntaxKind.LocalDeclarationStatement)
            {
                var localDeclaration = (LocalDeclarationStatementSyntax)statement;

                SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration);

                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                if (!CanRefactor(localInfo, semanticModel, context.CancellationToken))
                {
                    return;
                }

                RegisterRefactoring(context, IdentifierName(localInfo.Identifier), localDeclaration, selectedStatements.Count - 1);
            }
            else if (kind == SyntaxKind.ExpressionStatement)
            {
                var expressionStatement = (ExpressionStatementSyntax)statement;

                SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement);

                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                if (!CanRefactor(assignmentInfo, assignmentInfo.Left, semanticModel, context.CancellationToken))
                {
                    return;
                }

                RegisterRefactoring(context, assignmentInfo.Left, expressionStatement, selectedStatements.Count - 1);
            }
        }
コード例 #15
0
        public static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(ifStatement);

            StatementSyntax expressionStatement = (ExpressionStatementSyntax)statements[index + 1];

            SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo((ExpressionStatementSyntax)expressionStatement);

            ExpressionSyntax expression = invocationInfo.Expression;

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo((ExpressionStatementSyntax)ifStatement.SingleNonBlockStatementOrDefault());

            BinaryExpressionSyntax coalesceExpression = CSharpFactory.CoalesceExpression(expression.WithoutTrivia(), ParenthesizedExpression(assignmentInfo.AssignmentExpression));

            ParenthesizedExpressionSyntax newExpression = ParenthesizedExpression(coalesceExpression)
                                                          .WithTriviaFrom(expression);

            StatementSyntax newExpressionStatement = expressionStatement.ReplaceNode(expression, newExpression);

            IEnumerable <SyntaxTrivia> trivia = statementsInfo.Parent.DescendantTrivia(TextSpan.FromBounds(ifStatement.FullSpan.Start, expressionStatement.FullSpan.Start));

            if (trivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia()))
            {
                newExpressionStatement = newExpressionStatement.PrependToLeadingTrivia(trivia);
            }

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .Replace(expressionStatement, newExpressionStatement)
                                                         .RemoveAt(index);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
コード例 #16
0
        private static ImmutableArray <IfRefactoring> Analyze(
            IfStatementSyntax ifStatement,
            ExpressionSyntax condition,
            ExpressionStatementSyntax expressionStatement1,
            ExpressionStatementSyntax expressionStatement2,
            IfAnalysisOptions options,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            SimpleAssignmentStatementInfo assignment1 = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement1);

            if (!assignment1.Success)
            {
                return(Empty);
            }

            SimpleAssignmentStatementInfo assignment2 = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement2);

            if (!assignment2.Success)
            {
                return(Empty);
            }

            ExpressionSyntax left1  = assignment1.Left;
            ExpressionSyntax left2  = assignment2.Left;
            ExpressionSyntax right1 = assignment1.Right;
            ExpressionSyntax right2 = assignment2.Right;

            if (!SyntaxComparer.AreEquivalent(left1, left2))
            {
                return(Empty);
            }

            if (options.UseCoalesceExpression ||
                options.UseExpression)
            {
                SyntaxKind kind1 = right1.Kind();
                SyntaxKind kind2 = right2.Kind();

                if (kind1.IsBooleanLiteralExpression() &&
                    kind2.IsBooleanLiteralExpression() &&
                    kind1 != kind2)
                {
                    if (options.UseExpression)
                    {
                        return(new IfElseToAssignmentWithCondition(ifStatement, left1, condition, negate: kind1 == SyntaxKind.FalseLiteralExpression).ToImmutableArray());
                    }

                    return(Empty);
                }

                NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(condition, semanticModel: semanticModel, cancellationToken: cancellationToken);

                if (nullCheck.Success)
                {
                    IfRefactoring refactoring = CreateIfToAssignment(
                        ifStatement,
                        left1,
                        (nullCheck.IsCheckingNull) ? right2 : right1,
                        (nullCheck.IsCheckingNull) ? right1 : right2,
                        nullCheck,
                        options,
                        semanticModel,
                        cancellationToken);

                    if (refactoring != null)
                    {
                        return(refactoring.ToImmutableArray());
                    }
                }
            }

            if (options.UseConditionalExpression)
            {
                return(new IfElseToAssignmentWithConditionalExpression(ifStatement, left1, right1, right2).ToImmutableArray());
            }

            return(Empty);
        }
コード例 #17
0
        private static void AnalyzeLocalDeclarationStatement(SyntaxNodeAnalysisContext context)
        {
            var localDeclaration = (LocalDeclarationStatementSyntax)context.Node;

            if (localDeclaration.ContainsDiagnostics)
            {
                return;
            }

            if (localDeclaration.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            if (localDeclaration.IsConst)
            {
                return;
            }

            SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration);

            if (!localInfo.Success)
            {
                return;
            }

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(localDeclaration.NextStatement());

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (assignmentInfo.Statement.ContainsDiagnostics)
            {
                return;
            }

            if (assignmentInfo.Statement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            if (assignmentInfo.Left is not IdentifierNameSyntax identifierName)
            {
                return;
            }

            string name = identifierName.Identifier.ValueText;

            if (!string.Equals(localInfo.IdentifierText, name, StringComparison.Ordinal))
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            if (semanticModel.GetSymbol(identifierName, cancellationToken) is not ILocalSymbol localSymbol)
            {
                return;
            }

            if (!SymbolEqualityComparer.Default.Equals(localSymbol, semanticModel.GetDeclaredSymbol(localInfo.Declarator, cancellationToken)))
            {
                return;
            }

            ExpressionSyntax value = localInfo.Value;

            if (value != null)
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(localInfo.Type, cancellationToken);

                if (typeSymbol == null)
                {
                    return;
                }

                if (!semanticModel.IsDefaultValue(typeSymbol, value, cancellationToken))
                {
                    return;
                }

                if (IsReferenced(localSymbol, assignmentInfo.Right, semanticModel, cancellationToken))
                {
                    return;
                }
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.RemoveRedundantAssignment, localInfo.Identifier);

            if (value != null)
            {
                DiagnosticHelpers.ReportNode(context, DiagnosticRules.RemoveRedundantAssignmentFadeOut, localInfo.Initializer);
                DiagnosticHelpers.ReportToken(context, DiagnosticRules.RemoveRedundantAssignmentFadeOut, assignmentInfo.OperatorToken);
            }

            DiagnosticHelpers.ReportToken(context, DiagnosticRules.RemoveRedundantAssignmentFadeOut, localDeclaration.SemicolonToken);
            DiagnosticHelpers.ReportNode(context, DiagnosticRules.RemoveRedundantAssignmentFadeOut, assignmentInfo.Left);
        }
コード例 #18
0
        private static void AnalyzeSimpleAssignment(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            var assignment = (AssignmentExpressionSyntax)context.Node;

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(assignment);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (assignmentInfo.Left is not IdentifierNameSyntax identifierName)
            {
                return;
            }

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(assignmentInfo.Statement);

            if (!statementsInfo.Success)
            {
                return;
            }

            int index = statementsInfo.IndexOf(assignmentInfo.Statement);

            if (index == statementsInfo.Count - 1)
            {
                return;
            }

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

                SimpleAssignmentStatementInfo assignmentInfo2 = SyntaxInfo.SimpleAssignmentStatementInfo(previousStatement);

                if (assignmentInfo2.Success &&
                    assignmentInfo2.Left is IdentifierNameSyntax identifierName2 &&
                    string.Equals(identifierName.Identifier.ValueText, identifierName2.Identifier.ValueText, StringComparison.Ordinal))
                {
                    return;
                }
            }

            StatementSyntax nextStatement = statementsInfo[index + 1];

            if (nextStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            if (nextStatement is not ReturnStatementSyntax returnStatement)
            {
                return;
            }

            if (returnStatement.Expression?.WalkDownParentheses() is not IdentifierNameSyntax identifierName3)
            {
                return;
            }

            if (!string.Equals(identifierName.Identifier.ValueText, identifierName3.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            ISymbol symbol = context.SemanticModel.GetSymbol(identifierName, context.CancellationToken);

            switch (symbol?.Kind)
            {
            case SymbolKind.Local:
            {
                break;
            }

            case SymbolKind.Parameter:
            {
                if (((IParameterSymbol)symbol).RefKind != RefKind.None)
                {
                    return;
                }

                break;
            }

            default:
            {
                return;
            }
            }

            if (IsAssignedInsideAnonymousFunctionButDeclaredOutsideOfIt())
            {
                return;
            }

            bool result;
            RemoveRedundantAssignmentWalker walker = null;

            try
            {
                walker = RemoveRedundantAssignmentWalker.GetInstance();

                walker.Symbol            = symbol;
                walker.SemanticModel     = context.SemanticModel;
                walker.CancellationToken = context.CancellationToken;
                walker.Result            = false;

                walker.Visit(assignmentInfo.Right);

                result = walker.Result;
            }
            finally
            {
                if (walker != null)
                {
                    RemoveRedundantAssignmentWalker.Free(walker);
                }
            }

            if (result)
            {
                return;
            }

            if (IsDeclaredInTryStatementOrCatchClauseAndReferencedInFinallyClause(context, assignmentInfo.Statement, symbol))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.RemoveRedundantAssignment, assignment);

            bool IsAssignedInsideAnonymousFunctionButDeclaredOutsideOfIt()
            {
                SyntaxNode declaringSyntax = null;
                SyntaxNode n = assignment.Parent;

                do
                {
                    if (CSharpFacts.IsAnonymousFunctionExpression(n.Kind()))
                    {
                        if (declaringSyntax == null)
                        {
                            declaringSyntax = symbol.GetSyntaxOrDefault();

                            Debug.Assert(declaringSyntax != null, "");

                            if (declaringSyntax == null)
                            {
                                break;
                            }

                            SyntaxDebug.Assert(declaringSyntax.IsKind(SyntaxKind.VariableDeclarator, SyntaxKind.Parameter), declaringSyntax);
                        }

                        SyntaxNode n2 = declaringSyntax.Parent;

                        do
                        {
                            if (CSharpFacts.IsAnonymousFunctionExpression(n2.Kind()))
                            {
                                return(!object.ReferenceEquals(n, n2));
                            }

                            if (n2 is MemberDeclarationSyntax)
                            {
                                break;
                            }

                            n2 = n2.Parent;
                        }while (n2 != null);

                        return(true);
                    }
                    else if (n is MemberDeclarationSyntax)
                    {
                        break;
                    }

                    n = n.Parent;
                }while (n != null);

                return(false);
            }
        }
コード例 #19
0
        private static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context)
        {
            var ifStatement = (IfStatementSyntax)context.Node;

            if (ifStatement.ContainsDiagnostics)
            {
                return;
            }

            if (ifStatement.SpanContainsDirectives())
            {
                return;
            }

            if (!ifStatement.IsSimpleIf())
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = SyntaxInfo.StatementListInfo(ifStatement).Statements;

            if (!statements.Any())
            {
                return;
            }

            if (IsPartOfLazyInitialization())
            {
                return;
            }

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(
                ifStatement.Condition,
                semanticModel: context.SemanticModel,
                allowedStyles: NullCheckStyles.CheckingNull,
                cancellationToken: context.CancellationToken);

            if (!nullCheck.Success)
            {
                return;
            }

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.SingleNonBlockStatementOrDefault());

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(assignmentInfo.Left, nullCheck.Expression))
            {
                return;
            }

            if (!assignmentInfo.Right.IsSingleLine())
            {
                return;
            }

            int index = statements.IndexOf(ifStatement);

            if (index > 0 &&
                !context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseCoalesceExpression))
            {
                StatementSyntax previousStatement = statements[index - 1];

                if (!previousStatement.ContainsDiagnostics &&
                    !previousStatement.GetTrailingTrivia().Any(f => f.IsDirective) &&
                    !ifStatement.GetLeadingTrivia().Any(f => f.IsDirective) &&
                    CanUseCoalesceExpression(previousStatement, nullCheck.Expression))
                {
                    DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseCoalesceExpression, previousStatement);
                }
            }

            if (context.IsAnalyzerSuppressed(DiagnosticDescriptors.InlineLazyInitialization))
            {
                return;
            }

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

            StatementSyntax nextStatement = statements[index + 1];

            if (nextStatement.ContainsDiagnostics)
            {
                return;
            }

            SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo(nextStatement);

            if (!invocationInfo.Success)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(nullCheck.Expression, invocationInfo.Expression))
            {
                return;
            }

            if (ifStatement.GetTrailingTrivia().Any(f => f.IsDirective))
            {
                return;
            }

            if (nextStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.InlineLazyInitialization, ifStatement);

            bool IsPartOfLazyInitialization()
            {
                return(statements.Count == 2 &&
                       statements.IndexOf(ifStatement) == 0 &&
                       statements[1].IsKind(SyntaxKind.ReturnStatement));
            }
        }
コード例 #20
0
        private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode node, BlockSyntax body)
        {
            if (body == null)
            {
                return;
            }

            if (body.ContainsDiagnostics)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

            if (statements.Count != 2)
            {
                return;
            }

            if (!(statements[0] is IfStatementSyntax ifStatement))
            {
                return;
            }

            if (!(statements[1] is ReturnStatementSyntax returnStatement))
            {
                return;
            }

            ExpressionSyntax returnExpression = returnStatement.Expression;

            if (returnExpression?.IsKind(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression) != true)
            {
                return;
            }

            if (ifStatement.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            if (returnStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            SimpleIfStatementInfo simpleIf = SyntaxInfo.SimpleIfStatementInfo(ifStatement);

            if (!simpleIf.Success)
            {
                return;
            }

            StatementSyntax statement = simpleIf.IfStatement.SingleNonBlockStatementOrDefault();

            if (statement == null)
            {
                return;
            }

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(statement);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (!assignmentInfo.Left.IsKind(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression))
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(simpleIf.Condition, semanticModel: semanticModel, allowedStyles: NullCheckStyles.CheckingNull, cancellationToken: cancellationToken);

            if (!nullCheck.Success)
            {
                return;
            }

            ExpressionSyntax expression = nullCheck.Expression;

            if (!expression.IsKind(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression))
            {
                return;
            }

            if (!(semanticModel.GetSymbol(expression, cancellationToken) is IFieldSymbol fieldSymbol))
            {
                return;
            }

            if (!ExpressionEquals(expression, assignmentInfo.Left))
            {
                return;
            }

            if (fieldSymbol.Type.IsNullableType() &&
                returnExpression.Kind() == SyntaxKind.SimpleMemberAccessExpression)
            {
                var memberAccessExpression = (MemberAccessExpressionSyntax)returnExpression;

                if (memberAccessExpression.Name is IdentifierNameSyntax identifierName &&
                    string.Equals(identifierName.Identifier.ValueText, "Value", StringComparison.Ordinal))
                {
                    returnExpression = memberAccessExpression.Expression;
                }
            }

            if (!ExpressionEquals(expression, returnExpression))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context,
                                               DiagnosticDescriptors.SimplifyLazyInitialization,
                                               Location.Create(node.SyntaxTree, TextSpan.FromBounds(ifStatement.SpanStart, returnStatement.Span.End)));
        }
コード例 #21
0
        internal static void AnalyzeSimpleAssignment(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            var assignment = (AssignmentExpressionSyntax)context.Node;

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(assignment);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (!(assignmentInfo.Left is IdentifierNameSyntax identifierName))
            {
                return;
            }

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(assignmentInfo.Statement);

            if (!statementsInfo.Success)
            {
                return;
            }

            int index = statementsInfo.IndexOf(assignmentInfo.Statement);

            if (index == statementsInfo.Count - 1)
            {
                return;
            }

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

                SimpleAssignmentStatementInfo assignmentInfo2 = SyntaxInfo.SimpleAssignmentStatementInfo(previousStatement);

                if (assignmentInfo2.Success &&
                    assignmentInfo2.Left is IdentifierNameSyntax identifierName2 &&
                    string.Equals(identifierName.Identifier.ValueText, identifierName2.Identifier.ValueText, StringComparison.Ordinal))
                {
                    return;
                }
            }

            StatementSyntax nextStatement = statementsInfo[index + 1];

            if (nextStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            if (!(nextStatement is ReturnStatementSyntax returnStatement))
            {
                return;
            }

            if (!(returnStatement.Expression?.WalkDownParentheses() is IdentifierNameSyntax identifierName3))
            {
                return;
            }

            if (!string.Equals(identifierName.Identifier.ValueText, identifierName3.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            ISymbol symbol = context.SemanticModel.GetSymbol(identifierName, context.CancellationToken);

            switch (symbol?.Kind)
            {
            case SymbolKind.Local:
            {
                break;
            }

            case SymbolKind.Parameter:
            {
                if (((IParameterSymbol)symbol).RefKind != RefKind.None)
                {
                    return;
                }

                break;
            }

            default:
            {
                return;
            }
            }

            RemoveRedundantAssignmentWalker walker = RemoveRedundantAssignmentWalker.GetInstance();

            walker.Symbol            = symbol;
            walker.SemanticModel     = context.SemanticModel;
            walker.CancellationToken = context.CancellationToken;
            walker.Result            = false;

            walker.Visit(assignmentInfo.Right);

            bool result = walker.Result;

            RemoveRedundantAssignmentWalker.Free(walker);

            if (result)
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveRedundantAssignment, assignment);
        }
コード例 #22
0
ファイル: IfAnalysis.cs プロジェクト: peteri/Roslynator
        private static ImmutableArray <IfAnalysis> Analyze(
            LocalDeclarationStatementSyntax localDeclarationStatement,
            IfStatementSyntax ifStatement,
            IfAnalysisOptions options,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            VariableDeclaratorSyntax declarator = localDeclarationStatement
                                                  .Declaration?
                                                  .Variables
                                                  .SingleOrDefault(shouldThrow: false);

            if (declarator == null)
            {
                return(Empty);
            }

            ElseClauseSyntax elseClause = ifStatement.Else;

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

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

            if (!assignment1.Success)
            {
                return(Empty);
            }

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

            if (!assignment2.Success)
            {
                return(Empty);
            }

            if (assignment1.Left.Kind() != SyntaxKind.IdentifierName)
            {
                return(Empty);
            }

            if (assignment2.Left.Kind() != SyntaxKind.IdentifierName)
            {
                return(Empty);
            }

            string identifier1 = ((IdentifierNameSyntax)assignment1.Left).Identifier.ValueText;
            string identifier2 = ((IdentifierNameSyntax)assignment2.Left).Identifier.ValueText;

            if (!string.Equals(identifier1, identifier2, StringComparison.Ordinal))
            {
                return(Empty);
            }

            if (!string.Equals(identifier1, declarator.Identifier.ValueText, StringComparison.Ordinal))
            {
                return(Empty);
            }

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

            if (IsNullLiteralConvertedToNullableOfT(assignment1.Right, semanticModel, cancellationToken) ||
                IsNullLiteralConvertedToNullableOfT(assignment2.Right, semanticModel, cancellationToken))
            {
                return(Empty);
            }

            return(new LocalDeclarationAndIfElseToAssignmentWithConditionalExpressionAnalysis(localDeclarationStatement, ifStatement, assignment1.Right, assignment2.Right, semanticModel).ToImmutableArray());
        }
コード例 #23
0
        internal static void AnalyzeSimpleAssignment(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            var assignment = (AssignmentExpressionSyntax)context.Node;

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(assignment);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (!(assignmentInfo.Left is IdentifierNameSyntax identifierName))
            {
                return;
            }

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(assignmentInfo.Statement);

            if (!statementsInfo.Success)
            {
                return;
            }

            int index = statementsInfo.IndexOf(assignmentInfo.Statement);

            if (index == statementsInfo.Count - 1)
            {
                return;
            }

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

                SimpleAssignmentStatementInfo assignmentInfo2 = SyntaxInfo.SimpleAssignmentStatementInfo(previousStatement);

                if (assignmentInfo2.Success &&
                    assignmentInfo2.Left is IdentifierNameSyntax identifierName2 &&
                    string.Equals(identifierName.Identifier.ValueText, identifierName2.Identifier.ValueText, StringComparison.Ordinal))
                {
                    return;
                }
            }

            StatementSyntax nextStatement = statementsInfo[index + 1];

            if (nextStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            if (!(nextStatement is ReturnStatementSyntax returnStatement))
            {
                return;
            }

            if (!(returnStatement.Expression?.WalkDownParentheses() is IdentifierNameSyntax identifierName3))
            {
                return;
            }

            if (!string.Equals(identifierName.Identifier.ValueText, identifierName3.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            ISymbol symbol = context.SemanticModel.GetSymbol(identifierName, context.CancellationToken);

            if (symbol == null)
            {
                return;
            }

            if (!IsFixableSymbol(symbol))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveRedundantAssignment, assignment);
        }
コード例 #24
0
        public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context)
        {
            var ifStatement = (IfStatementSyntax)context.Node;

            if (!ifStatement.IsSimpleIf())
            {
                return;
            }

            if (ifStatement.ContainsDiagnostics)
            {
                return;
            }

            if (ifStatement.SpanContainsDirectives())
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = SyntaxInfo.StatementListInfo(ifStatement).Statements;

            if (!statements.Any())
            {
                return;
            }

            if (IsPartOfLazyInitialization(ifStatement, statements))
            {
                return;
            }

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, semanticModel: context.SemanticModel, cancellationToken: context.CancellationToken);

            if (!nullCheck.Success)
            {
                return;
            }

            SimpleAssignmentStatementInfo simpleAssignment = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.SingleNonBlockStatementOrDefault());

            if (!simpleAssignment.Success)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(simpleAssignment.Left, nullCheck.Expression))
            {
                return;
            }

            if (!simpleAssignment.Right.IsSingleLine())
            {
                return;
            }

            int index = statements.IndexOf(ifStatement);

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

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

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

            StatementSyntax nextStatement = statements[index + 1];

            if (nextStatement.ContainsDiagnostics)
            {
                return;
            }

            SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo(nextStatement);

            if (!invocationInfo.Success)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(nullCheck.Expression, invocationInfo.Expression))
            {
                return;
            }

            if (ifStatement.Parent.ContainsDirectives(TextSpan.FromBounds(ifStatement.SpanStart, nextStatement.Span.End)))
            {
                return;
            }

            context.ReportDiagnostic(DiagnosticDescriptors.InlineLazyInitialization, ifStatement);
        }
コード例 #25
0
        public static Task <Document> InlineLazyInitializationAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

            var assignmentStatement = (ExpressionStatementSyntax)ifStatement.SingleNonBlockStatementOrDefault();

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(assignmentStatement, walkDownParentheses: false);

            ExpressionSyntax right = assignmentInfo.Right;

            int index = statementsInfo.IndexOf(ifStatement);

            var expressionStatement2 = (ExpressionStatementSyntax)statementsInfo[index + 1];

            SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo(expressionStatement2);

            ExpressionSyntax expression = invocationInfo.Expression;

            var newLeading = new List <SyntaxTrivia>(ifStatement.GetLeadingTrivia());

            ExpressionSyntax coalesceExpression;

            if (document.SupportsLanguageFeature(CSharpLanguageFeature.NullCoalescingAssignmentOperator))
            {
                AddTrivia(ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, right.SpanStart)).ToSyntaxTriviaList());

                coalesceExpression = CoalesceAssignmentExpression(expression.WithoutTrivia(), right.WithoutTrivia());
            }
            else
            {
                AddTrivia(ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, assignmentInfo.AssignmentExpression.SpanStart)).ToSyntaxTriviaList());

                coalesceExpression = CoalesceExpression(expression.WithoutTrivia(), ParenthesizedExpression(assignmentInfo.AssignmentExpression.WithoutTrivia()));
            }

            AddTrivia(ifStatement.DescendantTrivia(TextSpan.FromBounds(right.Span.End, ifStatement.Span.End)).ToSyntaxTriviaList());
            AddTrivia(ifStatement.GetTrailingTrivia());
            AddTrivia(expressionStatement2.GetLeadingTrivia());

            ParenthesizedExpressionSyntax newExpression = ParenthesizedExpression(coalesceExpression)
                                                          .WithLeadingTrivia(newLeading)
                                                          .WithTrailingTrivia(expression.GetTrailingTrivia());

            StatementSyntax newExpressionStatement = expressionStatement2.ReplaceNode(expression, newExpression);

            StatementListInfo newStatements = statementsInfo
                                              .Replace(expressionStatement2, newExpressionStatement)
                                              .RemoveAt(index);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));

            void AddTrivia(SyntaxTriviaList trivia)
            {
                if (!trivia.IsEmptyOrWhitespace())
                {
                    newLeading.AddRange(trivia);
                }
            }
        }
コード例 #26
0
        internal static void AnalyzeSimpleAssignment(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            var assignment = (AssignmentExpressionSyntax)context.Node;

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(assignment);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (!(assignmentInfo.Left is IdentifierNameSyntax identifierName))
            {
                return;
            }

            StatementSyntax nextStatement = assignmentInfo.Statement.NextStatementOrDefault();

            if (nextStatement == null)
            {
                return;
            }

            if (nextStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            if (!(nextStatement is ReturnStatementSyntax returnStatement))
            {
                return;
            }

            if (!(returnStatement.Expression?.WalkDownParentheses() is IdentifierNameSyntax identifierName2))
            {
                return;
            }

            if (!string.Equals(identifierName.Identifier.ValueText, identifierName2.Identifier.ValueText, System.StringComparison.Ordinal))
            {
                return;
            }

            ISymbol symbol = context.SemanticModel.GetSymbol(identifierName, context.CancellationToken);

            if (symbol == null)
            {
                return;
            }

            if (!IsFixableSymbol(symbol))
            {
                return;
            }

            context.ReportDiagnostic(DiagnosticDescriptors.RemoveRedundantAssignment, assignment);
        }
コード例 #27
0
        private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode node, BlockSyntax body)
        {
            if (body == null)
            {
                return;
            }

            if (body.ContainsDiagnostics)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

            if (statements.Count != 2)
            {
                return;
            }

            if (!(statements[0] is IfStatementSyntax ifStatement))
            {
                return;
            }

            if (!(statements[1] is ReturnStatementSyntax returnStatement))
            {
                return;
            }

            TextSpan span = TextSpan.FromBounds(ifStatement.SpanStart, returnStatement.Span.End);

            if (body.ContainsDirectives(span))
            {
                return;
            }

            SimpleIfStatementInfo simpleIf = SyntaxInfo.SimpleIfStatementInfo(ifStatement);

            if (!simpleIf.Success)
            {
                return;
            }

            StatementSyntax statement = simpleIf.Statement.SingleNonBlockStatementOrDefault();

            if (statement == null)
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(simpleIf.Condition, allowedKinds: NullCheckKind.IsNull, semanticModel: semanticModel, cancellationToken: cancellationToken);

            if (!nullCheck.Success)
            {
                return;
            }

            IdentifierNameSyntax identifierName = GetIdentifierName(nullCheck.Expression);

            if (identifierName == null)
            {
                return;
            }

            if (!(semanticModel.GetSymbol(identifierName, cancellationToken) is IFieldSymbol fieldSymbol))
            {
                return;
            }

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(statement);

            if (!assignmentInfo.Success)
            {
                return;
            }

            string name = identifierName.Identifier.ValueText;

            IdentifierNameSyntax identifierName2 = GetIdentifierName(assignmentInfo.Left);

            if (!IsBackingField(identifierName2, name, fieldSymbol, semanticModel, cancellationToken))
            {
                return;
            }

            IdentifierNameSyntax identifierName3 = GetIdentifierName(returnStatement.Expression, semanticModel, cancellationToken);

            if (!IsBackingField(identifierName3, name, fieldSymbol, semanticModel, cancellationToken))
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.SimplifyLazyInitialization,
                Location.Create(node.SyntaxTree, span));
        }
コード例 #28
0
        public static void AnalyzeLocalDeclarationStatement(SyntaxNodeAnalysisContext context)
        {
            var localDeclaration = (LocalDeclarationStatementSyntax)context.Node;

            if (localDeclaration.ContainsDiagnostics)
            {
                return;
            }

            if (localDeclaration.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            if (localDeclaration.IsConst)
            {
                return;
            }

            SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration);

            if (!localInfo.Success)
            {
                return;
            }

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(localDeclaration.NextStatementOrDefault());

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (assignmentInfo.Statement.ContainsDiagnostics)
            {
                return;
            }

            if (assignmentInfo.Statement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            if (!(assignmentInfo.Left is IdentifierNameSyntax identifierName))
            {
                return;
            }

            string name = identifierName.Identifier.ValueText;

            if (!string.Equals(localInfo.IdentifierText, name, StringComparison.Ordinal))
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            var localSymbol = semanticModel.GetSymbol(identifierName, cancellationToken) as ILocalSymbol;

            if (localSymbol == null)
            {
                return;
            }

            if (!localSymbol.Equals(semanticModel.GetDeclaredSymbol(localInfo.Declarator, cancellationToken)))
            {
                return;
            }

            EqualsValueClauseSyntax initializer = localInfo.Initializer;
            ExpressionSyntax        value       = initializer?.Value;

            if (value != null)
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(localInfo.Type, cancellationToken);

                if (typeSymbol == null)
                {
                    return;
                }

                if (!semanticModel.IsDefaultValue(typeSymbol, value, cancellationToken))
                {
                    return;
                }

                if (IsReferenced(localSymbol, assignmentInfo.Right, semanticModel, cancellationToken))
                {
                    return;
                }
            }

            context.ReportDiagnostic(DiagnosticDescriptors.MergeLocalDeclarationWithAssignment, localInfo.Identifier);

            if (value != null)
            {
                context.ReportNode(DiagnosticDescriptors.MergeLocalDeclarationWithAssignmentFadeOut, initializer);
                context.ReportToken(DiagnosticDescriptors.MergeLocalDeclarationWithAssignmentFadeOut, assignmentInfo.OperatorToken);
            }

            context.ReportToken(DiagnosticDescriptors.MergeLocalDeclarationWithAssignmentFadeOut, localDeclaration.SemicolonToken);
            context.ReportNode(DiagnosticDescriptors.MergeLocalDeclarationWithAssignmentFadeOut, assignmentInfo.Left);
        }