Modified: 1216132 - Error when debugging eval()'d code
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / LabeledStatement.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.phpdt.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
14 import net.sourceforge.phpdt.internal.compiler.codegen.Label;
15 import net.sourceforge.phpdt.internal.compiler.flow.FlowContext;
16 import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
17 import net.sourceforge.phpdt.internal.compiler.flow.LabelFlowContext;
18 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
19
20 public class LabeledStatement extends Statement {
21
22         public Statement statement;
23
24         public char[] label;
25
26         public Label targetLabel;
27
28         // for local variables table attributes
29         int mergedInitStateIndex = -1;
30
31         /**
32          * LabeledStatement constructor comment.
33          */
34         public LabeledStatement(char[] l, Statement st, int s, int e) {
35
36                 this.statement = st;
37                 this.label = l;
38                 this.sourceStart = s;
39                 this.sourceEnd = e;
40         }
41
42         public FlowInfo analyseCode(BlockScope currentScope,
43                         FlowContext flowContext, FlowInfo flowInfo) {
44
45                 // need to stack a context to store explicit label, answer inits in case
46                 // of normal completion merged
47                 // with those relative to the exit path from break statement occurring
48                 // inside the labeled statement.
49                 if (statement == null) {
50                         return flowInfo;
51                 } else {
52                         LabelFlowContext labelContext;
53                         FlowInfo mergedInfo = statement.analyseCode(
54                                         currentScope,
55                                         (labelContext = new LabelFlowContext(flowContext, this,
56                                                         label, (targetLabel = new Label()), currentScope)),
57                                         flowInfo).mergedWith(labelContext.initsOnBreak);
58                         mergedInitStateIndex = currentScope.methodScope()
59                                         .recordInitializationStates(mergedInfo);
60                         return mergedInfo;
61                 }
62         }
63
64         public ASTNode concreteStatement() {
65
66                 // return statement.concreteStatement(); // for supporting nested
67                 // labels: a:b:c: someStatement (see 21912)
68                 return statement;
69         }
70
71         /**
72          * Code generation for labeled statement
73          * 
74          * may not need actual source positions recording
75          * 
76          * @param currentScope
77          *            net.sourceforge.phpdt.internal.compiler.lookup.BlockScope
78          * @param codeStream
79          *            net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
80          */
81         // public void generateCode(BlockScope currentScope, CodeStream codeStream)
82         // {
83         //              
84         // int pc = codeStream.position;
85         // if (targetLabel != null) {
86         // targetLabel.codeStream = codeStream;
87         // if (statement != null) {
88         // statement.generateCode(currentScope, codeStream);
89         // }
90         // targetLabel.place();
91         // }
92         // // May loose some local variable initializations : affecting the local
93         // variable attributes
94         // if (mergedInitStateIndex != -1) {
95         // codeStream.removeNotDefinitelyAssignedVariables(
96         // currentScope,
97         // mergedInitStateIndex);
98         // }
99         // codeStream.recordPositionsFrom(pc, this.sourceStart);
100         // }
101         public StringBuffer printStatement(int tab, StringBuffer output) {
102
103                 printIndent(tab, output).append(label).append(": "); //$NON-NLS-1$
104                 if (this.statement == null)
105                         output.append(';');
106                 else
107                         this.statement.printStatement(0, output);
108                 return output;
109         }
110
111         public void resolve(BlockScope scope) {
112
113                 statement.resolve(scope);
114         }
115
116         public String toString(int tab) {
117
118                 String s = tabString(tab);
119                 s += new String(label) + ": " + statement.toString(0); //$NON-NLS-1$
120                 return s;
121         }
122
123         public void traverse(ASTVisitor visitor, BlockScope blockScope) {
124
125                 if (visitor.visit(this, blockScope)) {
126                         statement.traverse(visitor, blockScope);
127                 }
128                 visitor.endVisit(this, blockScope);
129         }
130
131         public void resetStateForCodeGeneration() {
132                 if (this.targetLabel != null) {
133                         this.targetLabel.resetStateForCodeGeneration();
134                 }
135         }
136 }