private static void ChangeType(
            RefactoringContext context,
            VariableDeclarationSyntax variableDeclaration,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            TypeSyntax type = variableDeclaration.Type;

            if (variableDeclaration.Variables.SingleOrDefault(shouldThrow: false)?.Initializer?.Value != null &&
                typeSymbol.OriginalDefinition.EqualsOrInheritsFromTaskOfT(semanticModel))
            {
                ISymbol enclosingSymbol = semanticModel.GetEnclosingSymbol(variableDeclaration.SpanStart, cancellationToken);

                if (enclosingSymbol.IsAsyncMethod())
                {
                    ITypeSymbol typeArgument = ((INamedTypeSymbol)typeSymbol).TypeArguments[0];

                    context.RegisterRefactoring(
                        $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeArgument, semanticModel, type.SpanStart, SymbolDisplayFormats.Default)}' and insert 'await'",
                        c => ChangeTypeAndAddAwaitAsync(context.Document, variableDeclaration, typeArgument, c),
                        RefactoringIdentifiers.ChangeVarToExplicitType);
                }
            }

            context.RegisterRefactoring(
                $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeSymbol, semanticModel, type.SpanStart, SymbolDisplayFormats.Default)}'",
                c => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, c),
                RefactoringIdentifiers.ChangeVarToExplicitType);
        }
示例#2
0
        internal static async Task ChangeTypeAccordingToExpressionAsync(
            RefactoringContext context,
            ForEachStatementSyntax forEachStatement)
        {
            TypeSyntax type = forEachStatement.Type;

            if (type?.IsVar == false &&
                type.Span.Contains(context.Span))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement);

                if (info.ElementType != null)
                {
                    ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType;

                    if (!info.ElementType.Equals(typeSymbol))
                    {
                        context.RegisterRefactoring(
                            $"Change type to '{SymbolDisplay.GetMinimalString(info.ElementType, semanticModel, type.SpanStart)}'",
                            cancellationToken =>
                        {
                            return(ChangeTypeRefactoring.ChangeTypeAsync(
                                       context.Document,
                                       type,
                                       info.ElementType,
                                       cancellationToken));
                        });
                    }
                }
            }
        }
示例#3
0
        internal static async Task ChangeTypeAccordingToExpressionAsync(
            RefactoringContext context,
            ForEachStatementSyntax forEachStatement)
        {
            TypeSyntax type = forEachStatement.Type;

            if (type?.IsVar == false &&
                type.Span.Contains(context.Span))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ITypeSymbol elementType = semanticModel.GetForEachStatementInfo(forEachStatement).ElementType;

                if (elementType?.IsErrorType() == false)
                {
                    ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType;

                    if (!elementType.Equals(typeSymbol))
                    {
                        if (elementType.SupportsExplicitDeclaration())
                        {
                            context.RegisterRefactoring(
                                $"Change type to '{SymbolDisplay.GetMinimalString(elementType, semanticModel, type.SpanStart)}'",
                                cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, elementType, cancellationToken));
                        }
                        else
                        {
                            context.RegisterRefactoring(
                                "Change type to 'var'",
                                cancellationToken => ChangeTypeRefactoring.ChangeTypeToVarAsync(context.Document, type, cancellationToken));
                        }
                    }
                }
            }
        }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMethodReturnTypeToVoid) &&
                methodDeclaration.ReturnType?.IsVoid() == false &&
                methodDeclaration.Body?.Statements.Count > 0 &&
                !methodDeclaration.IsIterator() &&
                context.SupportsSemanticModel)
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                if (!IsAsyncMethodThatReturnsTask(methodDeclaration, semanticModel, context.CancellationToken))
                {
                    ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(methodDeclaration.Body);

                    if (analysis.Succeeded &&
                        analysis.ReturnStatements.All(node => IsReturnStatementWithoutExpression(node)))
                    {
                        context.RegisterRefactoring(
                            "Change return type to 'void'",
                            cancellationToken =>
                        {
                            return(ChangeTypeRefactoring.ChangeTypeAsync(
                                       context.Document,
                                       methodDeclaration.ReturnType,
                                       CSharpFactory.VoidType(),
                                       cancellationToken));
                        });
                    }
                }
            }
        }
