示例#1
0
        private static Task <Document> RefactorAsync(
            Document document,
            SingleLocalDeclarationStatementInfo localInfo,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(localInfo.Statement);

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

            IdentifierNameSyntax identifierName = FindLastReference(localSymbol, statementsInfo.Parent, 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);
            }

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

            var refactoring = new WrapStatements.WrapInUsingStatementRefactoring();

            return(refactoring.RefactorAsync(document, selectedStatements, cancellationToken));
        }
        public static async Task ComputeRefactoringAsync(
            RefactoringContext context,
            LocalDeclarationStatementSyntax localDeclaration)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(localDeclaration);

            if (!statementsInfo.Success)
            {
                return;
            }

            SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration);

            if (!localInfo.Success)
            {
                return;
            }

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

            ExpressionSyntax value = localInfo.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",
                ct => RefactorAsync(context.Document, localInfo, type, statementsInfo, ct),
                RefactoringIdentifiers.SplitDeclarationAndInitialization);
        }
        public static Task <Document> RefactorAsync(
            Document document,
            AssignmentExpressionSyntax assignmentExpression,
            CancellationToken cancellationToken)
        {
            var statement = (StatementSyntax)assignmentExpression.Parent;

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            statements = statements.RemoveAt(index);

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

            IEnumerable <SyntaxTrivia> trivia = statementsInfo
                                                .Parent
                                                .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));
        }
示例#4
0
        private static async Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement);

            var methodDeclaration = (MethodDeclarationSyntax)statementsInfo.Parent.Parent;

            SyntaxToken asyncKeyword = methodDeclaration.Modifiers.Find(SyntaxKind.AsyncKeyword);

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

            string name = methodDeclaration.Identifier.ValueText;

            name = NameGenerator.Default.EnsureUniqueLocalName(name, semanticModel, statement.SpanStart, cancellationToken: cancellationToken);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            List <StatementSyntax> localFunctionStatements = statements.Skip(index).ToList();

            localFunctionStatements[0] = localFunctionStatements[0].TrimLeadingTrivia();

            LocalFunctionStatementSyntax localFunction = LocalFunctionStatement(
                (asyncKeyword.IsKind(SyntaxKind.AsyncKeyword)) ? TokenList(SyntaxKind.AsyncKeyword) : default,
示例#5
0
        private static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            StatementListSelection selectedStatements,
            CancellationToken cancellationToken)
        {
            int count = selectedStatements.Count;

            StatementSyntax newStatement;

            if (count == 1 &&
                !ifStatement.AsCascade().Any(f => f.Statement?.Kind() == SyntaxKind.Block))
            {
                newStatement = selectedStatements.First();
            }
            else
            {
                newStatement = SyntaxFactory.Block(selectedStatements);
            }

            ElseClauseSyntax elseClause = SyntaxFactory.ElseClause(newStatement).WithFormatterAnnotation();

            IfStatementSyntax lastIfStatement = ifStatement.AsCascade().Last();

            IfStatementSyntax newIfStatement = ifStatement.ReplaceNode(
                lastIfStatement,
                lastIfStatement.WithElse(elseClause));

            SyntaxList <StatementSyntax> newStatements = selectedStatements
                                                         .UnderlyingList
                                                         .Replace(ifStatement, newIfStatement)
                                                         .RemoveRange(selectedStatements.FirstIndex, count);

            return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken));
        }
示例#6
0
        private static Task <Document> IfReturnToReturnWithConditionalExpressionAsync(
            Document document,
            IfReturnToReturnWithConditionalExpressionAnalysis analysis,
            CancellationToken cancellationToken = default)
        {
            IfStatementSyntax ifStatement = analysis.IfStatement;

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(ifStatement);

            ConditionalExpressionSyntax conditionalExpression = CreateConditionalExpression(ifStatement.Condition, analysis.Expression1, analysis.Expression2);

            StatementSyntax newStatement = ReturnStatement(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));
        }
