use of org.mozilla.javascript.ast.ArrayComprehensionLoop in project HL4A by HL4A.
the class IRFactory method arrayCompTransformHelper.
private Node arrayCompTransformHelper(ArrayComprehension node, String arrayName) {
decompiler.addToken(Token.LB);
int lineno = node.getLineno();
Node expr = transform(node.getResult());
List<ArrayComprehensionLoop> loops = node.getLoops();
int numLoops = loops.size();
// Walk through loops, collecting and defining their iterator symbols.
Node[] iterators = new Node[numLoops];
Node[] iteratedObjs = new Node[numLoops];
for (int i = 0; i < numLoops; i++) {
ArrayComprehensionLoop acl = loops.get(i);
decompiler.addName(" ");
decompiler.addToken(Token.FOR);
if (acl.isForEach()) {
decompiler.addName("each ");
}
decompiler.addToken(Token.LP);
AstNode iter = acl.getIterator();
String name = null;
if (iter.getType() == Token.NAME) {
name = iter.getString();
decompiler.addName(name);
} else {
// destructuring assignment
decompile(iter);
name = currentScriptOrFn.getNextTempName();
defineSymbol(Token.LP, name, false);
expr = createBinary(Token.COMMA, createAssignment(Token.ASSIGN, iter, createName(name)), expr);
}
Node init = createName(name);
// Define as a let since we want the scope of the variable to
// be restricted to the array comprehension
defineSymbol(Token.LET, name, false);
iterators[i] = init;
if (acl.isForOf()) {
decompiler.addName("of ");
} else {
decompiler.addToken(Token.IN);
}
iteratedObjs[i] = transform(acl.getIteratedObject());
decompiler.addToken(Token.RP);
}
// generate code for tmpArray.push(body)
Node call = createCallOrNew(Token.CALL, createPropertyGet(createName(arrayName), null, "push", 0));
Node body = new Node(Token.EXPR_VOID, call, lineno);
if (node.getFilter() != null) {
decompiler.addName(" ");
decompiler.addToken(Token.IF);
decompiler.addToken(Token.LP);
body = createIf(transform(node.getFilter()), body, null, lineno);
decompiler.addToken(Token.RP);
}
// Now walk loops in reverse to build up the body statement.
int pushed = 0;
try {
for (int i = numLoops - 1; i >= 0; i--) {
ArrayComprehensionLoop acl = loops.get(i);
Scope loop = createLoopNode(// no label
null, acl.getLineno());
pushScope(loop);
pushed++;
body = createForIn(Token.LET, loop, iterators[i], iteratedObjs[i], body, acl.isForEach(), acl.isForOf());
}
} finally {
for (int i = 0; i < pushed; i++) {
popScope();
}
}
decompiler.addToken(Token.RB);
// Now that we've accumulated any destructuring forms,
// add expr to the call node; it's pushed on each iteration.
call.addChildToBack(expr);
return body;
}
use of org.mozilla.javascript.ast.ArrayComprehensionLoop in project HL4A by HL4A.
the class Parser method arrayComprehension.
/**
* Parse a JavaScript 1.7 Array comprehension.
* @param result the first expression after the opening left-bracket
* @param pos start of LB token that begins the array comprehension
* @return the array comprehension or an error node
*/
private AstNode arrayComprehension(AstNode result, int pos) throws IOException {
List<ArrayComprehensionLoop> loops = new ArrayList<ArrayComprehensionLoop>();
while (peekToken() == Token.FOR) {
loops.add(arrayComprehensionLoop());
}
int ifPos = -1;
ConditionData data = null;
if (peekToken() == Token.IF) {
consumeToken();
ifPos = ts.tokenBeg - pos;
data = condition();
}
mustMatchToken(Token.RB, "msg.no.bracket.arg");
ArrayComprehension pn = new ArrayComprehension(pos, ts.tokenEnd - pos);
pn.setResult(result);
pn.setLoops(loops);
if (data != null) {
pn.setIfPosition(ifPos);
pn.setFilter(data.condition);
pn.setFilterLp(data.lp - pos);
pn.setFilterRp(data.rp - pos);
}
return pn;
}
use of org.mozilla.javascript.ast.ArrayComprehensionLoop in project HL4A by HL4A.
the class Parser method arrayComprehensionLoop.
private ArrayComprehensionLoop arrayComprehensionLoop() throws IOException {
if (nextToken() != Token.FOR)
codeBug();
int pos = ts.tokenBeg;
int eachPos = -1, lp = -1, rp = -1, inPos = -1;
boolean isForIn = false, isForOf = false;
ArrayComprehensionLoop pn = new ArrayComprehensionLoop(pos);
pushScope(pn);
try {
if (matchToken(Token.NAME)) {
if (ts.getString().equals("each")) {
eachPos = ts.tokenBeg - pos;
} else {
reportError("msg.no.paren.for");
}
}
if (mustMatchToken(Token.LP, "msg.no.paren.for")) {
lp = ts.tokenBeg - pos;
}
AstNode iter = null;
switch(peekToken()) {
case Token.LB:
case Token.LC:
// handle destructuring assignment
iter = destructuringPrimaryExpr();
markDestructuring(iter);
break;
case Token.NAME:
consumeToken();
iter = createNameNode();
break;
default:
reportError("msg.bad.var");
}
// be restricted to the array comprehension
if (iter.getType() == Token.NAME) {
defineSymbol(Token.LET, ts.getString(), true);
}
switch(nextToken()) {
case Token.IN:
inPos = ts.tokenBeg - pos;
isForIn = true;
break;
case Token.NAME:
if ("of".equals(ts.getString())) {
if (eachPos != -1) {
reportError("msg.invalid.for.each");
}
inPos = ts.tokenBeg - pos;
isForOf = true;
break;
}
// fallthru
default:
reportError("msg.in.after.for.name");
}
AstNode obj = expr();
if (mustMatchToken(Token.RP, "msg.no.paren.for.ctrl"))
rp = ts.tokenBeg - pos;
pn.setLength(ts.tokenEnd - pos);
pn.setIterator(iter);
pn.setIteratedObject(obj);
pn.setInPosition(inPos);
pn.setEachPosition(eachPos);
pn.setIsForEach(eachPos != -1);
pn.setParens(lp, rp);
pn.setIsForOf(isForOf);
return pn;
} finally {
popScope();
}
}
Aggregations