示例#5
0
        internal static async Task ChangeTypeAsync(
            RefactoringContext context,
            ForEachStatementSyntax forEachStatement)
        {
            TypeSyntax type = forEachStatement.Type;

            if (type?.Span.Contains(context.Span) != true)
            {
                return;
            }

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

            TypeAnalysis analysis = TypeAnalysis.AnalyzeType(forEachStatement, semanticModel);

            if (analysis.IsExplicit)
            {
                if (analysis.SupportsImplicit &&
                    context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar))
                {
                    context.RegisterRefactoring(
                        "Change type to 'var'",
                        cancellationToken => ChangeTypeRefactoring.ChangeTypeToVarAsync(context.Document, type, cancellationToken));
                }
            }
            else if (analysis.SupportsExplicit &&
                     context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType))
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken);

                context.RegisterRefactoring(
                    $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeSymbol, semanticModel, type.SpanStart, SymbolDisplayFormats.Default)}'",
                    cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken));
            }
        }
        private static void ChangeType(
            RefactoringContext context,
            VariableDeclarationSyntax variableDeclaration,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            TypeSyntax type = variableDeclaration.Type;

            if (variableDeclaration.Variables.SingleOrDefault(shouldthrow: false)?.Initializer?.Value != null &&
                typeSymbol.IsConstructedFromTaskOfT(semanticModel))
            {
                ISymbol enclosingSymbol = semanticModel.GetEnclosingSymbol(variableDeclaration.SpanStart, cancellationToken);

                if (enclosingSymbol.IsAsyncMethod())
                {
                    ITypeSymbol typeArgument = ((INamedTypeSymbol)typeSymbol).TypeArguments[0];

                    context.RegisterRefactoring(
                        $"Change type to '{SymbolDisplay.GetMinimalString(typeArgument, semanticModel, type.SpanStart)}' and insert 'await'",
                        c => ChangeTypeAndAddAwaitAsync(context.Document, variableDeclaration, typeArgument, c));
                }
            }

            context.RegisterRefactoring(
                $"Change type to '{SymbolDisplay.GetMinimalString(typeSymbol, semanticModel, type.Span.Start)}'",
                c => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, c));
        }
        private static async Task ChangeTypeAsync(
            RefactoringContext context,
            VariableDeclarationSyntax variableDeclaration)
        {
            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            TypeAnalysisFlags flags = CSharpAnalysis.AnalyzeType(variableDeclaration, semanticModel, context.CancellationToken);

            if (flags.IsExplicit())
            {
                if (flags.SupportsImplicit() &&
                    flags.IsValidSymbol() &&
                    context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar))
                {
                    context.RegisterRefactoring(
                        "Change type to 'var'",
                        cancellationToken =>
                    {
                        return(ChangeTypeRefactoring.ChangeTypeToVarAsync(
                                   context.Document,
                                   variableDeclaration.Type,
                                   cancellationToken));
                    });
                }
            }
            else if (flags.SupportsExplicit() &&
                     flags.IsValidSymbol() &&
                     context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType))
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(variableDeclaration.Type, context.CancellationToken);

                ChangeType(context, variableDeclaration, typeSymbol, semanticModel, context.CancellationToken);
            }
        }
        public static async Task ComputeRefactoringsAsync(
            RefactoringContext context,
            DeclarationExpressionSyntax declarationExpression)
        {
            if (declarationExpression.Type?.Span.Contains(context.Span) == true &&
                context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.ChangeExplicitTypeToVar,
                    RefactoringIdentifiers.ChangeVarToExplicitType))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                switch (CSharpAnalysis.AnalyzeType(
                            declarationExpression,
                            semanticModel,
                            context.CancellationToken))
                {
                case TypeAnalysisResult.Explicit:
                case TypeAnalysisResult.ExplicitButShouldBeImplicit:
                {
                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar))
                    {
                        context.RegisterRefactoring(
                            "Change type to 'var'",
                            cancellationToken =>
                            {
                                return(ChangeTypeRefactoring.ChangeTypeToVarAsync(
                                           context.Document,
                                           declarationExpression.Type,
                                           cancellationToken));
                            });
                    }

                    break;
                }

                case TypeAnalysisResult.Implicit:
                case TypeAnalysisResult.ImplicitButShouldBeExplicit:
                {
                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType))
                    {
                        TypeSyntax type = declarationExpression.Type;

                        var localSymbol = semanticModel.GetDeclaredSymbol(declarationExpression.Designation, context.CancellationToken) as ILocalSymbol;

                        ITypeSymbol typeSymbol = localSymbol.Type;

                        context.RegisterRefactoring(
                            $"Change type to '{SymbolDisplay.GetMinimalDisplayString(typeSymbol, type.Span.Start, semanticModel)}'",
                            cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken));
                    }

                    break;
                }
                }
            }
        }
 private static void RegisterChangeType(RefactoringContext context, MemberDeclarationSyntax member, TypeSyntax type, ITypeSymbol newType)
 {
     context.RegisterRefactoring(
         $"Change {GetText(member)} type to '{newType.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}'",
         cancellationToken =>
     {
         return(ChangeTypeRefactoring.ChangeTypeAsync(
                    context.Document,
                    type,
                    newType,
                    cancellationToken));
     });
 }
