private static async Task <SyntaxNode> ExpandUsingDirectiveAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
        {
            var usingDirective = (UsingDirectiveSyntax)node;
            var newName        = await Simplifier.ExpandAsync(usingDirective.Name, document, cancellationToken : cancellationToken).ConfigureAwait(false);

            return(usingDirective.WithName(newName));
        }
Ejemplo n.º 2
0
        protected override async Task <SemanticDocument> ExpandAsync(
            SelectionResult selection,
            CancellationToken cancellationToken
            )
        {
            var lastExpression = selection
                                 .GetFirstTokenInSelection()
                                 .GetCommonRoot(selection.GetLastTokenInSelection())
                                 .GetAncestors <ExpressionSyntax>()
                                 .LastOrDefault();

            if (lastExpression == null)
            {
                return(selection.SemanticDocument);
            }

            var newExpression = await Simplifier
                                .ExpandAsync(
                lastExpression,
                selection.SemanticDocument.Document,
                n => n != selection.GetContainingScope(),
                expandParameter : false,
                cancellationToken : cancellationToken
                )
                                .ConfigureAwait(false);

            return(await selection.SemanticDocument
                   .WithSyntaxRootAsync(
                       selection.SemanticDocument.Root.ReplaceNode(lastExpression, newExpression),
                       cancellationToken
                       )
                   .ConfigureAwait(false));
        }
Ejemplo n.º 3
0
        private async Task <Document> MoveDeclarationNearReferenceAsync(Document document, State state, CancellationToken cancellationToken)
        {
            var innermostStatements =
                state.InnermostBlock.Statements.Where(s => s != state.DeclarationStatement).ToList();
            var innermostAffectedIndex = innermostStatements.IndexOf(state.FirstStatementAffectedInInnermostBlock);

            var crossesMeaningfulBlock = CrossesMeaningfulBlock(state);
            var warningAnnotation      = crossesMeaningfulBlock
                ? WarningAnnotation.Create(CSharpFeaturesResources.Warning_colon_Declaration_changes_scope_and_may_change_meaning)
                : null;

            var canMergeDeclarationAndAssignment = await CanMergeDeclarationAndAssignmentAsync(document, state, cancellationToken).ConfigureAwait(false);

            if (canMergeDeclarationAndAssignment)
            {
                // Replace the first reference with a new declaration.
                var declarationStatement = CreateMergedDeclarationStatement(state, state.FirstStatementAffectedInInnermostBlock);
                declarationStatement = warningAnnotation == null
                    ? declarationStatement
                    : declarationStatement.WithAdditionalAnnotations(warningAnnotation);

                innermostStatements[innermostAffectedIndex] = declarationStatement.WithAdditionalAnnotations(Formatter.Annotation);
            }
            else
            {
                // If we're not merging with an existing declaration, make the declaration semantically
                // explicit to improve the chances that it won't break code.
                var explicitDeclarationStatement = await Simplifier.ExpandAsync(state.DeclarationStatement, document, cancellationToken : cancellationToken).ConfigureAwait(false);

                // place the declaration above the first statement that references it.
                var declarationStatement = warningAnnotation == null
                    ? explicitDeclarationStatement
                    : explicitDeclarationStatement.WithAdditionalAnnotations(warningAnnotation);

                innermostStatements.Insert(innermostAffectedIndex, declarationStatement.WithAdditionalAnnotations(Formatter.Annotation));
            }

            var newInnermostBlock = state.InnermostBlock.WithStatements(
                SyntaxFactory.List <StatementSyntax>(innermostStatements)).WithAdditionalAnnotations(Formatter.Annotation);

            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var rewriter = new Rewriter(state.InnermostBlock, newInnermostBlock, state.OutermostBlock, state.DeclarationStatement);
            var newRoot  = rewriter.Visit(tree.GetRoot(cancellationToken));

            return(document.WithSyntaxRoot(newRoot));
        }
Ejemplo n.º 4
0
        private static async Task <Tuple <SemanticDocument, ISet <ExpressionSyntax> > > ComplexifyParentingStatements(
            SemanticDocument semanticDocument,
            ISet <ExpressionSyntax> matches,
            CancellationToken cancellationToken)
        {
            // First, track the matches so that we can get back to them later.
            var newRoot             = semanticDocument.Root.TrackNodes(matches);
            var newDocument         = semanticDocument.Document.WithSyntaxRoot(newRoot);
            var newSemanticDocument = await SemanticDocument.CreateAsync(newDocument, cancellationToken).ConfigureAwait(false);

            var newMatches = newSemanticDocument.Root.GetCurrentNodes(matches.AsEnumerable()).ToSet();

            // Next, expand the topmost parenting expression of each match, being careful
            // not to expand the matches themselves.
            var topMostExpressions = newMatches
                                     .Select(m => m.AncestorsAndSelf().OfType <ExpressionSyntax>().Last())
                                     .Distinct();

            newRoot = await newSemanticDocument.Root
                      .ReplaceNodesAsync(
                topMostExpressions,
                computeReplacementAsync : async(oldNode, newNode, ct) =>
            {
                return(await Simplifier
                       .ExpandAsync(
                           oldNode,
                           newSemanticDocument.Document,
                           expandInsideNode: node =>
                {
                    var expression = node as ExpressionSyntax;
                    return expression == null ||
                    !newMatches.Contains(expression);
                },
                           cancellationToken: ct)
                       .ConfigureAwait(false));
            },
                cancellationToken : cancellationToken)
                      .ConfigureAwait(false);

            newDocument         = newSemanticDocument.Document.WithSyntaxRoot(newRoot);
            newSemanticDocument = await SemanticDocument.CreateAsync(newDocument, cancellationToken).ConfigureAwait(false);

            newMatches = newSemanticDocument.Root.GetCurrentNodes(matches.AsEnumerable()).ToSet();

            return(Tuple.Create(newSemanticDocument, newMatches));
        }
