Example #1
0
        public void NodeSelfAndChildrenRecursive () {
            var fl3 = new JSForLoop(
                new JSNullStatement(), new JSNullExpression(), new JSNullStatement(),
                new JSExpressionStatement(new JSStringIdentifier("loop3 iteration"))
            );
            fl3.Index = 2;

            var fl2 = new JSForLoop(
                new JSNullStatement(), new JSNullExpression(), new JSNullStatement(),
                new JSExpressionStatement(new JSStringIdentifier("loop2 iteration"))
            );
            fl2.Index = 1;

            var fl1 = new JSForLoop(
                new JSNullStatement(), new JSNullExpression(), new JSNullStatement(),
                fl2
            );
            fl1.Index = 0;

            var tree = new JSBlockStatement(
                fl1,
                fl3
            );

            DumpNodeSequence(tree.SelfAndChildrenRecursive);
        }
Example #2
0
        public void VisitNode(JSForLoop fl)
        {
            CheckLabel(fl);

            BlockStack.Push(new EnclosingBlockEntry {
                Block      = fl,
                ParentNode = ParentNode,
                Depth      = BlockStack.Count
            });

            try {
                VisitChildren(fl);
            } finally {
                BlockStack.Pop();
            }
        }
Example #3
0
        public void VisitNode(JSForLoop fl)
        {
            SynthesizeLoopLabel(fl);

            if (fl.Initializer != null)
            {
                Formatter.ConditionalNewLine();
                Formatter.NewLine();
                Comment("for ({0}; ...)", fl.Initializer);
                Visit(fl.Initializer);
            }

            Formatter.ConditionalNewLine();
            Formatter.NewLine();
            EmitLabelledBlock(
                IndexToLabel(fl.Index),
                (__) =>
                __.WriteSExpr(
                    "loop",
                    (_) => {
                Comment("for (...; {0}; ...)", fl.Condition);
                var synthetic = new JSIfStatement(
                    fl.Condition,
                    new JSNullStatement(),
                    new JSExpressionStatement(new JSBreakExpression {
                    TargetLoop = fl.Index
                })
                    );
                Visit(synthetic);

                _.ConditionalNewLine();
                _.NewLine();
                Comment("for (...) {{ ");
                EmitBlockInterior(fl.Statements);

                if (fl.Increment != null)
                {
                    _.ConditionalNewLine();
                    _.NewLine();
                    Comment("for (...; ...; {0})", fl.Increment);
                    Visit(fl.Increment);
                }
            },
                    true, true
                    )
                );
        }
Example #4
0
        public void VisitNode(JSForLoop loop)
        {
            Output.NewLine();

            BlockStack.Push(BlockType.ForHeader);
            WriteLoopLabel(loop);

            Output.WriteRaw("for");
            Output.Space();

            Output.LPar();

            if ((loop.Initializer != null) && !loop.Initializer.IsNull)
            {
                Visit(loop.Initializer);
            }
            Output.Semicolon(false);

            Visit(loop.Condition);
            Output.Semicolon(false);

            if ((loop.Increment != null) && !loop.Increment.IsNull)
            {
                Visit(loop.Increment);
            }

            Output.RPar();
            Output.Space();

            BlockStack.Pop();
            BlockStack.Push(BlockType.ForBody);

            VisitNode((JSBlockStatement)loop, true);

            BlockStack.Pop();
        }
