Beispiel #1
0
        public virtual Task <Document> InlineAsync(
            ExpressionStatementSyntax expressionStatement,
            SyntaxList <StatementSyntax> statements,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            int count = statements.Count;

            StatementSyntax[] newStatements = RewriteStatements(statements);

            newStatements[0]         = newStatements[0].WithLeadingTrivia(expressionStatement.GetLeadingTrivia());
            newStatements[count - 1] = newStatements[count - 1].WithTrailingTrivia(expressionStatement.GetTrailingTrivia());

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(expressionStatement);

            if (statementsInfo.Success)
            {
                StatementsInfo newInfo = statementsInfo.WithStatements(statementsInfo.Statements.ReplaceRange(expressionStatement, newStatements));

                return(Document.ReplaceNodeAsync(statementsInfo.Node, newInfo.Node, cancellationToken));
            }
            else
            {
                return(Document.ReplaceNodeAsync(expressionStatement, Block(newStatements), cancellationToken));
            }
        }
Beispiel #2
0
        public static Task <Document> RefactorAsync(
            Document document,
            UsingStatementSyntax usingStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(usingStatement);

            int index = statementsInfo.Statements.IndexOf(usingStatement);

            StatementsInfo newStatementsInfo = statementsInfo.RemoveAt(index);

            var statements = new List <StatementSyntax>()
            {
                SyntaxFactory.LocalDeclarationStatement(usingStatement.Declaration)
            };

            statements.AddRange(GetStatements(usingStatement));

            if (statements.Count > 0)
            {
                statements[0] = statements[0]
                                .WithLeadingTrivia(usingStatement.GetLeadingTrivia());

                statements[statements.Count - 1] = statements[statements.Count - 1]
                                                   .WithTrailingTrivia(usingStatement.GetTrailingTrivia());
            }

            newStatementsInfo = newStatementsInfo.WithStatements(newStatementsInfo.Statements.InsertRange(index, statements));

            return(document.ReplaceNodeAsync(statementsInfo.Node, newStatementsInfo.Node.WithFormatterAnnotation(), cancellationToken));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            SingleLocalDeclarationStatementInfo localInfo,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localInfo.Statement);

            var localSymbol = (ILocalSymbol)semanticModel.GetDeclaredSymbol(localInfo.Declarator, cancellationToken);

            IdentifierNameSyntax identifierName = FindLastReference(localSymbol, statementsInfo.Node, semanticModel, cancellationToken);

            TextSpan span;

            if (identifierName == null)
            {
                span = localInfo.Statement.Span;
            }
            else
            {
                int position = identifierName.SpanStart;
                span = TextSpan.FromBounds(localInfo.Statement.SpanStart, statementsInfo.First(f => f.Span.Contains(position)).Span.End);
            }

            StatementsSelection selectedStatements = StatementsSelection.Create(statementsInfo, span);

            var refactoring = new WrapStatements.WrapInUsingStatementRefactoring();

            return(refactoring.RefactorAsync(document, selectedStatements, cancellationToken));
        }
        public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(IfStatement);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ExpressionSyntax expression = IfRefactoringHelper.GetBooleanExpression(
                IfStatement.Condition,
                Expression1,
                Expression2,
                semanticModel,
                cancellationToken);

            StatementSyntax newStatement = CreateStatement(expression)
                                           .WithLeadingTrivia(IfStatement.GetLeadingTrivia())
                                           .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia())
                                           .WithFormatterAnnotation();

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .RemoveAt(index)
                                                         .ReplaceAt(index, newStatement);

            return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
        }
        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));
        }
        private static Task <Document> DuplicateStatementAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

            if (statementsInfo.Success)
            {
                int index = statementsInfo.Statements.IndexOf(statement);

                if (index == 0 &&
                    statementsInfo.IsInBlock &&
                    statementsInfo.Block.OpenBraceToken.GetFullSpanEndLine() == statement.GetFullSpanStartLine())
                {
                    statement = statement.PrependToLeadingTrivia(CSharpFactory.NewLine());
                }

                SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements.Insert(index + 1, statement.WithNavigationAnnotation());

                StatementsInfo newInfo = statementsInfo.WithStatements(newStatements);

                return(document.ReplaceNodeAsync(statementsInfo.Node, newInfo.Node, cancellationToken));
            }
            else
            {
                SyntaxList <StatementSyntax> statements = SyntaxFactory.List(new StatementSyntax[] { statement, statement.WithNavigationAnnotation() });

                BlockSyntax block = SyntaxFactory.Block(statements);

                return(document.ReplaceNodeAsync(statement, block, cancellationToken));
            }
        }
