예제 #1
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));
        }
예제 #2
0
        public static void ComputeRefactorings(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count < 2)
            {
                return;
            }

            int ifStatementCount = 0;

            for (int i = 0; i < selectedStatements.Count - 1; i++)
            {
                if (!(selectedStatements[i] is IfStatementSyntax ifStatement))
                {
                    break;
                }

                foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
                {
                    if (ifOrElse.IsElse)
                    {
                        return;
                    }

                    StatementSyntax statement = ifOrElse.Statement;

                    if (statement is BlockSyntax block)
                    {
                        statement = block.Statements.LastOrDefault();
                    }

                    if (statement == null)
                    {
                        return;
                    }

                    if (!statement.IsKind(
                            SyntaxKind.ReturnStatement,
                            SyntaxKind.ContinueStatement,
                            SyntaxKind.BreakStatement,
                            SyntaxKind.ThrowStatement))
                    {
                        return;
                    }
                }

                ifStatementCount++;
            }

            if (ifStatementCount == 0)
            {
                return;
            }

            Document document = context.Document;

            context.RegisterRefactoring(
                "Convert to if-else",
                ct => RefactorAsync(document, selectedStatements, ifStatementCount, ct),
                RefactoringIdentifiers.ConvertStatementsToIfElse);
        }
예제 #3
0
 public static ImmutableArray <IfAnalysis> Analyze(
     StatementListSelection selectedStatements,
     SemanticModel semanticModel,
     CancellationToken cancellationToken)
 {
     return(Analyze(selectedStatements, DefaultOptions, semanticModel, cancellationToken));
 }
예제 #4
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 void ComputeRefactorings(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count != 2)
            {
                return;
            }

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

            if (!simpleAssignment.Success)
            {
                return;
            }

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

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

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

            context.RegisterRefactoring(
                "Remove unnecessary assignment",
                ct => RefactorAsync(context.Document, simpleAssignment.Statement, returnStatement, ct),
                RefactoringDescriptors.RemoveUnnecessaryAssignment);
        }
예제 #6
0
        public static void ComputeRefactorings(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count != 2)
            {
                return;
            }

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

            if (!simpleAssignment.Success)
            {
                return;
            }

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

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

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

            context.RegisterRefactoring(
                "Merge statements",
                ct => RefactorAsync(context.Document, simpleAssignment.Statement, returnStatement, ct),
                RefactoringIdentifiers.MergeAssignmentExpressionWithReturnStatement);
        }
        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));
        }
예제 #8
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));
        }
예제 #9
0
        private static bool VerifyLocalDeclarationStatements(
            StatementListSelection selectedStatements,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            ITypeSymbol typeSymbol = null;

            for (int i = 0; i < selectedStatements.Count - 1; i++)
            {
                StatementSyntax statement = selectedStatements[i];

                if (!(statement is LocalDeclarationStatementSyntax localDeclaration))
                {
                    return(false);
                }

                VariableDeclarationSyntax declaration = localDeclaration.Declaration;

                foreach (VariableDeclaratorSyntax variable in declaration.Variables)
                {
                    var symbol = (ILocalSymbol)semanticModel.GetDeclaredSymbol(variable, cancellationToken);

                    if (symbol == null)
                    {
                        continue;
                    }

                    if (symbol.Type.IsErrorType())
                    {
                        continue;
                    }

                    if (typeSymbol == null)
                    {
                        typeSymbol = symbol.Type;
                    }
                    else if (!typeSymbol.Equals(symbol.Type))
                    {
                        return(false);
                    }

                    SyntaxList <StatementSyntax> statements = selectedStatements.UnderlyingList;

                    for (int j = selectedStatements.LastIndex + 1; j < statements.Count; j++)
                    {
                        foreach (SyntaxNode node in statements[j].DescendantNodes())
                        {
                            if (node.IsKind(SyntaxKind.IdentifierName) &&
                                symbol.Equals(semanticModel.GetSymbol(node, cancellationToken)))
                            {
                                return(false);
                            }
                        }
                    }
                }
            }

            return(true);
        }
