580 } 581 582 /** 583 * Checks whether a given target is a jump destination that lies outside a given split node 584 * @param splitNode the split node 585 * @param target the target node 586 * @return true if target resides outside the split node 587 */ 588 public boolean isExternalTarget(final SplitNode splitNode, final BreakableNode target) { 589 for (int i = sp; i-- > 0;) { 590 final LexicalContextNode next = stack[i]; 591 if (next == splitNode) { 592 return true; 593 } else if (next == target) { 594 return false; 595 } 596 } 597 throw new AssertionError(target + " was expected in lexical context " + LexicalContext.this + " but wasn't"); 598 } 599 600 @Override 601 public String toString() { 602 final StringBuffer sb = new StringBuffer(); 603 sb.append("[ "); 604 for (int i = 0; i < sp; i++) { 605 final Object node = stack[i]; 606 sb.append(node.getClass().getSimpleName()); 607 sb.append('@'); 608 sb.append(Debug.id(node)); 609 sb.append(':'); 610 if (node instanceof FunctionNode) { 611 final FunctionNode fn = (FunctionNode)node; 612 final Source source = fn.getSource(); 613 String src = source.toString(); 614 if (src.contains(File.pathSeparator)) { 615 src = src.substring(src.lastIndexOf(File.pathSeparator)); 616 } 617 src += ' '; 618 src += fn.getLineNumber(); 619 sb.append(src); | 580 } 581 582 /** 583 * Checks whether a given target is a jump destination that lies outside a given split node 584 * @param splitNode the split node 585 * @param target the target node 586 * @return true if target resides outside the split node 587 */ 588 public boolean isExternalTarget(final SplitNode splitNode, final BreakableNode target) { 589 for (int i = sp; i-- > 0;) { 590 final LexicalContextNode next = stack[i]; 591 if (next == splitNode) { 592 return true; 593 } else if (next == target) { 594 return false; 595 } 596 } 597 throw new AssertionError(target + " was expected in lexical context " + LexicalContext.this + " but wasn't"); 598 } 599 600 /** 601 * Checks whether the current context is inside a switch statement without explicit blocks (curly braces). 602 * @return true if in unprotected switch statement 603 */ 604 public boolean inUnprotectedSwitchContext() { 605 for (int i = sp; i > 0; i--) { 606 final LexicalContextNode next = stack[i]; 607 if (next instanceof Block) { 608 return stack[i - 1] instanceof SwitchNode; 609 } 610 } 611 return false; 612 } 613 614 @Override 615 public String toString() { 616 final StringBuffer sb = new StringBuffer(); 617 sb.append("[ "); 618 for (int i = 0; i < sp; i++) { 619 final Object node = stack[i]; 620 sb.append(node.getClass().getSimpleName()); 621 sb.append('@'); 622 sb.append(Debug.id(node)); 623 sb.append(':'); 624 if (node instanceof FunctionNode) { 625 final FunctionNode fn = (FunctionNode)node; 626 final Source source = fn.getSource(); 627 String src = source.toString(); 628 if (src.contains(File.pathSeparator)) { 629 src = src.substring(src.lastIndexOf(File.pathSeparator)); 630 } 631 src += ' '; 632 src += fn.getLineNumber(); 633 sb.append(src); |