Beispiel #7
0
        public static Task <Document> RefactorAsync(
            Document document,
            LocalFunctionStatementSyntax localFunction,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (localFunction == null)
            {
                throw new ArgumentNullException(nameof(localFunction));
            }

            StatementsInfo statementsInfos = SyntaxInfo.StatementsInfo(localFunction);

            SyntaxList <StatementSyntax> statements = statementsInfos.Statements;
            int index = statements.IndexOf(localFunction);

            if (index == 0 &&
                statementsInfos.Block.OpenBraceToken.GetFullSpanEndLine() == localFunction.GetFullSpanStartLine())
            {
                localFunction = localFunction.WithLeadingTrivia(localFunction.GetLeadingTrivia().Insert(0, NewLine()));
            }

            SyntaxList <StatementSyntax> newStatements = statements.Insert(index + 1, localFunction.WithNavigationAnnotation());

            return(document.ReplaceStatementsAsync(statementsInfos, newStatements, cancellationToken));
        }
Beispiel #8
0
        public static Task <Document> RefactorAsync(
            Document document,
            AssignmentExpressionSyntax assignmentExpression,
            CancellationToken cancellationToken)
        {
            var statement = (StatementSyntax)assignmentExpression.Parent;

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            statements = statements.RemoveAt(index);

            var returnStatement = (ReturnStatementSyntax)statement.NextStatementOrDefault();

            IEnumerable <SyntaxTrivia> trivia = statementsInfo
                                                .Node
                                                .DescendantTrivia(TextSpan.FromBounds(statement.SpanStart, returnStatement.SpanStart))
                                                .Where(f => !f.IsWhitespaceOrEndOfLineTrivia());

            trivia = statement
                     .GetLeadingTrivia()
                     .Concat(trivia);

            returnStatement = returnStatement
                              .WithExpression(assignmentExpression.Right.WithTriviaFrom(returnStatement.Expression))
                              .WithLeadingTrivia(trivia);

            statements = statements.ReplaceAt(index, returnStatement);

            return(document.ReplaceStatementsAsync(statementsInfo, statements, cancellationToken));
        }
Beispiel #9
0
        public static async Task ComputeRefactoringAsync(
            RefactoringContext context,
            LocalDeclarationStatementSyntax localDeclaration)
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration);

            if (!statementsInfo.Success)
            {
                return;
            }

            SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration);

            if (!localInfo.Success)
            {
                return;
            }

            if (!context.Span.IsEmptyAndContainedInSpan(localInfo.EqualsToken))
            {
                return;
            }

            ExpressionSyntax value = localInfo.Initializer?.Value;

            if (value == null)
            {
                return;
            }

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

            TypeSyntax type = localInfo.Type;

            if (type.IsVar)
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(value, context.CancellationToken);

                if (typeSymbol?.SupportsExplicitDeclaration() != true)
                {
                    return;
                }

                type = typeSymbol.ToMinimalTypeSyntax(semanticModel, type.SpanStart);
            }
            else
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken);

                if (typeSymbol?.IsErrorType() != false)
                {
                    return;
                }
            }

            context.RegisterRefactoring(
                "Split declaration and initialization",
                cancellationToken => RefactorAsync(context.Document, localInfo, type, statementsInfo, cancellationToken));
        }