예제 #10
0
        public static ImmutableArray <IfAnalysis> Analyze(
            StatementListSelection selectedStatements,
            IfAnalysisOptions options,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (selectedStatements.Count != 2)
            {
                return(Empty);
            }

            StatementSyntax[] statements = selectedStatements.ToArray();

            StatementSyntax statement1 = statements[0];
            StatementSyntax statement2 = statements[1];

            if (statement1.ContainsDiagnostics)
            {
                return(Empty);
            }

            if (statement2.ContainsDiagnostics)
            {
                return(Empty);
            }

            SyntaxKind kind1 = statement1.Kind();
            SyntaxKind kind2 = statement2.Kind();

            if (kind1 == SyntaxKind.IfStatement)
            {
                if (kind2 == SyntaxKind.ReturnStatement)
                {
                    var ifStatement = (IfStatementSyntax)statement1;

                    if (ifStatement.IsSimpleIf())
                    {
                        return(Analyze(ifStatement, (ReturnStatementSyntax)statement2, options, semanticModel, cancellationToken));
                    }
                }
            }
            else if (options.UseConditionalExpression)
            {
                if (kind1 == SyntaxKind.LocalDeclarationStatement)
                {
                    if (kind2 == SyntaxKind.IfStatement)
                    {
                        return(Analyze((LocalDeclarationStatementSyntax)statement1, (IfStatementSyntax)statement2, options, semanticModel, cancellationToken));
                    }
                }
                else if (kind1 == SyntaxKind.ExpressionStatement &&
                         kind2 == SyntaxKind.IfStatement)
                {
                    return(Analyze((ExpressionStatementSyntax)statement1, (IfStatementSyntax)statement2, options, semanticModel, cancellationToken));
                }
            }

            return(Empty);
        }
예제 #11
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (!(selectedStatements.Last() is WhileStatementSyntax whileStatement))
            {
                return;
            }

            if (selectedStatements.Count == 1)
            {
                context.RegisterRefactoring(
                    Title,
                    cancellationToken => RefactorAsync(context.Document, whileStatement, cancellationToken),
                    RefactoringIdentifiers.ConvertWhileToFor);
            }
            else
            {
                SyntaxKind kind = selectedStatements.First().Kind();

                if (kind == SyntaxKind.LocalDeclarationStatement)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (FindLocalDeclarationStatementIndex(
                            whileStatement,
                            selectedStatements.UnderlyingList,
                            selectedStatements.FirstIndex,
                            selectedStatements.Count,
                            mustBeReferencedInsideWhileStatement: false,
                            semanticModel: semanticModel,
                            cancellationToken: context.CancellationToken) == selectedStatements.FirstIndex)
                    {
                        List <LocalDeclarationStatementSyntax> localDeclarations = selectedStatements
                                                                                   .Take(selectedStatements.Count - 1)
                                                                                   .Cast <LocalDeclarationStatementSyntax>()
                                                                                   .ToList();

                        context.RegisterRefactoring(
                            Title,
                            cancellationToken => RefactorAsync(context.Document, whileStatement, localDeclarations, cancellationToken),
                            RefactoringIdentifiers.ConvertWhileToFor);
                    }
                }
                else if (kind == SyntaxKind.ExpressionStatement)
                {
                    if (VerifyExpressionStatements(selectedStatements))
                    {
                        List <ExpressionStatementSyntax> expressionStatements = selectedStatements
                                                                                .Take(selectedStatements.Count - 1)
                                                                                .Cast <ExpressionStatementSyntax>()
                                                                                .ToList();

                        context.RegisterRefactoring(
                            Title,
                            cancellationToken => RefactorAsync(context.Document, whileStatement, expressionStatements, cancellationToken),
                            RefactoringIdentifiers.ConvertWhileToFor);
                    }
                }
            }
        }
예제 #12
0
 public static async Task ComputeRefactoringAsync(RefactoringContext context, BlockSyntax block)
 {
     if (SelectedStatementsRefactoring.IsAnyRefactoringEnabled(context) &&
         StatementListSelection.TryCreate(block, context.Span, out StatementListSelection selectedStatements))
     {
         await SelectedStatementsRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false);
     }
 }
