public static void ChangeTypeAndAddAwait(
            CodeFixContext context,
            Diagnostic diagnostic,
            ExpressionSyntax expression,
            VariableDeclarationSyntax variableDeclaration,
            TypeSyntax type,
            ITypeSymbol newTypeSymbol,
            SemanticModel semanticModel)
        {
            AwaitExpressionSyntax newExpression = SyntaxFactory.AwaitExpression(expression).WithTriviaFrom(expression);

            VariableDeclarationSyntax newNode = variableDeclaration.ReplaceNode(expression, newExpression);

            TypeSyntax newType = newTypeSymbol.ToMinimalTypeSyntax(semanticModel, type.SpanStart).WithTriviaFrom(type);

            newNode = newNode.WithType(newType);

            string typeName = SymbolDisplay.GetMinimalString(newTypeSymbol, semanticModel, type.SpanStart);

            CodeAction codeAction = CodeAction.Create(
                $"Change type to '{typeName}' and add await",
                cancellationToken => context.Document.ReplaceNodeAsync(variableDeclaration, newNode, cancellationToken),
                EquivalenceKeyProvider.GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ChangeTypeAccordingToInitializer + "AddAwait"));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
コード例 #2
0
        private static void RegisterCodeFix(
            CodeFixContext context,
            Diagnostic diagnostic,
            SyntaxNode node,
            TypeSyntax type,
            ExpressionSyntax expression,
            ITypeSymbol newTypeSymbol,
            SemanticModel semanticModel,
            bool insertAwait     = false,
            string additionalKey = null)
        {
            Document document = context.Document;

            string typeName = SymbolDisplay.GetMinimalString(newTypeSymbol, semanticModel, type.SpanStart);

            string title = $"Change {GetText(node)} type to '{typeName}'";

            if (insertAwait)
            {
                title += " and insert 'await'";
            }

            CodeAction codeAction = CodeAction.Create(
                title,
                cancellationToken =>
            {
                SyntaxNode newNode = null;

                TypeSyntax newType = ParseTypeName(typeName)
                                     .WithTriviaFrom(type);

                if (insertAwait)
                {
                    var nodes = new SyntaxNode[] { type, expression };

                    newNode = node.ReplaceNodes(nodes, (f, g) =>
                    {
                        if (f == type)
                        {
                            return(newType);
                        }
                        else
                        {
                            return(AwaitExpression(
                                       Token(expression.GetLeadingTrivia(), SyntaxKind.AwaitKeyword, TriviaList(Space)),
                                       expression.WithoutLeadingTrivia()));
                        }
                    });

                    return(document.ReplaceNodeAsync(node, newNode, cancellationToken));
                }
                else
                {
                    return(document.ReplaceNodeAsync(type, newType, cancellationToken));
                }
            },
                EquivalenceKeyProvider.GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression, additionalKey));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
        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);
        }