Beispiel #10
0
        public static Task <Document> RefactorAsync(
            Document document,
            VariableDeclaratorSyntax declarator,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var declaration = (VariableDeclarationSyntax)declarator.Parent;

            var localDeclaration = (LocalDeclarationStatementSyntax)declaration.Parent;

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(localDeclaration);

            StatementSyntax nextStatement = statements[index + 1];

            var expressionStatement = (ExpressionStatementSyntax)nextStatement;

            var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression;

            ExpressionSyntax right = assignment.Right;

            EqualsValueClauseSyntax initializer = declarator.Initializer;

            ExpressionSyntax value = initializer?.Value;

            VariableDeclaratorSyntax newDeclarator = (value != null)
                ? declarator.ReplaceNode(value, right)
                : declarator.WithInitializer(EqualsValueClause(right));

            LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration.ReplaceNode(declarator, newDeclarator);

            SyntaxTriviaList trailingTrivia = localDeclaration.GetTrailingTrivia();

            if (!trailingTrivia.IsEmptyOrWhitespace())
            {
                newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(trailingTrivia.Concat(nextStatement.GetTrailingTrivia()));
            }
            else
            {
                newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(nextStatement.GetTrailingTrivia());
            }

            SyntaxTriviaList leadingTrivia = nextStatement.GetLeadingTrivia();

            if (!leadingTrivia.IsEmptyOrWhitespace())
            {
                newLocalDeclaration = newLocalDeclaration.WithLeadingTrivia(newLocalDeclaration.GetLeadingTrivia().Concat(leadingTrivia));
            }

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .Replace(localDeclaration, newLocalDeclaration)
                                                         .RemoveAt(index + 1);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
        internal static void ComputeRefactoring(RefactoringContext context, BinaryExpressionSelection binaryExpressionSelection)
        {
            BinaryExpressionSyntax binaryExpression = binaryExpressionSelection.BinaryExpression;

            SyntaxKind kind = binaryExpression.Kind();

            if (kind == SyntaxKind.LogicalAndExpression ||
                kind == SyntaxKind.LogicalOrExpression)
            {
                BinaryExpressionSyntax condition = GetCondition(binaryExpression);

                if (condition != null)
                {
                    SyntaxNode parent = condition.Parent;

                    switch (parent?.Kind())
                    {
                    case SyntaxKind.IfStatement:
                    {
                        if (kind == SyntaxKind.LogicalAndExpression)
                        {
                            var refactoring = new ExtractConditionFromIfToNestedIfRefactoring();
                            context.RegisterRefactoring(
                                refactoring.Title,
                                cancellationToken => refactoring.RefactorAsync(context.Document, (IfStatementSyntax)parent, condition, binaryExpressionSelection, cancellationToken));
                        }
                        else if (kind == SyntaxKind.LogicalOrExpression)
                        {
                            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo((StatementSyntax)parent);
                            if (statementsInfo.Success)
                            {
                                var refactoring = new ExtractConditionFromIfToIfRefactoring();
                                context.RegisterRefactoring(
                                    refactoring.Title,
                                    cancellationToken => refactoring.RefactorAsync(context.Document, statementsInfo, condition, binaryExpressionSelection, cancellationToken));
                            }
                        }

                        break;
                    }

                    case SyntaxKind.WhileStatement:
                    {
                        if (kind == SyntaxKind.LogicalAndExpression)
                        {
                            var refactoring = new ExtractConditionFromWhileToNestedIfRefactoring();
                            context.RegisterRefactoring(
                                refactoring.Title,
                                cancellationToken => refactoring.RefactorAsync(context.Document, (WhileStatementSyntax)parent, condition, binaryExpressionSelection, cancellationToken));
                        }

                        break;
                    }
                    }
                }
            }
        }
        public bool Analyze(
            MemberInvocationExpressionInfo invocationInfo,
            StatementSyntax statement,
            string name,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (statement.SpanOrTrailingTriviaContainsDirectives())
            {
                return(false);
            }

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

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

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

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

            if (!semanticModel.TryGetMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, cancellationToken))
            {
                return(false);
            }

            ITypeSymbol typeSymbol = methodInfo.ReturnType;

            int i = statements.IndexOf(statement);

            if (i != 0 &&
                IsFixableStatement(statements[i - 1], name, typeSymbol, semanticModel, cancellationToken))
            {
                return(false);
            }

            int j = i;

            while (j < statements.Count - 1)
            {
                if (!IsFixableStatement(statements[j + 1], name, typeSymbol, semanticModel, cancellationToken))
                {
                    break;
                }

                j++;
            }

            return(j > i);
        }
        public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken))
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            int position = IfStatement.SpanStart;

            ITypeSymbol targetType = GetTargetType(position, semanticModel, cancellationToken);

            BinaryExpressionSyntax coalesceExpression = RefactoringHelper.CreateCoalesceExpression(
                targetType,
                Left.WithoutTrivia(),
                Right.WithoutTrivia(),
                position,
                semanticModel);

            StatementSyntax statement = CreateStatement(coalesceExpression);

            if (IfStatement.IsSimpleIf())
            {
                StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement);

                SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

                int index = statements.IndexOf(IfStatement);

                StatementSyntax newNode = statement
                                          .WithLeadingTrivia(IfStatement.GetLeadingTrivia())
                                          .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia())
                                          .WithFormatterAnnotation();

                SyntaxList <StatementSyntax> newStatements = statements
                                                             .RemoveAt(index)
                                                             .ReplaceAt(index, newNode);

                return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                StatementSyntax newNode = statement
                                          .WithTriviaFrom(IfStatement)
                                          .WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(IfStatement, newNode, cancellationToken).ConfigureAwait(false));
            }
        }
        private static async Task <Document> RefactorAsync(
            Document document,
            ExpressionSyntax expression,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            if (statement.IsEmbedded())
            {
                return(await document.ReplaceNodeAsync(statement, Block(statement, CreateNullCheck(expression)), cancellationToken).ConfigureAwait(false));
            }
            else
            {
                StatementsInfo statementsInfo           = SyntaxInfo.StatementsInfo(statement);
                SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

                int statementIndex = statements.IndexOf(statement);

                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                ISymbol symbol = (statement is LocalDeclarationStatementSyntax localDeclaration)
                    ? semanticModel.GetDeclaredSymbol(localDeclaration.Declaration.Variables.First(), cancellationToken)
                    : semanticModel.GetSymbol(expression, cancellationToken);

                int lastStatementIndex = IncludeAllReferencesOfSymbol(symbol, expression.Kind(), statements, statementIndex + 1, semanticModel, cancellationToken);

                if (lastStatementIndex != -1)
                {
                    if (lastStatementIndex < statements.Count - 1)
                    {
                        lastStatementIndex = IncludeAllReferencesOfVariablesDeclared(statements, statementIndex + 1, lastStatementIndex, semanticModel, cancellationToken);
                    }

                    return(await RefactorAsync(
                               document,
                               expression,
                               statements,
                               statementsInfo,
                               statementIndex,
                               lastStatementIndex,
                               cancellationToken).ConfigureAwait(false));
                }
            }

            return(await document.InsertNodeAfterAsync(statement, CreateNullCheck(expression), cancellationToken).ConfigureAwait(false));
        }