示例#7
0
        private static Task <Document> DuplicateStatementAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement);

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

                if (index == 0 &&
                    statementsInfo.Parent is BlockSyntax block &&
                    block.OpenBraceToken.GetFullSpanEndLine() == statement.GetFullSpanStartLine())
                {
                    statement = statement.PrependToLeadingTrivia(CSharpFactory.NewLine());
                }

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

                StatementListInfo newInfo = statementsInfo.WithStatements(newStatements);

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

                BlockSyntax block = SyntaxFactory.Block(statements);

                return(document.ReplaceNodeAsync(statement, block, cancellationToken));
            }
        }
示例#8
0
        private static Task <Document> ConvertWhileStatementToForStatementAsync(
            Document document,
            WhileStatementSyntax whileStatement,
            CancellationToken cancellationToken)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(whileStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(whileStatement);

            SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)statements[index - 1]);

            var block = (BlockSyntax)whileStatement.Statement;

            var expressionStatement = (ExpressionStatementSyntax)block.Statements.Last();

            var postIncrementExpression = (PostfixUnaryExpressionSyntax)expressionStatement.Expression;

            BlockSyntax newBlock = block.WithStatements(block.Statements.Remove(expressionStatement));

            ForStatementSyntax forStatement = CSharpFactory.ForStatement(
                declaration: localInfo.Declaration.TrimTrivia(),
                condition: whileStatement.Condition,
                incrementor: postIncrementExpression.TrimTrivia(),
                statement: newBlock);

            forStatement = forStatement
                           .WithLeadingTrivia(localInfo.Statement.GetLeadingTrivia().AddRange(whileStatement.GetLeadingTrivia().EmptyIfWhitespace()))
                           .WithFormatterAnnotation();

            SyntaxList <StatementSyntax> newStatements = statements.ReplaceRange(index - 1, 2, new StatementSyntax[] { forStatement });

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
示例#9
0
        public static Task <Document> RefactorAsync(
            Document document,
            LocalFunctionStatementSyntax localFunction,
            bool copyAfter = true,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfos = SyntaxInfo.StatementListInfo(localFunction);

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

            if (index == 0)
            {
                if (copyAfter)
                {
                    if (statementsInfos.ParentAsBlock.OpenBraceToken.GetFullSpanEndLine() == localFunction.GetFullSpanStartLine())
                    {
                        localFunction = localFunction.WithLeadingTrivia(localFunction.GetLeadingTrivia().Insert(0, NewLine()));
                    }
                }
                else
                {
                    localFunction = localFunction.WithTrailingTrivia(localFunction.GetTrailingTrivia().Add(NewLine()));
                }
            }

            int insertIndex = (copyAfter) ? index + 1 : index;

            SyntaxList <StatementSyntax> newStatements = statements.Insert(insertIndex, localFunction.WithNavigationAnnotation());

            return(document.ReplaceStatementsAsync(statementsInfos, newStatements, cancellationToken));
        }
示例#10
0
        public static Task <Document> RefactorAsync(
            Document document,
            UsingStatementSyntax usingStatement,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(usingStatement);

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

            StatementListInfo 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.Parent, newStatementsInfo.Parent.WithFormatterAnnotation(), cancellationToken));
        }
        private static bool NullCheckExists(ExpressionSyntax expression, StatementSyntax statement)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(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, NullCheckStyles.NotEqualsToNull);

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

            return(CSharpFactory.AreEquivalent(expression, nullCheck.Expression));
        }
