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)); } }
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)); } }
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); }
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); }
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); }