예제 #13
0
        public static void ComputeRefactorings(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count < 2)
            {
                return;
            }

            StatementSyntax statement = null;

            for (int i = 0; i < selectedStatements.Count; i++)
            {
                if (!(selectedStatements[i] is IfStatementSyntax ifStatement))
                {
                    return;
                }

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

                ExpressionSyntax condition = ifStatement.Condition;

                if (condition?.IsMissing != false)
                {
                    return;
                }

                if (condition.WalkDownParentheses().IsKind(SyntaxKind.IsPatternExpression))
                {
                    return;
                }

                if (i == 0)
                {
                    statement = ifStatement.Statement;

                    if (statement == null)
                    {
                        return;
                    }
                }
                else if (!AreEquivalent(statement, ifStatement.Statement))
                {
                    return;
                }
            }

            Document document = context.Document;

            context.RegisterRefactoring(
                "Merge if statements",
                ct => RefactorAsync(document, selectedStatements, ct),
                RefactoringIdentifiers.MergeIfStatements);
        }
예제 #14
0
        public static void ComputeRefactoring(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.FirstIndex == 0)
            {
                return;
            }

            if (!CSharpFacts.IsJumpStatement(selectedStatements.Last().Kind()))
            {
                return;
            }

            StatementSyntax prevStatement = selectedStatements.UnderlyingList[selectedStatements.FirstIndex - 1];

            if (!(prevStatement is IfStatementSyntax ifStatement))
            {
                return;
            }

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                if (ifOrElse.IsElse)
                {
                    return;
                }

                StatementSyntax statement = ifOrElse.AsIf().Statement;

                if (statement is BlockSyntax block)
                {
                    statement = block.Statements.LastOrDefault();
                }

                if (statement == null)
                {
                    return;
                }

                if (!CSharpFacts.IsJumpStatement(statement.Kind()))
                {
                    return;
                }
            }

            context.RegisterRefactoring(
                "Wrap in else clause",
                cancellationToken => RefactorAsync(context.Document, ifStatement, selectedStatements, cancellationToken),
                RefactoringIdentifiers.WrapInElseClause);
        }
        public static void ComputeRefactoring(RefactoringContext context, StatementListSelection selectedStatements)
        {
            StatementSyntax lastStatement = selectedStatements.Last();

            if (!lastStatement.IsKind(SyntaxKind.ReturnStatement))
            {
                return;
            }

            if (selectedStatements.FirstIndex == 0)
            {
                return;
            }

            var returnStatement = (ReturnStatementSyntax)lastStatement;

            ExpressionSyntax expression = returnStatement.Expression;

            if (expression == null)
            {
                return;
            }

            StatementSyntax prevStatement = selectedStatements.UnderlyingList[selectedStatements.FirstIndex - 1];

            if (!prevStatement.IsKind(SyntaxKind.IfStatement))
            {
                return;
            }

            var ifStatement = (IfStatementSyntax)prevStatement;

            foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade())
            {
                if (ifOrElse.IsElse)
                {
                    return;
                }

                if (!IsLastStatementReturnStatement(ifOrElse))
                {
                    return;
                }
            }

            context.RegisterRefactoring(
                "Wrap in else clause",
                cancellationToken => RefactorAsync(context.Document, ifStatement, selectedStatements, cancellationToken));
        }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (!(selectedStatements.Last() is WhileStatementSyntax whileStatement))
            {
                return;
            }

            if (selectedStatements.Count == 1)
            {
                context.RegisterRefactoring(
                    Title,
                    cancellationToken => RefactorAsync(context.Document, whileStatement, cancellationToken));
            }
            else
            {
                SyntaxKind kind = selectedStatements.First().Kind();

                if (kind == SyntaxKind.LocalDeclarationStatement)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (VerifyLocalDeclarationStatements(selectedStatements, semanticModel, context.CancellationToken))
                    {
                        List <LocalDeclarationStatementSyntax> localDeclarations = selectedStatements
                                                                                   .Take(selectedStatements.Count - 1)
                                                                                   .Cast <LocalDeclarationStatementSyntax>()
                                                                                   .ToList();

                        context.RegisterRefactoring(
                            Title,
                            cancellationToken => RefactorAsync(context.Document, whileStatement, localDeclarations, cancellationToken));
                    }
                }
                else if (kind == SyntaxKind.ExpressionStatement)
                {
                    if (VerifyExpressionStatements(selectedStatements))
                    {
                        List <ExpressionStatementSyntax> expressionStatements = selectedStatements
                                                                                .Take(selectedStatements.Count - 1)
                                                                                .Cast <ExpressionStatementSyntax>()
                                                                                .ToList();

                        context.RegisterRefactoring(
                            Title,
                            cancellationToken => RefactorAsync(context.Document, whileStatement, expressionStatements, cancellationToken));
                    }
                }
            }
        }
        private static bool AreLocalDeclarations(
            StatementListSelection statements,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            ITypeSymbol prevTypeSymbol = null;

            for (int i = 0; i < statements.Count; i++)
            {
                StatementSyntax statement = statements[i];

                if (statement is not LocalDeclarationStatementSyntax localDeclaration)
                {
                    return(false);
                }

                TypeSyntax type = localDeclaration.Declaration?.Type;

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

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

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

                if (typeSymbol.IsErrorType())
                {
                    return(false);
                }

                if (prevTypeSymbol != null && !SymbolEqualityComparer.Default.Equals(prevTypeSymbol, typeSymbol))
                {
                    return(false);
                }

                prevTypeSymbol = typeSymbol;
            }

            return(true);
        }