Ejemplo n.º 5
0
        private static async Task MoveDeclarationToFirstReferenceAsync(
            Document document, State state, SyntaxEditor editor, SyntaxAnnotation warningAnnotation, CancellationToken cancellationToken)
        {
            // If we're not merging with an existing declaration, make the declaration semantically
            // explicit to improve the chances that it won't break code.
            var explicitDeclarationStatement = await Simplifier.ExpandAsync(
                state.DeclarationStatement, document, cancellationToken : cancellationToken).ConfigureAwait(false);

            // place the declaration above the first statement that references it.
            var declarationStatement = warningAnnotation == null
                ? explicitDeclarationStatement
                : explicitDeclarationStatement.WithAdditionalAnnotations(warningAnnotation);

            declarationStatement = declarationStatement.WithAdditionalAnnotations(Formatter.Annotation);

            var bannerService = document.GetRequiredLanguageService <IFileBannerFactsService>();

            var newNextStatement = state.FirstStatementAffectedInInnermostBlock;

            declarationStatement = declarationStatement.WithPrependedLeadingTrivia(
                bannerService.GetLeadingBlankLines(newNextStatement));

            editor.InsertBefore(
                state.FirstStatementAffectedInInnermostBlock,
                declarationStatement);

            editor.ReplaceNode(
                newNextStatement,
                newNextStatement.WithAdditionalAnnotations(Formatter.Annotation).WithLeadingTrivia(
                    bannerService.GetTriviaAfterLeadingBlankLines(newNextStatement)));

            // Move leading whitespace from the declaration statement to the next statement.
            var statementIndex = state.OutermostBlockStatements.IndexOf(state.DeclarationStatement);

            if (statementIndex + 1 < state.OutermostBlockStatements.Count)
            {
                var originalNextStatement = state.OutermostBlockStatements[statementIndex + 1];
                editor.ReplaceNode(
                    originalNextStatement,
                    (current, generator) => current.WithAdditionalAnnotations(Formatter.Annotation).WithPrependedLeadingTrivia(
                        bannerService.GetLeadingBlankLines(state.DeclarationStatement)));
            }
        }
        private async Task <ExpressionSyntax> CreateExpressionToInlineAsync(
            VariableDeclaratorSyntax variableDeclarator,
            Document document,
            CancellationToken cancellationToken)
        {
            var updatedDocument = document;

            var expression    = SkipRedundantExteriorParentheses(variableDeclarator.Initializer.Value);
            var semanticModel = await updatedDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var localSymbol   = (ILocalSymbol)semanticModel.GetDeclaredSymbol(variableDeclarator, cancellationToken);
            var newExpression = InitializerRewriter.Visit(expression, localSymbol, semanticModel);

            // If this is an array initializer, we need to transform it into an array creation
            // expression for inlining.
            if (newExpression.Kind() == SyntaxKind.ArrayInitializerExpression)
            {
                var arrayType        = (ArrayTypeSyntax)localSymbol.Type.GenerateTypeSyntax();
                var arrayInitializer = (InitializerExpressionSyntax)newExpression;

                // Add any non-whitespace trailing trivia from the equals clause to the type.
                var equalsToken = variableDeclarator.Initializer.EqualsToken;
                if (equalsToken.HasTrailingTrivia)
                {
                    var trailingTrivia = equalsToken.TrailingTrivia.SkipInitialWhitespace();
                    if (trailingTrivia.Any())
                    {
                        arrayType = arrayType.WithTrailingTrivia(trailingTrivia);
                    }
                }

                newExpression = SyntaxFactory.ArrayCreationExpression(arrayType, arrayInitializer);
            }

            newExpression = newExpression.WithAdditionalAnnotations(InitializerAnnotation);

            updatedDocument = await updatedDocument.ReplaceNodeAsync(variableDeclarator.Initializer.Value, newExpression, cancellationToken).ConfigureAwait(false);

            semanticModel = await updatedDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            newExpression = await FindInitializerAsync(updatedDocument, cancellationToken).ConfigureAwait(false);

            var newVariableDeclarator = await FindDeclaratorAsync(updatedDocument, cancellationToken).ConfigureAwait(false);

            localSymbol = (ILocalSymbol)semanticModel.GetDeclaredSymbol(newVariableDeclarator, cancellationToken);

            bool wasCastAdded;
            var  explicitCastExpression = newExpression.CastIfPossible(localSymbol.Type, newVariableDeclarator.SpanStart, semanticModel, out wasCastAdded);

            if (wasCastAdded)
            {
                updatedDocument = await updatedDocument.ReplaceNodeAsync(newExpression, explicitCastExpression, cancellationToken).ConfigureAwait(false);

                semanticModel = await updatedDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                newVariableDeclarator = await FindDeclaratorAsync(updatedDocument, cancellationToken).ConfigureAwait(false);
            }

            // Now that the variable declarator is normalized, make its initializer
            // value semantically explicit.
            newExpression = await Simplifier.ExpandAsync(newVariableDeclarator.Initializer.Value, updatedDocument, cancellationToken : cancellationToken).ConfigureAwait(false);

            return(newExpression.WithAdditionalAnnotations(ExpressionToInlineAnnotation));
        }
 SyntaxNode Expand(SyntaxNode node) =>
 Simplifier.ExpandAsync(node, document).Result;         //? async-counterpart?