Example #5
0
        public void VisitNode(JSWhileLoop whileLoop)
        {
            JSVariable       initVariable = null, lastVariable = null;
            JSBinaryOperator initOperator = null;
            JSExpression     initValue    = null;

            var prevEStmt = PreviousSibling as JSExpressionStatement;
            var prevVDS   = PreviousSibling as JSVariableDeclarationStatement;

            if (prevEStmt != null)
            {
                var boe = prevEStmt.Expression as JSBinaryOperatorExpression;
                if (
                    (boe != null) &&
                    (boe.Operator is JSAssignmentOperator) &&
                    (boe.Left is JSVariable)
                    )
                {
                    initVariable = (JSVariable)boe.Left;
                    initOperator = boe.Operator;
                    initValue    = boe.Right;
                }
            }
            else if (prevVDS != null)
            {
                var decl = prevVDS.Declarations.FirstOrDefault(
                    (d) => !d.IsNull
                    );
                if (decl != null)
                {
                    initVariable = (JSVariable)decl.Left;
                    initOperator = decl.Operator;
                    initValue    = decl.Right;
                }
            }

            var lastStatement = whileLoop.Statements.LastOrDefault();

            while ((lastStatement != null) && (lastStatement.GetType() == typeof(JSBlockStatement)))
            {
                lastStatement = ((JSBlockStatement)lastStatement).Statements.LastOrDefault();
            }

            var lastExpressionStatement = lastStatement as JSExpressionStatement;

            if (lastExpressionStatement != null)
            {
                var lastUoe = lastExpressionStatement.Expression as JSUnaryOperatorExpression;
                var lastBoe = lastExpressionStatement.Expression as JSBinaryOperatorExpression;

                if ((lastUoe != null) && (lastUoe.Operator is JSUnaryMutationOperator))
                {
                    lastVariable = lastUoe.Expression as JSVariable;
                }
                else if ((lastBoe != null) && (lastBoe.Operator is JSAssignmentOperator))
                {
                    lastVariable = lastBoe.Left as JSVariable;
                    if (
                        (lastVariable != null) &&
                        !lastBoe.Right.SelfAndChildrenRecursive.Any(
                            (n) => lastVariable.Equals(n)
                            )
                        )
                    {
                        lastVariable = null;
                    }
                }
            }

            var lastIfStatement = lastStatement as JSIfStatement;

            if (
                (lastIfStatement != null) &&
                whileLoop.Condition is JSBooleanLiteral &&
                ((JSBooleanLiteral)whileLoop.Condition).Value
                )
            {
                var innerStatement = lastIfStatement.TrueClause;
                while (innerStatement is JSBlockStatement)
                {
                    var bs = (JSBlockStatement)innerStatement;
                    if (bs.Statements.Count != 1)
                    {
                        innerStatement = null;
                        break;
                    }

                    innerStatement = bs.Statements[0];
                }

                var eStmt = innerStatement as JSExpressionStatement;

                if (eStmt != null)
                {
                    var breakExpr = eStmt.Expression as JSBreakExpression;
                    if ((breakExpr != null) && (breakExpr.TargetLoop == whileLoop.Index))
                    {
                        whileLoop.ReplaceChildRecursive(lastIfStatement, new JSNullStatement());

                        var doLoop = new JSDoLoop(
                            new JSUnaryOperatorExpression(JSOperator.LogicalNot, lastIfStatement.Condition, TypeSystem.Boolean),
                            whileLoop.Statements.ToArray()
                            );
                        doLoop.Index = whileLoop.Index;

                        ParentNode.ReplaceChild(whileLoop, doLoop);
                        VisitChildren(doLoop);
                        return;
                    }
                }
            }

            bool cantBeFor = false;

            if ((initVariable != null) && (lastVariable != null) &&
                !initVariable.Equals(lastVariable)
                )
            {
                cantBeFor = true;
            }
            else if ((initVariable ?? lastVariable) == null)
            {
                cantBeFor = true;
            }
            else if (!whileLoop.Condition.SelfAndChildrenRecursive.Any(
                         (n) => (initVariable ?? lastVariable).Equals(n)
                         ))
            {
                cantBeFor = true;
            }
            else if (
                !PostSwitchTransform && (
                    (lastStatement is JSSwitchStatement) ||
                    (lastStatement is JSLabelGroupStatement)
                    )
                )
            {
                cantBeFor = true;
            }

            if (!cantBeFor)
            {
                JSStatement initializer = null, increment = null;

                if (initVariable != null)
                {
                    initializer = PreviousSibling as JSStatement;

                    ParentNode.ReplaceChild(PreviousSibling, new JSNullStatement());
                }

                if (lastVariable != null)
                {
                    increment = lastExpressionStatement;

                    whileLoop.ReplaceChildRecursive(lastExpressionStatement, new JSNullStatement());
                }

                var forLoop = new JSForLoop(
                    initializer, whileLoop.Condition, increment,
                    whileLoop.Statements.ToArray()
                    );
                forLoop.Index = whileLoop.Index;

                ParentNode.ReplaceChild(whileLoop, forLoop);
                VisitChildren(forLoop);
            }
            else
            {
                VisitChildren(whileLoop);
            }
        }
        private JSForLoop ReplaceWhileLoopAndEnumerator(JSWhileLoop wl, JSExpression backingStore, JSExpression enumerator, TypeInfo enumeratorType, string arrayMember, string lengthMember)
        {
            var loopId             = _NextLoopId++;
            var arrayVariableName  = String.Format("a${0:x}", loopId);
            var indexVariableName  = String.Format("i${0:x}", loopId);
            var lengthVariableName = String.Format("l${0:x}", loopId);

            var currentPropertyReference = enumeratorType.Definition.Properties.First((p) => p.Name == "Current");
            var currentPropertyInfo      = enumeratorType.Source.GetProperty(currentPropertyReference);

            var itemType  = currentPropertyInfo.ReturnType;
            var arrayType = new ArrayType(itemType);

            var arrayVariable = new JSVariable(
                arrayVariableName, arrayType, Function.Method.Reference,
                JSDotExpression.New(backingStore, new JSStringIdentifier(arrayMember, arrayType))
                );
            var indexVariable = new JSVariable(
                indexVariableName, TypeSystem.Int32, Function.Method.Reference,
                JSLiteral.New(0)
                );
            var lengthVariable = new JSVariable(
                lengthVariableName, TypeSystem.Int32, Function.Method.Reference,
                JSDotExpression.New(backingStore, new JSStringIdentifier(lengthMember, TypeSystem.Int32))
                );

            var initializer = new JSVariableDeclarationStatement(
                new JSBinaryOperatorExpression(
                    JSOperator.Assignment, arrayVariable, arrayVariable.DefaultValue, arrayVariable.IdentifierType
                    ),
                new JSBinaryOperatorExpression(
                    JSOperator.Assignment, indexVariable, indexVariable.DefaultValue, indexVariable.IdentifierType
                    ),
                new JSBinaryOperatorExpression(
                    JSOperator.Assignment, lengthVariable, lengthVariable.DefaultValue, lengthVariable.IdentifierType
                    )
                );

            var condition = new JSBinaryOperatorExpression(
                JSOperator.LessThan,
                indexVariable, lengthVariable, TypeSystem.Boolean
                );

            var increment = new JSUnaryOperatorExpression(
                JSOperator.PostIncrement,
                indexVariable, TypeSystem.Int32
                );

            var result = new JSForLoop(
                initializer, condition, new JSExpressionStatement(increment),
                wl.Statements.ToArray()
                );

            result.Index = wl.Index;

            new PropertyAccessReplacer(
                enumerator, new JSProperty(currentPropertyReference, currentPropertyInfo),
                new JSIndexerExpression(
                    arrayVariable, indexVariable,
                    itemType
                    )
                ).Visit(result);

            return(result);
        }