private static StatementContainer GetStatementContainer(SyntaxNode node) { SyntaxNode parent = node.Parent; if (parent != null) { StatementContainer container; if (StatementContainer.TryCreate(parent, out container)) { return(container); } } return(null); }
private StatementContainer GetStatementContainer(BinaryExpressionSyntax binaryExpression) { SyntaxNode node = binaryExpression.Parent.Parent; if (node != null) { StatementContainer container; if (StatementContainer.TryCreate(node, out container)) { return(container); } } return(null); }
private static async Task<Document> RefactorAsync( Document document, ExpressionSyntax expression, StatementSyntax statement, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); if (EmbeddedStatement.IsEmbeddedStatement(statement)) { return await document.ReplaceNodeAsync(statement, Block(statement, CreateNullCheck(expression)), cancellationToken).ConfigureAwait(false); } else { IStatementContainer container; if (StatementContainer.TryCreate(statement, out container)) { SyntaxList<StatementSyntax> statements = container.Statements; int statementIndex = statements.IndexOf(statement); ISymbol symbol = (statement.IsKind(SyntaxKind.LocalDeclarationStatement)) ? semanticModel.GetDeclaredSymbol(((LocalDeclarationStatementSyntax)statement).Declaration.Variables.First(), cancellationToken) : semanticModel.GetSymbol(expression, cancellationToken); int lastStatementIndex = IncludeAllReferencesOfSymbol(symbol, expression.Kind(), statements, statementIndex + 1, semanticModel, cancellationToken); if (lastStatementIndex != -1) { if (lastStatementIndex < statements.Count - 1) lastStatementIndex = IncludeAllReferencesOfVariablesDeclared(statements, statementIndex + 1, lastStatementIndex, semanticModel, cancellationToken); return await RefactorAsync( document, expression, statements, container, statementIndex, lastStatementIndex, cancellationToken).ConfigureAwait(false); } } } return await document.InsertNodeAfterAsync(statement, CreateNullCheck(expression), cancellationToken).ConfigureAwait(false); }
private static bool NullCheckExists(ExpressionSyntax expression, StatementSyntax statement) { if (!EmbeddedStatement.IsEmbeddedStatement(statement)) { StatementContainer container; if (StatementContainer.TryCreate(statement, out container)) { SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(statement); if (index < statements.Count - 1) { StatementSyntax nextStatement = statements[index + 1]; if (nextStatement.IsKind(SyntaxKind.IfStatement)) { var ifStatement = (IfStatementSyntax)nextStatement; ExpressionSyntax condition = ifStatement.Condition; if (condition?.IsKind(SyntaxKind.NotEqualsExpression) == true) { var notEqualsExpression = (BinaryExpressionSyntax)condition; ExpressionSyntax left = notEqualsExpression.Left; if (left?.IsEquivalentTo(expression, topLevel: false) == true) { ExpressionSyntax right = notEqualsExpression.Right; if (right?.IsKind(SyntaxKind.NullLiteralExpression) == true) { return(true); } } } } } } } return(false); }
public async Task <Solution> InlineAndRemoveMethodAsync( ExpressionStatementSyntax expressionStatement, SyntaxList <StatementSyntax> statements) { if (expressionStatement.SyntaxTree == MethodDeclaration.SyntaxTree) { DocumentEditor editor = await DocumentEditor.CreateAsync(Document, CancellationToken).ConfigureAwait(false); StatementSyntax[] newStatements = RewriteStatements(statements); int count = statements.Count; newStatements[0] = newStatements[0].WithLeadingTrivia(expressionStatement.GetLeadingTrivia()); newStatements[count - 1] = newStatements[count - 1].WithTrailingTrivia(expressionStatement.GetTrailingTrivia()); StatementContainer container; if (StatementContainer.TryCreate(expressionStatement, out container)) { SyntaxNode newNode = container.NodeWithStatements(container.Statements.ReplaceRange(expressionStatement, newStatements)); editor.ReplaceNode(container.Node, newNode); } else { editor.ReplaceNode(expressionStatement, Block(newStatements)); } editor.RemoveNode(MethodDeclaration); return(editor.GetChangedDocument().Solution()); } else { Document newDocument = await InlineMethodAsync(expressionStatement, statements).ConfigureAwait(false); DocumentId documentId = Document.Solution().GetDocumentId(MethodDeclaration.SyntaxTree); newDocument = await newDocument.Solution().GetDocument(documentId).RemoveMemberAsync(MethodDeclaration, CancellationToken).ConfigureAwait(false); return(newDocument.Solution()); } }
public static void ComputeRefactoring(RefactoringContext context, ReturnStatementSyntax returnStatement) { ExpressionSyntax expression = returnStatement.Expression; if (expression != null) { IStatementContainer container; if (StatementContainer.TryCreate(returnStatement, out container)) { SyntaxList <StatementSyntax> statements = container.Statements; if (statements.Count > 1) { int index = statements.IndexOf(returnStatement); if (index == statements.Count - 1) { StatementSyntax prevStatement = statements[index - 1]; if (prevStatement.IsKind(SyntaxKind.IfStatement)) { var ifStatement = (IfStatementSyntax)prevStatement; IfStatement ifElse = IfStatement.Create(ifStatement); if (ifElse.EndsWithIf && ifElse .Nodes .Where(f => f.IsIf) .All(f => IsLastStatementReturnStatement(f))) { context.RegisterRefactoring( "Wrap in else", cancellationToken => RefactorAsync(context.Document, ifStatement, returnStatement, container, cancellationToken)); } } } } } } }
public static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context) { if (context.Node.ContainsDiagnostics) { return; } var ifStatement = (IfStatementSyntax)context.Node; if (!ifStatement.IsSimpleIf()) { StatementContainer container; if (StatementContainer.TryCreate(ifStatement, out container)) { int index = container.Statements.IndexOf(ifStatement); ReturnStatementSyntax returnStatement = FindReturnStatementBelow(container.Statements, index); if (returnStatement?.ContainsDiagnostics == false) { ExpressionSyntax expression = returnStatement.Expression; if (expression != null && !ifStatement.SpanOrTrailingTriviaContainsDirectives() && !returnStatement.SpanOrLeadingTriviaContainsDirectives()) { SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); if (IsLocalDeclaredInScopeOrNonRefOrOutParameterOfEnclosingSymbol(symbol, container.Node, semanticModel, cancellationToken) && ifStatement .GetChain() .All(ifOrElse => IsSymbolAssignedInLastStatement(ifOrElse, symbol, semanticModel, cancellationToken))) { context.ReportDiagnostic(DiagnosticDescriptors.UseReturnInsteadOfAssignment, ifStatement); } } } } } }
private static void RegisterRefactoring( RefactoringContext context, StatementSyntax statement, InitializerExpressionSyntax initializer, ExpressionSyntax expression) { StatementContainer container; if (StatementContainer.TryCreate(statement, out container)) { context.RegisterRefactoring( Title, cancellationToken => RefactorAsync( context.Document, container, statement, initializer, expression.WithoutTrivia(), cancellationToken)); } }
public Task <Document> InlineMethodAsync( ExpressionStatementSyntax expressionStatement, SyntaxList <StatementSyntax> statements) { int count = statements.Count; StatementSyntax[] newStatements = RewriteStatements(statements); newStatements[0] = newStatements[0].WithLeadingTrivia(expressionStatement.GetLeadingTrivia()); newStatements[count - 1] = newStatements[count - 1].WithTrailingTrivia(expressionStatement.GetTrailingTrivia()); if (StatementContainer.TryCreate(expressionStatement, out StatementContainer container)) { SyntaxNode newNode = container.NodeWithStatements(container.Statements.ReplaceRange(expressionStatement, newStatements)); return(Document.ReplaceNodeAsync(container.Node, newNode, CancellationToken)); } else { return(Document.ReplaceNodeAsync(expressionStatement, Block(newStatements), CancellationToken)); } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveUnreachableCode)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out StatementSyntax statement)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.UnreachableCodeDetected: { Debug.Assert(context.Span.Start == statement.SpanStart, statement.ToString()); if (context.Span.Start != statement.SpanStart) { break; } CodeAction codeAction = CreateCodeActionForIfElse(context.Document, diagnostic, statement.Parent); if (codeAction != null) { context.RegisterCodeFix(codeAction, diagnostic); break; } if (StatementContainer.TryCreate(statement, out StatementContainer container)) { codeAction = CodeAction.Create( Title, cancellationToken => { SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(statement); if (index == statements.Count - 1) { return(context.Document.RemoveStatementAsync(statement, cancellationToken)); } else { SyntaxRemoveOptions removeOptions = RemoveHelper.DefaultRemoveOptions; if (statement.GetLeadingTrivia().IsEmptyOrWhitespace()) { removeOptions &= ~SyntaxRemoveOptions.KeepLeadingTrivia; } if (statements.Last().GetTrailingTrivia().IsEmptyOrWhitespace()) { removeOptions &= ~SyntaxRemoveOptions.KeepTrailingTrivia; } return(context.Document.RemoveNodesAsync(statements.Skip(index), removeOptions, cancellationToken)); } }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } break; } } } }
public static async Task <Document> RefactorAsync( Document document, VariableDeclaratorSyntax declarator, CancellationToken cancellationToken) { var declaration = (VariableDeclarationSyntax)declarator.Parent; var localDeclaration = (LocalDeclarationStatementSyntax)declaration.Parent; StatementContainer container; if (StatementContainer.TryCreate(localDeclaration, out container)) { SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(localDeclaration); StatementSyntax nextStatement = statements[index + 1]; var expressionStatement = (ExpressionStatementSyntax)nextStatement; var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; ExpressionSyntax right = assignment.Right; EqualsValueClauseSyntax initializer = declarator.Initializer; ExpressionSyntax value = initializer?.Value; VariableDeclaratorSyntax newDeclarator = (value != null) ? declarator.ReplaceNode(value, right) : declarator.WithInitializer(EqualsValueClause(right)); LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration.ReplaceNode(declarator, newDeclarator); SyntaxTriviaList trailingTrivia = nextStatement.GetTrailingTrivia(); IEnumerable <SyntaxTrivia> trivia = container .Node .DescendantTrivia(TextSpan.FromBounds(localDeclaration.Span.End, right.SpanStart)); if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(trivia.Concat(trailingTrivia)); } else { newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(trailingTrivia); } SyntaxList <StatementSyntax> newStatements = statements .Replace(localDeclaration, newLocalDeclaration) .RemoveAt(index + 1); return(await document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false)); } Debug.Assert(false, ""); return(document); }
public static void ComputeRefactoring(RefactoringContext context, ExpressionSyntax expression) { SyntaxNode parent = expression.Parent; if (parent != null) { SyntaxKind kind = parent.Kind(); if (kind == SyntaxKind.LogicalAndExpression || kind == SyntaxKind.LogicalOrExpression) { BinaryExpressionSyntax binaryExpression = GetCondition((BinaryExpressionSyntax)parent); if (binaryExpression != null) { parent = binaryExpression.Parent; switch (parent?.Kind()) { case SyntaxKind.IfStatement: { if (kind == SyntaxKind.LogicalAndExpression) { var refactoring = new ExtractConditionFromIfToNestedIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, binaryExpression, expression, cancellationToken)); } else if (kind == SyntaxKind.LogicalOrExpression) { StatementContainer container; if (StatementContainer.TryCreate((StatementSyntax)parent, out container)) { var refactoring = new ExtractConditionFromIfToIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, container, binaryExpression, expression, cancellationToken)); } } break; } case SyntaxKind.WhileStatement: { if (kind == SyntaxKind.LogicalAndExpression) { StatementContainer container; if (StatementContainer.TryCreate((StatementSyntax)parent, out container)) { var refactoring = new ExtractConditionFromWhileToNestedIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, (WhileStatementSyntax)parent, binaryExpression, expression, cancellationToken)); } } break; } } } } } }
public static async Task <Document> RefactorAsync( Document document, StatementSyntax statement, CancellationToken cancellationToken) { StatementContainer container; if (StatementContainer.TryCreate(statement, out container)) { SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(statement); StatementSyntax nextStatemnt = statements[index + 1]; switch (statement.Kind()) { case SyntaxKind.IfStatement: { var ifStatement = (IfStatementSyntax)statement; var expressionStatement = (ExpressionStatementSyntax)GetSingleStatementOrDefault(ifStatement.Statement); var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; ExpressionSyntax left = assignment.Left; ExpressionSyntax right = assignment.Right; BinaryExpressionSyntax coalesceExpression = CoalesceExpression( left.WithoutLeadingTrivia().WithTrailingTrivia(Space), right.WithLeadingTrivia(Space)); AssignmentExpressionSyntax newAssignment = assignment.WithRight(coalesceExpression.WithTriviaFrom(right)); ExpressionStatementSyntax newNode = expressionStatement.WithExpression(newAssignment); IEnumerable <SyntaxTrivia> trivia = ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, expressionStatement.SpanStart)); if (trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { newNode = newNode.WithLeadingTrivia(ifStatement.GetLeadingTrivia()); } else { newNode = newNode .WithLeadingTrivia(ifStatement.GetLeadingTrivia().Concat(trivia)) .WithFormatterAnnotation(); } return(await document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken).ConfigureAwait(false)); } case SyntaxKind.ExpressionStatement: { var expressionStatement = (ExpressionStatementSyntax)statement; var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; return(await RefactorAsync(document, expressionStatement, (IfStatementSyntax)nextStatemnt, index, container, assignment.Right, cancellationToken).ConfigureAwait(false)); } case SyntaxKind.LocalDeclarationStatement: { var localDeclaration = (LocalDeclarationStatementSyntax)statement; ExpressionSyntax value = localDeclaration .Declaration .Variables .First() .Initializer .Value; return(await RefactorAsync(document, localDeclaration, (IfStatementSyntax)nextStatemnt, index, container, value, cancellationToken).ConfigureAwait(false)); } } } Debug.Assert(false, statement.Kind().ToString()); return(document); }
private static ReduceIfNestingAnalysis AnalyzeCore( IfStatementSyntax ifStatement, SemanticModel semanticModel, SyntaxKind jumpKind, ReduceIfNestingOptions options, INamedTypeSymbol taskSymbol = null, CancellationToken cancellationToken = default(CancellationToken)) { if (!StatementContainer.TryCreate(ifStatement, out StatementContainer container)) { return(Fail(ifStatement)); } CSharpSyntaxNode node = container.Node; SyntaxNode parent = node.Parent; SyntaxKind parentKind = parent.Kind(); SyntaxList <StatementSyntax> statements = container.Statements; if (container.IsSwitchSection || parentKind == SyntaxKind.SwitchSection) { SyntaxNode switchSection = (container.IsSwitchSection) ? node : parent; if (!options.AllowSwitchSection()) { return(Fail(switchSection)); } if (ifStatement != statements.LastButOneOrDefault()) { return(Fail(switchSection)); } if (!IsFixableJumpStatement(statements.Last(), ref jumpKind)) { return(Fail(switchSection)); } if (!options.AllowNestedFix() && IsNestedFix(switchSection.Parent, semanticModel, options, taskSymbol, cancellationToken)) { return(Fail(switchSection)); } return(Success(jumpKind, switchSection)); } if (parentKind.Is( SyntaxKind.ForStatement, SyntaxKind.ForEachStatement, SyntaxKind.DoStatement, SyntaxKind.WhileStatement)) { if (!options.AllowLoop()) { return(Fail(parent)); } StatementSyntax lastStatement = statements.Last(); if (ifStatement == lastStatement) { jumpKind = SyntaxKind.ContinueStatement; } else { if (ifStatement != statements.LastButOneOrDefault()) { return(Fail(parent)); } if (!IsFixableJumpStatement(lastStatement, ref jumpKind)) { return(Fail(parent)); } } if (!options.AllowNestedFix() && IsNestedFix(parent.Parent, semanticModel, options, taskSymbol, cancellationToken)) { return(Fail(parent)); } return(Success(jumpKind, parent)); } if (!IsFixable(ifStatement, statements, ref jumpKind)) { return(Fail(node)); } switch (parentKind) { case SyntaxKind.ConstructorDeclaration: case SyntaxKind.DestructorDeclaration: case SyntaxKind.SetAccessorDeclaration: case SyntaxKind.AddAccessorDeclaration: case SyntaxKind.RemoveAccessorDeclaration: { if (jumpKind == SyntaxKind.None) { jumpKind = SyntaxKind.ReturnStatement; } else if (jumpKind != SyntaxKind.ReturnStatement) { return(Fail(parent)); } return(Success(jumpKind, parent)); } case SyntaxKind.OperatorDeclaration: case SyntaxKind.ConversionOperatorDeclaration: case SyntaxKind.GetAccessorDeclaration: { if (jumpKind == SyntaxKind.None) { return(Fail(parent)); } return(Success(jumpKind, parent)); } case SyntaxKind.MethodDeclaration: { var methodDeclaration = (MethodDeclarationSyntax)parent; if (jumpKind != SyntaxKind.None) { return(Success(jumpKind, parent)); } if (methodDeclaration.ReturnsVoid()) { return(Success(SyntaxKind.ReturnStatement, parent)); } if (methodDeclaration.Modifiers.Contains(SyntaxKind.AsyncKeyword) && taskSymbol != null && semanticModel .GetDeclaredSymbol(methodDeclaration, cancellationToken)? .ReturnType .Equals(taskSymbol) == true) { return(Success(SyntaxKind.ReturnStatement, parent)); } if (semanticModel .GetDeclaredSymbol(methodDeclaration, cancellationToken)? .ReturnType .IsIEnumerableOrConstructedFromIEnumerableOfT() == true && methodDeclaration.ContainsYield()) { return(Success(SyntaxKind.YieldBreakStatement, parent)); } break; } case SyntaxKind.LocalFunctionStatement: { var localFunction = (LocalFunctionStatementSyntax)parent; if (jumpKind != SyntaxKind.None) { return(Success(jumpKind, parent)); } if (localFunction.ReturnsVoid()) { return(Success(SyntaxKind.ReturnStatement, parent)); } if (localFunction.Modifiers.Contains(SyntaxKind.AsyncKeyword) && taskSymbol != null && ((IMethodSymbol)semanticModel.GetDeclaredSymbol(localFunction, cancellationToken))? .ReturnType .Equals(taskSymbol) == true) { return(Success(SyntaxKind.ReturnStatement, parent)); } if (((IMethodSymbol)semanticModel.GetDeclaredSymbol(localFunction, cancellationToken))? .ReturnType .IsIEnumerableOrConstructedFromIEnumerableOfT() == true && localFunction.ContainsYield()) { return(Success(SyntaxKind.YieldBreakStatement, parent)); } break; } case SyntaxKind.AnonymousMethodExpression: case SyntaxKind.SimpleLambdaExpression: case SyntaxKind.ParenthesizedLambdaExpression: { var anonymousFunction = (AnonymousFunctionExpressionSyntax)parent; if (jumpKind != SyntaxKind.None) { return(Success(jumpKind, parent)); } var methodSymbol = semanticModel.GetSymbol(anonymousFunction, cancellationToken) as IMethodSymbol; if (methodSymbol == null) { return(Fail(parent)); } if (methodSymbol.ReturnsVoid) { return(Success(SyntaxKind.ReturnStatement, parent)); } if (anonymousFunction.AsyncKeyword.IsKind(SyntaxKind.AsyncKeyword) && methodSymbol.ReturnType.Equals(taskSymbol)) { return(Success(SyntaxKind.ReturnStatement, parent)); } break; } case SyntaxKind.IfStatement: { ifStatement = (IfStatementSyntax)parent; if (ifStatement.Parent is ElseClauseSyntax elseClause) { if (ifStatement.Else != null) { return(Fail(parent)); } if (!options.AllowIfInsideIfElse()) { return(Fail(parent)); } return(AnalyzeCore(ifStatement.GetTopmostIf(), semanticModel, jumpKind, options, taskSymbol, cancellationToken)); } else { if (!IsFixable(ifStatement)) { return(Fail(parent)); } if (!options.AllowNestedFix()) { return(Fail(parent)); } return(AnalyzeCore(ifStatement, semanticModel, jumpKind, options, taskSymbol, cancellationToken)); } } case SyntaxKind.ElseClause: { if (!options.AllowIfInsideIfElse()) { return(Fail(parent)); } var elseClause = (ElseClauseSyntax)parent; return(AnalyzeCore(elseClause.GetTopmostIf(), semanticModel, jumpKind, options, taskSymbol, cancellationToken)); } } return(Fail(parent)); }
public static void Analyze(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement) { if (!StatementContainer.TryCreate(ifStatement, out StatementContainer container)) { return; } ReturnStatementSyntax returnStatement = GetReturnStatement(ifStatement.Statement); LiteralExpressionSyntax booleanLiteral = GetBooleanLiteral(returnStatement); if (booleanLiteral == null) { return; } ReturnStatementSyntax returnStatement2 = null; LiteralExpressionSyntax booleanLiteral2 = null; TextSpan span = ifStatement.Span; ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause != null) { returnStatement2 = GetReturnStatement(elseClause.Statement); booleanLiteral2 = GetBooleanLiteral(returnStatement2); if (booleanLiteral2 == null) { return; } } else { SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(ifStatement); if (index == statements.Count - 1) { return; } if (index > 0 && ((statements[index - 1] is IfStatementSyntax ifStatement2) && ifStatement2.Else == null && GetBooleanLiteral(ifStatement2.Statement) != null)) { return; } StatementSyntax nextStatement = statements[index + 1]; if (nextStatement.Kind() != SyntaxKind.ReturnStatement) { return; } returnStatement2 = (ReturnStatementSyntax)nextStatement; booleanLiteral2 = GetBooleanLiteral(returnStatement2); if (booleanLiteral2 == null) { return; } span = TextSpan.FromBounds(ifStatement.SpanStart, returnStatement2.Span.End); } if (booleanLiteral.Kind() == booleanLiteral2.Kind()) { return; } if (!container.Node .DescendantTrivia(span) .All(f => f.IsWhitespaceOrEndOfLineTrivia())) { return; } context.ReportDiagnostic(DiagnosticDescriptors.ReplaceIfStatementWithReturnStatement, ifStatement.IfKeyword); context.ReportToken(DiagnosticDescriptors.ReplaceIfStatementWithReturnStatementFadeOut, ifStatement.IfKeyword); context.ReportToken(DiagnosticDescriptors.ReplaceIfStatementWithReturnStatementFadeOut, ifStatement.OpenParenToken); context.ReportToken(DiagnosticDescriptors.ReplaceIfStatementWithReturnStatementFadeOut, ifStatement.CloseParenToken); context.ReportNode(DiagnosticDescriptors.ReplaceIfStatementWithReturnStatementFadeOut, ifStatement.Statement); if (elseClause != null) { context.ReportNode(DiagnosticDescriptors.ReplaceIfStatementWithReturnStatementFadeOut, elseClause); } else { context.ReportNode(DiagnosticDescriptors.ReplaceIfStatementWithReturnStatementFadeOut, returnStatement2); } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsAnyCodeFixEnabled( CodeFixIdentifiers.RemoveUnreachableCode, CodeFixIdentifiers.RemoveEmptySwitchStatement, CodeFixIdentifiers.IntroduceLocalVariable, CodeFixIdentifiers.RemoveJumpStatement)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out StatementSyntax statement)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.UnreachableCodeDetected: { if (context.Span.Start == statement.SpanStart) { StatementContainer container; if (StatementContainer.TryCreate(statement, out container)) { CodeAction codeAction = CodeAction.Create( "Remove unreachable code", cancellationToken => { SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(statement); if (index == statements.Count - 1) { return(context.Document.RemoveStatementAsync(statement, context.CancellationToken)); } else { SyntaxRemoveOptions removeOptions = RemoveHelper.DefaultRemoveOptions; if (statement.GetLeadingTrivia().IsEmptyOrWhitespace()) { removeOptions &= ~SyntaxRemoveOptions.KeepLeadingTrivia; } if (statements.Last().GetTrailingTrivia().IsEmptyOrWhitespace()) { removeOptions &= ~SyntaxRemoveOptions.KeepTrailingTrivia; } return(context.Document.RemoveNodesAsync(statements.Skip(index), removeOptions, context.CancellationToken)); } }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } } break; } case CompilerDiagnosticIdentifiers.EmptySwitchBlock: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveEmptySwitchStatement)) { break; } if (!statement.IsKind(SyntaxKind.SwitchStatement)) { break; } var switchStatement = (SwitchStatementSyntax)statement; CodeAction codeAction = CodeAction.Create( "Remove switch statement", cancellationToken => context.Document.RemoveStatementAsync(switchStatement, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.OnlyAssignmentCallIncrementDecrementAndNewObjectExpressionsCanBeUsedAsStatement: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.IntroduceLocalVariable)) { break; } if (!statement.IsKind(SyntaxKind.ExpressionStatement)) { break; } var expressionStatement = (ExpressionStatementSyntax)statement; ExpressionSyntax expression = expressionStatement.Expression; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (semanticModel.GetSymbol(expression, context.CancellationToken)?.IsErrorType() == false) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, context.CancellationToken); if (typeSymbol?.IsErrorType() == false) { bool addAwait = typeSymbol.IsConstructedFromTaskOfT(semanticModel) && semanticModel.GetEnclosingSymbol(expressionStatement.SpanStart, context.CancellationToken).IsAsyncMethod(); CodeAction codeAction = CodeAction.Create( IntroduceLocalVariableRefactoring.GetTitle(expression), cancellationToken => IntroduceLocalVariableRefactoring.RefactorAsync(context.Document, expressionStatement, typeSymbol, addAwait, semanticModel, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } } break; } case CompilerDiagnosticIdentifiers.NoEnclosingLoopOutOfWhichToBreakOrContinue: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveJumpStatement)) { break; } CodeAction codeAction = CodeAction.Create( $"Remove {statement.GetTitle()}", cancellationToken => context.Document.RemoveStatementAsync(statement, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }