Ejemplo n.º 1
0
        private static Task <Document> RefactorAsync(
            Document document,
            SyntaxNode declaration,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            BlockSyntax body = GetBody();

            SyntaxList <StatementSyntax> statements = body.Statements;

            int position = statements[0].SpanStart;

            string name = NameGenerator.Default.EnsureUniqueLocalName("items", semanticModel, position);

            IdentifierNameSyntax identifierName = IdentifierName(name);

            TypeSyntax listType = semanticModel
                                  .GetTypeByMetadataName("System.Collections.Generic.List`1")
                                  .Construct(typeSymbol)
                                  .ToMinimalTypeSyntax(semanticModel, position);

            LocalDeclarationStatementSyntax localDeclarationStatement = LocalDeclarationStatement(
                VarType(),
                name,
                EqualsValueClause(ObjectCreationExpression(listType, ArgumentList())));

            localDeclarationStatement = localDeclarationStatement.WithFormatterAnnotation();

            SyntaxList <StatementSyntax> newStatements = InsertLocalDeclarationStatement(statements, localDeclarationStatement);

            ReturnStatementSyntax returnStatement = ReturnStatement(identifierName).WithFormatterAnnotation();

            newStatements = InsertReturnStatement(newStatements, returnStatement);

            BlockSyntax newBlock = body.WithStatements(newStatements);

            var rewriter = new YieldRewriter(identifierName, typeSymbol, semanticModel);

            newBlock = (BlockSyntax)rewriter.Visit(newBlock);

            return(document.ReplaceNodeAsync(body, newBlock, cancellationToken));

            BlockSyntax GetBody()
            {
                switch (declaration)
                {
                case MethodDeclarationSyntax methodDeclaration:
                    return(methodDeclaration.Body);

                case LocalFunctionStatementSyntax localFunction:
                    return(localFunction.Body);

                case AccessorDeclarationSyntax accessorDeclaration:
                    return(accessorDeclaration.Body);
                }

                throw new InvalidOperationException();
            }
        }
        private static async Task <Document> RefactorAsync(
            Document document,
            YieldStatementSyntax yieldStatement,
            BlockSyntax block,
            SyntaxList <StatementSyntax> statements,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            int position = statements[0].SpanStart;

            string name = NameGenerator.Default.EnsureUniqueLocalName("items", semanticModel, position);

            IdentifierNameSyntax identifierName = IdentifierName(name);

            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(yieldStatement.Expression, cancellationToken);

            TypeSyntax listType = semanticModel
                                  .GetTypeByMetadataName(MetadataNames.System_Collections_Generic_List_T)
                                  .Construct(typeSymbol)
                                  .ToMinimalTypeSyntax(semanticModel, position);

            LocalDeclarationStatementSyntax localDeclarationStatement = LocalDeclarationStatement(
                VarType(),
                name,
                EqualsValueClause(ObjectCreationExpression(listType, ArgumentList())));

            localDeclarationStatement = localDeclarationStatement.WithFormatterAnnotation();

            SyntaxList <StatementSyntax> newStatements = InsertLocalDeclarationStatement(statements, localDeclarationStatement);

            ReturnStatementSyntax returnStatement = ReturnStatement(identifierName).WithFormatterAnnotation();

            newStatements = InsertReturnStatement(newStatements, returnStatement);

            BlockSyntax newBlock = block.WithStatements(newStatements);

            var rewriter = new YieldRewriter(identifierName, typeSymbol, semanticModel);

            newBlock = (BlockSyntax)rewriter.Visit(newBlock);

            return(await document.ReplaceNodeAsync(block, newBlock, cancellationToken).ConfigureAwait(false));
        }