private static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, StatementListSelection selectedStatements, CancellationToken cancellationToken) { int count = selectedStatements.Count; StatementSyntax newStatement; if (count == 1 && !ifStatement.AsCascade().Any(f => f.Statement?.Kind() == SyntaxKind.Block)) { newStatement = selectedStatements.First(); } else { newStatement = SyntaxFactory.Block(selectedStatements); } ElseClauseSyntax elseClause = SyntaxFactory.ElseClause(newStatement).WithFormatterAnnotation(); IfStatementSyntax lastIfStatement = ifStatement.AsCascade().Last(); IfStatementSyntax newIfStatement = ifStatement.ReplaceNode( lastIfStatement, lastIfStatement.WithElse(elseClause)); SyntaxList <StatementSyntax> newStatements = selectedStatements .UnderlyingList .Replace(ifStatement, newIfStatement) .RemoveRange(selectedStatements.FirstIndex, count); return(document.ReplaceStatementsAsync(SyntaxInfo.StatementListInfo(selectedStatements), newStatements, cancellationToken)); }
private static IfStatementSyntax CreateNewIfStatement(IfStatementSyntax ifStatement) { IEnumerable <StatementSyntax> statements = ifStatement .AsCascade() .Select(ifOrElse => { StatementSyntax statement = ifOrElse.Statement; if (statement is BlockSyntax block) { statement = block.Statements.Last(); } return(statement); }); return(ifStatement.ReplaceNodes( statements, (statement, _) => { if (statement.IsKind(SyntaxKind.ThrowStatement)) { return statement; } var expressionStatement = (ExpressionStatementSyntax)statement; var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; return ReturnStatement(assignment.Right).WithTriviaFrom(statement); })); }
private static HashSet <AwaitExpressionSyntax> GetAwaitExpressionsFromIfStatement( IfStatementSyntax ifStatement, bool endsWithElse) { HashSet <AwaitExpressionSyntax> awaitExpressions = null; foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { if (ifOrElse.IsElse && !endsWithElse) { return(null); } AwaitExpressionSyntax awaitExpression = GetLastReturnAwaitExpressionOfDefault(ifOrElse.Statement); if (awaitExpression != null) { (awaitExpressions ?? (awaitExpressions = new HashSet <AwaitExpressionSyntax>())).Add(awaitExpression); } else { return(null); } } return(awaitExpressions); }
private static IEnumerable <SwitchSectionSyntax> CreateSwitchSections(IfStatementSyntax ifStatement) { foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { if (ifOrElse.IsIf) { ifStatement = ifOrElse.AsIf(); var condition = ifStatement.Condition.WalkDownParentheses() as BinaryExpressionSyntax; List <SwitchLabelSyntax> labels = CreateSwitchLabels(condition, new List <SwitchLabelSyntax>()); labels.Reverse(); SwitchSectionSyntax section = SwitchSection( List(labels), AddBreakStatementIfNecessary(ifStatement.Statement)); yield return(section); } else { yield return(DefaultSwitchSection(AddBreakStatementIfNecessary(ifOrElse.Statement))); } } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, IfStatementSyntax ifStatement) { if (!ifStatement.IsTopmostIf()) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { if (ifOrElse.IsIf) { if (!CanRefactor(ifOrElse.AsIf(), semanticModel, context.CancellationToken)) { return; } } else if (ContainsBreakStatementThatBelongsToParentLoop(ifOrElse.AsElse().Statement)) { return; } } context.RegisterRefactoring( (ifStatement.IsSimpleIf()) ? "Replace if with switch" : "Replace if-else with switch", cancellationToken => RefactorAsync(context.Document, ifStatement, cancellationToken), RefactoringIdentifiers.ReplaceIfWithSwitch); }
private static bool VerifyIfStatement( IfStatementSyntax ifStatement, int expectedCount, bool endsWithElse) { int count = 0; foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { if (ifOrElse.IsElse && !endsWithElse) { return(false); } AwaitExpressionSyntax awaitExpression = GetAwaitExpression(ifOrElse.Statement); if (awaitExpression == null) { return(false); } count++; } return(expectedCount == count); }
public static BracesAnalysis AnalyzeBraces(IfStatementSyntax ifStatement) { var anyHasEmbedded = false; var anyHasBlock = false; var allSupportsEmbedded = true; int cnt = 0; foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { cnt++; StatementSyntax statement = ifOrElse.Statement; if (!anyHasEmbedded && statement.Kind() != SyntaxKind.Block) { anyHasEmbedded = true; } if (!anyHasBlock && statement.Kind() == SyntaxKind.Block) { anyHasBlock = true; } if (allSupportsEmbedded && !SupportsEmbedded(statement)) { allSupportsEmbedded = false; } if (cnt > 1 && anyHasEmbedded && !allSupportsEmbedded) { return(BracesAnalysisFlags.AddBraces); } } if (cnt > 1 && allSupportsEmbedded && anyHasBlock) { if (anyHasEmbedded) { return(BracesAnalysisFlags.AddBraces | BracesAnalysisFlags.RemoveBraces); } else { return(BracesAnalysisFlags.RemoveBraces); } } return(BracesAnalysisFlags.None);
private static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { return(document.ReplaceNodeAsync(ifStatement, GetNewStatements(), cancellationToken)); IEnumerable <StatementSyntax> GetNewStatements() { ElseClauseSyntax parentElse = null; foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { if (ifOrElse.IsIf) { IfStatementSyntax newIfStatement = ifOrElse.AsIf(); ElseClauseSyntax elseClause = newIfStatement.Else; newIfStatement = newIfStatement.WithElse(null); if (parentElse != null) { newIfStatement = newIfStatement.PrependToLeadingTrivia(parentElse.GetLeadingTrivia()); } if (elseClause != null) { newIfStatement = newIfStatement.AppendToTrailingTrivia(CSharpFactory.NewLine()); } yield return(newIfStatement.WithFormatterAnnotation()); parentElse = ifStatement.Else; } else { StatementSyntax statement = ifOrElse.Statement; if (statement is BlockSyntax block) { foreach (StatementSyntax newStatement in block.Statements.Select(f => f.WithFormatterAnnotation())) { yield return(newStatement); } } else { yield return(statement); } } } } }
private static IEnumerable <BlockSyntax> GetBlockStatements(IfStatementSyntax ifStatement) { foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { StatementSyntax statement = ifOrElse.Statement; if (statement?.Kind() == SyntaxKind.Block) { yield return((BlockSyntax)statement); } } }
private static IEnumerable <StatementSyntax> GetEmbeddedStatements(IfStatementSyntax topmostIf) { foreach (IfStatementOrElseClause ifOrElse in topmostIf.AsCascade()) { StatementSyntax statement = ifOrElse.Statement; if (statement?.IsKind(SyntaxKind.Block) == false) { yield return(statement); } } }
/// <summary> /// Initializes a new instance of <see cref="IfStatementCascadeInfo"/>. /// </summary> /// <param name="ifStatement"></param> public IfStatementCascadeInfo(IfStatementSyntax ifStatement) { int count = 0; IfStatementOrElseClause last = default; foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { count++; last = ifOrElse; } IfStatement = ifStatement; Count = count; Last = last; }
private static IfStatementSyntax CreateNewIfStatement(IfStatementSyntax ifStatement) { IEnumerable <ExpressionStatementSyntax> expressionStatements = ifStatement .AsCascade() .Select(ifOrElse => (ExpressionStatementSyntax)GetLastStatementOrDefault(ifOrElse.Statement)); return(ifStatement.ReplaceNodes( expressionStatements, (f, _) => { var assignment = (AssignmentExpressionSyntax)f.Expression; return ReturnStatement(assignment.Right).WithTriviaFrom(f); })); }
public static void ComputeRefactoring( RefactoringContext context, IfStatementSyntax ifStatement, SemanticModel semanticModel) { if (!ifStatement.IsTopmostIf()) { return; } ExpressionSyntax switchExpression = null; foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { if (ifOrElse.IsIf) { IfStatementSyntax ifStatement2 = ifOrElse.AsIf(); (bool success, ExpressionSyntax switchExpression)result = Analyze(ifStatement2.Condition?.WalkDownParentheses(), switchExpression, semanticModel, context.CancellationToken); if (!result.success) { return; } switchExpression = result.switchExpression; if (ContainsBreakStatementThatBelongsToParentIterationStatement(ifStatement2.Statement)) { return; } } else if (ContainsBreakStatementThatBelongsToParentIterationStatement(ifOrElse.AsElse().Statement)) { return; } } Document document = context.Document; context.RegisterRefactoring( "Convert to 'switch'", ct => RefactorAsync(document, ifStatement, ct), RefactoringIdentifiers.ConvertIfToSwitch); }
public static void ComputeRefactoring(RefactoringContext context, IfStatementSyntax ifStatement) { if (ifStatement.IsParentKind(SyntaxKind.ElseClause)) { return; } if (ifStatement.Else == null) { return; } foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { StatementSyntax statement = ifOrElse.Statement; if (statement is BlockSyntax block) { statement = block.Statements.LastOrDefault(); } if (statement == null) { return; } if (!statement.IsKind( SyntaxKind.ReturnStatement, SyntaxKind.ContinueStatement, SyntaxKind.BreakStatement, SyntaxKind.ThrowStatement)) { return; } } context.RegisterRefactoring( "Split if-else", cancellationToken => RefactorAsync(context.Document, ifStatement, cancellationToken), RefactoringIdentifiers.SplitIfElse); }
public static BracesAnalysis AnalyzeBraces(IfStatementSyntax ifStatement) { bool anyHasEmbedded = false; bool anyHasBlock = false; bool allSupportsEmbedded = true; int cnt = 0; foreach (IfStatementOrElseClause ifOrElse in ifStatement.AsCascade()) { cnt++; StatementSyntax statement = ifOrElse.Statement; if (!anyHasEmbedded && statement.Kind() != SyntaxKind.Block) { anyHasEmbedded = true; } if (!anyHasBlock && statement.Kind() == SyntaxKind.Block) { anyHasBlock = true; } if (allSupportsEmbedded && !SupportsEmbedded(statement)) { allSupportsEmbedded = false; } if (cnt > 1 && anyHasEmbedded && !allSupportsEmbedded) { return(BracesAnalysisFlags.AddBraces); } } if (cnt > 1 && allSupportsEmbedded && anyHasBlock) { if (anyHasEmbedded) { return(BracesAnalysisFlags.AddBraces | BracesAnalysisFlags.RemoveBraces); } else { return(BracesAnalysisFlags.RemoveBraces); } } return(BracesAnalysisFlags.None); bool SupportsEmbedded(StatementSyntax statement) { if (statement.IsParentKind(SyntaxKind.IfStatement) && ((IfStatementSyntax)statement.Parent).Condition?.IsMultiLine() == true) { return(false); } if (statement.Kind() == SyntaxKind.Block) { var block = (BlockSyntax)statement; if (!block.OpenBraceToken.TrailingTrivia.IsEmptyOrWhitespace()) { return(false); } if (!block.CloseBraceToken.LeadingTrivia.IsEmptyOrWhitespace()) { return(false); } statement = block.Statements.SingleOrDefault(shouldThrow: false); if (statement == null) { return(false); } if (statement.Kind() == SyntaxKind.IfStatement && block.IsParentKind(SyntaxKind.IfStatement) && ((IfStatementSyntax)block.Parent).Else != null && ((IfStatementSyntax)statement).GetCascadeInfo().EndsWithIf) { return(false); } } return(!statement.IsKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.LabeledStatement) && statement.IsSingleLine()); } }