public override void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression) { base.VisitUnaryOperatorExpression(unaryOperatorExpression); if (unaryOperatorExpression.Operator != UnaryOperatorType.Not) { return; } var invocation = AlUtil.GetInnerMostExpression(unaryOperatorExpression.Expression) as InvocationExpression; if (invocation == null) { return; } var rr = ctx.Resolve(invocation) as AlInvocationResolveResult; if (rr == null || rr.IsError) { return; } if (rr.Member.DeclaringType.Name != "Enumerable" || rr.Member.DeclaringType.Namespace != "System.Linq") { return; } if (!new[] { "All", "Any" }.Contains(rr.Member.Name)) { return; } if (invocation.Arguments.Count != 1) { return; } var arg = invocation.Arguments.First(); var match = argumentPattern.Match(arg); if (!match.Success) { return; } AddIssue(new CodeIssue( unaryOperatorExpression, ctx.TranslateString("Simplify LINQ expression"), ctx.TranslateString("Simplify LINQ expression"), s => { var target = invocation.Target.Clone() as MemberReferenceExpression; target.MemberName = target.MemberName == "All" ? "Any" : "All"; var expr = arg.Clone(); var nmatch = argumentPattern.Match(expr); var cond = nmatch.Get <Expression>("expr").Single(); cond.ReplaceWith(AlUtil.InvertCondition(cond)); var simplifiedInvocation = new InvocationExpression( target, expr ); s.Replace(unaryOperatorExpression, simplifiedInvocation); } )); }
void GenerateNewScript(Script script, IfElseStatement ifStatement) { var mergedIfStatement = new IfElseStatement { Condition = AlUtil.InvertCondition(ifStatement.Condition), TrueStatement = new ContinueStatement() }; mergedIfStatement.Condition.AcceptVisitor(_insertParenthesesVisitor); script.Replace(ifStatement, mergedIfStatement); SimplifyIfFlowAction.InsertBody(script, ifStatement); }
public override System.Collections.Generic.IEnumerable <CodeAction> GetActions(RefactoringContext context) { Expression expr = null; AstNode token; if (!NegateRelationalExpressionAction.GetLogicalExpression(context, out expr, out token)) { yield break; } var uOp = expr as UnaryOperatorExpression; if (uOp != null) { yield return(new CodeAction( string.Format(context.TranslateString("Invert '{0}'"), expr), script => { script.Replace(uOp, AlUtil.InvertCondition(AlUtil.GetInnerMostExpression(uOp.Expression))); }, token )); yield break; } var negativeExpression = AlUtil.InvertCondition(expr); if (expr.Parent is ParenthesizedExpression && expr.Parent.Parent is UnaryOperatorExpression) { var unaryOperatorExpression = expr.Parent.Parent as UnaryOperatorExpression; if (unaryOperatorExpression.Operator == UnaryOperatorType.Not) { yield return(new CodeAction( string.Format(context.TranslateString("Invert '{0}'"), unaryOperatorExpression), script => { script.Replace(unaryOperatorExpression, negativeExpression); }, token )); yield break; } } var newExpression = new UnaryOperatorExpression(UnaryOperatorType.Not, new ParenthesizedExpression(negativeExpression)); yield return(new CodeAction( string.Format(context.TranslateString("Invert '{0}'"), expr), script => { script.Replace(expr, newExpression); }, token )); }
public override System.Collections.Generic.IEnumerable <CodeAction> GetActions(RefactoringContext context) { Expression expr = null; AstNode token; if (!GetLogicalExpression(context, out expr, out token)) { yield break; } yield return(new CodeAction( string.Format(context.TranslateString("Negate '{0}'"), expr), script => { script.Replace(expr, AlUtil.InvertCondition(expr)); }, token )); }
public override IEnumerable <CodeAction> GetActions(RefactoringContext context) { // TODO: Invert if without else // ex. if (cond) DoSomething () == if (!cond) return; DoSomething () // beware of loop contexts return should be continue then. var ifStatement = GetIfElseStatement(context); if (!(ifStatement != null && !ifStatement.TrueStatement.IsNull && !ifStatement.FalseStatement.IsNull)) { yield break; } yield return(new CodeAction(context.TranslateString("Invert if"), script => { script.Replace(ifStatement.Condition, AlUtil.InvertCondition(ifStatement.Condition.Clone())); script.Replace(ifStatement.TrueStatement, ifStatement.FalseStatement.Clone()); script.Replace(ifStatement.FalseStatement, ifStatement.TrueStatement.Clone()); script.FormatText(ifStatement); }, ifStatement)); }
protected override CodeAction GetAction(RefactoringContext context, ConditionalExpression conditionalExpr) { if (context.Location != conditionalExpr.Condition.StartLocation && context.Location < conditionalExpr.Condition.EndLocation || context.Location != conditionalExpr.TrueExpression.StartLocation && conditionalExpr.TrueExpression.Contains(context.Location) || context.Location != conditionalExpr.FalseExpression.StartLocation && conditionalExpr.FalseExpression.Contains(context.Location)) { return(null); } var node = conditionalExpr.GetNodeAt(context.Location); if (node == null) { return(null); } return(new CodeAction(context.TranslateString("Invert '?:'"), script => { script.Replace(conditionalExpr.Condition, AlUtil.InvertCondition(conditionalExpr.Condition.Clone())); script.Replace(conditionalExpr.TrueExpression, conditionalExpr.FalseExpression.Clone()); script.Replace(conditionalExpr.FalseExpression, conditionalExpr.TrueExpression.Clone()); script.FormatText(conditionalExpr); }, node)); }
protected override CodeAction GetAction(RefactoringContext context, WhileStatement node) { if (!node.WhileToken.Contains(context.Location)) { return(null); } return(new CodeAction( context.TranslateString("Extract condition to internal 'if' statement"), script => { script.Replace(node.Condition, new PrimitiveExpression(true)); var ifStmt = new IfElseStatement( AlUtil.InvertCondition(node.Condition), new BreakStatement() ); var block = node.EmbeddedStatement as BlockStatement; if (block != null) { script.InsertAfter(block.LBraceToken, ifStmt); } else { var blockStatement = new BlockStatement { ifStmt }; if (!(node.EmbeddedStatement is EmptyStatement)) { blockStatement.Statements.Add(node.EmbeddedStatement.Clone()); } script.Replace(node.EmbeddedStatement, blockStatement); } }, node )); }
AssignmentExpression GetTransformedAssignmentExpression(RefactoringContext context, ForeachStatement foreachStatement) { var enumerableToIterate = foreachStatement.InExpression.Clone(); Statement statement = foreachStatement.EmbeddedStatement; Expression leftExpression, rightExpression; if (!ExtractExpression(statement, out leftExpression, out rightExpression)) { return(null); } if (leftExpression == null || rightExpression == null) { return(null); } var type = context.Resolve(leftExpression).Type; if (!IsLinqSummableType(type)) { return(null); } if (rightExpression.DescendantsAndSelf.OfType <AssignmentExpression>().Any()) { // Reject loops such as // int k = 0; // foreach (var x in y) { k += (z = 2); } return(null); } if (rightExpression.DescendantsAndSelf.OfType <UnaryOperatorExpression>().Any(IsUnaryModifierExpression)) { // int k = 0; // foreach (var x in y) { k += (z++); } return(null); } var zeroLiteral = new PrimitiveExpression(0); Expression baseExpression = enumerableToIterate; for (;;) { ConditionalExpression condition = rightExpression as ConditionalExpression; if (condition == null) { break; } if (SameNode(zeroLiteral, condition.TrueExpression)) { baseExpression = new InvocationExpression(new MemberReferenceExpression(baseExpression.Clone(), "Where"), BuildLambda(foreachStatement.VariableName, AlUtil.InvertCondition(condition.Condition))); rightExpression = condition.FalseExpression.Clone(); continue; } if (SameNode(zeroLiteral, condition.FalseExpression)) { baseExpression = new InvocationExpression(new MemberReferenceExpression(baseExpression.Clone(), "Where"), BuildLambda(foreachStatement.VariableName, condition.Condition.Clone())); rightExpression = condition.TrueExpression.Clone(); continue; } break; } var primitiveOne = new PrimitiveExpression(1); bool isPrimitiveOne = SameNode(primitiveOne, rightExpression); var arguments = new List <Expression>(); string method = isPrimitiveOne ? "Count" : "Sum"; if (!isPrimitiveOne && !IsIdentifier(rightExpression, foreachStatement.VariableName)) { var lambda = BuildLambda(foreachStatement.VariableName, rightExpression); arguments.Add(lambda); } var rightSide = new InvocationExpression(new MemberReferenceExpression(baseExpression, method), arguments); return(new AssignmentExpression(leftExpression.Clone(), AssignmentOperatorType.Add, rightSide)); }
public override void VisitConditionalExpression(ConditionalExpression conditionalExpression) { base.VisitConditionalExpression(conditionalExpression); bool?trueBranch = GetBool(AlUtil.GetInnerMostExpression(conditionalExpression.TrueExpression)); bool?falseBranch = GetBool(AlUtil.GetInnerMostExpression(conditionalExpression.FalseExpression)); if (trueBranch == falseBranch || trueBranch == true && falseBranch == false) // Handled by RedundantTernaryExpressionIssue { return; } AddIssue(new CodeIssue( conditionalExpression.QuestionMarkToken.StartLocation, conditionalExpression.FalseExpression.EndLocation, ctx.TranslateString("Simplify conditional expression"), ctx.TranslateString("Simplify conditional expression"), script => { if (trueBranch == false && falseBranch == true) { script.Replace(conditionalExpression, AlUtil.InvertCondition(conditionalExpression.Condition)); return; } if (trueBranch == true) { script.Replace( conditionalExpression, new BinaryOperatorExpression( conditionalExpression.Condition.Clone(), BinaryOperatorType.ConditionalOr, conditionalExpression.FalseExpression.Clone() ) ); return; } if (trueBranch == false) { script.Replace( conditionalExpression, new BinaryOperatorExpression( AlUtil.InvertCondition(conditionalExpression.Condition), BinaryOperatorType.ConditionalAnd, conditionalExpression.FalseExpression.Clone() ) ); return; } if (falseBranch == true) { script.Replace( conditionalExpression, new BinaryOperatorExpression( AlUtil.InvertCondition(conditionalExpression.Condition), BinaryOperatorType.ConditionalOr, conditionalExpression.TrueExpression.Clone() ) ); return; } if (falseBranch == false) { script.Replace( conditionalExpression, new BinaryOperatorExpression( conditionalExpression.Condition.Clone(), BinaryOperatorType.ConditionalAnd, conditionalExpression.TrueExpression.Clone() ) ); return; } // Should never happen } )); }
public override void VisitIfElseStatement(IfElseStatement ifElseStatement) { base.VisitIfElseStatement(ifElseStatement); var match = ifPattern.Match(ifElseStatement); if (match.Success) { var varDeclaration = ifElseStatement.GetPrevSibling(s => s.Role == BlockStatement.StatementRole) as VariableDeclarationStatement; var target = match.Get <Expression>("target").Single(); var match2 = varDelarationPattern.Match(varDeclaration); if (match2.Success) { var initializer = varDeclaration.Variables.FirstOrDefault(); if (initializer != null && target is IdentifierExpression && ((IdentifierExpression)target).Identifier != initializer.Name) { return; } var expr = match.Get <Expression>("condition").Single(); if (!ConvertIfToOrExpressionIssue.CheckTarget(target, expr)) { return; } AddIssue(new CodeIssue( ifElseStatement.IfToken, ctx.TranslateString("Convert to '&&' expresssion"), ctx.TranslateString("Replace with '&&'"), script => { var variable = initializer; var initalizerExpression = variable.Initializer.Clone(); var bOp = initalizerExpression as BinaryOperatorExpression; if (bOp != null && bOp.Operator == BinaryOperatorType.ConditionalOr) { initalizerExpression = new ParenthesizedExpression(initalizerExpression); } script.Replace( varDeclaration, new VariableDeclarationStatement( varDeclaration.Type.Clone(), variable.Name, new BinaryOperatorExpression(initalizerExpression, BinaryOperatorType.ConditionalAnd, AlUtil.InvertCondition(expr)) ) ); script.Remove(ifElseStatement); } ) { IssueMarker = IssueMarker.DottedLine }); return; } else { var expr = match.Get <Expression>("condition").Single(); if (!ConvertIfToOrExpressionIssue.CheckTarget(target, expr)) { return; } AddIssue(new CodeIssue( ifElseStatement.IfToken, ctx.TranslateString("Convert to '&=' expresssion"), ctx.TranslateString("Replace with '&='"), script => script.Replace( ifElseStatement, new ExpressionStatement( new AssignmentExpression( target.Clone(), AssignmentOperatorType.BitwiseAnd, AlUtil.InvertCondition(expr) ) ) ) ) { IssueMarker = IssueMarker.DottedLine }); } } }