Ejemplo n.º 1
0
Archivo: if.cs Proyecto: formist/LinkMe
        public override void CleanupNodes()
        {
            base.CleanupNodes();

            if (Parser.Settings.EvalLiteralExpressions &&
                Parser.Settings.IsModificationAllowed(TreeModifications.EvaluateNumericExpressions))
            {
                // if the if-condition is a constant, we can eliminate one of the two branches
                ConstantWrapper constantCondition = Condition as ConstantWrapper;
                if (constantCondition != null)
                {
                    // instead, replace the condition with a 1 if it's always true or a 0 if it's always false
                    if (constantCondition.IsNotOneOrPositiveZero)
                    {
                        try
                        {
                            Condition = new ConstantWrapper(constantCondition.ToBoolean() ? 1 : 0, PrimitiveType.Number, null, Parser);
                        }
                        catch (InvalidCastException)
                        {
                            // ignore any invalid cast exceptions
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public override void CleanupNodes()
        {
            base.CleanupNodes();

            if (Parser.Settings.EvalLiteralExpressions &&
                Parser.Settings.IsModificationAllowed(TreeModifications.EvaluateNumericExpressions))
            {
                ConstantWrapper constantCondition = Condition as ConstantWrapper;
                if (constantCondition != null)
                {
                    try
                    {
                        // if condition is always false, change it to a zero (only one byte)
                        // and if it is always true, remove it (default behavior)
                        if (constantCondition.ToBoolean())
                        {
                            // always true -- don't need a condition at all
                            Condition = null;
                        }
                        else if (constantCondition.IsNotOneOrPositiveZero)
                        {
                            // always false and it's not already a zero. Make it so (only one byte)
                            Condition = new ConstantWrapper(0, PrimitiveType.Number, null, Parser);
                        }
                    }
                    catch (InvalidCastException)
                    {
                        // ignore any invalid cast exceptions
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public override void CleanupNodes()
        {
            base.CleanupNodes();

            if (Parser.Settings.EvalLiteralExpressions &&
                Parser.Settings.IsModificationAllowed(TreeModifications.EvaluateNumericExpressions))
            {
                // if the condition is a literal, evaluating the condition doesn't do anything, AND
                // we know now whether it's true or not.
                ConstantWrapper literalCondition = m_condition as ConstantWrapper;
                if (literalCondition != null)
                {
                    try
                    {
                        // if the boolean represenation of the literal is true, we can replace the condition operator
                        // with the true expression; otherwise we can replace it with the false expression
                        Parent.ReplaceChild(this, literalCondition.ToBoolean() ? m_trueExpression : m_falseExpression);
                    }
                    catch (InvalidCastException)
                    {
                        // ignore any invalid cast errors
                    }
                }
            }
        }
Ejemplo n.º 4
0
 public override void Visit(ConstantWrapper node)
 {
     if (node != null)
     {
         // no children, so don't bother calling the base.
         if (node.PrimitiveType == PrimitiveType.Boolean
             && m_parser.Settings.IsModificationAllowed(TreeModifications.BooleanLiteralsToNotOperators))
         {
             node.Parent.ReplaceChild(node, new NumericUnary(
                 node.Context,
                 m_parser,
                 new ConstantWrapper(node.ToBoolean() ? 0 : 1, PrimitiveType.Number, node.Context, m_parser),
                 JSToken.LogicalNot));
         }
     }
 }
Ejemplo n.º 5
0
        public override void CleanupNodes()
        {
            base.CleanupNodes();

            if (Parser.Settings.EvalLiteralExpressions &&
                Parser.Settings.IsModificationAllowed(TreeModifications.EvaluateNumericExpressions))
            {
                // if the condition is a constant, we can simplify things
                ConstantWrapper constantCondition = Condition as ConstantWrapper;
                if (constantCondition != null && constantCondition.IsNotOneOrPositiveZero)
                {
                    try
                    {
                        // the condition is a constant, so it is always either true or false
                        // we can replace the condition with a one or a zero -- only one byte
                        Condition = new ConstantWrapper(constantCondition.ToBoolean() ? 1 : 0, PrimitiveType.Number, null, Parser);
                    }
                    catch (InvalidCastException)
                    {
                        // ignore any invalid cast errors
                    }
                }
            }
        }
Ejemplo n.º 6
0
        public override void CleanupNodes()
        {
            base.CleanupNodes();

            // see if the condition is a constant
            if (Parser.Settings.EvalLiteralExpressions &&
                Parser.Settings.IsModificationAllowed(TreeModifications.EvaluateNumericExpressions))
            {
                ConstantWrapper constantCondition = Condition as ConstantWrapper;
                if (constantCondition != null)
                {
                    // TODO: we'd RATHER eliminate the statement altogether if the condition is always false,
                    // but we'd need to make sure var'd variables and declared functions are properly handled.
                    try
                    {
                        bool isTrue = constantCondition.ToBoolean();
                        if (isTrue)
                        {
                            // the condition is always true; we should change it to a for(;;) statement.
                            // less bytes than while(1)

                            // check to see if we want to combine a preceding var with a for-statement
                            AstNode initializer = null;
                            if (Parser.Settings.IsModificationAllowed(TreeModifications.MoveVarIntoFor))
                            {
                                // if the previous statement is a var, we can move it to the initializer
                                // and save even more bytes. The parent should always be a block. If not,
                                // then assume there is no previous.
                                Block parentBlock = Parent as Block;
                                if (parentBlock != null)
                                {
                                    int whileIndex = parentBlock.StatementIndex(this);
                                    if (whileIndex > 0)
                                    {
                                        Var previousVar = parentBlock[whileIndex - 1] as Var;
                                        if (previousVar != null)
                                        {
                                            initializer = previousVar;
                                            parentBlock.ReplaceChild(previousVar, null);
                                        }
                                    }
                                }
                            }

                            // create the for using our body and replace ourselves with it
                            ForNode forNode = new ForNode(Context, Parser, initializer, null, null, Body);
                            Parent.ReplaceChild(this, forNode);
                        }
                        else if (constantCondition.IsNotOneOrPositiveZero)
                        {
                            // the condition is always false, so we can replace the condition
                            // with a zero -- only one byte
                            Condition = new ConstantWrapper(0, PrimitiveType.Number, null, Parser);
                        }
                    }
                    catch (InvalidCastException)
                    {
                        // ignore any invalid cast exceptions
                    }
                }
            }
        }
Ejemplo n.º 7
0
        public override void CleanupNodes()
        {
            base.CleanupNodes();

            if (Parser.Settings.EvalLiteralExpressions &&
                Parser.Settings.IsModificationAllowed(TreeModifications.EvaluateNumericExpressions))
            {
                // see if our operand is a ConstantWrapper
                ConstantWrapper literalOperand = Operand as ConstantWrapper;
                if (literalOperand != null)
                {
                    // must be number, boolean, string, or null
                    switch (OperatorToken)
                    {
                    case JSToken.Plus:
                        try
                        {
                            // replace with a constant representing operand.ToNumber,
                            Parent.ReplaceChild(this, new ConstantWrapper(literalOperand.ToNumber(), PrimitiveType.Number, Context, Parser));
                        }
                        catch (InvalidCastException)
                        {
                            // some kind of casting in ToNumber caused a situation where we don't want
                            // to perform the combination on these operands
                        }
                        break;

                    case JSToken.Minus:
                        try
                        {
                            // replace with a constant representing the negative of operand.ToNumber
                            Parent.ReplaceChild(this, new ConstantWrapper(-literalOperand.ToNumber(), PrimitiveType.Number, Context, Parser));
                        }
                        catch (InvalidCastException)
                        {
                            // some kind of casting in ToNumber caused a situation where we don't want
                            // to perform the combination on these operands
                        }
                        break;

                    case JSToken.BitwiseNot:
                        try
                        {
                            // replace with a constant representing the bitwise-not of operant.ToInt32
                            Parent.ReplaceChild(this, new ConstantWrapper(Convert.ToDouble(~literalOperand.ToInt32()), PrimitiveType.Number, Context, Parser));
                        }
                        catch (InvalidCastException)
                        {
                            // some kind of casting in ToNumber caused a situation where we don't want
                            // to perform the combination on these operands
                        }
                        break;

                    case JSToken.LogicalNot:
                        // replace with a constant representing the opposite of operand.ToBoolean
                        try
                        {
                            Parent.ReplaceChild(this, new ConstantWrapper(!literalOperand.ToBoolean(), PrimitiveType.Boolean, Context, Parser));
                        }
                        catch (InvalidCastException)
                        {
                            // ignore any invalid cast exceptions
                        }
                        break;
                    }
                }
            }
        }
Ejemplo n.º 8
0
        private ConstantWrapper Equal(ConstantWrapper left, ConstantWrapper right)
        {
            ConstantWrapper newLiteral = null;

            if (m_parser.Settings.IsModificationAllowed(TreeModifications.EvaluateNumericExpressions))
            {
                PrimitiveType leftType = left.PrimitiveType;
                if (leftType == right.PrimitiveType)
                {
                    // the values are the same type
                    switch (leftType)
                    {
                        case PrimitiveType.Null:
                            // null == null is true
                            newLiteral = new ConstantWrapper(true, PrimitiveType.Boolean, null, m_parser);
                            break;

                        case PrimitiveType.Boolean:
                            // compare boolean values
                            newLiteral = new ConstantWrapper(left.ToBoolean() == right.ToBoolean(), PrimitiveType.Boolean, null, m_parser);
                            break;

                        case PrimitiveType.String:
                            // compare string ordinally
                            newLiteral = new ConstantWrapper(string.CompareOrdinal(left.ToString(), right.ToString()) == 0, PrimitiveType.Boolean, null, m_parser);
                            break;

                        case PrimitiveType.Number:
                            try
                            {
                                // compare the values
                                // +0 and -0 are treated as "equal" in C#, so we don't need to test them separately.
                                // and NaN is always unequal to everything else, including itself.
                                if (left.IsOkayToCombine && right.IsOkayToCombine)
                                {
                                    newLiteral = new ConstantWrapper(left.ToNumber() == right.ToNumber(), PrimitiveType.Boolean, null, m_parser);
                                }
                            }
                            catch (InvalidCastException)
                            {
                                // some kind of casting in ToNumber caused a situation where we don't want
                                // to perform the combination on these operands
                            }
                            break;
                    }
                }
                else if (left.IsOkayToCombine && right.IsOkayToCombine)
                {
                    try
                    {
                        // numeric comparison
                        // +0 and -0 are treated as "equal" in C#, so we don't need to test them separately.
                        // and NaN is always unequal to everything else, including itself.
                        newLiteral = new ConstantWrapper(left.ToNumber() == right.ToNumber(), PrimitiveType.Boolean, null, m_parser);
                    }
                    catch (InvalidCastException)
                    {
                        // some kind of casting in ToNumber caused a situation where we don't want
                        // to perform the combination on these operands
                    }
                }
            }

            return newLiteral;
        }
Ejemplo n.º 9
0
        private ConstantWrapper LogicalOr(ConstantWrapper left, ConstantWrapper right)
        {
            ConstantWrapper newLiteral = null;
            if (m_parser.Settings.IsModificationAllowed(TreeModifications.EvaluateNumericExpressions))
            {
                try
                {
                    // if the left-hand side evaluates to true, return the left-hand side.
                    // if the left-hand side is false, return the right-hand side.
                    newLiteral = left.ToBoolean() ? left : right;
                }
                catch (InvalidCastException)
                {
                    // if we couldn't cast to bool, ignore
                }
            }

            return newLiteral;
        }
Ejemplo n.º 10
0
 public override void Visit(ConstantWrapper node)
 {
     if (node != null)
     {
         // measure
         if (node.PrimitiveType == PrimitiveType.Boolean)
         {
             if (m_measure)
             {
                 // if we are converting true/false literals to !0/!1, then
                 // a logical-not doesn't add or subtract anything. But if we aren't,
                 // we need to add/subtract the difference in the length between the
                 // "true" and "false" strings
                 if (!m_parser.Settings.MinifyCode
                     || !m_parser.Settings.IsModificationAllowed(TreeModifications.BooleanLiteralsToNotOperators))
                 {
                     // converting true to false adds a character, false to true subtracts
                     m_delta += node.ToBoolean() ? 1 : -1;
                 }
             }
             else
             {
                 // convert - just flip the boolean value
                 node.Value = !node.ToBoolean();
             }
         }
         else
         {
             // just the same typical operation as most other nodes for other types
             TypicalHandler(node);
         }
     }
 }