示例#12
0
        public static Task <Document> RefactorAsync(
            Document document,
            StatementListSelection selectedStatements,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ImmutableArray <IfStatementSyntax> ifStatements = selectedStatements.Cast <IfStatementSyntax>().ToImmutableArray();

            IfStatementSyntax newIfStatement = IfStatement(
                BinaryExpression(SyntaxKind.LogicalOrExpression, ifStatements.Select(f => f.Condition)),
                Block(CreateStatements(ifStatements)));

            SyntaxList <StatementSyntax> statements = selectedStatements.UnderlyingList;

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

            SyntaxList <StatementSyntax> newStatements = statements.Replace(
                ifStatements[0],
                newIfStatement
                .WithLeadingTrivia(ifStatements[0].GetLeadingTrivia())
                .WithTrailingTrivia(ifStatements[ifStatements.Length - 1].GetTrailingTrivia()));

            for (int i = 1; i < ifStatements.Length; i++)
            {
                newStatements = newStatements.RemoveAt(index + 1);
            }

            return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken));
        }
示例#13
0
        private static Task <Document> IfReturnToReturnWithBooleanExpressionAsync(
            Document document,
            IfReturnToReturnWithBooleanExpressionAnalysis analysis,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(analysis.IfStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(analysis.IfStatement);

            ExpressionSyntax expression = GetBooleanExpression(
                analysis.IfStatement.Condition,
                analysis.Expression1,
                analysis.Expression2,
                analysis.SemanticModel,
                cancellationToken);

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

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

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
        public static Task <Document> RefactorAsync(
            Document document,
            ObjectCreationExpressionSyntax objectCreation,
            StatementListSelection selectedStatements,
            CancellationToken cancellationToken = default)
        {
            ExpressionStatementSyntax[] expressionStatements = selectedStatements
                                                               .Skip(1)
                                                               .Cast <ExpressionStatementSyntax>()
                                                               .ToArray();

            StatementSyntax firstStatement = selectedStatements.First();

            SyntaxList <StatementSyntax> newStatements = selectedStatements.UnderlyingList.Replace(
                firstStatement,
                firstStatement.ReplaceNode(
                    objectCreation,
                    objectCreation.WithInitializer(CreateInitializer(objectCreation, expressionStatements))));

            int count = expressionStatements.Length;
            int index = selectedStatements.FirstIndex + 1;

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

            return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken));
        }
示例#15
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());

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(expressionStatement);

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

                return(Document.ReplaceNodeAsync(statementsInfo.Parent, newInfo.Parent, cancellationToken));
            }
            else
            {
                return(Document.ReplaceNodeAsync(expressionStatement, Block(newStatements), cancellationToken));
            }
        }
示例#16
0
        private static Task <Document> RefactorAsync(
            Document document,
            LocalDeclarationStatementSyntax localDeclaration,
            CancellationToken cancellationToken)
        {
            VariableDeclaratorSyntax variableDeclarator = localDeclaration
                                                          .Declaration
                                                          .Variables
                                                          .Single();

            ExpressionSyntax expression = variableDeclarator
                                          .Initializer
                                          .Value
                                          .WalkDownParentheses();

            AsExpressionInfo asExpressionInfo = SyntaxInfo.AsExpressionInfo(expression);

            PrefixUnaryExpressionSyntax newCondition = LogicalNotExpression(
                ParenthesizedExpression(
                    IsPatternExpression(
                        asExpressionInfo.Expression,
                        DeclarationPattern(
                            asExpressionInfo.Type,
                            SingleVariableDesignation(variableDeclarator.Identifier)))));

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(localDeclaration);

            int index = statementsInfo.IndexOf(localDeclaration);

            var ifStatement = (IfStatementSyntax)statementsInfo[index + 1];

            SyntaxTriviaList leadingTrivia = statementsInfo.Parent
                                             .DescendantTrivia(TextSpan.FromBounds(localDeclaration.SpanStart, ifStatement.SpanStart))
                                             .ToSyntaxTriviaList()
                                             .EmptyIfWhitespace();

            leadingTrivia = localDeclaration.GetLeadingTrivia().AddRange(leadingTrivia);

            StatementSyntax newStatement = ifStatement.Statement;

            if (ifStatement.SingleNonBlockStatementOrDefault() is ReturnStatementSyntax returnStatement &&
                returnStatement.Expression?.WalkDownParentheses() is IdentifierNameSyntax identifierName &&
                string.Equals(identifierName.Identifier.ValueText, variableDeclarator.Identifier.ValueText, System.StringComparison.Ordinal))
            {
                newStatement = newStatement.ReplaceNode(returnStatement.Expression, NullLiteralExpression().WithTriviaFrom(returnStatement.Expression));
            }

            IfStatementSyntax newIfStatement = ifStatement
                                               .WithCondition(newCondition.WithTriviaFrom(ifStatement.Condition))
                                               .WithStatement(newStatement)
                                               .WithLeadingTrivia(leadingTrivia)
                                               .WithFormatterAnnotation();

            SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements.ReplaceRange(index, 2, newIfStatement);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
        public bool Analyze(
            SimpleMemberInvocationExpressionInfo invocationInfo,
            StatementSyntax statement,
            string name,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (statement.SpanOrTrailingTriviaContainsDirectives())
            {
                return(false);
            }

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement);

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

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

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

            IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationInfo.InvocationExpression, cancellationToken);

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

            ITypeSymbol returnType = methodSymbol.ReturnType;

            int i = statements.IndexOf(statement);

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

            int j = i;

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

                j++;
            }

            return(j > i);
        }