예제 #18
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));
        }
예제 #19
0
        private static bool VerifyExpressionStatements(StatementListSelection selectedStatements)
        {
            for (int i = 0; i < selectedStatements.Count - 1; i++)
            {
                StatementSyntax statement = selectedStatements[i];

                if (!(statement is ExpressionStatementSyntax expressionStatement))
                {
                    return(false);
                }

                if (!CSharpFacts.CanBeInitializerExpressionInForStatement(expressionStatement.Expression.Kind()))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #20
0
        public async Task ComputeRefactoringAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(selectedStatements.FirstOrDefault() as LocalDeclarationStatementSyntax);

            if (!localInfo.Success)
            {
                return;
            }

            ExpressionSyntax value = localInfo.Value;

            if (value == null)
            {
                return;
            }

            if (value.Kind() == SyntaxKind.DefaultExpression)
            {
                return;
            }

            if (value is LiteralExpressionSyntax)
            {
                return;
            }

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

            var typeSymbol = semanticModel.GetTypeSymbol(localInfo.Type, context.CancellationToken) as INamedTypeSymbol;

            if (typeSymbol?.Implements(SpecialType.System_IDisposable, allInterfaces: true) != true)
            {
                return;
            }

            context.RegisterRefactoring(
                $"Using '{localInfo.IdentifierText}'",
                cancellationToken => RefactorAsync(context.Document, selectedStatements, cancellationToken),
                RefactoringIdentifiers.WrapInUsingStatement);
        }
예제 #21
0
        public static void ComputeRefactorings(RefactoringContext context, StatementListSelection selectedStatements)
        {
            int count = 0;

            for (int i = 0; i < selectedStatements.Count; i++)
            {
                if (!(selectedStatements[i] is IfStatementSyntax))
                {
                    return;
                }

                count++;
            }

            if (count <= 1)
            {
                return;
            }

            context.RegisterRefactoring(
                "Merge if statements",
                cancellationToken => RefactorAsync(context.Document, selectedStatements, cancellationToken));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            StatementListSelection selectedStatements,
            CancellationToken cancellationToken = default)
        {
            LocalDeclarationStatementSyntax[] localDeclarations = selectedStatements
                                                                  .Cast <LocalDeclarationStatementSyntax>()
                                                                  .ToArray();

            LocalDeclarationStatementSyntax localDeclaration = localDeclarations[0];

            SyntaxList <StatementSyntax> statements = selectedStatements.UnderlyingList;

            int index = statements.IndexOf(localDeclaration);

            VariableDeclaratorSyntax[] variables = localDeclarations
                                                   .Skip(1)
                                                   .Select(f => f.Declaration)
                                                   .SelectMany(f => f.Variables)
                                                   .ToArray();

            LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration
                                                                  .AddDeclarationVariables(variables)
                                                                  .WithTrailingTrivia(localDeclarations[localDeclarations.Length - 1].GetTrailingTrivia())
                                                                  .WithFormatterAnnotation();

            SyntaxList <StatementSyntax> newStatements = statements.Replace(
                localDeclaration,
                newLocalDeclaration);

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

            return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken));
        }
        public Task <Document> RefactorAsync(
            Document document,
            StatementListSelection selectedStatements,
            CancellationToken cancellationToken = default)
        {
            StatementSyntax[] statements = selectedStatements.ToArray();

            int index = selectedStatements.FirstIndex;

            SyntaxTriviaList leadingTrivia  = statements[0].GetLeadingTrivia();
            SyntaxTriviaList trailingTrivia = statements[statements.Length - 1].GetTrailingTrivia();

            statements[0] = statements[0].WithLeadingTrivia();
            statements[statements.Length - 1] = statements[statements.Length - 1].WithTrailingTrivia();

            SyntaxList <StatementSyntax> newStatements = selectedStatements.UnderlyingList;

            int cnt = statements.Length;

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

            TStatement statement = CreateStatement(statements.ToImmutableArray());

            statement = statement
                        .WithLeadingTrivia(leadingTrivia)
                        .WithTrailingTrivia(trailingTrivia)
                        .WithFormatterAnnotation();

            newStatements = newStatements.Insert(index, statement);

            return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken));
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count <= 1)
            {
                return;
            }

            StatementSyntax firstStatement = selectedStatements.First();

            SemanticModel semanticModel = null;
            ISymbol       symbol        = null;
            ObjectCreationExpressionSyntax objectCreation = null;

            SyntaxKind kind = firstStatement.Kind();

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

                VariableDeclaratorSyntax variable = localDeclaration
                                                    .Declaration?
                                                    .Variables
                                                    .SingleOrDefault(shouldThrow: false);

                objectCreation = variable?.Initializer?.Value as ObjectCreationExpressionSyntax;

                if (objectCreation != null)
                {
                    semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    symbol = semanticModel.GetDeclaredSymbol(variable, context.CancellationToken);
                }
            }
            else if (kind == SyntaxKind.ExpressionStatement)
            {
                var expressionStatement = (ExpressionStatementSyntax)firstStatement;

                if (expressionStatement.Expression is AssignmentExpressionSyntax assignment)
                {
                    objectCreation = assignment.Right as ObjectCreationExpressionSyntax;

                    if (objectCreation != null)
                    {
                        semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        symbol = semanticModel.GetSymbol(assignment.Left, context.CancellationToken);
                    }
                }
            }

            if (objectCreation == null)
            {
                return;
            }

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

            for (int i = 1; i < selectedStatements.Count; i++)
            {
                if (!IsValidAssignmentStatement(selectedStatements[i], symbol, semanticModel, context.CancellationToken))
                {
                    return;
                }
            }

            context.RegisterRefactoring(
                "Collapse to initializer",
                ct => RefactorAsync(context.Document, objectCreation, selectedStatements, ct),
                RefactoringIdentifiers.CollapseToInitializer);
        }