示例#10
0
 private static void RegisterChangeType(RefactoringContext context, MemberDeclarationSyntax member, TypeSyntax type, ITypeSymbol newType, SemanticModel semanticModel)
 {
     context.RegisterRefactoring(
         $"Change {GetText(member)} type to '{SymbolDisplay.GetMinimalString(newType, semanticModel, type.Span.Start)}'",
         cancellationToken =>
     {
         return(ChangeTypeRefactoring.ChangeTypeAsync(
                    context.Document,
                    type,
                    newType,
                    cancellationToken));
     });
 }
示例#11
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMethodReturnTypeToVoid))
            {
                TypeSyntax returnType = methodDeclaration.ReturnType;

                if (returnType?.IsVoid() == false)
                {
                    BlockSyntax body = methodDeclaration.Body;

                    if (body != null)
                    {
                        SyntaxList <StatementSyntax> statements = body.Statements;

                        if (statements.Any() &&
                            !ContainsOnlyThrowStatement(statements) &&
                            !methodDeclaration.ContainsYield())
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken);

                            if (methodSymbol?.IsOverride == false &&
                                !methodSymbol.ImplementsInterfaceMember() &&
                                !IsAsyncMethodThatReturnsTask(methodSymbol, semanticModel))
                            {
                                ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body);

                                if (analysis.Succeeded &&
                                    analysis.ReturnStatements.All(IsReturnStatementWithoutExpression))
                                {
                                    context.RegisterRefactoring(
                                        "Change return type to 'void'",
                                        cancellationToken =>
                                    {
                                        return(ChangeTypeRefactoring.ChangeTypeAsync(
                                                   context.Document,
                                                   returnType,
                                                   CSharpFactory.VoidType(),
                                                   cancellationToken));
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }
        public static async Task ComputeRefactoringsAsync(
            RefactoringContext context,
            DeclarationExpressionSyntax declarationExpression)
        {
            if (declarationExpression.Type?.Span.Contains(context.Span) == true &&
                context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.ChangeExplicitTypeToVar,
                    RefactoringIdentifiers.ChangeVarToExplicitType))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(declarationExpression, semanticModel, context.CancellationToken);

                if (analysis.IsExplicit)
                {
                    if (analysis.SupportsImplicit &&
                        context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar))
                    {
                        context.RegisterRefactoring(
                            "Change type to 'var'",
                            cancellationToken =>
                        {
                            return(ChangeTypeRefactoring.ChangeTypeToVarAsync(
                                       context.Document,
                                       declarationExpression.Type,
                                       cancellationToken));
                        },
                            RefactoringIdentifiers.ChangeExplicitTypeToVar);
                    }
                }
                else if (analysis.SupportsExplicit &&
                         context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType))
                {
                    TypeSyntax type = declarationExpression.Type;

                    var localSymbol = semanticModel.GetDeclaredSymbol(declarationExpression.Designation, context.CancellationToken) as ILocalSymbol;

                    ITypeSymbol typeSymbol = localSymbol.Type;

                    context.RegisterRefactoring(
                        $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeSymbol, semanticModel, type.SpanStart, SymbolDisplayFormats.Default)}'",
                        cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken),
                        RefactoringIdentifiers.ChangeVarToExplicitType);
                }
            }
        }
        private static void ChangeType(
            RefactoringContext context,
            VariableDeclarationSyntax variableDeclaration,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            TypeSyntax type = variableDeclaration.Type;

            if (variableDeclaration.Variables.Count == 1 &&
                variableDeclaration.Variables[0].Initializer?.Value != null &&
                typeSymbol.IsNamedType())
            {
                INamedTypeSymbol taskOfT = semanticModel.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");

                if (((INamedTypeSymbol)typeSymbol).ConstructedFrom.Equals(taskOfT) &&
                    AsyncAnalysis.IsPartOfAsyncBlock(variableDeclaration, semanticModel, cancellationToken))
                {
                    ITypeSymbol typeArgumentType = ((INamedTypeSymbol)typeSymbol).TypeArguments[0];

                    context.RegisterRefactoring(
                        $"Change type to '{typeArgumentType.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}' and insert 'await'",
                        c =>
                    {
                        return(ChangeTypeAndAddAwaitAsync(
                                   context.Document,
                                   variableDeclaration,
                                   typeArgumentType,
                                   c));
                    });
                }
            }

            context.RegisterRefactoring(
                $"Change type to '{typeSymbol.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}'",
                c =>
            {
                return(ChangeTypeRefactoring.ChangeTypeAsync(
                           context.Document,
                           type,
                           typeSymbol,
                           c));
            });
        }
