Example #1
0
        public static async Task <Document> RefactorAsync(
            Document document,
            ForStatementSyntax forStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

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

            IEnumerable <IdentifierNameSyntax> identifierNames = await GetIdentifierNamesAsync(document, forStatement, oldRoot, semanticModel, cancellationToken).ConfigureAwait(false);

            List <ElementAccessExpressionSyntax> expressions = identifierNames
                                                               .Select(f => f.Parent.Parent.Parent)
                                                               .Cast <ElementAccessExpressionSyntax>()
                                                               .ToList();

            var rewriter = new ForToForEachSyntaxRewriter(expressions, ElementName);

            ForEachStatementSyntax forEachStatement = ForEachStatement(
                IdentifierName("var"),
                ElementName,
                GetCollectionExpression(forStatement),
                (StatementSyntax)rewriter.Visit(forStatement.Statement));

            forEachStatement = forEachStatement
                               .WithTriviaFrom(forStatement)
                               .WithFormatterAnnotation();

            SyntaxNode newRoot = oldRoot.ReplaceNode(forStatement, forEachStatement);

            return(document.WithSyntaxRoot(newRoot));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            ForStatementSyntax forStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            StatementSyntax statement = forStatement.Statement;

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

            string identifier = Identifier.EnsureUniqueLocalName(Identifier.DefaultForEachVariableName, statement.SpanStart, semanticModel, cancellationToken);
            IdentifierNameSyntax identifierName = IdentifierName(identifier);

            var condition = (BinaryExpressionSyntax)forStatement.Condition;
            var memberAccessExpression  = (MemberAccessExpressionSyntax)condition.Right;
            ExpressionSyntax expression = memberAccessExpression.Expression;

            ISymbol symbol = semanticModel.GetDeclaredSymbol(forStatement.Declaration.Variables.First(), cancellationToken);
            ImmutableArray <SyntaxNode> nodes = await document.FindSymbolNodesAsync(symbol, cancellationToken).ConfigureAwait(false);

            StatementSyntax newStatement = statement.ReplaceNodes(
                nodes.Select(f => f.Parent.Parent.Parent),
                (f, g) => identifierName.WithTriviaFrom(f));

            ForEachStatementSyntax forEachStatement = ForEachStatement(
                VarType(),
                identifier,
                expression,
                newStatement);

            forEachStatement = forEachStatement
                               .WithTriviaFrom(forStatement)
                               .WithFormatterAnnotation();

            return(await document.ReplaceNodeAsync(forStatement, forEachStatement, cancellationToken).ConfigureAwait(false));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            ForStatementSyntax forStatement,
            CancellationToken cancellationToken = default)
        {
            StatementSyntax statement = forStatement.Statement;

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

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

            IdentifierNameSyntax identifierName = IdentifierName(name);

            var condition = (BinaryExpressionSyntax)forStatement.Condition;
            var memberAccessExpression  = (MemberAccessExpressionSyntax)condition.Right;
            ExpressionSyntax expression = memberAccessExpression.Expression;

            ISymbol symbol = semanticModel.GetDeclaredSymbol(forStatement.Declaration.Variables[0], cancellationToken);
            ImmutableArray <SyntaxNode> nodes = await SyntaxFinder.FindReferencesAsync(symbol, document, cancellationToken : cancellationToken).ConfigureAwait(false);

            StatementSyntax newStatement = statement.ReplaceNodes(
                nodes.Select(f => f.Parent.Parent.Parent),
                (f, _) => identifierName.WithTriviaFrom(f));

            TypeSyntax type = VarType();

            if (semanticModel.GetTypeSymbol(expression, cancellationToken) is INamedTypeSymbol namedType &&
                !namedType.OriginalDefinition.Implements(SpecialType.System_Collections_Generic_IEnumerable_T, allInterfaces: true))
            {
                IPropertySymbol member = namedType.FindMember <IPropertySymbol>(
                    "this[]",
                    f => f.Parameters.SingleOrDefault(shouldThrow: false)?.Type.SpecialType == SpecialType.System_Int32,
                    includeBaseTypes: true);

                Debug.Assert(member != null, "");

                if (member != null)
                {
                    type = member.Type.ToTypeSyntax().WithSimplifierAnnotation();
                }
            }

            ForEachStatementSyntax forEachStatement = ForEachStatement(
                type,
                Identifier(name).WithRenameAnnotation(),
                expression,
                newStatement);

            forEachStatement = forEachStatement
                               .WithTriviaFrom(forStatement)
                               .WithFormatterAnnotation();

            return(await document.ReplaceNodeAsync(forStatement, forEachStatement, cancellationToken).ConfigureAwait(false));
        }
        public static void ComputeCodeFix(
            CodeFixContext context,
            Diagnostic diagnostic,
            ExpressionSyntax expression,
            SemanticModel semanticModel)
        {
            TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken);

            ITypeSymbol type = typeInfo.Type;

            if (!(type is INamedTypeSymbol namedTypeSymbol))
            {
                return;
            }

            ITypeSymbol convertedType = typeInfo.ConvertedType;

            if (type == convertedType)
            {
                return;
            }

            if (namedTypeSymbol.ConstructedFrom.SpecialType != SpecialType.System_Collections_Generic_IEnumerable_T)
            {
                return;
            }

            if (!namedTypeSymbol.TypeArguments[0].Equals(convertedType))
            {
                return;
            }

            CodeAction codeAction = CodeAction.Create(
                "Replace yield return with foreach",
                cancellationToken =>
            {
                string name = DefaultNames.ForEachVariable;

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

                ForEachStatementSyntax forEachStatement = ForEachStatement(
                    type: VarType(),
                    identifier: Identifier(name),
                    expression: expression.TrimTrivia(),
                    statement: YieldReturnStatement(IdentifierName(name)));

                SyntaxNode yieldStatement = expression.Parent;

                forEachStatement = forEachStatement.WithTriviaFrom(yieldStatement);

                return(context.Document.ReplaceNodeAsync(yieldStatement, forEachStatement, cancellationToken));
            },
                EquivalenceKeyProvider.GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceYieldReturnWithForEach));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
        private static Task <Document> RefactorAsync(
            Document document,
            ExpressionSyntax expression,
            SemanticModel semanticModel,
            System.Threading.CancellationToken cancellationToken)
        {
            string name = DefaultNames.ForEachVariable;

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

            ForEachStatementSyntax forEachStatement = ForEachStatement(
                type: VarType(),
                identifier: Identifier(name),
                expression: expression.TrimTrivia(),
                statement: YieldReturnStatement(IdentifierName(name)));

            SyntaxNode yieldStatement = expression.Parent;

            forEachStatement = forEachStatement.WithTriviaFrom(yieldStatement);

            return(document.ReplaceNodeAsync(yieldStatement, forEachStatement, cancellationToken));
        }
