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); }