improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / internal / compiler / ast / BreakStatement.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpeclipse.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
14 import net.sourceforge.phpdt.internal.compiler.flow.FlowContext;
15 import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
16 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
17
18 public class BreakStatement extends BranchStatement {
19         
20         public BreakStatement(char[] label, int sourceStart, int e) {
21                 super(label, sourceStart, e);
22         }
23
24         public FlowInfo analyseCode(
25                 BlockScope currentScope,
26                 FlowContext flowContext,
27                 FlowInfo flowInfo) {
28
29                 // here requires to generate a sequence of finally blocks invocations depending corresponding
30                 // to each of the traversed try statements, so that execution will terminate properly.
31
32                 // lookup the label, this should answer the returnContext
33                 FlowContext targetContext = (label == null) 
34                         ? flowContext.getTargetContextForDefaultBreak()
35                         : flowContext.getTargetContextForBreakLabel(label);
36
37                 if (targetContext == null) {
38                         if (label == null) {
39                                 currentScope.problemReporter().invalidBreak(this);
40                         } else {
41                                 currentScope.problemReporter().undefinedLabel(this); 
42                         }
43                         return flowInfo; // pretend it did not break since no actual target
44                 }
45                 
46                 targetLabel = targetContext.breakLabel();
47                 FlowContext traversedContext = flowContext;
48                 int subIndex = 0, maxSub = 5;
49                 subroutines = new ASTNode[maxSub];
50                 
51                 do {
52                         ASTNode sub;
53                         if ((sub = traversedContext.subRoutine()) != null) {
54                                 if (subIndex == maxSub) {
55                                         System.arraycopy(subroutines, 0, (subroutines = new ASTNode[maxSub*=2]), 0, subIndex); // grow
56                                 }
57                                 subroutines[subIndex++] = sub;
58                                 if (sub.cannotReturn()) {
59                                         break;
60                                 }
61                         }
62                         traversedContext.recordReturnFrom(flowInfo.unconditionalInits());
63
64                         ASTNode node;
65                         if ((node = traversedContext.associatedNode) instanceof TryStatement) {
66                                 TryStatement tryStatement = (TryStatement) node;
67                                 flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits                 
68                         } else if (traversedContext == targetContext) {
69                                 // only record break info once accumulated through subroutines, and only against target context
70                                 targetContext.recordBreakFrom(flowInfo);
71                                 break;
72                         }
73                 } while ((traversedContext = traversedContext.parent) != null);
74                 
75                 // resize subroutines
76                 if (subIndex != maxSub) {
77                         System.arraycopy(subroutines, 0, (subroutines = new ASTNode[subIndex]), 0, subIndex);
78                 }
79                 return FlowInfo.DEAD_END;
80         }
81         
82         public String toString(int tab) {
83
84                 String s = tabString(tab);
85                 s += "break "; //$NON-NLS-1$
86                 if (label != null)
87                         s += new String(label);
88                 return s;
89         }
90         public StringBuffer printStatement(int tab, StringBuffer output) {
91
92                 printIndent(tab, output).append("break "); //$NON-NLS-1$
93                 if (label != null) output.append(label);
94                 return output.append(';');
95         }
96         public void traverse(
97                 IAbstractSyntaxTreeVisitor visitor,
98                 BlockScope blockscope) {
99
100                 visitor.visit(this, blockscope);
101                 visitor.endVisit(this, blockscope);
102         }
103 }