public override SyntaxNode VisitReturnStatement(ReturnStatementSyntax node) { if (RemoveTestTriviaAnnotation(node.GetLeadingTrivia())) { return(null); } return(base.VisitReturnStatement(node)); }
private static SyntaxNode InsertStartRowAssignmentBeforeReturn(SyntaxNode root, ReturnStatementSyntax returnStatement) { var startRowAssignment = SyntaxFactory.ExpressionStatement( SyntaxFactory.ParseExpression($"{TypeNames.PXView}.{DelegateNames.StartRow} = 0") .WithLeadingTrivia(returnStatement.GetLeadingTrivia())); switch (returnStatement.Parent) { case IfStatementSyntax ifStatement: var ifStatementWithBlock = ifStatement.WithStatement( SyntaxFactory.Block(startRowAssignment, returnStatement)); return(root.ReplaceNode(ifStatement, ifStatementWithBlock)); case ElseClauseSyntax elseClause: var elseClauseWithBlock = elseClause.WithStatement( SyntaxFactory.Block(startRowAssignment, returnStatement)); return(root.ReplaceNode(elseClause, elseClauseWithBlock)); case WhileStatementSyntax whileStatement: var whileStatementWithBlock = whileStatement.WithStatement( SyntaxFactory.Block(startRowAssignment, returnStatement)); return(root.ReplaceNode(whileStatement, whileStatementWithBlock)); case DoStatementSyntax doStatement: var doStatementWithBlock = doStatement.WithStatement( SyntaxFactory.Block(startRowAssignment, returnStatement)); return(root.ReplaceNode(doStatement, doStatementWithBlock)); case ForStatementSyntax forStatement: var forStatementWithBlock = forStatement.WithStatement( SyntaxFactory.Block(startRowAssignment, returnStatement)); return(root.ReplaceNode(forStatement, forStatementWithBlock)); case ForEachStatementSyntax forEachStatement: var forEachStatementWithBlock = forEachStatement.WithStatement( SyntaxFactory.Block(startRowAssignment, returnStatement)); return(root.ReplaceNode(forEachStatement, forEachStatementWithBlock)); case BlockSyntax block: case SwitchSectionSyntax switchSection: return(root.InsertNodesBefore(returnStatement, startRowAssignment.ToEnumerable())); default: return(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().Parenthesize()).WithTriviaFrom(expression))); } else { return(ExpressionStatement(AwaitExpression(expression.WithoutTrivia().Parenthesize()).WithTriviaFrom(expression)) .WithLeadingTrivia(node.GetLeadingTrivia()) .WithAdditionalAnnotations(_asyncAwaitAnnotationAndFormatterAnnotation)); } } return(base.VisitReturnStatement(node)); }
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; } } } }