private LabeledStatement matchJumpLabelName() throws IOException { LabeledStatement label = null; if (peekTokenOrEOL() == Token.NAME) { consumeToken(); if (labelSet != null) { label = labelSet.get(ts.getString()); } if (label == null) { reportError("msg.undef.label"); } } return label; }
private void recordLabel(Label label, LabeledStatement bundle) throws IOException { // current token should be colon that primaryExpr left untouched if (peekToken() != Token.COLON) codeBug(); consumeToken(); String name = label.getName(); if (labelSet == null) { labelSet = new HashMap<String,LabeledStatement>(); } else { LabeledStatement ls = labelSet.get(name); if (ls != null) { if (compilerEnv.isIdeMode()) { Label dup = ls.getLabelByName(name); reportError("msg.dup.label", dup.getAbsolutePosition(), dup.getLength()); } reportError("msg.dup.label", label.getPosition(), label.getLength()); } } bundle.addLabel(label); labelSet.put(name, bundle); }
private Node transformLabeledStatement(LabeledStatement ls) { Label label = ls.getFirstLabel(); List<Label> labels = ls.getLabels(); decompiler.addName(label.getName()); if (labels.size() > 1) { // more than one label for (Label lb : labels.subList(1, labels.size())) { decompiler.addEOL(Token.COLON); decompiler.addName(lb.getName()); } } if (ls.getStatement().getType() == Token.BLOCK) { // reuse OBJECTLIT for ':' workaround, cf. transformObjectLiteral() decompiler.addToken(Token.OBJECTLIT); decompiler.addEOL(Token.LC); } else { decompiler.addEOL(Token.COLON); } Node statement = transform(ls.getStatement()); if (ls.getStatement().getType() == Token.BLOCK) { decompiler.addEOL(Token.RC); } // Make a target and put it _after_ the statement node. Add in the // LABEL node, so breaks get the right target. Node breakTarget = Node.newTarget(); Node block = new Node(Token.BLOCK, label, statement, breakTarget); label.target = breakTarget; return block; }
private BreakStatement breakStatement() throws IOException { if (currentToken != Token.BREAK) codeBug(); consumeToken(); int lineno = ts.lineno, pos = ts.tokenBeg, end = ts.tokenEnd; Name breakLabel = null; if (peekTokenOrEOL() == Token.NAME) { breakLabel = createNameNode(); end = getNodeEnd(breakLabel); } // matchJumpLabelName only matches if there is one LabeledStatement labels = matchJumpLabelName(); // always use first label as target Jump breakTarget = labels == null ? null : labels.getFirstLabel(); if (breakTarget == null && breakLabel == null) { if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) { if (breakLabel == null) { reportError("msg.bad.break", pos, end - pos); } } else { breakTarget = loopAndSwitchSet.get(loopAndSwitchSet.size() - 1); } } BreakStatement pn = new BreakStatement(pos, end - pos); pn.setBreakLabel(breakLabel); // can be null if it's a bad break in error-recovery mode if (breakTarget != null) pn.setBreakTarget(breakTarget); pn.setLineno(lineno); return pn; }
private ContinueStatement continueStatement() throws IOException { if (currentToken != Token.CONTINUE) codeBug(); consumeToken(); int lineno = ts.lineno, pos = ts.tokenBeg, end = ts.tokenEnd; Name label = null; if (peekTokenOrEOL() == Token.NAME) { label = createNameNode(); end = getNodeEnd(label); } // matchJumpLabelName only matches if there is one LabeledStatement labels = matchJumpLabelName(); Loop target = null; if (labels == null && label == null) { if (loopSet == null || loopSet.size() == 0) { reportError("msg.continue.outside"); } else { target = loopSet.get(loopSet.size() - 1); } } else { if (labels == null || !(labels.getStatement() instanceof Loop)) { reportError("msg.continue.nonloop", pos, end - pos); } target = labels == null ? null : (Loop)labels.getStatement(); } ContinueStatement pn = new ContinueStatement(pos, end - pos); if (target != null) // can be null in error-recovery mode pn.setTarget(target); pn.setLabel(label); pn.setLineno(lineno); return pn; }
private void print(LabeledStatement node) throws IOException { for (Label label : node.getLabels()) { writer.append(label.getName()).append(':').ws(); } print(node.getStatement()); }