public static async Task <Document> RefactorAsync( Document document, ExpressionStatementSyntax statement, ReturnStatementSyntax returnStatement, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var block = (BlockSyntax)statement.Parent; SyntaxList <StatementSyntax> statements = block.Statements; int index = statements.IndexOf(statement); SyntaxList <StatementSyntax> newStatements = statements.RemoveAt(index); var assignmentExpression = (AssignmentExpressionSyntax)statement.Expression; ReturnStatementSyntax newReturnStatement = returnStatement .WithExpression(assignmentExpression.Right) .WithLeadingTrivia(assignmentExpression.GetLeadingTrivia()) .WithTrailingTrivia(returnStatement.GetTrailingTrivia()) .WithFormatterAnnotation(); newStatements = newStatements.Replace(newStatements[index], newReturnStatement); root = root.ReplaceNode(block, block.WithStatements(newStatements)); return(document.WithSyntaxRoot(root)); }
private static async Task <Document> MergeLocalDeclarationWithReturnStatementAsync( Document document, LocalDeclarationStatementSyntax localDeclaration, ReturnStatementSyntax returnStatement, BlockSyntax block, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken); ReturnStatementSyntax newReturnStatement = returnStatement .WithExpression(localDeclaration.Declaration.Variables[0].Initializer.Value.WithoutTrivia()) .WithLeadingTrivia(localDeclaration.GetLeadingTrivia()) .WithTrailingTrivia(returnStatement.GetTrailingTrivia()) .WithAdditionalAnnotations(Formatter.Annotation); int index = block.Statements.IndexOf(localDeclaration); SyntaxList <StatementSyntax> newStatements = block.Statements .RemoveAt(index) .RemoveAt(index) .Insert(index, newReturnStatement); BlockSyntax newBlock = block.WithStatements(newStatements); SyntaxNode newRoot = oldRoot.ReplaceNode(block, newBlock); return(document.WithSyntaxRoot(newRoot)); }
private async Task <Document> GenerateExplicitConversion(Document document, ReturnStatementSyntax returnStatement, CancellationToken cancellationToken) { var mappingEngine = await CreateMappingEngine(document, returnStatement, cancellationToken); var returnExpressionTypeInfo = mappingEngine.GetExpressionTypeInfo(returnStatement.Expression); var mappingExpression = mappingEngine.MapExpression(returnStatement.Expression, returnExpressionTypeInfo.Type, returnExpressionTypeInfo.ConvertedType); return(await ReplaceNode(document, returnStatement, returnStatement.WithExpression(mappingExpression), cancellationToken)); }
private async Task <Document> GenerateExplicitConversion(Document document, ReturnStatementSyntax returnStatement, CancellationToken cancellationToken) { var(mappingEngine, semanticModel) = await CreateMappingEngine(document, returnStatement, cancellationToken); var returnExpressionTypeInfo = mappingEngine.GetExpressionTypeInfo(returnStatement.Expression); var mappingExpression = mappingEngine.MapExpression(returnStatement.Expression !.WithoutTrivia(), returnExpressionTypeInfo.GetAnnotatedType(), returnExpressionTypeInfo.GetAnnotatedTypeForConverted(), new MappingContext(returnStatement, semanticModel)); return(await ReplaceNode(document, returnStatement, returnStatement.WithExpression(mappingExpression), cancellationToken)); }
public static async Task <Document> RefactorAsync( Document document, ReturnStatementSyntax returnStatement, ITypeSymbol typeSymbol, CancellationToken cancellationToken = default(CancellationToken)) { ExpressionSyntax expression = typeSymbol.ToDefaultExpression(); ReturnStatementSyntax newReturnStatement = returnStatement.WithExpression(expression); return(await document.ReplaceNodeAsync(returnStatement, newReturnStatement, cancellationToken).ConfigureAwait(false)); }
public override SyntaxNode VisitReturnStatement(ReturnStatementSyntax node) { var newNode = node.WithExpression( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ParseName("System.Threading.Tasks.Task") .WithAdditionalAnnotations(Simplifier.Annotation), SyntaxFactory.IdentifierName("FromResult")), SyntaxFactory.ArgumentList().AddArguments(SyntaxFactory.Argument(node.Expression)))); return(base.VisitReturnStatement(newNode)); }
private async Task <Document> ReplaceWithEmptyEnumerable(Document document, ReturnStatementSyntax returnNullStatement, MethodDeclarationSyntax method, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var typeSymbol = semanticModel.GetSymbolInfo(method.ReturnType, cancellationToken).Symbol as INamedTypeSymbol; var genericTypeArgument = typeSymbol.TypeArguments.Single(); var empty = SyntaxFactory.ParseExpression($"Enumerable.Empty<{genericTypeArgument.Name}>()"); var returnEmptyStatement = returnNullStatement.WithExpression(empty); SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken); var newRoot = root.ReplaceNode(returnNullStatement, returnEmptyStatement); return(document.WithSyntaxRoot(newRoot)); }
private SyntaxNode RewriteExit(ReturnStatementSyntax returnStatement) { return(returnStatement.WithExpression( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("Task"), IdentifierName("FromResult"))) .WithArgumentList( ArgumentList( SingletonSeparatedList <ArgumentSyntax>( Argument( returnStatement.Expression)))) )); }
/// <summary> /// Normalizes the <paramref name="statement" />. /// </summary> public override SyntaxNode VisitReturnStatement(ReturnStatementSyntax statement) { var methodSymbol = SemanticModel.GetEnclosingSymbol(statement.SpanStart) as IMethodSymbol; if (methodSymbol == null) { return(base.VisitReturnStatement(statement)); } if (!IsFormulaType(methodSymbol.ReturnType)) { return(base.VisitReturnStatement(statement)); } return(statement.WithExpression(ReplaceImplicitConversion(statement.Expression))); }
public static async Task <Document> RefactorAsync( Document document, ReturnStatementSyntax returnStatement, ITypeSymbol typeSymbol, ISymbol symbol, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); ExpressionSyntax expression = SyntaxUtility.CreateDefaultValue(typeSymbol); root = root.ReplaceNode( returnStatement, returnStatement.WithExpression(expression)); return(document.WithSyntaxRoot(root)); }
public override SyntaxNode VisitReturnStatement(ReturnStatementSyntax node) { ExpressionSyntax expression = node.Expression; if (expression?.IsKind(SyntaxKind.AwaitExpression) == false) { if (KeepReturnStatement) { return(node.WithExpression(AwaitExpression(expression.WithoutTrivia()).WithTriviaFrom(expression))); } else { return(ExpressionStatement(AwaitExpression(expression.WithoutTrivia()).WithTriviaFrom(expression)).WithTriviaFrom(node)); } } return(base.VisitReturnStatement(node)); }
public override SyntaxNode VisitReturnStatement(ReturnStatementSyntax node) { ExpressionSyntax expression = node.Expression; if (expression?.IsKind(SyntaxKind.AwaitExpression) == false) { if (KeepReturnStatement) { return(node.WithExpression(AwaitExpression(expression.WithoutTrivia().Parenthesize()).WithTriviaFrom(expression))); } else { return(ExpressionStatement(AwaitExpression(expression.WithoutTrivia().Parenthesize()).WithTriviaFrom(expression)) .WithLeadingTrivia(node.GetLeadingTrivia()) .WithAdditionalAnnotations(_asyncAwaitAnnotationAndFormatterAnnotation)); } } return(base.VisitReturnStatement(node)); }
private SyntaxResult <SyntaxNode> TranslateStatement_Return(ReturnStatement returnStatement, TranslatorState state) { ReturnStatementSyntax returnStatementSyntax = SyntaxFactory.ReturnStatement(); if (returnStatement.Expression != null) { var expression = TranslateExpression(returnStatement.Expression, state); if (expression.IsError) { returnStatementSyntax = returnStatementSyntax.WithTrailingTrivia(expression.Errors); } else { returnStatementSyntax = returnStatementSyntax.WithExpression(expression.Syntax); } } return(returnStatementSyntax); }
private static async Task <StatementsInfo> RefactorAsync( Document document, StatementsInfo statementsInfo, StatementSyntax statement, StatementSyntax newStatement, int index, int count, bool removeReturnStatement, SemanticModel semanticModel, CancellationToken cancellationToken) { ReturnStatementSyntax returnStatement = FindReturnStatementBelow(statementsInfo.Statements, index); ExpressionSyntax expression = returnStatement.Expression; ExpressionSyntax newExpression = null; ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); if (symbol.IsLocal() && index > 0) { LocalDeclarationStatementSyntax localDeclarationStatement = FindLocalDeclarationStatementAbove(statementsInfo.Statements, index); if (localDeclarationStatement?.ContainsDiagnostics == false && !localDeclarationStatement.SpanOrTrailingTriviaContainsDirectives() && !statement.GetLeadingTrivia().Any(f => f.IsDirective)) { SeparatedSyntaxList <VariableDeclaratorSyntax> declarators = localDeclarationStatement.Declaration.Variables; VariableDeclaratorSyntax declarator = FindVariableDeclarator(semanticModel, symbol, declarators, cancellationToken); if (declarator != null) { ExpressionSyntax value = declarator.Initializer?.Value; if (removeReturnStatement || value != null) { IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, document.Solution(), cancellationToken).ConfigureAwait(false); if (referencedSymbols.First().Locations.Count() == count + 1) { newExpression = value; if (declarators.Count == 1) { statementsInfo = statementsInfo.RemoveNode(localDeclarationStatement, RemoveHelper.GetRemoveOptions(localDeclarationStatement)); index--; } else { statementsInfo = statementsInfo.ReplaceNode(localDeclarationStatement, localDeclarationStatement.RemoveNode(declarator, RemoveHelper.GetRemoveOptions(declarator))); } returnStatement = FindReturnStatementBelow(statementsInfo.Statements, index); } } } } } if (removeReturnStatement) { statementsInfo = statementsInfo.RemoveNode(returnStatement, RemoveHelper.GetRemoveOptions(returnStatement)); } else if (newExpression != null) { statementsInfo = statementsInfo.ReplaceNode(returnStatement, returnStatement.WithExpression(newExpression.WithTriviaFrom(expression))); } return(statementsInfo.ReplaceNode(statementsInfo.Statements[index], newStatement)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsAnyCodeFixEnabled( CodeFixIdentifiers.UseYieldReturnInsteadOfReturn, CodeFixIdentifiers.RemoveReturnKeyword, CodeFixIdentifiers.RemoveReturnExpression)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); ReturnStatementSyntax returnStatement = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <ReturnStatementSyntax>(); Debug.Assert(returnStatement != null, $"{nameof(returnStatement)} is null"); if (returnStatement == null) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.CannotReturnValueFromIterator: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseYieldReturnInsteadOfReturn)) { break; } ExpressionSyntax expression = returnStatement.Expression; if (expression != null) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ISymbol containingSymbol = semanticModel.GetEnclosingSymbol(returnStatement.SpanStart, context.CancellationToken); if (containingSymbol?.IsKind(SymbolKind.Method) == true) { var methodSymbol = (IMethodSymbol)containingSymbol; ITypeSymbol returnType = methodSymbol.ReturnType; var replacementKind = SyntaxKind.None; if (returnType.SpecialType == SpecialType.System_Collections_IEnumerable) { if (semanticModel .GetTypeSymbol(expression, context.CancellationToken) .IsIEnumerableOrConstructedFromIEnumerableOfT()) { replacementKind = SyntaxKind.ForEachStatement; } else { replacementKind = SyntaxKind.YieldReturnStatement; } } else if (returnType.IsNamedType()) { var namedTypeSymbol = (INamedTypeSymbol)returnType; if (namedTypeSymbol.IsConstructedFromIEnumerableOfT()) { if (semanticModel.IsImplicitConversion(expression, namedTypeSymbol.TypeArguments[0])) { replacementKind = SyntaxKind.YieldReturnStatement; } else { replacementKind = SyntaxKind.ForEachStatement; } } } if (replacementKind == SyntaxKind.YieldReturnStatement || (replacementKind == SyntaxKind.ForEachStatement && !returnStatement.SpanContainsDirectives())) { CodeAction codeAction = CodeAction.Create( "Use yield return instead of return", cancellationToken => UseYieldReturnInsteadOfReturnRefactoring.RefactorAsync(context.Document, returnStatement, replacementKind, semanticModel, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } } } break; } case CompilerDiagnosticIdentifiers.SinceMethodReturnsVoidReturnKeywordMustNotBeFollowedByObjectExpression: case CompilerDiagnosticIdentifiers.SinceMethodIsAsyncMethodThatReturnsTaskReturnKeywordMustNotBeFollowedByObjectExpression: { if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveReturnExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ISymbol symbol = semanticModel.GetEnclosingSymbol(returnStatement.SpanStart, context.CancellationToken); if (symbol?.IsMethod() == true) { var methodSymbol = (IMethodSymbol)symbol; if (methodSymbol.ReturnsVoid || methodSymbol.ReturnType.Equals(semanticModel.GetTypeByMetadataName(MetadataNames.System_Threading_Tasks_Task))) { CodeAction codeAction = CodeAction.Create( "Remove return expression", cancellationToken => { ReturnStatementSyntax newNode = returnStatement .WithExpression(null) .WithFormatterAnnotation(); return(context.Document.ReplaceNodeAsync(returnStatement, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic, CodeFixIdentifiers.RemoveReturnExpression)); context.RegisterCodeFix(codeAction, diagnostic); } } } if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveReturnKeyword)) { ExpressionSyntax expression = returnStatement.Expression; if (expression.IsKind( SyntaxKind.InvocationExpression, SyntaxKind.ObjectCreationExpression, SyntaxKind.PreDecrementExpression, SyntaxKind.PreIncrementExpression, SyntaxKind.PostDecrementExpression, SyntaxKind.PostIncrementExpression) || expression is AssignmentExpressionSyntax) { CodeAction codeAction = CodeAction.Create( "Remove 'return'", cancellationToken => { SyntaxTriviaList leadingTrivia = returnStatement .GetLeadingTrivia() .AddRange(returnStatement.ReturnKeyword.TrailingTrivia.EmptyIfWhitespace()) .AddRange(expression.GetLeadingTrivia().EmptyIfWhitespace()); ExpressionStatementSyntax newNode = SyntaxFactory.ExpressionStatement( expression.WithLeadingTrivia(leadingTrivia), returnStatement.SemicolonToken); return(context.Document.ReplaceNodeAsync(returnStatement, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic, CodeFixIdentifiers.RemoveReturnKeyword)); context.RegisterCodeFix(codeAction, diagnostic); } } break; } } } }
public override StatementSyntax VisitReturnStatement(ReturnStatementSyntax node) { return(node.WithExpression( node.Expression.Accept( expressionSyntaxVisitor))); }