Esempio n. 1
0
        public JsNode VisitForeachStatement(ForeachStatement node)
        {
            if (node.InExpression != null)
            {
                var expRes = node.InExpression.Resolve();
                var et     = expRes.Type.GetDefinitionOrArrayType();
                //var et = node.expression.entity_typeref.GetEntityType();
                if (et != null)
                {
                    var jta = Sk.GetJsTypeAttribute(et);
                    if (jta != null && jta.NativeEnumerator)
                    {
                        var node2 = new JsForInStatement
                        {
                            Initializer = Js.Var(node.VariableName),
                            Member      = VisitExpression(node.InExpression),
                            Statement   = VisitStatement(node.EmbeddedStatement)
                        };
                        return(node2);
                    }
                    else if (jta != null && jta.NativeArrayEnumerator)
                    {
                        VariableIteratorCounter++;
                        var iteratorName    = "$i" + VariableIteratorCounter;
                        var lengthCacheName = "$l" + VariableIteratorCounter;
                        var exp2            = VisitExpression(node.InExpression);
                        var target          = exp2;
                        var targetCacheName = "$t" + VariableIteratorCounter;
                        if (exp2.NodeType != JsNodeType.MemberExpression || ((JsMemberExpression)exp2).PreviousMember != null)                        //is not simple name
                        {
                            target = Js.Member(targetCacheName);
                        }
                        var itemAccess = target.IndexerAccess(Js.Member(iteratorName));
                        var node2      = new JsForStatement();

                        node2.Condition = Js.Member(iteratorName).LessThan(Js.Member(lengthCacheName));
                        node2.Iterators = new List <JsStatement> {
                            Js.Member(iteratorName).PlusPlus().Statement(), Js.Member(node.VariableName).Assign(itemAccess).Statement()
                        };
                        if (target != exp2)                        //use target caching
                        {
                            node2.Initializers = new List <JsStatement> {
                                Js.Var(iteratorName, Js.Value(0)).AndVar(targetCacheName, exp2.Clone()).AndVar(lengthCacheName, target.Clone().Member("length")).AndVar(node.VariableName, itemAccess.Clone()).Statement()
                            };
                        }
                        else
                        {
                            node2.Initializers = new List <JsStatement> {
                                Js.Var(iteratorName, Js.Value(0)).AndVar(lengthCacheName, exp2.Clone().Member("length")).AndVar(node.VariableName, itemAccess.Clone()).Statement()
                            };
                        }
                        node2.Statement = VisitStatement(node.EmbeddedStatement);
                        return(node2);
                    }
                }
            }

            var iteratorName2 = "$it" + VariableIteratorCounter;

            VariableIteratorCounter++;
            var     node3               = Js.Var(iteratorName2, VisitExpression(node.InExpression).Member("GetEnumerator").Invoke()).Statement();
            var     whileNode           = Js.While(Js.Member(iteratorName2).Member("MoveNext").Invoke());
            var     getCurrentStatement = Js.Var(node.VariableName, Js.Member(iteratorName2).Member("get_Current").Invoke()).Statement();
            var     jsStatement         = VisitStatement(node.EmbeddedStatement);
            JsBlock block;

            if (jsStatement is JsBlock)
            {
                block = (JsBlock)jsStatement;
            }
            else
            {
                block = Js.Block().Add(jsStatement);
            }
            block.Statements.Insert(0, getCurrentStatement);
            whileNode.Statement = block;

            var block2 = Js.Block().Add(node3).Add(whileNode);

            return(block2);
        }