예제 #25
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInUsingStatement))
            {
                var refactoring = new WrapStatements.WrapInUsingStatementRefactoring();
                await refactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.CollapseToInitializer))
            {
                await CollapseToInitializerRefactoring.ComputeRefactoringsAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeIfStatements))
            {
                MergeIfStatementsRefactoring.ComputeRefactorings(context, selectedStatements);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ConvertStatementsToIfElse))
            {
                ConvertStatementsToIfElseRefactoring.ComputeRefactorings(context, selectedStatements);
            }

            if (context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf,
                    RefactoringIdentifiers.ConvertIfToConditionalOperator,
                    RefactoringIdentifiers.SimplifyIf))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                IfAnalysisOptions options = IfStatementRefactoring.GetIfAnalysisOptions(context);

                foreach (IfAnalysis analysis in IfAnalysis.Analyze(selectedStatements, options, semanticModel, context.CancellationToken))
                {
                    string refactoringId = IfStatementRefactoring.GetRefactoringIdentifier(analysis);

                    if (context.IsRefactoringEnabled(refactoringId))
                    {
                        context.RegisterRefactoring(
                            analysis.Title,
                            cancellationToken => IfRefactoring.RefactorAsync(context.Document, analysis, cancellationToken),
                            equivalenceKey: refactoringId);
                    }
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeLocalDeclarations))
            {
                await MergeLocalDeclarationsRefactoring.ComputeRefactoringsAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeAssignmentExpressionWithReturnStatement))
            {
                MergeAssignmentExpressionWithReturnStatementRefactoring.ComputeRefactorings(context, selectedStatements);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.CheckExpressionForNull))
            {
                await CheckExpressionForNullRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ConvertWhileToFor))
            {
                await ConvertWhileToForRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInCondition))
            {
                context.RegisterRefactoring(
                    WrapInIfStatementRefactoring.Title,
                    ct => WrapInIfStatementRefactoring.Instance.RefactorAsync(context.Document, selectedStatements, ct),
                    RefactoringIdentifiers.WrapInCondition);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInTryCatch))
            {
                context.RegisterRefactoring(
                    WrapInTryCatchRefactoring.Title,
                    ct => WrapInTryCatchRefactoring.Instance.RefactorAsync(context.Document, selectedStatements, ct),
                    RefactoringIdentifiers.WrapInTryCatch);
            }
        }
