001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
011:
012: import org.eclipse.jdt.internal.compiler.ASTVisitor;
013: import org.eclipse.jdt.internal.compiler.flow.*;
014: import org.eclipse.jdt.internal.compiler.lookup.*;
015:
016: public class ContinueStatement extends BranchStatement {
017:
018: public ContinueStatement(char[] label, int sourceStart,
019: int sourceEnd) {
020: super (label, sourceStart, sourceEnd);
021: }
022:
023: public FlowInfo analyseCode(BlockScope currentScope,
024: FlowContext flowContext, FlowInfo flowInfo) {
025:
026: // here requires to generate a sequence of finally blocks invocations depending corresponding
027: // to each of the traversed try statements, so that execution will terminate properly.
028:
029: // lookup the label, this should answer the returnContext
030: FlowContext targetContext = (label == null) ? flowContext
031: .getTargetContextForDefaultContinue() : flowContext
032: .getTargetContextForContinueLabel(label);
033:
034: if (targetContext == null) {
035: if (label == null) {
036: currentScope.problemReporter().invalidContinue(this );
037: } else {
038: currentScope.problemReporter().undefinedLabel(this );
039: }
040: return flowInfo; // pretend it did not continue since no actual target
041: }
042:
043: if (targetContext == FlowContext.NotContinuableContext) {
044: currentScope.problemReporter().invalidContinue(this );
045: return flowInfo; // pretend it did not continue since no actual target
046: }
047: this .initStateIndex = currentScope.methodScope()
048: .recordInitializationStates(flowInfo);
049:
050: targetLabel = targetContext.continueLabel();
051: FlowContext traversedContext = flowContext;
052: int subCount = 0;
053: subroutines = new SubRoutineStatement[5];
054:
055: do {
056: SubRoutineStatement sub;
057: if ((sub = traversedContext.subroutine()) != null) {
058: if (subCount == subroutines.length) {
059: System
060: .arraycopy(
061: subroutines,
062: 0,
063: subroutines = new SubRoutineStatement[subCount * 2],
064: 0, subCount); // grow
065: }
066: subroutines[subCount++] = sub;
067: if (sub.isSubRoutineEscaping()) {
068: break;
069: }
070: }
071: traversedContext.recordReturnFrom(flowInfo
072: .unconditionalInits());
073:
074: if (traversedContext instanceof InsideSubRoutineFlowContext) {
075: ASTNode node = traversedContext.associatedNode;
076: if (node instanceof TryStatement) {
077: TryStatement tryStatement = (TryStatement) node;
078: flowInfo
079: .addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
080: }
081: } else if (traversedContext == targetContext) {
082: // only record continue info once accumulated through subroutines, and only against target context
083: targetContext.recordContinueFrom(flowContext, flowInfo);
084: break;
085: }
086: } while ((traversedContext = traversedContext.parent) != null);
087:
088: // resize subroutines
089: if (subCount != subroutines.length) {
090: System.arraycopy(subroutines, 0,
091: subroutines = new SubRoutineStatement[subCount], 0,
092: subCount);
093: }
094: return FlowInfo.DEAD_END;
095: }
096:
097: public StringBuffer printStatement(int tab, StringBuffer output) {
098: printIndent(tab, output).append("continue "); //$NON-NLS-1$
099: if (label != null)
100: output.append(label);
101: return output.append(';');
102: }
103:
104: public void traverse(ASTVisitor visitor, BlockScope blockScope) {
105: visitor.visit(this, blockScope);
106: visitor.endVisit(this, blockScope);
107: }
108: }
|