//x = cond ? y : z; // //== // //if(cond) //{ // x = y; //} //else //{ // x = z; //} // //x - phi variable //y, z - expressions public bool TryMatchInternal(IfStatement theIfStatement, out Statement result) { result = null; if (theIfStatement == null) { return false; } VariableReference xVariableReference = null; VariableReference x1VariableReference = null; Expression yExpressionValue; Expression zExpressionValue; if (theIfStatement.Else == null || theIfStatement.Then.Statements.Count != 1 || theIfStatement.Else.Statements.Count != 1 || theIfStatement.Then.Statements[0].CodeNodeType != CodeNodeType.ExpressionStatement || theIfStatement.Else.Statements[0].CodeNodeType != CodeNodeType.ExpressionStatement) { return false; } BinaryExpression thenAssignExpression = (theIfStatement.Then.Statements[0] as ExpressionStatement).Expression as BinaryExpression; BinaryExpression elseAssignExpression = (theIfStatement.Else.Statements[0] as ExpressionStatement).Expression as BinaryExpression; if (!IsAssignToVariableExpression(thenAssignExpression, out x1VariableReference) || !IsAssignToVariableExpression(elseAssignExpression, out xVariableReference)) { return false; } if (xVariableReference != x1VariableReference) { return false; } if (!ShouldInlineExpressions(thenAssignExpression, elseAssignExpression)) { /// Although correct syntax, nesting ternary expressions makes the code very unreadable. return false; } yExpressionValue = GetRightExpressionMapped(thenAssignExpression); zExpressionValue = GetRightExpressionMapped(elseAssignExpression); ConditionExpression ternaryConditionExpression = new ConditionExpression(theIfStatement.Condition, yExpressionValue, zExpressionValue, null); BinaryExpression ternaryAssign = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(xVariableReference, null), ternaryConditionExpression, this.typeSystem, null); result = new ExpressionStatement(ternaryAssign) { Parent = theIfStatement.Parent }; FixContext(xVariableReference.Resolve(), 1, 0, result as ExpressionStatement); return true; }
public override Expression CloneExpressionOnly() { ConditionExpression result = new ConditionExpression(Condition.CloneExpressionOnly(), Then.CloneExpressionOnly(), Else.CloneExpressionOnly(), null); return result; }
private bool TryTransformTernary(ConditionExpression ternary, out Expression transformed) { transformed = null; LiteralExpression literal; bool isLiteralInThen; LiteralExpression literalInThen = ternary.Then as LiteralExpression; LiteralExpression literalInElse = ternary.Else as LiteralExpression; // Transforms the case: Method() && someVar > 12 ? 0 : 1 if (literalInThen != null && literalInElse != null) { bool areValidValues = false; bool shouldBeNegated = false; if (literalInThen.ExpressionType.FullName == Constants.Int32 && literalInElse.ExpressionType.FullName == Constants.Int32) { int valueInThen = (int)literalInThen.Value; int valueInElse = (int)literalInElse.Value; if ((valueInThen == 0 && valueInElse == 1) || (valueInThen == 1 && valueInElse == 0)) { areValidValues = true; if (valueInThen == 0 && valueInElse == 1) { shouldBeNegated = true; } } } else if (literalInThen.ExpressionType.FullName == Constants.Boolean && literalInElse.ExpressionType.FullName == Constants.Boolean) { bool valueInThen = (bool)literalInThen.Value; bool valueInElse = (bool)literalInElse.Value; if ((valueInThen == false && valueInElse == true) || (valueInThen == true && valueInElse == false)) { areValidValues = true; if (valueInThen == false && valueInElse == true) { shouldBeNegated = true; } } } if (areValidValues) { if (shouldBeNegated) { transformed = Transform(Negator.Negate(ternary.Condition, typeSystem)); } else { transformed = Transform(ternary.Condition); } return true; } } if (literalInThen != null) { literal = literalInThen; isLiteralInThen = true; } else if (literalInElse != null) { literal = literalInElse; isLiteralInThen = false; } else // Transforms the case: someCondition ? (int)boolVar1 : (int)boolVar2 { CastExpression thenCast = ternary.Then as CastExpression; CastExpression elseCast = ternary.Else as CastExpression; if (thenCast != null && elseCast != null && thenCast.TargetType.FullName == Constants.Int32 && thenCast.Expression.ExpressionType.FullName == Constants.Boolean && elseCast.TargetType.FullName == Constants.Int32 && elseCast.Expression.ExpressionType.FullName == Constants.Boolean) { ternary.Then = thenCast.Expression; ternary.Else = elseCast.Expression; transformed = ternary; return true; } return false; } bool isTrueLikeValue; if (literal.ExpressionType.FullName == Constants.Int32) { isTrueLikeValue = (int)literal.Value != 0 ? true : false; } else if (literal.ExpressionType.FullName == Constants.Boolean) { isTrueLikeValue = (bool)literal.Value; } else { return false; } BinaryOperator newOperator; Expression newLeft = null; Expression newRight = null; newLeft = Transform(ternary.Condition); Expression expression; if (isLiteralInThen) { expression = ternary.Else; } else { expression = ternary.Then; } ConditionExpression nestedTernary = expression as ConditionExpression; CastExpression castExpression = expression as CastExpression; Expression nestedBinaryAsExpression = null; bool isNestedBinaryInUnary = false; if (nestedTernary == null && (castExpression == null || castExpression.TargetType.FullName != Constants.Int32 || castExpression.Expression.ExpressionType.FullName != Constants.Boolean) && !IsBinaryExpression(expression, out nestedBinaryAsExpression, out isNestedBinaryInUnary) && expression.ExpressionType.FullName != Constants.Boolean) { return false; } bool isRightTransformed = false; if (castExpression != null) { newRight = castExpression.Expression; isRightTransformed = true; } else { if (nestedBinaryAsExpression != null) { BinaryExpression nestedBinary = GetBinaryExpression(isNestedBinaryInUnary, nestedBinaryAsExpression); if (TryTransformBinary(nestedBinary)) { newRight = GetResultExpression(isNestedBinaryInUnary, nestedBinaryAsExpression, nestedBinary); isRightTransformed = true; } } else if (nestedTernary != null && TryTransformTernary(nestedTernary, out newRight)) { isRightTransformed = true; } } if (!isRightTransformed) { newRight = expression; } if (newLeft == null || newRight == null) { return false; } if (isTrueLikeValue) { newOperator = BinaryOperator.LogicalOr; newLeft = isLiteralInThen ? newLeft : Negator.Negate(newLeft, this.typeSystem); } else { newOperator = BinaryOperator.LogicalAnd; newLeft = isLiteralInThen ? Negator.Negate(newLeft, this.typeSystem) : newLeft; } transformed = new BinaryExpression(newOperator, newLeft, newRight, this.typeSystem, ternary.MappedInstructions); return true; }
public override void VisitConditionExpression(ConditionExpression node) { WriteKeyword(KeyWordWriter.If); WriteToken("("); Visit(node.Condition); WriteToken(","); WriteSpace(); Visit(node.Then); WriteToken(","); WriteSpace(); Visit(node.Else); WriteToken(")"); }
public override Expression Clone() { ConditionExpression result = new ConditionExpression(Condition.Clone(), Then.Clone(), Else.Clone(), instructions); return result; }
private void TryProcessConditionExpression(ConditionExpression node) { if (processStep == ProcessStep.Replace) { Expression expression; if (TryGetVariableExpression(node.Condition, out expression)) { node.Condition = expression; } } }
public override void VisitConditionExpression(ConditionExpression node) { TryProcessConditionExpression(node); states.Push(Step.Expression); Visit(node.Condition); states.Pop(); Visit(node.Then); Visit(node.Else); }
public override void VisitConditionExpression(ConditionExpression node) { expressions.Push(ExpressionKind.None); base.VisitConditionExpression(node); expressions.Pop(); }
public override void VisitConditionExpression(ConditionExpression node) { WriteToken("("); Visit(node.Condition); WriteTokenBetweenSpace("?"); Visit(node.Then); WriteTokenBetweenSpace(":"); Visit(node.Else); WriteToken(")"); }
public virtual void VisitConditionExpression(ConditionExpression node) { Visit(node.Condition); Visit(node.Then); Visit(node.Else); }