//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(")");
 }
Exemplo n.º 10
0
 public virtual void VisitConditionExpression(ConditionExpression node)
 {
     Visit(node.Condition);
     Visit(node.Then);
     Visit(node.Else);
 }