private static Task <Document> RefactorAsync( Document document, ExpressionSyntax expression, CancellationToken cancellationToken) { return(document.ReplaceNodeAsync(expression, Negator.LogicallyNegate(expression), cancellationToken)); }
private static async Task <Document> RefactorAsync( Document document, ExpressionSyntax expression, CancellationToken cancellationToken) { return(await document.ReplaceNodeAsync(expression, Negator.LogicallyNegate(expression), cancellationToken).ConfigureAwait(false)); }
public static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ExpressionSyntax condition = conditionalExpression.Condition; ExpressionSyntax newNode = (conditionalExpression.WhenTrue.WalkDownParentheses().IsKind(SyntaxKind.TrueLiteralExpression)) ? condition : Negator.LogicallyNegate(condition, semanticModel, cancellationToken); SyntaxTriviaList trailingTrivia = conditionalExpression .DescendantTrivia(TextSpan.FromBounds(condition.Span.End, conditionalExpression.Span.End)) .ToSyntaxTriviaList() .EmptyIfWhitespace() .AddRange(conditionalExpression.GetTrailingTrivia()); newNode = newNode .WithLeadingTrivia(conditionalExpression.GetLeadingTrivia()) .WithTrailingTrivia(trailingTrivia); return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false)); }
public static async Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken = default(CancellationToken)) { ElseClauseSyntax elseClause = ifStatement.Else; StatementSyntax whenTrue = ifStatement.Statement; StatementSyntax whenFalse = elseClause.Statement; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ElseClauseSyntax newElseClause = null; if ((whenFalse as BlockSyntax)?.Statements.Any() != false) { newElseClause = elseClause.WithStatement(whenTrue.WithTriviaFrom(whenFalse)); } IfStatementSyntax newIfStatement = ifStatement .WithCondition(Negator.LogicallyNegate(ifStatement.Condition, semanticModel, cancellationToken)) .WithStatement(whenFalse.WithTriviaFrom(whenTrue)) .WithElse(newElseClause) .WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(ifStatement, newIfStatement, cancellationToken).ConfigureAwait(false)); }
public static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken) { ExpressionSyntax condition = conditionalExpression.Condition; ExpressionSyntax newNode = (conditionalExpression.WhenTrue.IsKind(SyntaxKind.TrueLiteralExpression)) ? condition : Negator.LogicallyNegate(condition); TextSpan span = TextSpan.FromBounds( conditionalExpression.Condition.Span.End, conditionalExpression.FullSpan.End); IEnumerable <SyntaxTrivia> trivia = conditionalExpression.DescendantTrivia(span); if (trivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia())) { newNode = newNode.WithTrailingTrivia(trivia); } else { newNode = newNode.WithoutTrailingTrivia(); } return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false)); }
public override SyntaxNode VisitBlock(BlockSyntax node) { _block = node; if (node.LastStatementOrDefault(skipLocalFunction: true) is IfStatementSyntax ifStatement && IsFixable(ifStatement)) { SyntaxList <StatementSyntax> statements = node.Statements; int index = statements.IndexOf(ifStatement); ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement); var block = (BlockSyntax)ifStatement.Statement; ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition); IfStatementSyntax newIfStatement = ifStatement .WithCondition(newCondition) .WithStatement(block.WithStatements(SingletonList(_jumpStatement))) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .ReplaceAt(index, newIfStatement) .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation())); node = node.WithStatements(newStatements); } return(node); }
public override SyntaxNode VisitBlock(BlockSyntax node) { node = (BlockSyntax)base.VisitBlock(node); SyntaxList <StatementSyntax> statements = node.Statements; var ifStatement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement)) as IfStatementSyntax; if (ifStatement != null && IsFixable(ifStatement) && ((BlockSyntax)ifStatement.Parent).Statements.IsLastStatement(ifStatement, skipLocalFunction: true)) { var block = (BlockSyntax)ifStatement.Statement; ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition); IfStatementSyntax newIfStatement = ifStatement .WithCondition(newCondition) .WithStatement(block.WithStatements(SingletonList(_jumpStatement))) .WithFormatterAnnotation(); int index = statements.IndexOf(ifStatement); SyntaxList <StatementSyntax> newStatements = statements .ReplaceAt(index, newIfStatement) .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation())); node = node.WithStatements(newStatements); } return(node); }
private static async Task <Document> InvertIfElseAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ElseClauseSyntax elseClause = ifStatement.Else; StatementSyntax whenTrue = ifStatement.Statement; StatementSyntax whenFalse = elseClause.Statement; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); IfStatementSyntax newIfStatement = ifStatement.Update( ifKeyword: ifStatement.IfKeyword, openParenToken: ifStatement.OpenParenToken, condition: Negator.LogicallyNegate(ifStatement.Condition, semanticModel, cancellationToken), closeParenToken: ifStatement.CloseParenToken, statement: whenFalse.WithTriviaFrom(whenTrue), @else: elseClause.WithStatement(whenTrue.WithTriviaFrom(whenFalse))); newIfStatement = newIfStatement.WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(ifStatement, newIfStatement, cancellationToken).ConfigureAwait(false)); }
public static Task <Document> RefactorAsync( Document document, BinaryExpressionSyntax binaryExpression, CancellationToken cancellationToken = default(CancellationToken)) { ExpressionSyntax newNode = Negator.LogicallyNegate(binaryExpression) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(binaryExpression, newNode, cancellationToken)); }
private static async Task <Document> RefactorAsync( Document document, ExpressionSyntax expression, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ExpressionSyntax newNode = Negator.LogicallyNegate(expression, semanticModel, cancellationToken); return(await document.ReplaceNodeAsync(expression, newNode, cancellationToken).ConfigureAwait(false)); }
private static Task <Document> IfToReturnWithExpressionAsync( Document document, IfToReturnWithExpressionAnalysis analysis, CancellationToken cancellationToken = default(CancellationToken)) { ExpressionSyntax expression = analysis.Expression; if (analysis.Negate) { expression = Negator.LogicallyNegate(expression, analysis.SemanticModel, cancellationToken); } StatementSyntax statement; if (analysis.IsYield) { statement = YieldReturnStatement(expression); } else { statement = ReturnStatement(expression); } IfStatementSyntax ifStatement = analysis.IfStatement; if (ifStatement.IsSimpleIf()) { StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(ifStatement); StatementSyntax newNode = statement .WithLeadingTrivia(ifStatement.GetLeadingTrivia()) .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia()) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index, newNode); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); } else { StatementSyntax newNode = statement .WithTriviaFrom(ifStatement) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken)); } }
public static Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken = default(CancellationToken)) { ConditionalExpressionSyntax newConditionalExpression = conditionalExpression .WithCondition(Negator.LogicallyNegate(conditionalExpression.Condition)) .WithWhenTrue(conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue)) .WithWhenFalse(conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse)) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(conditionalExpression, newConditionalExpression, cancellationToken)); }
public static async Task <Document> RefactorAsync( Document document, BinaryExpressionSyntax binaryExpression, CancellationToken cancellationToken = default(CancellationToken)) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ExpressionSyntax newNode = Negator.LogicallyNegate(binaryExpression, semanticModel, cancellationToken); newNode = newNode.WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(binaryExpression, newNode, cancellationToken).ConfigureAwait(false)); }
public static ExpressionSyntax GetBooleanExpression(ExpressionSyntax condition, ExpressionSyntax expression1, ExpressionSyntax expression2) { switch (expression1.Kind()) { case SyntaxKind.TrueLiteralExpression: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(expression2); case SyntaxKind.FalseLiteralExpression: return(condition); default: return(LogicalOrExpression(condition, expression2)); } } case SyntaxKind.FalseLiteralExpression: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(Negator.LogicallyNegate(condition)); case SyntaxKind.FalseLiteralExpression: return(expression2); default: return(LogicalAndExpression(Negator.LogicallyNegate(condition), expression2)); } } default: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression1)); case SyntaxKind.FalseLiteralExpression: return(LogicalAndExpression(condition, expression1)); default: throw new InvalidOperationException(); } } } }
private static ReturnStatementSyntax CreateReturnStatement(IfStatementSyntax ifStatement) { ExpressionSyntax expression = ifStatement.Condition; if (GetBooleanLiteral(ifStatement.Statement).IsKind(SyntaxKind.FalseLiteralExpression)) { expression = Negator.LogicallyNegate(expression); } return(ReturnStatement( ReturnKeyword().WithTrailingTrivia(Space), expression, SemicolonToken())); }
public static ExpressionSyntax GetBooleanExpression(ExpressionSyntax condition, ExpressionSyntax expression1, ExpressionSyntax expression2) { switch (expression1.Kind()) { case SyntaxKind.TrueLiteralExpression: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(expression2); case SyntaxKind.FalseLiteralExpression: return(condition); default: return(LogicalOrExpression(condition, expression2)); } } case SyntaxKind.FalseLiteralExpression: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(Negator.LogicallyNegate(condition)); case SyntaxKind.FalseLiteralExpression: return(expression2); default: return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression2)); } } default: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression1)); case SyntaxKind.FalseLiteralExpression: return(LogicalAndExpression(condition.Parenthesize().WithSimplifierAnnotation(), expression1.Parenthesize().WithSimplifierAnnotation())); default: return(LogicalOrExpression(ParenthesizedExpression(LogicalAndExpression(condition, expression1)), expression2)); } } } }
public static async Task <Document> RefactorAsync( Document document, BinaryExpressionSyntax binaryExpression, CancellationToken cancellationToken) { ExpressionSyntax left = binaryExpression.Left; ExpressionSyntax right = binaryExpression.Right; SyntaxToken operatorToken = binaryExpression.OperatorToken; ExpressionSyntax newNode = binaryExpression; TextSpan span = TextSpan.FromBounds(left.Span.End, right.Span.Start); IEnumerable <SyntaxTrivia> trivia = binaryExpression.DescendantTrivia(span); bool isWhiteSpaceOrEndOfLine = trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()); if (left.IsBooleanLiteralExpression()) { SyntaxTriviaList leadingTrivia = binaryExpression.GetLeadingTrivia(); if (!isWhiteSpaceOrEndOfLine) { leadingTrivia = leadingTrivia.AddRange(trivia); } newNode = Negator.LogicallyNegate(right) .WithLeadingTrivia(leadingTrivia); } else if (right.IsBooleanLiteralExpression()) { SyntaxTriviaList trailingTrivia = binaryExpression.GetTrailingTrivia(); if (!isWhiteSpaceOrEndOfLine) { trailingTrivia = trailingTrivia.InsertRange(0, trivia); } newNode = Negator.LogicallyNegate(left) .WithTrailingTrivia(trailingTrivia); } #if DEBUG else { Debug.Assert(false, binaryExpression.ToString()); } #endif return(await document.ReplaceNodeAsync(binaryExpression, newNode.WithFormatterAnnotation(), cancellationToken).ConfigureAwait(false)); }
public static ExpressionSyntax GetExpression(ExpressionSyntax condition, ExpressionSyntax expression1, ExpressionSyntax expression2) { switch (expression1.Kind()) { case SyntaxKind.TrueLiteralExpression: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(expression2); case SyntaxKind.FalseLiteralExpression: return(condition); default: return(LogicalOrExpression(condition, expression2)); } } case SyntaxKind.FalseLiteralExpression: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(Negator.LogicallyNegate(condition)); case SyntaxKind.FalseLiteralExpression: return(expression2); default: return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression2)); } } default: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(LogicalOrExpression(Negator.LogicallyNegate(condition), expression1)); case SyntaxKind.FalseLiteralExpression: return(LogicalAndExpression(condition, expression1, addParenthesesIfNecessary: true)); default: return(LogicalOrExpression(ParenthesizedExpression(LogicalAndExpression(condition, expression1)), expression2)); } } } }
public static Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken = default(CancellationToken)) { ConditionalExpressionSyntax newNode = conditionalExpression.Update( condition: Negator.LogicallyNegate(conditionalExpression.Condition), questionToken: conditionalExpression.QuestionToken, whenTrue: conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue), colonToken: conditionalExpression.ColonToken, whenFalse: conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse)); newNode = newNode.WithFormatterAnnotation(); return(document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken)); }
public static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken = default(CancellationToken)) { StatementSyntax trueStatement = ifStatement.Statement; StatementSyntax falseStatement = ifStatement.Else.Statement; IfStatementSyntax newIfStatement = ifStatement .WithCondition(Negator.LogicallyNegate(ifStatement.Condition)) .WithStatement(falseStatement.WithTriviaFrom(trueStatement)) .WithElse(ifStatement.Else.WithStatement(trueStatement.WithTriviaFrom(falseStatement))) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(ifStatement, newIfStatement, cancellationToken)); }
public override SyntaxNode VisitBlock(BlockSyntax node) { _block = node; if (node.LastStatementOrDefault(skipLocalFunction: true) is IfStatementSyntax ifStatement && IsFixable(ifStatement)) { SyntaxList <StatementSyntax> statements = node.Statements; int index = statements.IndexOf(ifStatement); if (_recursive) { ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement); } var block = (BlockSyntax)ifStatement.Statement; ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition); BlockSyntax newBlock = block.WithStatements(SingletonList(_jumpStatement)); if (!block .Statements .First() .GetLeadingTrivia() .Any(f => f.IsEndOfLineTrivia())) { newBlock = newBlock.WithCloseBraceToken(newBlock.CloseBraceToken.AppendToTrailingTrivia(NewLine())); } IfStatementSyntax newIfStatement = ifStatement .WithCondition(newCondition) .WithStatement(newBlock) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .ReplaceAt(index, newIfStatement) .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation())); node = node.WithStatements(newStatements); } return(node); }
public static Task <Document> RefactorAsync( Document document, InvocationExpressionSyntax invocationExpression, string memberName, ExpressionSyntax expression, CancellationToken cancellationToken = default(CancellationToken)) { var memberAccessExpression = (MemberAccessExpressionSyntax)invocationExpression.Expression; MemberAccessExpressionSyntax newMemberAccessExpression = memberAccessExpression .WithName(SyntaxFactory.IdentifierName(memberName).WithTriviaFrom(memberAccessExpression.Name)); InvocationExpressionSyntax newNode = invocationExpression .ReplaceNode(expression, Negator.LogicallyNegate(expression)) .WithExpression(newMemberAccessExpression); return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken)); }
private static Task <Document> IfElseToAssignmentWithConditionAsync( Document document, IfElseToAssignmentWithConditionAnalysis analysis, CancellationToken cancellationToken = default(CancellationToken)) { ExpressionSyntax right = analysis.Right.WithoutTrivia(); if (analysis.Negate) { right = Negator.LogicallyNegate(right, analysis.SemanticModel, cancellationToken); } ExpressionStatementSyntax newNode = SimpleAssignmentStatement(analysis.Left.WithoutTrivia(), right) .WithTriviaFrom(analysis.IfStatement) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(analysis.IfStatement, newNode, cancellationToken)); }
private SyntaxNode Rewrite(StatementListInfo statementsInfo, IfStatementSyntax ifStatement) { SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(ifStatement); ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition, _semanticModel, _cancellationToken); if (_recursive) { ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement); } var block = (BlockSyntax)ifStatement.Statement; BlockSyntax newBlock = block.WithStatements(SingletonList(_jumpStatement)); if (!block .Statements .First() .GetLeadingTrivia() .Any(f => f.IsEndOfLineTrivia())) { newBlock = newBlock.WithCloseBraceToken(newBlock.CloseBraceToken.AppendToTrailingTrivia(NewLine())); } IfStatementSyntax newIfStatement = ifStatement .WithCondition(newCondition) .WithStatement(newBlock) .WithFormatterAnnotation(); if (CSharpFacts.IsJumpStatementOrYieldBreakStatement(statements.Last().Kind()) && CSharpFacts.IsJumpStatementOrYieldBreakStatement(block.Statements.Last().Kind())) { statements = statements.RemoveAt(statements.Count - 1); } SyntaxList <StatementSyntax> newStatements = statements .ReplaceAt(index, newIfStatement) .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation())); return(statementsInfo.WithStatements(newStatements).Parent); }
public static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { ExpressionSyntax condition = ifStatement.Condition; AssignmentExpressionSyntax assignment = GetSimpleAssignmentExpression(ifStatement.GetSingleStatementOrDefault()); if (assignment.Right.IsKind(SyntaxKind.FalseLiteralExpression)) { condition = Negator.LogicallyNegate(condition); } ExpressionStatementSyntax newNode = SimpleAssignmentStatement(assignment.Left, condition) .WithTriviaFrom(ifStatement) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken)); }
private static ExpressionSyntax GetBooleanExpression( ExpressionSyntax condition, ExpressionSyntax expression1, ExpressionSyntax expression2, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { switch (expression1.Kind()) { case SyntaxKind.TrueLiteralExpression: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(expression2); case SyntaxKind.FalseLiteralExpression: return(condition); default: return(LogicalOrExpression(condition, expression2)); } } case SyntaxKind.FalseLiteralExpression: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(Negator.LogicallyNegate(condition, semanticModel, cancellationToken)); case SyntaxKind.FalseLiteralExpression: return(expression2); default: return(LogicalAndExpression(Negator.LogicallyNegate(condition, semanticModel, cancellationToken), expression2)); } } default: { switch (expression2.Kind()) { case SyntaxKind.TrueLiteralExpression: return(LogicalOrExpression(Negator.LogicallyNegate(condition, semanticModel, cancellationToken), expression1)); case SyntaxKind.FalseLiteralExpression: return(LogicalAndExpression(condition, expression1)); default: throw new InvalidOperationException(); } } } BinaryExpressionSyntax LogicalAndExpression(ExpressionSyntax left, ExpressionSyntax right) { return(CSharpFactory.LogicalAndExpression( left.Parenthesize(), right.Parenthesize())); } BinaryExpressionSyntax LogicalOrExpression(ExpressionSyntax left, ExpressionSyntax right) { return(CSharpFactory.LogicalOrExpression( left.Parenthesize(), right.Parenthesize())); } }
public static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken) { ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); ExpressionSyntax condition = info.Condition; ExpressionSyntax whenTrue = info.WhenTrue; ExpressionSyntax whenFalse = info.WhenFalse; SyntaxKind trueKind = whenTrue.Kind(); SyntaxKind falseKind = whenFalse.Kind(); ExpressionSyntax newNode = null; if (trueKind == SyntaxKind.TrueLiteralExpression) { if (falseKind == SyntaxKind.FalseLiteralExpression) { newNode = CreateNewNode(conditionalExpression, condition); } else { SyntaxTriviaList trailingTrivia = info .QuestionToken .LeadingTrivia .AddRange(info.QuestionToken.TrailingTrivia) .AddRange(whenTrue.GetLeadingTrivia()) .EmptyIfWhitespace(); newNode = LogicalOrExpression( condition.Parenthesize().AppendToTrailingTrivia(trailingTrivia), Token(info.ColonToken.LeadingTrivia, SyntaxKind.BarBarToken, info.ColonToken.TrailingTrivia), whenFalse); } } else if (falseKind == SyntaxKind.FalseLiteralExpression) { SyntaxTriviaList trailingTrivia = whenTrue .GetTrailingTrivia() .AddRange(info.ColonToken.LeadingTrivia) .AddRange(info.ColonToken.TrailingTrivia) .AddRange(whenFalse.GetLeadingTrivia()) .EmptyIfWhitespace() .AddRange(whenFalse.GetTrailingTrivia()); newNode = LogicalAndExpression( condition.Parenthesize(), Token(info.QuestionToken.LeadingTrivia, SyntaxKind.AmpersandAmpersandToken, info.QuestionToken.TrailingTrivia), whenTrue.WithTrailingTrivia(trailingTrivia)); } else if (trueKind == SyntaxKind.FalseLiteralExpression && falseKind == SyntaxKind.TrueLiteralExpression) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); newNode = CreateNewNode(conditionalExpression, Negator.LogicallyNegate(condition, semanticModel, cancellationToken)); } return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false)); }
private static async Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { ExpressionSyntax condition = ifStatement.Condition; ElseClauseSyntax elseClause = ifStatement.Else; if ((ifStatement.Statement as BlockSyntax)?.Statements.Any() == false) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ExpressionSyntax newCondition = Negator.LogicallyNegate(condition, semanticModel, cancellationToken); StatementSyntax statement = elseClause.Statement; if (statement is IfStatementSyntax nestedIf) { newCondition = LogicalAndExpression(newCondition.Parenthesize(), nestedIf.Condition.Parenthesize()); statement = nestedIf.Statement; } cancellationToken.ThrowIfCancellationRequested(); IfStatementSyntax newNode = ifStatement.Update( ifStatement.IfKeyword, ifStatement.OpenParenToken, newCondition, ifStatement.CloseParenToken, statement, default(ElseClauseSyntax)); newNode = newNode.WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken).ConfigureAwait(false)); } else if (elseClause != null) { WhileStatementSyntax whileStatement; if (ifStatement.Parent is BlockSyntax block) { whileStatement = (WhileStatementSyntax)block.Parent; } else { block = Block(); whileStatement = (WhileStatementSyntax)ifStatement.Parent; } cancellationToken.ThrowIfCancellationRequested(); BlockSyntax newBlock = (ifStatement.Statement is BlockSyntax ifBlock) ? block.WithStatements(ifBlock.Statements) : block.WithStatements(SingletonList(ifStatement.Statement)); SyntaxNode newNode = whileStatement.Update( whileStatement.WhileKeyword, whileStatement.OpenParenToken, ifStatement.Condition, whileStatement.CloseParenToken, newBlock); newNode = newNode.WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(whileStatement, newNode, cancellationToken).ConfigureAwait(false)); } else { var block = (BlockSyntax)ifStatement.Parent; SyntaxList <StatementSyntax> statements = block.Statements; BlockSyntax newBlock = block.WithStatements(statements.Remove(ifStatement)); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ExpressionSyntax newCondition = Negator.LogicallyNegate(condition, semanticModel, cancellationToken); SyntaxNode newNode = block.Parent; switch (block.Parent) { case WhileStatementSyntax whileStatement: { cancellationToken.ThrowIfCancellationRequested(); if (statements.IsFirst(ifStatement)) { newNode = whileStatement.Update( whileStatement.WhileKeyword, whileStatement.OpenParenToken, newCondition, whileStatement.CloseParenToken, newBlock); } else { newNode = DoStatement( Token(whileStatement.WhileKeyword.LeadingTrivia, SyntaxKind.DoKeyword, whileStatement.CloseParenToken.TrailingTrivia), newBlock.WithoutTrailingTrivia(), WhileKeyword(), OpenParenToken(), newCondition, CloseParenToken(), SemicolonToken().WithTrailingTrivia(newBlock.GetTrailingTrivia())); } break; } case DoStatementSyntax doStatement: { cancellationToken.ThrowIfCancellationRequested(); if (statements.IsLast(ifStatement)) { newNode = doStatement.Update( doStatement.DoKeyword, newBlock, doStatement.WhileKeyword, doStatement.OpenParenToken, newCondition, doStatement.CloseParenToken, doStatement.SemicolonToken); } else { newNode = WhileStatement( Token(doStatement.DoKeyword.LeadingTrivia, SyntaxKind.WhileKeyword, SyntaxTriviaList.Empty), OpenParenToken(), newCondition, Token(SyntaxTriviaList.Empty, SyntaxKind.CloseParenToken, doStatement.DoKeyword.TrailingTrivia), newBlock.WithTrailingTrivia(doStatement.GetTrailingTrivia())); } break; } default: { Debug.Fail(block.Parent.Kind().ToString()); break; } } newNode = newNode.WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(block.Parent, newNode, cancellationToken).ConfigureAwait(false)); } }
private static async Task <ExpressionSyntax> CreateNewNode( Document document, BinaryExpressionSyntax binaryExpression, CancellationToken cancellationToken) { ExpressionSyntax left = binaryExpression.Left; ExpressionSyntax right = binaryExpression.Right; SyntaxToken operatorToken = binaryExpression.OperatorToken; TextSpan span = TextSpan.FromBounds(left.Span.End, right.Span.Start); IEnumerable <SyntaxTrivia> trivia = binaryExpression.DescendantTrivia(span); bool isWhiteSpaceOrEndOfLine = trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()); if (left.IsBooleanLiteralExpression()) { SyntaxTriviaList leadingTrivia = binaryExpression.GetLeadingTrivia(); if (!isWhiteSpaceOrEndOfLine) { leadingTrivia = leadingTrivia.AddRange(trivia); } if (right.IsKind(SyntaxKind.LogicalNotExpression)) { var logicalNot = (PrefixUnaryExpressionSyntax)right; ExpressionSyntax operand = logicalNot.Operand; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); if (semanticModel.GetTypeInfo(operand, cancellationToken).ConvertedType.IsNullableOf(SpecialType.System_Boolean)) { return(binaryExpression .WithLeft(Negator.LogicallyNegate(left)) .WithRight(operand.WithTriviaFrom(right))); } } return(Negator.LogicallyNegate(right) .WithLeadingTrivia(leadingTrivia)); } else if (right.IsBooleanLiteralExpression()) { SyntaxTriviaList trailingTrivia = binaryExpression.GetTrailingTrivia(); if (!isWhiteSpaceOrEndOfLine) { trailingTrivia = trailingTrivia.InsertRange(0, trivia); } if (left.IsKind(SyntaxKind.LogicalNotExpression)) { var logicalNot = (PrefixUnaryExpressionSyntax)left; ExpressionSyntax operand = logicalNot.Operand; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); if (semanticModel.GetTypeInfo(operand, cancellationToken).ConvertedType.IsNullableOf(SpecialType.System_Boolean)) { return(binaryExpression .WithLeft(operand.WithTriviaFrom(left)) .WithRight(Negator.LogicallyNegate(right))); } } return(Negator.LogicallyNegate(left) .WithTrailingTrivia(trailingTrivia)); } Debug.Fail(binaryExpression.ToString()); return(binaryExpression); }
public static async Task <Document> InvertIfAsync( Document document, IfStatementSyntax ifStatement, bool recursive = false, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); StatementSyntax statement = ifStatement.Statement; StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; InvertIfAnalysis analysis = InvertIfAnalysis.Create(ifStatement, statement); int ifStatementIndex = statements.IndexOf(ifStatement); StatementSyntax lastStatement = analysis.LastStatement; int lastStatementIndex = statements.IndexOf(lastStatement); bool isLastStatementRedundant = IsLastStatementRedundant(); bool shouldUseElseClause = !CSharpFacts.IsJumpStatement(lastStatement.Kind()); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); SyntaxList <StatementSyntax> newStatements = statements; if (!recursive) { Refactor(); } else { IfStatementSyntax lastIfStatement = ifStatement; InvertIfAnalysis a = analysis.AnalyzeNextStatement(); do { lastIfStatement = a.IfStatement; a = a.AnalyzeNextStatement(); } while (a.Success); int firstLastStatementIndex = lastStatementIndex; int index = statements.IndexOf(lastIfStatement); int firstIndex = ifStatementIndex; while (index >= firstIndex) { ifStatementIndex = index; ifStatement = (IfStatementSyntax)statements[ifStatementIndex]; statement = ifStatement.Statement; Refactor(); lastStatementIndex = firstLastStatementIndex + newStatements.Count - statements.Count; lastStatement = (statement is BlockSyntax block) ? block.Statements.Last() : statement; index--; } } return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); void Refactor() { cancellationToken.ThrowIfCancellationRequested(); SyntaxList <StatementSyntax> nextStatements = newStatements .Skip(ifStatementIndex + 1) .Take(lastStatementIndex - ifStatementIndex) .ToSyntaxList() .TrimTrivia(); BlockSyntax newStatement; SyntaxList <StatementSyntax> newNextStatements; if (statement is BlockSyntax block) { newStatement = block.WithStatements(nextStatements); newNextStatements = block.Statements; } else { newStatement = Block(nextStatements); newNextStatements = SingletonList(statement); } if (isLastStatementRedundant) { newNextStatements = newNextStatements.RemoveAt(newNextStatements.Count - 1); } ElseClauseSyntax elseClause = null; if (newNextStatements.Any() && shouldUseElseClause) { elseClause = ElseClause(Block(newNextStatements)); newNextStatements = default; } IfStatementSyntax newIfStatement = ifStatement.Update( ifKeyword: ifStatement.IfKeyword, openParenToken: ifStatement.OpenParenToken, condition: Negator.LogicallyNegate(ifStatement.Condition, semanticModel, cancellationToken), closeParenToken: ifStatement.CloseParenToken, statement: newStatement, @else: elseClause); newIfStatement = newIfStatement.WithFormatterAnnotation(); SyntaxList <StatementSyntax> newNodes = newNextStatements.Insert(0, newIfStatement); newStatements = newStatements.ReplaceRange(ifStatementIndex, lastStatementIndex - ifStatementIndex + 1, newNodes); } bool IsLastStatementRedundant() { StatementSyntax jumpStatement = analysis.JumpStatement; switch (jumpStatement.Kind()) { case SyntaxKind.ReturnStatement: { if (((ReturnStatementSyntax)jumpStatement).Expression == null && RemoveRedundantStatementAnalysis.IsFixable(lastStatement, SyntaxKind.ReturnStatement)) { return(true); } break; } case SyntaxKind.ContinueStatement: { if (RemoveRedundantStatementAnalysis.IsFixable(lastStatement, SyntaxKind.ContinueStatement)) { return(true); } break; } } return(false); } }