示例#18
0
        public static Task <Document> RemoveRedundantAssignmentAfterLocalDeclarationAsync(
            Document document,
            VariableDeclaratorSyntax declarator,
            CancellationToken cancellationToken = default)
        {
            var declaration = (VariableDeclarationSyntax)declarator.Parent;

            var localDeclaration = (LocalDeclarationStatementSyntax)declaration.Parent;

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(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));
        }
示例#19
0
        private static void Analyze(
            SyntaxNodeAnalysisContext context,
            StatementSyntax containingStatement,
            SyntaxToken token,
            StatementSyntax statement)
        {
            if (token.IsMissing)
            {
                return;
            }

            if (statement?.IsKind(SyntaxKind.Block, SyntaxKind.EmptyStatement) != false)
            {
                return;
            }

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(containingStatement);

            if (!statementsInfo.Success)
            {
                return;
            }

            SyntaxTree syntaxTree = containingStatement.SyntaxTree;

            if (!syntaxTree.IsMultiLineSpan(TextSpan.FromBounds(token.SpanStart, statement.SpanStart)))
            {
                return;
            }

            StatementSyntax nextStatement = containingStatement.NextStatement();

            if (nextStatement == null)
            {
                return;
            }

            if (syntaxTree.GetLineCount(TextSpan.FromBounds(statement.Span.End, nextStatement.SpanStart)) > 2)
            {
                return;
            }

            SyntaxTrivia trivia = statement
                                  .GetTrailingTrivia()
                                  .FirstOrDefault(f => f.IsEndOfLineTrivia());

            if (!trivia.IsEndOfLineTrivia())
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(
                context,
                DiagnosticRules.AddEmptyLineAfterEmbeddedStatement,
                Location.Create(syntaxTree, trivia.Span.WithLength(0)));
        }