示例#14
0
        private static void ComputeRefactoring(
            RefactoringContext context,
            IMethodSymbol methodSymbol,
            SemanticModel semanticModel,
            BlockSyntax body,
            TypeSyntax returnType)
        {
            if (methodSymbol?.IsOverride != false)
            {
                return;
            }

            if (methodSymbol.ImplementsInterfaceMember())
            {
                return;
            }

            if (methodSymbol.IsAsync &&
                methodSymbol.ReturnType.HasMetadataName(MetadataNames.System_Threading_Tasks_Task))
            {
                return;
            }

            ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body);

            if (!analysis.Succeeded)
            {
                return;
            }

            if (!analysis.ReturnStatements.All(f => (f as ReturnStatementSyntax)?.Expression == null))
            {
                return;
            }

            context.RegisterRefactoring(
                "Change return type to 'void'",
                ct => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, returnType, CSharpFactory.VoidType(), ct),
                RefactoringIdentifiers.ChangeMethodReturnTypeToVoid);
        }
        internal static async Task ChangeTypeAsync(
            RefactoringContext context,
            ForEachStatementSyntax forEachStatement)
        {
            TypeSyntax type = forEachStatement.Type;

            if (type?.Span.Contains(context.Span) != true)
            {
                return;
            }

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

            TypeAnalysisResult result = ForEachStatementAnalysis.AnalyzeType(
                forEachStatement,
                semanticModel,
                context.CancellationToken);

            if (result == TypeAnalysisResult.Explicit)
            {
                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar))
                {
                    context.RegisterRefactoring(
                        "Change type to 'var'",
                        cancellationToken => ChangeTypeRefactoring.ChangeTypeToVarAsync(context.Document, type, cancellationToken));
                }
            }
            else if (result == TypeAnalysisResult.ImplicitButShouldBeExplicit)
            {
                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType))
                {
                    ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type, context.CancellationToken).Type;

                    context.RegisterRefactoring(
                        $"Change type to '{typeSymbol.ToMinimalDisplayString(semanticModel, type.Span.Start, SyntaxUtility.DefaultSymbolDisplayFormat)}'",
                        cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken));
                }
            }
        }
        private static async Task ChangeTypeAsync(
            RefactoringContext context,
            VariableDeclarationSyntax variableDeclaration)
        {
            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            TypeAnalysisResult result = VariableDeclarationAnalysis.AnalyzeType(
                variableDeclaration,
                semanticModel,
                context.CancellationToken);

            if (result == TypeAnalysisResult.Explicit || result == TypeAnalysisResult.ExplicitButShouldBeImplicit)
            {
                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar))
                {
                    context.RegisterRefactoring(
                        "Change type to 'var'",
                        cancellationToken =>
                    {
                        return(ChangeTypeRefactoring.ChangeTypeToVarAsync(
                                   context.Document,
                                   variableDeclaration.Type,
                                   cancellationToken));
                    });
                }
            }
            else if (result == TypeAnalysisResult.Implicit || result == TypeAnalysisResult.ImplicitButShouldBeExplicit)
            {
                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType))
                {
                    ITypeSymbol typeSymbol = semanticModel
                                             .GetTypeInfo(variableDeclaration.Type, context.CancellationToken)
                                             .Type;

                    ChangeType(context, variableDeclaration, typeSymbol, semanticModel, context.CancellationToken);
                }
            }
        }
        private static async Task ChangeTypeAccordingToExpressionAsync(
            RefactoringContext context,
            VariableDeclarationSyntax variableDeclaration)
        {
            TypeSyntax type = variableDeclaration.Type;

            if (type?.IsVar == false)
            {
                ExpressionSyntax initializerValue = variableDeclaration.Variables.SingleOrDefault(shouldthrow: false)?.Initializer?.Value;

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

                    ITypeSymbol initializerTypeSymbol = semanticModel.GetTypeSymbol(initializerValue);

                    if (initializerTypeSymbol?.IsErrorType() == false)
                    {
                        ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType;

                        if (!initializerTypeSymbol.Equals(typeSymbol))
                        {
                            if (initializerTypeSymbol.SupportsExplicitDeclaration())
                            {
                                ChangeType(context, variableDeclaration, initializerTypeSymbol, semanticModel, context.CancellationToken);
                            }
                            else
                            {
                                context.RegisterRefactoring(
                                    "Change type to 'var'",
                                    cancellationToken => ChangeTypeRefactoring.ChangeTypeToVarAsync(context.Document, type, cancellationToken));
                            }
                        }
                    }
                }
            }
        }
