public static void ComputeRefactoring(RefactoringContext context, SelectedStatementsInfo info) { if (info.IsSingleSelected) { StatementSyntax[] statements = info.SelectedNodes().ToArray(); StatementSyntax first = statements[0]; if (first.IsKind(SyntaxKind.IfStatement)) { var ifStatement = (IfStatementSyntax)first; if (IfElseAnalysis.IsTopmostIf(ifStatement) && CanBeReplacedWithSwitch(ifStatement)) { string title = (IfElseAnalysis.IsIsolatedIf(ifStatement)) ? "Replace if with switch" : "Replace if-else with switch"; context.RegisterRefactoring( title, cancellationToken => { return(RefactorAsync( context.Document, ifStatement, cancellationToken)); }); } } } }
private void AnalyzeStatement(SyntaxNodeAnalysisContext context) { if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true) { return; } AnalyzeEmbeddedStatement(context); if (context.Node.IsKind(SyntaxKind.IfStatement) && !IfElseAnalysis.IsIsolatedIf((IfStatementSyntax)context.Node)) { return; } StatementSyntax statement = EmbeddedStatementAnalysis.GetEmbeddedStatementThatShouldBeInsideBlock(context.Node); if (statement != null) { context.ReportDiagnostic( DiagnosticDescriptors.AddBraces, statement.GetLocation(), SyntaxHelper.GetNodeTitle(context.Node)); } }
public override SyntaxNode VisitIfStatement(IfStatementSyntax node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (_previousIf == null || _previousIf.Equals(IfElseAnalysis.GetPreviousIf(node))) { if (node.Statement != null && !node.Statement.IsKind(SyntaxKind.Block)) { IfStatementSyntax ifStatement = node.WithStatement(SyntaxFactory.Block(node.Statement)); _previousIf = ifStatement; return(base.VisitIfStatement(ifStatement)); } else { _previousIf = node; } } return(base.VisitIfStatement(node)); }
private void AnalyzeStatement(SyntaxNodeAnalysisContext context) { if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true) { return; } if (!context.Node.IsKind(SyntaxKind.IfStatement) || IfElseAnalysis.IsIsolatedIf((IfStatementSyntax)context.Node)) { BlockSyntax block = EmbeddedStatementAnalysis.GetBlockThatCanBeEmbeddedStatement(context.Node); if (block != null && !block.OpenBraceToken.IsMissing && !block.CloseBraceToken.IsMissing && block.OpenBraceToken.LeadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) && block.OpenBraceToken.TrailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) && block.CloseBraceToken.LeadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) && block.CloseBraceToken.TrailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { context.ReportDiagnostic( DiagnosticDescriptors.RemoveBraces, block.GetLocation(), SyntaxHelper.GetNodeTitle(context.Node)); context.FadeOutBraces(DiagnosticDescriptors.RemoveBracesFadeOut, block); } } }
private static bool CheckContainingNode(SyntaxNode node) { switch (node.Kind()) { case SyntaxKind.ForEachStatement: case SyntaxKind.ForStatement: case SyntaxKind.UsingStatement: case SyntaxKind.WhileStatement: case SyntaxKind.DoStatement: case SyntaxKind.LockStatement: case SyntaxKind.FixedStatement: case SyntaxKind.UnsafeStatement: case SyntaxKind.TryStatement: case SyntaxKind.CheckedStatement: case SyntaxKind.UncheckedStatement: return(true); case SyntaxKind.IfStatement: return(IfElseAnalysis.IsTopmostIf((IfStatementSyntax)node)); case SyntaxKind.ElseClause: return(IfElseAnalysis.IsEndOfChain((ElseClauseSyntax)node)); } return(false); }
private static IEnumerable <SwitchSectionSyntax> CreateSwitchSections(IfStatementSyntax ifStatement) { foreach (SyntaxNode node in IfElseAnalysis.GetChain(ifStatement)) { if (node.IsKind(SyntaxKind.IfStatement)) { ifStatement = (IfStatementSyntax)node; var condition = ifStatement.Condition as BinaryExpressionSyntax; List <SwitchLabelSyntax> labels = CreateSwitchLabels(condition, new List <SwitchLabelSyntax>()); labels.Reverse(); SwitchSectionSyntax section = SwitchSection( List(labels), AddBreakStatementIfNecessary(ifStatement.Statement)); yield return(section); } else { var elseClause = (ElseClauseSyntax)node; yield return(DefaultSwitchSection(AddBreakStatementIfNecessary(elseClause.Statement))); } } }
private static SyntaxNode GetContainingBlock(SyntaxNode node) { if (node.IsKind(SyntaxKind.ElseClause)) { return(IfElseAnalysis.GetTopmostIf((ElseClauseSyntax)node)?.Parent); } else { return(node.Parent); } }
internal IfElseAnalysisResult(IfStatementSyntax ifStatement) { if (ifStatement == null) { throw new ArgumentNullException(nameof(ifStatement)); } bool anyHasEmbedded = false; bool anyHasBlock = false; bool allSupportsEmbedded = true; int cnt = 0; foreach (SyntaxNode node in IfElseAnalysis.GetChain(ifStatement)) { cnt++; StatementSyntax statement = GetStatement(node); if (!anyHasEmbedded && !statement.IsKind(SyntaxKind.Block)) { anyHasEmbedded = true; } if (!anyHasBlock && statement.IsKind(SyntaxKind.Block)) { anyHasBlock = true; } if (allSupportsEmbedded && !SupportsEmbedded(statement)) { allSupportsEmbedded = false; } if (cnt > 1 && anyHasEmbedded && !allSupportsEmbedded) { AddBraces = true; return; } } if (cnt > 1 && allSupportsEmbedded && anyHasBlock) { RemoveBraces = true; if (anyHasEmbedded) { AddBraces = true; } } }
public static bool CanRefactor( IfStatementSyntax ifStatement, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (IfElseAnalysis.IsTopmostIf(ifStatement)) { ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause != null) { ExpressionSyntax condition = ifStatement.Condition; if (condition != null) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(condition, cancellationToken); if (typeSymbol?.IsBoolean() == true) { AssignmentExpressionSyntax trueExpression = GetSimpleAssignmentExpression(ifStatement.Statement); ExpressionSyntax trueRight = trueExpression?.Right; if (trueRight?.IsBooleanLiteralExpression() == true) { AssignmentExpressionSyntax falseExpression = GetSimpleAssignmentExpression(elseClause.Statement); ExpressionSyntax falseRight = falseExpression?.Right; if (falseRight?.IsBooleanLiteralExpression() == true) { var trueBooleanLiteral = (LiteralExpressionSyntax)trueRight; var falseBooleanLiteral = (LiteralExpressionSyntax)falseRight; if (trueBooleanLiteral.IsKind(SyntaxKind.TrueLiteralExpression) != falseBooleanLiteral.IsKind(SyntaxKind.TrueLiteralExpression) && trueExpression.Left?.IsEquivalentTo(falseExpression.Left, topLevel: false) == true) { return(true); } } } } } } } return(false); }
private static IfStatementSyntax GetTopmostIf(BlockSyntax block) { SyntaxNode parent = block.Parent; switch (parent?.Kind()) { case SyntaxKind.IfStatement: return(IfElseAnalysis.GetTopmostIf((IfStatementSyntax)parent)); case SyntaxKind.ElseClause: return(IfElseAnalysis.GetTopmostIf((ElseClauseSyntax)parent)); default: return(null); } }
private static SyntaxNode GetNewRoot(StatementSyntax statement, SyntaxNode oldRoot, IEnumerable <StatementSyntax> newNodes) { if (statement.Parent.IsKind(SyntaxKind.ElseClause)) { IfStatementSyntax ifStatement = IfElseAnalysis.GetTopmostIf((ElseClauseSyntax)statement.Parent); var block = (BlockSyntax)ifStatement.Parent; int index = block.Statements.IndexOf(ifStatement); BlockSyntax newBlock = block.RemoveNode(statement.Parent, SyntaxRemoveOptions.KeepNoTrivia); newBlock = newBlock.WithStatements(newBlock.Statements.InsertRange(index + 1, newNodes)); return(oldRoot.ReplaceNode(block, newBlock)); } else { return(oldRoot.ReplaceNode(statement.Parent, newNodes)); } }
public static void Analyze(SyntaxNodeAnalysisContext context, IfStatementSyntax ifStatement) { if (IfElseAnalysis.IsIsolatedIf(ifStatement) && ConditionAllowsMerging(ifStatement.Condition)) { IfStatementSyntax nestedIf = GetNestedIfStatement(ifStatement); if (nestedIf != null && nestedIf.Else == null && ConditionAllowsMerging(nestedIf.Condition) && TriviaAllowsMerging(ifStatement, nestedIf)) { context.ReportDiagnostic( DiagnosticDescriptors.MergeIfStatementWithNestedIfStatement, ifStatement.GetLocation()); FadeOut(context, ifStatement, nestedIf); } } }
private static bool CanBeReplacedWithSwitch(IfStatementSyntax ifStatement) { foreach (SyntaxNode node in IfElseAnalysis.GetChain(ifStatement)) { if (node.IsKind(SyntaxKind.IfStatement)) { ifStatement = (IfStatementSyntax)node; var condition = ifStatement.Condition as BinaryExpressionSyntax; if (condition == null || !IsValidCondition(condition, null)) { return(false); } } } return(true); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); IfStatementSyntax ifStatement = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <IfStatementSyntax>(); if (ifStatement == null) { return; } ifStatement = IfElseAnalysis.GetTopmostIf(ifStatement); CodeAction codeAction = CodeAction.Create( "Add braces to if-else", cancellationToken => AddBracesToIfElseRefactoring.RefactorAsync(context.Document, ifStatement, cancellationToken), DiagnosticIdentifiers.AddBracesToIfElse + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, context.Diagnostics); }
private static IfStatementSyntax GetTopmostIf(StatementSyntax statement) { SyntaxNode parent = statement.Parent; if (parent != null) { if (parent.IsKind(SyntaxKind.ElseClause)) { return(IfElseAnalysis.GetTopmostIf((ElseClauseSyntax)parent)); } else { var parentStatement = parent as IfStatementSyntax; if (parentStatement != null) { return(IfElseAnalysis.GetTopmostIf(parentStatement)); } } } return(null); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, IfStatementSyntax ifStatement) { if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.SwapStatementsInIfElse, RefactoringIdentifiers.ReplaceIfElseWithConditionalExpression) && IfElseAnalysis.IsTopmostIf(ifStatement) && context.Span.IsBetweenSpans(ifStatement)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceIfElseWithConditionalExpression)) { ReplaceIfElseWithConditionalExpressionRefactoring.ComputeRefactoring(context, ifStatement); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapStatementsInIfElse) && SwapStatementInIfElseRefactoring.CanRefactor(ifStatement)) { context.RegisterRefactoring( "Swap statements in if-else", cancellationToken => { return(SwapStatementInIfElseRefactoring.RefactorAsync( context.Document, ifStatement, cancellationToken)); }); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddBooleanComparison) && ifStatement.Condition != null && ifStatement.Condition.Span.Contains(context.Span) && context.SupportsSemanticModel) { await AddBooleanComparisonRefactoring.ComputeRefactoringAsync(context, ifStatement.Condition).ConfigureAwait(false); } }
private static IEnumerable <StatementSyntax> GetEmbeddedStatements(IfStatementSyntax topmostIf) { foreach (SyntaxNode node in IfElseAnalysis.GetChain(topmostIf)) { switch (node.Kind()) { case SyntaxKind.IfStatement: { var ifStatement = (IfStatementSyntax)node; StatementSyntax statement = ifStatement.Statement; if (statement?.IsKind(SyntaxKind.Block) == false) { yield return(statement); } break; } case SyntaxKind.ElseClause: { var elseClause = (ElseClauseSyntax)node; StatementSyntax statement = elseClause.Statement; if (statement?.IsKind(SyntaxKind.Block) == false) { yield return(statement); } break; } } } }
private static StatementSyntax GetStatement( RefactoringContext context, BlockSyntax block, SyntaxNode parent) { switch (parent?.Kind()) { case SyntaxKind.WhileStatement: case SyntaxKind.DoStatement: case SyntaxKind.ForStatement: case SyntaxKind.ForEachStatement: case SyntaxKind.FixedStatement: case SyntaxKind.CheckedStatement: case SyntaxKind.UncheckedStatement: case SyntaxKind.UnsafeStatement: case SyntaxKind.UsingStatement: case SyntaxKind.LockStatement: { if (block.OpenBraceToken.Span.Contains(context.Span) || block.CloseBraceToken.Span.Contains(context.Span)) { if (parent.IsKind(SyntaxKind.UsingStatement)) { var usingStatement = (UsingStatementSyntax)parent; while (usingStatement.Parent?.IsKind(SyntaxKind.UsingStatement) == true) { usingStatement = (UsingStatementSyntax)usingStatement.Parent; } return(usingStatement); } return((StatementSyntax)parent); } break; } case SyntaxKind.TryStatement: { var tryStatement = (TryStatementSyntax)parent; if (tryStatement.Block?.OpenBraceToken.Span.Contains(context.Span) == true) { return((StatementSyntax)parent); } break; } case SyntaxKind.IfStatement: { var ifStatement = (IfStatementSyntax)parent; if (IfElseAnalysis.IsTopmostIf(ifStatement) && block.OpenBraceToken.Span.Contains(context.Span)) { return(ifStatement); } if (ifStatement.Else == null && block.CloseBraceToken.Span.Contains(context.Span)) { return(ifStatement); } break; } case SyntaxKind.ElseClause: { var elseClause = (ElseClauseSyntax)parent; if (block.CloseBraceToken.Span.Contains(context.Span)) { return(IfElseAnalysis.GetTopmostIf(elseClause)); } break; } case SyntaxKind.CatchClause: { var catchClause = (CatchClauseSyntax)parent; if (catchClause.Parent?.IsKind(SyntaxKind.TryStatement) == true) { var tryStatement = (TryStatementSyntax)catchClause.Parent; if (tryStatement.Finally == null && catchClause.Block?.CloseBraceToken.Span.Contains(context.Span) == true) { return(tryStatement); } } break; } case SyntaxKind.FinallyClause: { var finallyClause = (FinallyClauseSyntax)parent; if (finallyClause.Parent?.IsKind(SyntaxKind.TryStatement) == true) { var tryStatement = (TryStatementSyntax)finallyClause.Parent; if (finallyClause.Block?.CloseBraceToken.Span.Contains(context.Span) == true) { return(tryStatement); } } break; } } return(null); }
public static void ComputeRefactoring(RefactoringContext context, IfStatementSyntax ifStatement) { if (IfElseAnalysis.IsTopmostIf(ifStatement)) { ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause != null) { StatementSyntax statement2 = elseClause.Statement; if (statement2?.IsKind(SyntaxKind.IfStatement) == false) { StatementSyntax statement1 = GetStatementOrDefault(ifStatement.Statement); if (statement1 != null) { statement2 = GetStatementOrDefault(statement2); if (statement2 != null) { SyntaxKind kind1 = statement1.Kind(); SyntaxKind kind2 = statement2.Kind(); if (kind1 == SyntaxKind.ReturnStatement) { if (kind2 == SyntaxKind.ReturnStatement) { ComputeRefactoring( context, ifStatement, (ReturnStatementSyntax)statement1, (ReturnStatementSyntax)statement2); } } else if (kind1 == SyntaxKind.YieldReturnStatement) { if (kind2 == SyntaxKind.YieldReturnStatement) { ComputeRefactoring( context, ifStatement, (YieldStatementSyntax)statement1, (YieldStatementSyntax)statement2); } } else if (kind1 == SyntaxKind.ExpressionStatement) { if (kind2 == SyntaxKind.ExpressionStatement) { ComputeRefactoring( context, ifStatement, (ExpressionStatementSyntax)statement1, (ExpressionStatementSyntax)statement2); } } } } } } } }