Beispiel #15
0
        public override Task <Document> RefactorAsync(
            Document document,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(IfStatement);

            TStatement newStatement = CreateNewStatement();

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .RemoveAt(index)
                                                         .ReplaceAt(index - 1, newStatement);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
Beispiel #16
0
        public virtual async Task <Solution> InlineAndRemoveAsync(
            ExpressionStatementSyntax expressionStatement,
            SyntaxList <StatementSyntax> statements,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (expressionStatement.SyntaxTree == Declaration.SyntaxTree)
            {
                DocumentEditor editor = await DocumentEditor.CreateAsync(Document, cancellationToken).ConfigureAwait(false);

                StatementSyntax[] newStatements = RewriteStatements(statements);

                int count = statements.Count;

                newStatements[0]         = newStatements[0].WithLeadingTrivia(expressionStatement.GetLeadingTrivia());
                newStatements[count - 1] = newStatements[count - 1].WithTrailingTrivia(expressionStatement.GetTrailingTrivia());

                StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(expressionStatement);

                if (statementsInfo.Success)
                {
                    StatementsInfo newStatementsInfo = statementsInfo.WithStatements(statementsInfo.Statements.ReplaceRange(expressionStatement, newStatements));

                    editor.ReplaceNode(statementsInfo.Node, newStatementsInfo.Node);
                }
                else
                {
                    editor.ReplaceNode(expressionStatement, Block(newStatements));
                }

                editor.RemoveNode(Declaration);

                return(editor.GetChangedDocument().Solution());
            }
            else
            {
                Document newDocument = await InlineAsync(expressionStatement, statements, cancellationToken).ConfigureAwait(false);

                DocumentId documentId = Document.Solution().GetDocumentId(Declaration.SyntaxTree);

                newDocument = await newDocument.Solution().GetDocument(documentId).RemoveMemberAsync(Declaration, cancellationToken).ConfigureAwait(false);

                return(newDocument.Solution());
            }
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            SyntaxKind jumpKind,
            bool recursive,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(ifStatement);

            CSharpSyntaxNode node = statementsInfo.Node;

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var rewriter = new ReduceIfStatementRewriter(jumpKind, recursive, semanticModel, cancellationToken);

            SyntaxNode newNode = rewriter.Visit(node);

            return(await document.ReplaceNodeAsync(node, newNode, cancellationToken).ConfigureAwait(false));
        }
        public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken))
        {
            ExpressionSyntax expression = Expression;

            if (Negate)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                expression = LogicalNegationHelper.LogicallyNegate(expression, semanticModel, cancellationToken);
            }

            StatementSyntax statement = CreateStatement(expression);

            if (IfStatement.IsSimpleIf())
            {
                StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement);

                SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

                int index = statements.IndexOf(IfStatement);

                StatementSyntax newNode = statement
                                          .WithLeadingTrivia(IfStatement.GetLeadingTrivia())
                                          .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia())
                                          .WithFormatterAnnotation();

                SyntaxList <StatementSyntax> newStatements = statements
                                                             .RemoveAt(index)
                                                             .ReplaceAt(index, newNode);

                return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                StatementSyntax newNode = statement
                                          .WithTriviaFrom(IfStatement)
                                          .WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(IfStatement, newNode, cancellationToken).ConfigureAwait(false));
            }
        }
Beispiel #19
0
        public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            var ifStatement = (IfStatementSyntax)context.Node;

            if (!ifStatement.IsSimpleIf())
            {
                StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(ifStatement);
                if (statementsInfo.Success)
                {
                    int index = statementsInfo.Statements.IndexOf(ifStatement);

                    ReturnStatementSyntax returnStatement = FindReturnStatementBelow(statementsInfo.Statements, index);
                    if (returnStatement?.ContainsDiagnostics == false)
                    {
                        ExpressionSyntax expression = returnStatement.Expression;
                        if (expression != null &&
                            !ifStatement.SpanOrTrailingTriviaContainsDirectives() &&
                            !returnStatement.SpanOrLeadingTriviaContainsDirectives())
                        {
                            SemanticModel     semanticModel     = context.SemanticModel;
                            CancellationToken cancellationToken = context.CancellationToken;

                            ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken);

                            if (IsLocalDeclaredInScopeOrNonRefOrOutParameterOfEnclosingSymbol(symbol, statementsInfo.Node, semanticModel, cancellationToken) &&
                                ifStatement
                                .GetChain()
                                .All(ifOrElse => IsSymbolAssignedInLastStatement(ifOrElse, symbol, semanticModel, cancellationToken)))
                            {
                                context.ReportDiagnostic(DiagnosticDescriptors.UseReturnInsteadOfAssignment, ifStatement);
                            }
                        }
                    }
                }
            }
        }
        public override Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(IfStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(IfStatement);

            ConditionalExpressionSyntax conditionalExpression = IfRefactoringHelper.CreateConditionalExpression(IfStatement.Condition, Expression1, Expression2);

            StatementSyntax newStatement = CreateStatement(conditionalExpression)
                                           .WithLeadingTrivia(IfStatement.GetLeadingTrivia())
                                           .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia())
                                           .WithFormatterAnnotation();

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .RemoveAt(index)
                                                         .ReplaceAt(index, newStatement);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