示例#18
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, YieldStatementSyntax yieldStatement)
        {
            if (context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression,
                    RefactoringIdentifiers.AddCastExpression,
                    RefactoringIdentifiers.CallToMethod) &&
                yieldStatement.IsYieldReturn() &&
                yieldStatement.Expression != null)
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                MemberDeclarationSyntax containingMember = await ReturnExpressionRefactoring.GetContainingMethodOrPropertyOrIndexerAsync(yieldStatement.Expression, semanticModel, context.CancellationToken).ConfigureAwait(false);

                if (containingMember != null)
                {
                    TypeSyntax memberType = ReturnExpressionRefactoring.GetMemberType(containingMember);

                    if (memberType != null)
                    {
                        ITypeSymbol memberTypeSymbol = semanticModel.GetTypeSymbol(memberType, context.CancellationToken);

                        if (memberTypeSymbol?.SpecialType != SpecialType.System_Collections_IEnumerable)
                        {
                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(yieldStatement.Expression, context.CancellationToken);

                            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression) &&
                                typeSymbol?.IsErrorType() == false &&
                                !typeSymbol.IsVoid() &&
                                (memberTypeSymbol == null ||
                                 memberTypeSymbol.IsErrorType() ||
                                 !memberTypeSymbol.IsConstructedFromIEnumerableOfT() ||
                                 !((INamedTypeSymbol)memberTypeSymbol).TypeArguments[0].Equals(typeSymbol)))
                            {
                                INamedTypeSymbol newTypeSymbol = semanticModel
                                                                 .Compilation
                                                                 .GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T)
                                                                 .Construct(typeSymbol);

                                TypeSyntax newType = CSharpFactory.Type(newTypeSymbol, semanticModel, memberType.SpanStart);

                                context.RegisterRefactoring(
                                    $"Change {ReturnExpressionRefactoring.GetText(containingMember)} type to '{SymbolDisplay.GetMinimalDisplayString(newTypeSymbol, memberType.SpanStart, semanticModel)}'",
                                    cancellationToken =>
                                {
                                    return(ChangeTypeRefactoring.ChangeTypeAsync(
                                               context.Document,
                                               memberType,
                                               newType,
                                               cancellationToken));
                                });
                            }

                            if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) &&
                                yieldStatement.Expression.Span.Contains(context.Span) &&
                                memberTypeSymbol?.IsNamedType() == true)
                            {
                                var namedTypeSymbol = (INamedTypeSymbol)memberTypeSymbol;

                                if (namedTypeSymbol.IsConstructedFromIEnumerableOfT())
                                {
                                    ITypeSymbol argumentSymbol = namedTypeSymbol.TypeArguments[0];

                                    if (argumentSymbol != typeSymbol)
                                    {
                                        ModifyExpressionRefactoring.ComputeRefactoring(
                                            context,
                                            yieldStatement.Expression,
                                            argumentSymbol,
                                            semanticModel);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceStatementWithIfStatement) &&
                context.Span.IsBetweenSpans(yieldStatement))
            {
                var refactoring = new ReplaceYieldStatementWithIfStatementRefactoring();
                await refactoring.ComputeRefactoringAsync(context, yieldStatement).ConfigureAwait(false);
            }
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, YieldStatementSyntax yieldStatement)
        {
            if (context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression,
                    RefactoringIdentifiers.AddCastExpression,
                    RefactoringIdentifiers.CallToMethod,
                    RefactoringIdentifiers.CreateConditionFromBooleanExpression) &&
                yieldStatement.IsYieldReturn() &&
                yieldStatement.Expression != null &&
                context.SupportsSemanticModel)
            {
                if (context.IsAnyRefactoringEnabled(
                        RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression,
                        RefactoringIdentifiers.AddCastExpression,
                        RefactoringIdentifiers.CallToMethod))
                {
                    MemberDeclarationSyntax containingMember = ReturnExpressionRefactoring.GetContainingMethodOrPropertyOrIndexer(yieldStatement.Expression);

                    if (containingMember != null)
                    {
                        TypeSyntax memberType = ReturnExpressionRefactoring.GetMemberType(containingMember);

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

                            ITypeSymbol memberTypeSymbol = semanticModel
                                                           .GetTypeInfo(memberType, context.CancellationToken)
                                                           .Type;

                            if (memberTypeSymbol?.SpecialType != SpecialType.System_Collections_IEnumerable)
                            {
                                ITypeSymbol typeSymbol = semanticModel
                                                         .GetTypeInfo(yieldStatement.Expression, context.CancellationToken)
                                                         .Type;

                                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression) &&
                                    typeSymbol?.IsErrorType() == false &&
                                    (memberTypeSymbol == null ||
                                     memberTypeSymbol.IsErrorType() ||
                                     !SyntaxAnalyzer.IsGenericIEnumerable(memberTypeSymbol) ||
                                     !((INamedTypeSymbol)memberTypeSymbol).TypeArguments[0].Equals(typeSymbol)))
                                {
                                    TypeSyntax newType = QualifiedName(
                                        ParseName("System.Collections.Generic"),
                                        GenericName(
                                            Identifier("IEnumerable"),
                                            TypeArgumentList(
                                                SingletonSeparatedList(
                                                    CSharpFactory.Type(typeSymbol)))));

                                    context.RegisterRefactoring(
                                        $"Change {ReturnExpressionRefactoring.GetText(containingMember)} type to 'IEnumerable<{typeSymbol.ToDisplayString(SyntaxUtility.DefaultSymbolDisplayFormat)}>'",
                                        cancellationToken =>
                                    {
                                        return(ChangeTypeRefactoring.ChangeTypeAsync(
                                                   context.Document,
                                                   memberType,
                                                   newType,
                                                   cancellationToken));
                                    });
                                }

                                if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) &&
                                    yieldStatement.Expression.Span.Contains(context.Span) &&
                                    memberTypeSymbol?.IsNamedType() == true)
                                {
                                    var namedTypeSymbol = (INamedTypeSymbol)memberTypeSymbol;

                                    if (namedTypeSymbol.ConstructedFrom.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T)
                                    {
                                        ITypeSymbol argumentSymbol = namedTypeSymbol.TypeArguments[0];

                                        if (argumentSymbol != typeSymbol)
                                        {
                                            ModifyExpressionRefactoring.ComputeRefactoring(
                                                context,
                                                yieldStatement.Expression,
                                                argumentSymbol,
                                                semanticModel);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.CreateConditionFromBooleanExpression))
                {
                    await CreateConditionFromBooleanExpressionRefactoring.ComputeRefactoringAsync(context, yieldStatement.Expression).ConfigureAwait(false);
                }
            }
        }
