Esempio n. 1
0
        private static bool ShouldCreateExpressionStatement(
            TypeSyntax returnType,
            ExpressionSyntax expression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (returnType == null)
            {
                return(true);
            }

            if (returnType.IsVoid())
            {
                return(true);
            }

            SyntaxKind kind = expression.Kind();

            if (kind == SyntaxKind.ThrowExpression)
            {
                return(true);
            }

            if (kind == SyntaxKind.AwaitExpression &&
                !semanticModel
                .GetTypeSymbol(returnType, cancellationToken)
                .OriginalDefinition
                .EqualsOrInheritsFrom(MetadataNames.System_Threading_Tasks_Task_T))
            {
                return(true);
            }

            return(false);
        }
        private static async Task <Document> RefactorAsync(
            Document document,
            MethodDeclarationSyntax methodDeclaration,
            CancellationToken cancellationToken)
        {
            BlockSyntax body = Block();

            TypeSyntax returnType = methodDeclaration.ReturnType;

            if (returnType?.IsVoid() == false)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken);

                ExpressionSyntax expression = methodSymbol.ReturnType.GetDefaultValueSyntax(returnType);

                body = body.AddStatements(ReturnStatement(expression));
            }

            body = body.WithFormatterAnnotation();

            MethodDeclarationSyntax newNode = methodDeclaration
                                              .WithModifiers(methodDeclaration.Modifiers.Replace(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword))
                                              .WithBody(body)
                                              .WithSemicolonToken(default(SyntaxToken))
                                              .WithTrailingTrivia(methodDeclaration.GetTrailingTrivia());

            return(await document.ReplaceNodeAsync(methodDeclaration, newNode, cancellationToken).ConfigureAwait(false));
        }
        private static async Task RenameMethodAccoringToTypeNameAsync(
            RefactoringContext context,
            MethodDeclarationSyntax methodDeclaration)
        {
            TypeSyntax returnType = methodDeclaration.ReturnType;

            if (returnType?.IsVoid() == false)
            {
                SyntaxToken identifier = methodDeclaration.Identifier;

                if (context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(identifier))
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

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

                    ITypeSymbol typeSymbol = GetType(returnType, semanticModel, context.CancellationToken);

                    if (typeSymbol != null)
                    {
                        string newName = Identifier.CreateName(typeSymbol);

                        if (!string.IsNullOrEmpty(newName))
                        {
                            newName = "Get" + newName;

                            if (methodSymbol.IsAsync)
                            {
                                newName += "Async";
                            }

                            string oldName = identifier.ValueText;

                            if (!string.Equals(oldName, newName, StringComparison.Ordinal))
                            {
                                bool isUnique = await Identifier.IsUniqueMemberNameAsync(
                                    methodSymbol,
                                    newName,
                                    context.Solution,
                                    context.CancellationToken).ConfigureAwait(false);

                                if (isUnique)
                                {
                                    context.RegisterRefactoring(
                                        $"Rename '{oldName}' to '{newName}'",
                                        cancellationToken => Renamer.RenameSymbolAsync(context.Document, methodSymbol, newName, cancellationToken));
                                }
                            }
                        }
                    }
                }
            }
        }
        private static async Task RenameMethodAccoringToTypeNameAsync(
            RefactoringContext context,
            MethodDeclarationSyntax methodDeclaration)
        {
            TypeSyntax returnType = methodDeclaration.ReturnType;

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

            SyntaxToken identifier = methodDeclaration.Identifier;

            if (!context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(identifier))
                return;

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

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

            ITypeSymbol typeSymbol = GetType(returnType, semanticModel, context.CancellationToken);

            if (typeSymbol == null)
                return;

            string newName = NameGenerator.CreateName(typeSymbol);

            if (string.IsNullOrEmpty(newName))
                return;

            newName = "Get" + newName;

            if (methodSymbol.IsAsync)
                newName += "Async";

            string oldName = identifier.ValueText;

            if (string.Equals(oldName, newName, StringComparison.Ordinal))
                return;

            if (!await MemberNameGenerator.IsUniqueMemberNameAsync(
                newName,
                methodSymbol,
                context.Solution,
                cancellationToken: context.CancellationToken).ConfigureAwait(false))
            {
                return;
            }

            context.RegisterRefactoring(
                $"Rename '{oldName}' to '{newName}'",
                cancellationToken => Renamer.RenameSymbolAsync(context.Solution, methodSymbol, newName, default(OptionSet), cancellationToken),
                RefactoringIdentifiers.RenameMethodAccordingToTypeName);
        }
        private static BlockSyntax CreateBlock(ExpressionSyntax expression, MethodDeclarationSyntax methodDeclaration)
        {
            TypeSyntax returnType = methodDeclaration.ReturnType;

            if (returnType == null || returnType.IsVoid())
            {
                return(Block(ExpressionStatement(expression)));
            }
            else
            {
                return(CreateBlock(expression));
            }
        }
Esempio n. 6
0
 private static BlockSyntax CreateBlock(TypeSyntax returnType, ExpressionSyntax expression, SyntaxToken semicolon)
 {
     if (returnType == null ||
         returnType.IsVoid() ||
         expression.IsKind(SyntaxKind.ThrowExpression))
     {
         return(CreateBlockWithExpressionStatement(expression, semicolon));
     }
     else
     {
         return(CreateBlockWithReturnStatement(expression, semicolon));
     }
 }
Esempio n. 7
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 ComputeRefactoringAsync(RefactoringContext context, LocalFunctionStatementSyntax localFunction)
        {
            TypeSyntax returnType = localFunction.ReturnType;

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

            BlockSyntax body = localFunction.Body;

            if (body == null)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

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

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

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

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

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

            ComputeRefactoring(context, methodSymbol, semanticModel, body, returnType);
        }
Esempio n. 9
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?.Statements.Count > 0 &&
                        !methodDeclaration.IsIterator())
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

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

                            if (analysis.Succeeded &&
                                analysis.ReturnStatements.All(node => IsReturnStatementWithoutExpression(node)))
                            {
                                context.RegisterRefactoring(
                                    "Change return type to 'void'",
                                    cancellationToken =>
                                {
                                    return(ChangeTypeRefactoring.ChangeTypeAsync(
                                               context.Document,
                                               returnType,
                                               CSharpFactory.VoidType(),
                                               cancellationToken));
                                });
                            }
                        }
                    }
                }
            }
        }
        private static bool ShouldCreateExpressionStatement(
            TypeSyntax returnType,
            ExpressionSyntax expression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (returnType == null)
            {
                return(true);
            }

            if (returnType.IsVoid())
            {
                return(true);
            }

            SyntaxKind kind = expression.Kind();

            if (kind == SyntaxKind.ThrowExpression)
            {
                return(true);
            }

            if (kind == SyntaxKind.AwaitExpression)
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(returnType, cancellationToken);

                if (typeSymbol?.IsNamedType() == true &&
                    !((INamedTypeSymbol)typeSymbol).ConstructedFrom.EqualsOrInheritsFrom(semanticModel.GetTypeByMetadataName(MetadataNames.System_Threading_Tasks_Task_T)))
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 11
0
 ExpressionSyntax ExecutePipeline(TypeSyntax returnType, IEnumerable <SyntaxNode> parameters)
 => (ExpressionSyntax)generator.ExecutePipeline(returnType.IsVoid() ? null : returnType, parameters);
        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);
        }