public static OptionalParentheses ( Expression expr ) : Expression | ||
expr | Expression | |
return | Expression |
static bool?IsForward(ExpressionStatement statement, string name, out Expression step) { step = null; if (statement == null) { return(null); } var forwardPattern = new Choice { PatternHelper.OptionalParentheses(new UnaryOperatorExpression(UnaryOperatorType.Increment, new IdentifierExpression(name))), PatternHelper.OptionalParentheses(new UnaryOperatorExpression(UnaryOperatorType.PostIncrement, new IdentifierExpression(name))), PatternHelper.OptionalParentheses(new AssignmentExpression(new IdentifierExpression(name), AssignmentOperatorType.Add, PatternHelper.OptionalParentheses(new AnyNode("step")))) }; var match = forwardPattern.Match(statement.Expression); if (match.Success) { step = match.Get <Expression>("step").FirstOrDefault(); return(true); } var backwardPattern = new Choice { PatternHelper.OptionalParentheses(new UnaryOperatorExpression(UnaryOperatorType.Decrement, new IdentifierExpression(name))), PatternHelper.OptionalParentheses(new UnaryOperatorExpression(UnaryOperatorType.PostDecrement, new IdentifierExpression(name))), PatternHelper.OptionalParentheses(new AssignmentExpression(new IdentifierExpression(name), AssignmentOperatorType.Subtract, PatternHelper.OptionalParentheses(new AnyNode("step")))) }; match = backwardPattern.Match(statement.Expression); if (match.Success) { step = match.Get <Expression>("step").FirstOrDefault(); return(false); } return(null); }
Expression GetNewCondition(Expression condition, VariableInitializer initializer, bool?direction, Expression step, out Expression newInitializer) { var name = initializer.Name; newInitializer = null; var bOp = condition as BinaryOperatorExpression; if (bOp == null || direction == null) { return(null); } if (direction == true) { var upwardPattern = new Choice { PatternHelper.OptionalParentheses(new BinaryOperatorExpression(PatternHelper.OptionalParentheses(new IdentifierExpression(name)), BinaryOperatorType.LessThan, PatternHelper.OptionalParentheses(new AnyNode("bound")))), PatternHelper.OptionalParentheses(new BinaryOperatorExpression(PatternHelper.OptionalParentheses(new AnyNode("bound")), BinaryOperatorType.GreaterThan, PatternHelper.OptionalParentheses(new IdentifierExpression(name)))) }; var upMatch = upwardPattern.Match(condition); if (upMatch.Success) { var bound = upMatch.Get <Expression>("bound").FirstOrDefault(); newInitializer = direction == true?Subtract(bound, step) : bound.Clone(); return(GetNewBound(name, false, initializer.Initializer.Clone(), step)); } var altUpwardPattern = new Choice { PatternHelper.OptionalParentheses(new BinaryOperatorExpression(PatternHelper.OptionalParentheses(new IdentifierExpression(name)), BinaryOperatorType.LessThanOrEqual, PatternHelper.OptionalParentheses(new AnyNode("bound")))), PatternHelper.OptionalParentheses(new BinaryOperatorExpression(PatternHelper.OptionalParentheses(new AnyNode("bound")), BinaryOperatorType.GreaterThanOrEqual, PatternHelper.OptionalParentheses(new IdentifierExpression(name)))) }; var altUpMatch = altUpwardPattern.Match(condition); if (altUpMatch.Success) { var bound = altUpMatch.Get <Expression>("bound").FirstOrDefault(); newInitializer = bound.Clone(); return(GetNewBound(name, false, initializer.Initializer.Clone(), step)); } } var downPattern = new Choice { PatternHelper.OptionalParentheses(new BinaryOperatorExpression(PatternHelper.OptionalParentheses(new IdentifierExpression(name)), BinaryOperatorType.GreaterThanOrEqual, PatternHelper.OptionalParentheses(new AnyNode("bound")))), PatternHelper.OptionalParentheses(new BinaryOperatorExpression(PatternHelper.OptionalParentheses(new AnyNode("bound")), BinaryOperatorType.LessThanOrEqual, PatternHelper.OptionalParentheses(new IdentifierExpression(name)))) }; var downMatch = downPattern.Match(condition); if (!downMatch.Success) { return(null); } var bound2 = downMatch.Get <Expression>("bound").FirstOrDefault(); newInitializer = direction == true?Subtract(bound2, step) : bound2.Clone(); return(GetNewBound(name, true, initializer.Initializer.Clone(), step)); }
static List <AstNode> SearchCasts(RefactoringContext ctx, Statement embeddedStatement, Expression obj, AstType type, out ResolveResult rr) { var cast = new Choice { PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastTo(type.Clone())), PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastAs(type.Clone())) }; rr = ctx.Resolve(type); if (rr == null || rr.IsError) { return(null); } return(embeddedStatement.DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => cast.IsMatch(n)).ToList()); }
public ConvertIfToNullCoalescingAction() { var leftPattern = PatternHelper.OptionalParentheses(new AnyNode(comparedNodeGroupName)); var rightPattern = PatternHelper.OptionalParentheses(new NullReferenceExpression()); var choicePattern = new Choice(); var equalityPattern = PatternHelper.CommutativeOperator(leftPattern, BinaryOperatorType.Equality, rightPattern); var inequalityPattern = PatternHelper.CommutativeOperator(leftPattern.Clone(), BinaryOperatorType.InEquality, rightPattern.Clone()); choicePattern.Add(equalityPattern); choicePattern.Add(inequalityPattern); var namedChoicePattern = new NamedNode(expressionGroupName, choicePattern); ActionPattern = PatternHelper.OptionalParentheses(namedChoicePattern); }
internal static Expression CheckNode(IfElseStatement node, out Expression rightSide) { rightSide = null; var match = ActionPattern.Match(node.Condition); if (!match.Success) { return(null); } var conditionExpression = match.Get <BinaryOperatorExpression>(expressionGroupName).Single(); bool isEqualityComparison = conditionExpression.Operator == BinaryOperatorType.Equality; Expression comparedNode = match.Get <Expression>(comparedNodeGroupName).Single(); Statement contentStatement; if (isEqualityComparison) { contentStatement = node.TrueStatement; if (!IsEmpty(node.FalseStatement)) { return(null); } } else { contentStatement = node.FalseStatement; if (!IsEmpty(node.TrueStatement)) { return(null); } } contentStatement = GetSimpleStatement(contentStatement); if (contentStatement == null) { return(null); } var leftExpressionPattern = PatternHelper.OptionalParentheses(comparedNode); var expressionPattern = new AssignmentExpression(leftExpressionPattern, AssignmentOperatorType.Assign, new AnyNode(valueOnNullGroupName)); var statementPattern = new ExpressionStatement(PatternHelper.OptionalParentheses(expressionPattern)); var statementMatch = statementPattern.Match(contentStatement); if (!statementMatch.Success) { return(null); } rightSide = statementMatch.Get <Expression>(valueOnNullGroupName).Single(); return(comparedNode); }
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 = CSharpUtil.GetInnerMostExpression(outerIs) as IsExpression; var obj = CSharpUtil.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)); }
protected override CodeAction GetAction(RefactoringContext ctx, IfElseStatement ifElseStatement) { var isExpr = ctx.GetNode <IsExpression>(); if (isExpr == null || !isExpr.IsToken.Contains(ctx.Location)) { return(null); } int foundCasts; var action = ScanIfElse(ctx, ifElseStatement, out isExpr, out foundCasts); if (action != null) { return(action); } isExpr = ctx.GetNode <IsExpression>(); var node = isExpr.Parent; while (node is ParenthesizedExpression) { node = node.Parent; } var uOp = node as UnaryOperatorExpression; if (uOp != null && uOp.Operator == UnaryOperatorType.Not) { var rr = ctx.Resolve(isExpr.Type); if (rr == null || rr.IsError || rr.Type.IsReferenceType == false) { return(null); } 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(isExpr.Expression.Clone(), isExpr.Type.Clone())); var binaryOperatorIdentifier = new IdentifierExpression(varName); var binaryOperatorExpression = new BinaryOperatorExpression(binaryOperatorIdentifier, BinaryOperatorType.Equality, new NullReferenceExpression()); if (IsEmbeddedStatement(ifElseStatement)) { var block = new BlockStatement(); block.Add(varDec); var newIf = (IfElseStatement)ifElseStatement.Clone(); newIf.Condition = binaryOperatorExpression; block.Add(newIf); script.Replace(ifElseStatement, block); } else { script.InsertBefore(ifElseStatement, varDec); script.Replace(uOp, binaryOperatorExpression); } }, isExpr.IsToken)); } var obj = isExpr.Expression; var castToType = isExpr.Type; var cast = new Choice { PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastTo(castToType.Clone())), PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastAs(castToType.Clone())) }; var rr2 = ctx.Resolve(castToType); if (rr2 == null || rr2.IsError || rr2.Type.IsReferenceType == false) { return(null); } var foundCasts2 = isExpr.GetParent <Statement>().DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => isExpr.StartLocation < n.StartLocation && cast.IsMatch(n)).ToList(); return(new CodeAction(ctx.TranslateString("Use 'as' and check for null"), script => { var varName = ctx.GetNameProposal(CreateMethodDeclarationAction.GuessNameFromType(rr2.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.InEquality, 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 node2 in newIf.DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => cast.IsMatch(n))) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); node2.ReplaceWith(id); } block.Add(newIf); script.Replace(ifElseStatement, block); } else { script.InsertBefore(ifElseStatement, varDec); script.Replace(isExpr, binaryOperatorExpression); foreach (var c in foundCasts2) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); script.Replace(c, id); } } script.Link(linkedNodes); }, isExpr.IsToken)); }
protected override CodeAction GetAction(RefactoringContext context, IfElseStatement node) { var match = ActionPattern.Match(node.Condition); if (!match.Success) { return(null); } var conditionExpression = match.Get <BinaryOperatorExpression>(expressionGroupName).Single(); bool isEqualityComparison = conditionExpression.Operator == BinaryOperatorType.Equality; Expression comparedNode = match.Get <Expression>(comparedNodeGroupName).Single(); Statement contentStatement; if (isEqualityComparison) { contentStatement = node.TrueStatement; if (!IsEmpty(node.FalseStatement)) { return(null); } } else { contentStatement = node.FalseStatement; if (!IsEmpty(node.TrueStatement)) { return(null); } } contentStatement = GetSimpleStatement(contentStatement); if (contentStatement == null) { return(null); } var leftExpressionPattern = PatternHelper.OptionalParentheses(comparedNode); var expressionPattern = new AssignmentExpression(leftExpressionPattern, AssignmentOperatorType.Assign, new AnyNode(valueOnNullGroupName)); var statementPattern = new ExpressionStatement(PatternHelper.OptionalParentheses(expressionPattern)); var statementMatch = statementPattern.Match(contentStatement); if (!statementMatch.Success) { return(null); } var rightSide = statementMatch.Get <Expression>(valueOnNullGroupName).Single(); return(new CodeAction(context.TranslateString("Convert if statement to ?? expression"), script => { var previousNode = node.GetPrevSibling(sibling => sibling is Statement); var previousDeclaration = previousNode as VariableDeclarationStatement; if (previousDeclaration != null && previousDeclaration.Variables.Count() == 1) { var variable = previousDeclaration.Variables.First(); var comparedNodeIdentifierExpression = comparedNode as IdentifierExpression; if (comparedNodeIdentifierExpression != null && comparedNodeIdentifierExpression.Identifier == variable.Name) { script.Replace(variable.Initializer, new BinaryOperatorExpression(variable.Initializer.Clone(), BinaryOperatorType.NullCoalescing, rightSide.Clone())); script.Remove(node); return; } } var previousExpressionStatement = previousNode as ExpressionStatement; if (previousExpressionStatement != null) { var previousAssignment = previousExpressionStatement.Expression as AssignmentExpression; if (previousAssignment != null && comparedNode.IsMatch(previousAssignment.Left)) { var newExpression = new BinaryOperatorExpression(previousAssignment.Right.Clone(), BinaryOperatorType.NullCoalescing, rightSide.Clone()); script.Replace(previousAssignment.Right, newExpression); script.Remove(node); return; } } var coalescedExpression = new BinaryOperatorExpression(comparedNode.Clone(), BinaryOperatorType.NullCoalescing, rightSide.Clone()); var newAssignment = new ExpressionStatement(new AssignmentExpression(comparedNode.Clone(), coalescedExpression)); script.Replace(node, newAssignment); }, node)); }