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); } )); }
Expression Subtract(Expression expr, Expression step) { if (step != null && AlUtil.GetInnerMostExpression(expr).IsMatch(AlUtil.GetInnerMostExpression(step))) { return(new PrimitiveExpression(0)); } var pe = expr as PrimitiveExpression; if (pe != null) { if (step == null) { return(new PrimitiveExpression((int)pe.Value - 1)); } var stepExpr = step as PrimitiveExpression; if (stepExpr != null) { return(new PrimitiveExpression((int)pe.Value - (int)stepExpr.Value)); } } var bOp = expr as BinaryOperatorExpression; if (bOp != null) { if (bOp.Operator == BinaryOperatorType.Subtract) { var right = Add(bOp.Right, step); if (zeroExpr.IsMatch(right)) { return(bOp.Left.Clone()); } return(new BinaryOperatorExpression(bOp.Left.Clone(), BinaryOperatorType.Subtract, right)); } if (bOp.Operator == BinaryOperatorType.Add) { var right = Subtract(bOp.Right, step); if (zeroExpr.IsMatch(right)) { return(bOp.Left.Clone()); } return(new BinaryOperatorExpression(bOp.Left.Clone(), BinaryOperatorType.Add, Subtract(bOp.Right, step))); } } if (step == null) { return(new BinaryOperatorExpression(expr.Clone(), BinaryOperatorType.Subtract, new PrimitiveExpression(1))); } return(new BinaryOperatorExpression(expr.Clone(), BinaryOperatorType.Subtract, AlUtil.AddParensForUnaryExpressionIfRequired(step.Clone()))); }
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 )); }
bool CheckNullComparison(BinaryOperatorExpression binaryOperatorExpression, Expression right, Expression nullNode) { if (binaryOperatorExpression.Operator != BinaryOperatorType.Equality && binaryOperatorExpression.Operator != BinaryOperatorType.InEquality) { return(false); } // note null == null is checked by similiar expression comparison. var expr = AlUtil.GetInnerMostExpression(right); var rr = ctx.Resolve(expr); if (rr.Type.IsReferenceType == false) { // nullable check if (NullableType.IsNullable(rr.Type)) { return(false); } var conversion = ctx.GetConversion(nullNode); if (conversion.ConversionAfterUserDefinedOperator == Conversion.IdentityConversion) { return(false); } // check for user operators foreach (var op in rr.Type.GetMethods(m => m.SymbolKind == SymbolKind.Operator && m.Parameters.Count == 2)) { if (op.Parameters[0].Type.IsReferenceType == false && op.Parameters[1].Type.IsReferenceType == false) { continue; } if (binaryOperatorExpression.Operator == BinaryOperatorType.Equality && op.Name == "op_Equality") { return(false); } if (binaryOperatorExpression.Operator == BinaryOperatorType.InEquality && op.Name == "op_Inequality") { return(false); } } AddIssue(binaryOperatorExpression, binaryOperatorExpression.Operator != BinaryOperatorType.Equality); return(true); } return(false); }
protected override CodeAction GetAction(RefactoringContext context, UnaryOperatorExpression node) { if (node.Operator != UnaryOperatorType.PostIncrement && node.Operator != UnaryOperatorType.PostDecrement) { return(null); } string desc = node.Operator == UnaryOperatorType.PostIncrement ? context.TranslateString("Replace with '{0} += 1'") : context.TranslateString("Replace with '{0} -= 1'"); return(new CodeAction( string.Format(desc, AlUtil.GetInnerMostExpression(node.Expression)), s => s.Replace(node, new AssignmentExpression( AlUtil.GetInnerMostExpression(node.Expression).Clone(), node.Operator == UnaryOperatorType.PostIncrement ? AssignmentOperatorType.Add : AssignmentOperatorType.Subtract, new PrimitiveExpression(1) )), node.OperatorToken )); }
public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) { if (CheckConstant(binaryOperatorExpression)) { return; } if (AlUtil.GetInnerMostExpression(binaryOperatorExpression.Left) is NullReferenceExpression) { if (CheckNullComparison(binaryOperatorExpression, binaryOperatorExpression.Right, binaryOperatorExpression.Left)) { return; } } if (AlUtil.GetInnerMostExpression(binaryOperatorExpression.Right) is NullReferenceExpression) { if (CheckNullComparison(binaryOperatorExpression, binaryOperatorExpression.Left, binaryOperatorExpression.Right)) { return; } } base.VisitBinaryOperatorExpression(binaryOperatorExpression); }
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 } )); }
static CodeAction HandleNegatedCase(BaseRefactoringContext ctx, IfElseStatement ifElseStatement, Match match, out IsExpression isExpression, out int foundCastCount) { foundCastCount = 0; var outerIs = match.Get <Expression>("isExpression").Single(); isExpression = AlUtil.GetInnerMostExpression(outerIs) as IsExpression; var obj = AlUtil.GetInnerMostExpression(isExpression.Expression); var castToType = isExpression.Type; var cast = new Choice { PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastTo(castToType.Clone())), PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastAs(castToType.Clone())) }; var rr = ctx.Resolve(castToType); if (rr == null || rr.IsError || rr.Type.IsReferenceType == false) { return(null); } var foundCasts = ifElseStatement.GetParent <BlockStatement>().DescendantNodes(n => n.StartLocation >= ifElseStatement.StartLocation && !cast.IsMatch(n)).Where(n => cast.IsMatch(n)).ToList(); foundCastCount = foundCasts.Count; return(new CodeAction(ctx.TranslateString("Use 'as' and check for null"), script => { var varName = ctx.GetNameProposal(CreateMethodDeclarationAction.GuessNameFromType(rr.Type), ifElseStatement.StartLocation); var varDec = new VariableDeclarationStatement(new PrimitiveType("var"), varName, new AsExpression(obj.Clone(), castToType.Clone())); var binaryOperatorIdentifier = new IdentifierExpression(varName); var binaryOperatorExpression = new BinaryOperatorExpression(binaryOperatorIdentifier, BinaryOperatorType.Equality, new NullReferenceExpression()); var linkedNodes = new List <AstNode>(); linkedNodes.Add(varDec.Variables.First().NameToken); linkedNodes.Add(binaryOperatorIdentifier); if (IsEmbeddedStatement(ifElseStatement)) { var block = new BlockStatement(); block.Add(varDec); var newIf = (IfElseStatement)ifElseStatement.Clone(); newIf.Condition = binaryOperatorExpression; foreach (var node in newIf.DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => cast.IsMatch(n))) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); node.ReplaceWith(id); } block.Add(newIf); script.Replace(ifElseStatement, block); } else { script.InsertBefore(ifElseStatement, varDec); script.Replace(ifElseStatement.Condition, binaryOperatorExpression); foreach (var c in foundCasts) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); script.Replace(c, id); } } script.Link(linkedNodes); }, isExpression.IsToken)); }