예제 #26
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, SwitchSectionSyntax switchSection)
        {
            if (SelectedStatementsRefactoring.IsAnyRefactoringEnabled(context) &&
                StatementListSelection.TryCreate(switchSection, context.Span, out StatementListSelection selectedStatements))
            {
                await SelectedStatementsRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitSwitchLabels))
            {
                SplitSwitchLabelsRefactoring.ComputeRefactoring(context, switchSection);
            }

            if (context.Span.IsEmpty &&
                context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.AddBracesToSwitchSection,
                    RefactoringIdentifiers.AddBracesToSwitchSections,
                    RefactoringIdentifiers.RemoveBracesFromSwitchSection,
                    RefactoringIdentifiers.RemoveBracesFromSwitchSections))
            {
                var switchStatement = (SwitchStatementSyntax)switchSection.Parent;

                SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections;

                BracesAnalysis analysis = BracesAnalysis.AnalyzeBraces(switchSection);

                if (analysis.AddBraces)
                {
                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddBracesToSwitchSection))
                    {
                        context.RegisterRefactoring(
                            AddBracesToSwitchSectionRefactoring.Title,
                            cancellationToken => AddBracesToSwitchSectionRefactoring.RefactorAsync(context.Document, switchSection, cancellationToken),
                            RefactoringIdentifiers.AddBracesToSwitchSection);
                    }

                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddBracesToSwitchSections) &&
                        sections.Any(f => f != switchSection && AddBracesToSwitchSectionAnalysis.CanAddBraces(f)))
                    {
                        context.RegisterRefactoring(
                            AddBracesToSwitchSectionsRefactoring.Title,
                            cancellationToken => AddBracesToSwitchSectionsRefactoring.RefactorAsync(context.Document, switchStatement, null, cancellationToken),
                            RefactoringIdentifiers.AddBracesToSwitchSections);
                    }
                }
                else if (analysis.RemoveBraces)
                {
                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveBracesFromSwitchSection))
                    {
                        context.RegisterRefactoring(
                            RemoveBracesFromSwitchSectionRefactoring.Title,
                            cancellationToken => RemoveBracesFromSwitchSectionRefactoring.RefactorAsync(context.Document, switchSection, cancellationToken),
                            RefactoringIdentifiers.RemoveBracesFromSwitchSection);
                    }

                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveBracesFromSwitchSections) &&
                        sections.Any(f => f != switchSection && RemoveBracesFromSwitchSectionRefactoring.CanRemoveBraces(f)))
                    {
                        context.RegisterRefactoring(
                            RemoveBracesFromSwitchSectionsRefactoring.Title,
                            cancellationToken => RemoveBracesFromSwitchSectionsRefactoring.RefactorAsync(context.Document, switchStatement, null, cancellationToken),
                            RefactoringIdentifiers.RemoveBracesFromSwitchSections);
                    }
                }
            }
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count <= 1)
            {
                return;
            }

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

            if (!AreLocalDeclarations(selectedStatements, semanticModel, context.CancellationToken))
            {
                return;
            }

            context.RegisterRefactoring(
                "Merge local declarations",
                ct => RefactorAsync(context.Document, selectedStatements, ct),
                RefactoringDescriptors.MergeLocalDeclarations);
        }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInUsingStatement))
            {
                var refactoring = new WrapStatements.WrapInUsingStatementRefactoring();
                await refactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.CollapseToInitializer))
            {
                await CollapseToInitializerRefactoring.ComputeRefactoringsAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeIfStatements))
            {
                MergeIfStatementsRefactoring.ComputeRefactorings(context, selectedStatements);
            }

            if (context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf,
                    RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf,
                    RefactoringIdentifiers.SimplifyIf))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                var options = new IfAnalysisOptions(
                    useCoalesceExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf),
                    useConditionalExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf),
                    useBooleanExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.SimplifyIf),
                    useExpression: false);

                foreach (IfAnalysis analysis in IfAnalysis.Analyze(selectedStatements, options, semanticModel, context.CancellationToken))
                {
                    context.RegisterRefactoring(
                        analysis.Title,
                        cancellationToken => IfRefactoring.RefactorAsync(context.Document, analysis, cancellationToken));
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeLocalDeclarations))
            {
                await MergeLocalDeclarationsRefactoring.ComputeRefactoringsAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeAssignmentExpressionWithReturnStatement))
            {
                MergeAssignmentExpressionWithReturnStatementRefactoring.ComputeRefactorings(context, selectedStatements);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.CheckExpressionForNull))
            {
                await CheckExpressionForNullRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceWhileWithFor))
            {
                await ReplaceWhileWithForRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInElseClause))
            {
                WrapInElseClauseRefactoring.ComputeRefactoring(context, selectedStatements);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInCondition))
            {
                context.RegisterRefactoring(
                    WrapInIfStatementRefactoring.Title,
                    ct => WrapInIfStatementRefactoring.Instance.RefactorAsync(context.Document, selectedStatements, ct));
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInTryCatch))
            {
                context.RegisterRefactoring(
                    WrapInTryCatchRefactoring.Title,
                    ct => WrapInTryCatchRefactoring.Instance.RefactorAsync(context.Document, selectedStatements, ct));
            }
        }
        internal static async Task ComputeRefactoringAsync(RefactoringContext context, StatementListSelection selectedStatements)
        {
            if (selectedStatements.Count <= 1)
            {
                return;
            }

            StatementSyntax statement = selectedStatements.First();

            SyntaxKind kind = statement.Kind();

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

                SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration);

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

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

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

                SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(expressionStatement);

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

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

                RegisterRefactoring(context, assignmentInfo.Left, expressionStatement, selectedStatements.Count - 1);
            }
        }
