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));
        }
        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));
        }
예제 #3
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));
            }
        }
예제 #4
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));
        }
예제 #5
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));
            }
        }
예제 #6
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));
        }
예제 #7
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));
        }
예제 #8
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));
        }
예제 #9
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,
        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);
        }
예제 #11
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));
        }
예제 #12
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));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            ExpressionSyntax expression,
            SyntaxList <StatementSyntax> statements,
            StatementListInfo statementsInfo,
            int statementIndex,
            int lastStatementIndex,
            CancellationToken cancellationToken)
        {
            IEnumerable <StatementSyntax> blockStatements = statements
                                                            .Skip(statementIndex + 1)
                                                            .Take(lastStatementIndex - statementIndex);

            IfStatementSyntax ifStatement = CreateNullCheck(expression, List(blockStatements));

            if (lastStatementIndex < statements.Count - 1)
            {
                ifStatement = ifStatement.AppendToTrailingTrivia(NewLine());
            }

            IEnumerable <StatementSyntax> newStatements = statements.Take(statementIndex + 1)
                                                          .Concat(new IfStatementSyntax[] { ifStatement })
                                                          .Concat(statements.Skip(lastStatementIndex + 1));

            return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken));
        }
예제 #14
0
 internal static Task <Document> ReplaceStatementsAsync(
     this Document document,
     StatementListInfo statementsInfo,
     StatementListInfo newStatementsInfo,
     CancellationToken cancellationToken = default)
 {
     return(document.ReplaceNodeAsync(statementsInfo.Parent, newStatementsInfo.Parent, cancellationToken));
 }
예제 #15
0
 /// <summary>
 /// Creates a new document with the specified statements replaced with new statements.
 /// </summary>
 /// <param name="document"></param>
 /// <param name="statementsInfo"></param>
 /// <param name="newStatements"></param>
 /// <param name="cancellationToken"></param>
 public static Task <Document> ReplaceStatementsAsync(
     this Document document,
     StatementListInfo statementsInfo,
     IEnumerable <StatementSyntax> newStatements,
     CancellationToken cancellationToken = default)
 {
     return(ReplaceStatementsAsync(document, statementsInfo, List(newStatements), cancellationToken));
 }
예제 #16
0
 internal static Task <Document> ReplaceStatementsAsync(
     this Document document,
     StatementListInfo statementsInfo,
     SyntaxList <StatementSyntax> newStatements,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(document.ReplaceNodeAsync(statementsInfo.Parent, statementsInfo.WithStatements(newStatements).Parent, cancellationToken));
 }
예제 #17
0
            private SyntaxNode Rewrite(StatementListInfo statementsInfo)
            {
                _statementsInfo = statementsInfo;

                var ifStatement = (IfStatementSyntax)_statementsInfo.Statements.LastButOne();

                return(Rewrite(_statementsInfo, ifStatement));
            }
예제 #18
0
        private static Task <Document> RefactorAsync(
            Document document,
            StatementListInfo statementsInfo,
            StatementSyntax statement,
            InitializerExpressionSyntax initializer,
            ExpressionSyntax initializedExpression,
            CancellationToken cancellationToken)
        {
            ExpressionStatementSyntax[] expressions = CreateExpressionStatements(initializer, initializedExpression).ToArray();

            expressions[expressions.Length - 1] = expressions[expressions.Length - 1]
                                                  .WithTrailingTrivia(statement.GetTrailingTrivia());

            var objectCreationExpression = (ObjectCreationExpressionSyntax)initializer.Parent;

            ObjectCreationExpressionSyntax newObjectCreationExpression = objectCreationExpression.WithInitializer(null);

            if (newObjectCreationExpression.ArgumentList == null)
            {
                TypeSyntax type = newObjectCreationExpression.Type;

                newObjectCreationExpression = newObjectCreationExpression
                                              .WithArgumentList(ArgumentList().WithTrailingTrivia(type.GetTrailingTrivia()))
                                              .WithType(type.WithoutTrailingTrivia());
            }

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            StatementSyntax newStatement = statement.ReplaceNode(objectCreationExpression, newObjectCreationExpression);

            SyntaxKind statementKind = statement.Kind();

            if (statementKind == SyntaxKind.ExpressionStatement)
            {
                var expressionStatement = (ExpressionStatementSyntax)newStatement;

                newStatement = expressionStatement
                               .WithExpression(expressionStatement.Expression.WithoutTrailingTrivia());
            }
            else if (statementKind == SyntaxKind.LocalDeclarationStatement)
            {
                var localDeclaration = (LocalDeclarationStatementSyntax)newStatement;

                newStatement = localDeclaration
                               .WithDeclaration(localDeclaration.Declaration.WithoutTrailingTrivia());
            }

            SyntaxList <StatementSyntax> newStatements = statements.Replace(statement, newStatement);

            SyntaxNode newNode = statementsInfo
                                 .WithStatements(newStatements.InsertRange(index + 1, expressions))
                                 .Parent
                                 .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(statementsInfo.Parent, newNode, cancellationToken));
        }
예제 #19
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));
        }
예제 #20
0
        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);
        }
예제 #21
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));
        }
예제 #22
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)));
        }
예제 #23
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));
            }
        }
예제 #24
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));
        }
예제 #25
0
        /// <summary>
        /// Creates a new document with the specified statements replaced with new statements.
        /// </summary>
        /// <param name="document"></param>
        /// <param name="statementsInfo"></param>
        /// <param name="newStatements"></param>
        /// <param name="cancellationToken"></param>
        public static Task <Document> ReplaceStatementsAsync(
            this Document document,
            StatementListInfo statementsInfo,
            SyntaxList <StatementSyntax> newStatements,
            CancellationToken cancellationToken = default)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            return(document.ReplaceNodeAsync(statementsInfo.Parent, statementsInfo.WithStatements(newStatements).Parent, cancellationToken));
        }
예제 #26
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));
        }
        public Task <Document> RefactorAsync(
            Document document,
            StatementListInfo statementsInfo,
            BinaryExpressionSyntax condition,
            ExpressionSyntax expression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var ifStatement = (IfStatementSyntax)condition.Parent;

            IfStatementSyntax newIfStatement = RemoveExpressionFromCondition(ifStatement, condition, expression)
                                               .WithFormatterAnnotation();

            SyntaxNode newNode = AddNextIf(statementsInfo, ifStatement, newIfStatement, expression);

            return(document.ReplaceNodeAsync(statementsInfo.Parent, newNode, cancellationToken));
        }
예제 #28
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));
        }