示例#20
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, YieldStatementSyntax yieldStatement)
        {
            if (context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression,
                    RefactoringIdentifiers.AddCastExpression,
                    RefactoringIdentifiers.CallToMethod)
                && yieldStatement.IsYieldReturn()
                && yieldStatement.Expression != null)
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ISymbol memberSymbol = ReturnExpressionRefactoring.GetContainingMethodOrPropertySymbol(yieldStatement.Expression, semanticModel, context.CancellationToken);

                if (memberSymbol != null)
                {
                    SyntaxNode node = await memberSymbol
                        .DeclaringSyntaxReferences[0]
                        .GetSyntaxAsync(context.CancellationToken)
                        .ConfigureAwait(false);

                    TypeSyntax type = ReturnExpressionRefactoring.GetTypeOrReturnType(node);

                    if (type != null)
                    {
                        ITypeSymbol memberTypeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken);

                        if (memberTypeSymbol?.SpecialType != SpecialType.System_Collections_IEnumerable)
                        {
                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(yieldStatement.Expression, context.CancellationToken);

                            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToYieldReturnExpression)
                                && typeSymbol?.IsErrorType() == false
                                && !typeSymbol.IsVoid()
                                && !memberSymbol.IsOverride
                                && (memberTypeSymbol == null
                                    || memberTypeSymbol.IsErrorType()
                                    || !memberTypeSymbol.IsConstructedFromIEnumerableOfT()
                                    || !((INamedTypeSymbol)memberTypeSymbol).TypeArguments[0].Equals(typeSymbol)))
                            {
                                INamedTypeSymbol newTypeSymbol = semanticModel
                                    .Compilation
                                    .GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T)
                                    .Construct(typeSymbol);

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

                                context.RegisterRefactoring(
                                    $"Change {ReturnExpressionRefactoring.GetText(node)} type to '{SymbolDisplay.GetMinimalString(newTypeSymbol, semanticModel, type.SpanStart)}'",
                                    cancellationToken =>
                                    {
                                        return ChangeTypeRefactoring.ChangeTypeAsync(
                                            context.Document,
                                            type,
                                            newType,
                                            cancellationToken);
                                    });
                            }

                            if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod)
                                && yieldStatement.Expression.Span.Contains(context.Span)
                                && memberTypeSymbol?.IsNamedType() == true)
                            {
                                var namedTypeSymbol = (INamedTypeSymbol)memberTypeSymbol;

                                if (namedTypeSymbol.IsConstructedFromIEnumerableOfT())
                                {
                                    ITypeSymbol argumentSymbol = namedTypeSymbol.TypeArguments[0];

                                    if (argumentSymbol != typeSymbol)
                                    {
                                        ModifyExpressionRefactoring.ComputeRefactoring(
                                           context,
                                           yieldStatement.Expression,
                                           argumentSymbol,
                                           semanticModel);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceStatementWithIfElse)
                && (context.Span.IsEmptyAndContainedInSpan(yieldStatement.YieldKeyword)
                    || context.Span.IsEmptyAndContainedInSpan(yieldStatement.ReturnOrBreakKeyword)
                    || context.Span.IsBetweenSpans(yieldStatement)))
            {
                await ReplaceStatementWithIfStatementRefactoring.ReplaceYieldReturnWithIfElse.ComputeRefactoringAsync(context, yieldStatement).ConfigureAwait(false);
            }
        }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration)
        {
            TypeSyntax returnType = methodDeclaration.ReturnType;

            if (returnType?.IsVoid() != false)
            {
                return;
            }

            BlockSyntax body = methodDeclaration.Body;

            if (body == null)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

            if (!statements.Any())
            {
                return;
            }

            if (statements.SingleOrDefault(shouldThrow: false)?.Kind() == SyntaxKind.ThrowStatement)
            {
                return;
            }

            if (methodDeclaration.ContainsYield())
            {
                return;
            }

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

            IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken);

            if (methodSymbol?.IsOverride != false)
            {
                return;
            }

            if (methodSymbol.ImplementsInterfaceMember())
            {
                return;
            }

            if (IsAsyncMethodThatReturnsTask(methodSymbol, semanticModel))
            {
                return;
            }

            ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body);

            if (!analysis.Succeeded)
            {
                return;
            }

            if (!analysis.ReturnStatements.All(IsReturnStatementWithoutExpression))
            {
                return;
            }

            context.RegisterRefactoring(
                "Change return type to 'void'",
                ct => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, returnType, CSharpFactory.VoidType(), ct),
                RefactoringIdentifiers.ChangeMethodReturnTypeToVoid);
        }