예제 #30
0
        private static Task <Document> RefactorAsync(
            Document document,
            StatementListSelection selectedStatements,
            int ifStatementCount,
            CancellationToken cancellationToken)
        {
            IfStatementSyntax newIfStatement = null;

            for (int i = ifStatementCount - 1; i >= 0; i--)
            {
                var ifStatement = (IfStatementSyntax)selectedStatements[i];

                IfStatementSyntax lastIf = ifStatement.GetCascadeInfo().Last.AsIf();

                StatementSyntax elseStatement = newIfStatement;

                if (elseStatement == null)
                {
                    if (selectedStatements.Count - ifStatementCount > 1)
                    {
                        elseStatement = Block(selectedStatements.Skip(ifStatementCount));
                    }
                    else
                    {
                        elseStatement = selectedStatements.Last();

                        if (!elseStatement.IsKind(SyntaxKind.IfStatement) &&
                            lastIf.Statement.IsKind(SyntaxKind.Block))
                        {
                            elseStatement = Block(elseStatement);
                        }
                    }
                }

                StatementSyntax newStatement = lastIf.Statement;

                if (!newStatement.IsKind(SyntaxKind.Block))
                {
                    if (elseStatement.IsKind(SyntaxKind.Block))
                    {
                        newStatement = Block(newStatement);
                    }
                    else if (elseStatement.IsKind(SyntaxKind.IfStatement) &&
                             ((IfStatementSyntax)elseStatement).AsCascade().All(f => f.Statement.IsKind(SyntaxKind.Block)))
                    {
                        newStatement = Block(newStatement);
                    }
                }

                IfStatementSyntax newLastIf = lastIf.Update(
                    lastIf.IfKeyword,
                    lastIf.OpenParenToken,
                    lastIf.Condition,
                    lastIf.CloseParenToken,
                    newStatement,
                    ElseClause(elseStatement));

                newIfStatement = ifStatement.ReplaceNode(lastIf, newLastIf);
            }

            SyntaxList <StatementSyntax> newStatements = selectedStatements.UnderlyingList
                                                         .Replace(selectedStatements.First(), newIfStatement.WithFormatterAnnotation())
                                                         .RemoveRange(selectedStatements.FirstIndex + 1, selectedStatements.Count - 1);

            return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken));
        }