Example #6
0
        private static async Task <Document> RefactorAsync(
            Document document,
            UsingStatementSyntax usingStatement,
            CancellationToken cancellationToken)
        {
            VariableDeclaratorSyntax declarator = usingStatement.Declaration.Variables.Single();

            var whileStatement = (WhileStatementSyntax)usingStatement.Statement.SingleNonBlockStatementOrDefault();

            SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(declarator.Initializer.Value);

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

            string name = NameGenerator.Default.EnsureUniqueLocalName(DefaultNames.ForEachVariable, semanticModel, usingStatement.SpanStart, cancellationToken: cancellationToken);

            StatementSyntax statement = whileStatement.Statement;

            var rewriter = new Rewriter(
                semanticModel.GetDeclaredSymbol(declarator, cancellationToken),
                declarator.Identifier.ValueText,
                name,
                semanticModel,
                cancellationToken);

            var newStatement = (StatementSyntax)rewriter.Visit(statement);

            ForEachStatementSyntax forEachStatement = ForEachStatement(
                VarType(),
                Identifier(name).WithRenameAnnotation(),
                invocationInfo.Expression,
                newStatement);

            forEachStatement = forEachStatement
                               .WithTriviaFrom(usingStatement)
                               .WithFormatterAnnotation();

            return(await document.ReplaceNodeAsync(usingStatement, forEachStatement, cancellationToken).ConfigureAwait(false));
        }