示例#20
0
        private static Task <Document> IfToReturnWithExpressionAsync(
            Document document,
            IfToReturnWithExpressionAnalysis analysis,
            CancellationToken cancellationToken = default)
        {
            ExpressionSyntax expression = analysis.Expression;

            if (analysis.Invert)
            {
                expression = SyntaxInverter.LogicallyInvert(expression, analysis.SemanticModel, cancellationToken);
            }

            StatementSyntax statement;

            if (analysis.IsYield)
            {
                statement = YieldReturnStatement(expression);
            }
            else
            {
                statement = ReturnStatement(expression);
            }

            IfStatementSyntax ifStatement = analysis.IfStatement;

            if (ifStatement.IsSimpleIf())
            {
                StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(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(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
            }
            else
            {
                StatementSyntax newNode = statement
                                          .WithTriviaFrom(ifStatement)
                                          .WithFormatterAnnotation();

                return(document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken));
            }
        }
示例#21
0
        private static Task <Document> SplitLocalDeclarationAsync(
            Document document,
            LocalDeclarationStatementSyntax statement,
            CancellationToken cancellationToken)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement);

            SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements.ReplaceRange(
                statement,
                SplitLocalDeclaration(statement));

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
示例#22
0
        private static async Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement);

            var methodDeclaration = (MethodDeclarationSyntax)statementsInfo.Parent.Parent;

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

            string name = methodDeclaration.Identifier.ValueText;

            if (!name.EndsWith("Iterator", StringComparison.Ordinal))
            {
                name += "Iterator";
            }

            name = NameGenerator.Default.EnsureUniqueLocalName(name, semanticModel, statement.SpanStart, cancellationToken: cancellationToken);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            List <StatementSyntax> localFunctionStatements = statements.Skip(index).ToList();

            int lastIndex = localFunctionStatements.Count - 1;

            localFunctionStatements[lastIndex] = localFunctionStatements[lastIndex].WithoutTrailingTrivia();

            LocalFunctionStatementSyntax localFunction = LocalFunctionStatement(
                default(SyntaxTokenList),
                methodDeclaration.ReturnType.WithoutTrivia(),
                Identifier(name).WithRenameAnnotation(),
                ParameterList(),
                Block(localFunctionStatements).WithTrailingTrivia(statements.Last().GetTrailingTrivia()));

            localFunction = localFunction.WithFormatterAnnotation();

            ReturnStatementSyntax returnStatement = ReturnStatement(
                Token(SyntaxKind.ReturnKeyword).WithLeadingTrivia(statement.GetLeadingTrivia()),
                InvocationExpression(IdentifierName(name)),
                SemicolonToken());

            SyntaxList <StatementSyntax> newStatements = statements.ReplaceRange(
                index,
                statements.Count - index,
                new StatementSyntax[] { returnStatement, localFunction });

            return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
        }
示例#23
0
        private static Task <Document> RefactorAsync(
            Document document,
            LocalDeclarationStatementSyntax localDeclaration,
            CancellationToken cancellationToken)
        {
            VariableDeclaratorSyntax variableDeclarator = localDeclaration
                                                          .Declaration
                                                          .Variables
                                                          .Single();

            ExpressionSyntax expression = variableDeclarator
                                          .Initializer
                                          .Value
                                          .WalkDownParentheses();

            AsExpressionInfo asExpressionInfo = SyntaxInfo.AsExpressionInfo(expression);

            PrefixUnaryExpressionSyntax newCondition = LogicalNotExpression(
                ParenthesizedExpression(
                    IsPatternExpression(
                        asExpressionInfo.Expression,
                        DeclarationPattern(
                            asExpressionInfo.Type,
                            SingleVariableDesignation(variableDeclarator.Identifier)))));

            StatementListInfo statements = SyntaxInfo.StatementListInfo(localDeclaration);

            int index = statements.IndexOf(localDeclaration);

            var ifStatement = (IfStatementSyntax)statements[index + 1];

            SyntaxTriviaList leadingTrivia = localDeclaration
                                             .DescendantTrivia(TextSpan.FromBounds(localDeclaration.SpanStart, ifStatement.SpanStart))
                                             .ToSyntaxTriviaList()
                                             .EmptyIfWhitespace();

            leadingTrivia = localDeclaration.GetLeadingTrivia().AddRange(leadingTrivia);

            IfStatementSyntax newIfStatement = ifStatement
                                               .WithCondition(newCondition.WithTriviaFrom(ifStatement.Condition))
                                               .WithLeadingTrivia(leadingTrivia);

            StatementListInfo newStatements = statements.RemoveAt(index).ReplaceAt(index, newIfStatement);

            return(document.ReplaceStatementsAsync(statements, newStatements, cancellationToken));
        }
        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
            {
                StatementListInfo            statementsInfo = SyntaxInfo.StatementListInfo(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));
        }
        private static async Task <Document> RefactorAsync(
            Document document,
            SwitchStatementSyntax switchStatement,
            CancellationToken cancellationToken)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(switchStatement);

            StatementListInfo newStatementsInfo = await RefactorAsync(
                document,
                switchStatement,
                statementsInfo,
                CreateNewSwitchStatement,
                switchStatement.Sections.Count,
                switchStatement.Sections.Any(f => f.ContainsDefaultLabel()),
                cancellationToken).ConfigureAwait(false);

            return(await document.ReplaceNodeAsync(statementsInfo.Parent, newStatementsInfo.Parent, cancellationToken).ConfigureAwait(false));
        }