Beispiel #21
0
        private static void RegisterRefactoring(
            RefactoringContext context,
            StatementSyntax statement,
            InitializerExpressionSyntax initializer,
            ExpressionSyntax expression)
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

            if (statementsInfo.Success)
            {
                context.RegisterRefactoring(
                    Title,
                    cancellationToken => RefactorAsync(
                        context.Document,
                        statementsInfo,
                        statement,
                        initializer,
                        expression.WithoutTrivia(),
                        cancellationToken));
            }
        }
        private static Task <Document> RefactorAsync(
            Document document,
            LocalDeclarationStatementSyntax localDeclaration,
            ConditionalExpressionSyntax conditionalExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            VariableDeclaratorSyntax variableDeclarator = localDeclaration.Declaration.Variables[0];

            LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration.RemoveNode(variableDeclarator.Initializer, SyntaxRemoveOptions.KeepExteriorTrivia);

            TypeSyntax type = newLocalDeclaration.Declaration.Type;

            if (type.IsVar)
            {
                newLocalDeclaration = newLocalDeclaration.ReplaceNode(
                    type,
                    semanticModel.GetTypeSymbol(conditionalExpression)
                    .ToMinimalTypeSyntax(semanticModel, type.SpanStart)
                    .WithTriviaFrom(type));
            }

            IdentifierNameSyntax left = IdentifierName(variableDeclarator.Identifier.ValueText);

            IfStatementSyntax ifStatement = IfElseStatement(
                conditionalExpression.Condition.WalkDownParentheses().WithoutTrivia(),
                SimpleAssignmentStatement(left, conditionalExpression.WhenTrue.WithoutTrivia()),
                SimpleAssignmentStatement(left, conditionalExpression.WhenFalse.WithoutTrivia()));

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            SyntaxList <StatementSyntax> newStatements = statements
                                                         .Replace(localDeclaration, newLocalDeclaration.WithFormatterAnnotation())
                                                         .Insert(statements.IndexOf(localDeclaration) + 1, ifStatement.WithFormatterAnnotation());

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            ExpressionSyntax expression,
            StatementSyntax statement,
            int statementCount,
            CancellationToken cancellationToken)
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int statementIndex = statements.IndexOf(statement);

            return(RefactorAsync(
                       document,
                       expression,
                       statements,
                       statementsInfo,
                       statementIndex,
                       statementIndex + statementCount,
                       cancellationToken));
        }
        public static Task <Document> InlineLazyInitializationAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(ifStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(ifStatement);

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

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

            ExpressionSyntax expression = invocationInfo.Expression;

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

            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.Node.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));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            SingleLocalDeclarationStatementInfo localInfo,
            TypeSyntax type,
            CancellationToken cancellationToken)
        {
            LocalDeclarationStatementSyntax localStatement = localInfo.Statement;

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localStatement);

            int index = statementsInfo.IndexOf(localStatement);

            VariableDeclaratorSyntax declarator = localInfo.Declarator;

            VariableDeclaratorSyntax newDeclarator = declarator.WithInitializer(null);

            VariableDeclarationSyntax newDeclaration = localInfo.Declaration.ReplaceNode(declarator, newDeclarator);

            if (type != null)
            {
                newDeclaration = newDeclaration.WithType(type.WithTriviaFrom(newDeclaration.Type));
            }

            LocalDeclarationStatementSyntax newLocalStatement = localStatement
                                                                .WithDeclaration(newDeclaration)
                                                                .WithTrailingTrivia(NewLine())
                                                                .WithFormatterAnnotation();

            ExpressionStatementSyntax assignmentStatement = SimpleAssignmentStatement(IdentifierName(localInfo.Identifier), localInfo.Initializer.Value)
                                                            .WithTrailingTrivia(localStatement.GetTrailingTrivia())
                                                            .WithFormatterAnnotation();

            StatementsInfo newStatementsInfo = statementsInfo
                                               .Insert(index + 1, assignmentStatement)
                                               .ReplaceAt(index, newLocalStatement);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatementsInfo, cancellationToken));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            LocalDeclarationStatementSyntax localDeclaration,
            CancellationToken cancellationToken)
        {
            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration);

            int index = statementsInfo.Statements.IndexOf(localDeclaration);

            StatementSyntax nextStatement = statementsInfo.Statements[index + 1];

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ExpressionSyntax value = GetExpressionToInline(localDeclaration, semanticModel, cancellationToken);

            StatementSyntax newStatement = GetStatementWithInlinedExpression(nextStatement, value);

            SyntaxTriviaList leadingTrivia = localDeclaration.GetLeadingTrivia();

            IEnumerable <SyntaxTrivia> trivia = statementsInfo
                                                .Node
                                                .DescendantTrivia(TextSpan.FromBounds(localDeclaration.SpanStart, nextStatement.Span.Start));

            if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
            {
                newStatement = newStatement.WithLeadingTrivia(leadingTrivia.Concat(trivia));
            }
            else
            {
                newStatement = newStatement.WithLeadingTrivia(leadingTrivia);
            }

            SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements
                                                         .Replace(nextStatement, newStatement)
                                                         .RemoveAt(index);

            return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
        }
        private static Task <Document> RefactorAsync <TNode>(
            Document document,
            WhileStatementSyntax whileStatement,
            ForStatementSyntax forStatement,
            List <TNode> list,
            CancellationToken cancellationToken) where TNode : StatementSyntax
        {
            forStatement = forStatement
                           .TrimLeadingTrivia()
                           .PrependToLeadingTrivia(list[0].GetLeadingTrivia());

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(whileStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(list[0]);

            IEnumerable <StatementSyntax> newStatements = statements.Take(index)
                                                          .Concat(new ForStatementSyntax[] { forStatement })
                                                          .Concat(statements.Skip(index + list.Count + 1));

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
        public async Task <Document> RefactorAsync(
            Document document,
            ExpressionStatementSyntax expressionStatement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            InvocationExpressionSyntax invocationExpression = GetInvocationExpression(expressionStatement);

            semanticModel.TryGetMethodInfo(invocationExpression, out MethodInfo methodInfo, cancellationToken);

            MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression);

            ITypeSymbol typeSymbol = methodInfo.ReturnType;

            string name = ((IdentifierNameSyntax)WalkDownMethodChain(invocationInfo).Expression).Identifier.ValueText;

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(expressionStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(expressionStatement);

            string indentation = CSharpFormatter.GetIncreasedIndentation(expressionStatement, cancellationToken).ToString();

            var sb = new StringBuilder(invocationExpression.ToString());

            int j = index;

            while (j < statements.Count - 1)
            {
                StatementSyntax statement = statements[j + 1];

                if (!IsFixableStatement(statement, name, typeSymbol, semanticModel, cancellationToken))
                {
                    break;
                }

                sb.AppendLine();
                sb.Append(indentation);
                sb.Append(GetTextToAppend((ExpressionStatementSyntax)statement));

                j++;
            }

            StatementSyntax lastStatement = statements[j];

            SyntaxList <StatementSyntax> newStatements = statements;

            while (j > index)
            {
                newStatements = newStatements.RemoveAt(j);
                j--;
            }

            ExpressionSyntax newInvocationExpression = SyntaxFactory.ParseExpression(sb.ToString());

            SyntaxTriviaList trailingTrivia = statementsInfo
                                              .Node
                                              .DescendantTrivia(TextSpan.FromBounds(invocationExpression.Span.End, lastStatement.Span.End))
                                              .ToSyntaxTriviaList()
                                              .EmptyIfWhitespace()
                                              .AddRange(lastStatement.GetTrailingTrivia());

            ExpressionStatementSyntax newExpressionStatement = expressionStatement
                                                               .ReplaceNode(invocationExpression, newInvocationExpression)
                                                               .WithLeadingTrivia(expressionStatement.GetLeadingTrivia())
                                                               .WithTrailingTrivia(trailingTrivia)
                                                               .WithFormatterAndSimplifierAnnotations();

            newStatements = newStatements.ReplaceAt(index, newExpressionStatement);

            return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
        }
Beispiel #29
0
        public static async Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

            int index = statementsInfo.Statements.IndexOf(statement);

            switch (statement.Kind())
            {
            case SyntaxKind.IfStatement:
            {
                var ifStatement = (IfStatementSyntax)statement;

                IfStatementInfo ifStatementInfo = SyntaxInfo.IfStatementInfo(ifStatement);

                IEnumerable <ExpressionStatementSyntax> expressionStatements = ifStatementInfo
                                                                               .Nodes
                                                                               .Select(ifOrElse => (ExpressionStatementSyntax)GetLastStatementOrDefault(ifOrElse.Statement));

                IfStatementSyntax newIfStatement = ifStatement.ReplaceNodes(
                    expressionStatements,
                    (f, _) =>
                    {
                        var assignment = (AssignmentExpressionSyntax)f.Expression;

                        return(ReturnStatement(assignment.Right).WithTriviaFrom(f));
                    });

                StatementsInfo newStatementsInfo = await RefactorAsync(
                    document,
                    statementsInfo,
                    ifStatement,
                    newIfStatement,
                    index,
                    ifStatementInfo.Nodes.Length,
                    ifStatementInfo.EndsWithElse,
                    semanticModel,
                    cancellationToken).ConfigureAwait(false);

                return(await document.ReplaceNodeAsync(statementsInfo.Node, newStatementsInfo.Node, cancellationToken).ConfigureAwait(false));
            }

            case SyntaxKind.SwitchStatement:
            {
                var switchStatement = (SwitchStatementSyntax)statement;

                SyntaxList <SwitchSectionSyntax> newSections = switchStatement
                                                               .Sections
                                                               .Select(CreateNewSection)
                                                               .ToSyntaxList();

                SwitchStatementSyntax newSwitchStatement = switchStatement.WithSections(newSections);

                StatementsInfo newStatementsInfo = await RefactorAsync(
                    document,
                    statementsInfo,
                    switchStatement,
                    newSwitchStatement,
                    index,
                    switchStatement.Sections.Count,
                    switchStatement.Sections.Any(f => f.ContainsDefaultLabel()),
                    semanticModel,
                    cancellationToken).ConfigureAwait(false);

                return(await document.ReplaceNodeAsync(statementsInfo.Node, newStatementsInfo.Node, cancellationToken).ConfigureAwait(false));
            }
            }

            Debug.Fail(statement.Kind().ToString());

            return(document);
        }
Beispiel #30
0
        public static void AnalyzeLocalDeclarationStatement(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            var localDeclaration = (LocalDeclarationStatementSyntax)context.Node;

            if (localDeclaration.IsConst)
            {
                return;
            }

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localDeclaration);

            if (!statementsInfo.Success)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

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

            int index = statements.IndexOf(localDeclaration);

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

            LocalDeclarationStatementInfo localInfo = SyntaxInfo.LocalDeclarationStatementInfo(localDeclaration);

            if (!localInfo.Success)
            {
                return;
            }

            ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(localInfo.Type, context.CancellationToken);

            if (typeSymbol?.SupportsConstantValue() != true)
            {
                return;
            }

            foreach (VariableDeclaratorSyntax declarator in localInfo.Variables)
            {
                if (!HasConstantValue(declarator.Initializer?.Value, typeSymbol, context.SemanticModel, context.CancellationToken))
                {
                    return;
                }
            }

            if (!CanBeMarkedAsConst(localInfo.Variables, statements, index + 1))
            {
                return;
            }

            context.ReportDiagnostic(DiagnosticDescriptors.MarkLocalVariableAsConst, localInfo.Type);
        }