示例#26
0
        private static Task <Document> RefactorAsync(
            Document document,
            StatementListSelection selectedStatements,
            CancellationToken cancellationToken)
        {
            ImmutableArray <IfStatementSyntax> ifStatements = selectedStatements.Cast <IfStatementSyntax>().ToImmutableArray();

            SyntaxList <StatementSyntax> newStatements = selectedStatements.UnderlyingList.Replace(
                ifStatements[0],
                ifStatements[0]
                .WithCondition(BinaryExpression(SyntaxKind.LogicalOrExpression, ifStatements.Select(f => f.Condition)))
                .WithLeadingTrivia(ifStatements[0].GetLeadingTrivia())
                .WithTrailingTrivia(ifStatements[ifStatements.Length - 1].GetTrailingTrivia()));

            newStatements = newStatements.RemoveRange(selectedStatements.FirstIndex + 1, selectedStatements.Count - 1);

            return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken));
        }
示例#27
0
        private static Task <Document> ToAssignmentWithConditionalExpressionAsync(
            Document document,
            ToAssignmentWithConditionalExpressionAnalysis analysis,
            StatementSyntax newStatement,
            CancellationToken cancellationToken = default)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(analysis.IfStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(analysis.IfStatement);

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

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
示例#28
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());

                StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(expressionStatement);

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

                    editor.ReplaceNode(statementsInfo.Parent, newStatementsInfo.Parent);
                }
                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))
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

            SyntaxNode node = statementsInfo.Parent;

            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));
        }
示例#30
0
        private static async Task <Document> RefactorAsync(
            Document document,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement);

            var methodDeclaration = (MethodDeclarationSyntax)statementsInfo.Parent.Parent;

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

            string name = methodDeclaration.Identifier.ValueText;

            name = NameGenerator.Default.EnsureUniqueLocalName(name, semanticModel, statement.SpanStart, cancellationToken: cancellationToken);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            List <StatementSyntax> localFunctionStatements = statements.Skip(index).ToList();

            localFunctionStatements[0] = localFunctionStatements[0].TrimLeadingTrivia();

            LocalFunctionStatementSyntax localFunction = LocalFunctionStatement(
                default(SyntaxTokenList),
                methodDeclaration.ReturnType.WithoutTrivia(),
                Identifier(name).WithRenameAnnotation(),
                ParameterList(),
                Block(localFunctionStatements));

            ReturnStatementSyntax returnStatement = ReturnStatement(
                Token(TriviaList(NewLine()), SyntaxKind.ReturnKeyword, TriviaList()),
                InvocationExpression(IdentifierName(name)),
                Token(SyntaxTriviaList.Empty, SyntaxKind.SemicolonToken, TriviaList(NewLine(), NewLine())));

            SyntaxList <StatementSyntax> newStatements = statements.ReplaceRange(
                index,
                statements.Count - index,
                new StatementSyntax[] { returnStatement.WithFormatterAnnotation(), localFunction.WithFormatterAnnotation() });

            return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
        }