It's now possible to assign a value to a variable
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / LabeledStatement.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.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.IAbstractSyntaxTreeVisitor;
14 import net.sourceforge.phpdt.internal.compiler.codegen.*;
15 import net.sourceforge.phpdt.internal.compiler.flow.*;
16 import net.sourceforge.phpdt.internal.compiler.lookup.*;
17
18 public class LabeledStatement extends Statement {
19         
20         public Statement statement;
21         public char[] label;
22         public Label targetLabel;
23
24         // for local variables table attributes
25         int mergedInitStateIndex = -1;
26         
27         /**
28          * LabeledStatement constructor comment.
29          */
30         public LabeledStatement(char[] l, Statement st, int s, int e) {
31                 
32                 this.statement = st;
33                 this.label = l;
34                 this.sourceStart = s;
35                 this.sourceEnd = e;
36         }
37         
38         public FlowInfo analyseCode(
39                 BlockScope currentScope,
40                 FlowContext flowContext,
41                 FlowInfo flowInfo) {
42
43                 // need to stack a context to store explicit label, answer inits in case of normal completion merged
44                 // with those relative to the exit path from break statement occurring inside the labeled statement.
45                 if (statement == null) {
46                         return flowInfo;
47                 } else {
48                         LabelFlowContext labelContext;
49                         FlowInfo mergedInfo =
50                                 statement
51                                         .analyseCode(
52                                                 currentScope,
53                                                 (labelContext =
54                                                         new LabelFlowContext(
55                                                                 flowContext,
56                                                                 this,
57                                                                 label,
58                                                                 (targetLabel = new Label()),
59                                                                 currentScope)),
60                                                 flowInfo)
61                                         .mergedWith(labelContext.initsOnBreak);
62                         mergedInitStateIndex =
63                                 currentScope.methodScope().recordInitializationStates(mergedInfo);
64                         return mergedInfo;
65                 }
66         }
67         
68         public AstNode concreteStatement() {
69                 
70                 return statement.concreteStatement();
71         }
72         
73         /**
74          * Code generation for labeled statement
75          *
76          * may not need actual source positions recording
77          *
78          * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
79          * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
80          */
81         public void generateCode(BlockScope currentScope, CodeStream codeStream) {
82                 
83                 int pc = codeStream.position;
84                 if (targetLabel != null) {
85                         targetLabel.codeStream = codeStream;
86                         if (statement != null) {
87                                 statement.generateCode(currentScope, codeStream);
88                         }
89                         targetLabel.place();
90                 }
91                 // May loose some local variable initializations : affecting the local variable attributes
92                 if (mergedInitStateIndex != -1) {
93                         codeStream.removeNotDefinitelyAssignedVariables(
94                                 currentScope,
95                                 mergedInitStateIndex);
96                 }
97                 codeStream.recordPositionsFrom(pc, this.sourceStart);
98         }
99         
100         public void resolve(BlockScope scope) {
101                 
102                 statement.resolve(scope);
103         }
104         
105         public String toString(int tab) {
106
107                 String s = tabString(tab);
108                 s += new String(label) + ": " + statement.toString(0); //$NON-NLS-1$
109                 return s;
110         }
111
112         public void traverse(
113                 IAbstractSyntaxTreeVisitor visitor,
114                 BlockScope blockScope) {
115
116                 if (visitor.visit(this, blockScope)) {
117                         statement.traverse(visitor, blockScope);
118                 }
119                 visitor.endVisit(this, blockScope);
120         }
121
122         public void resetStateForCodeGeneration() {
123
124                 this.targetLabel.resetStateForCodeGeneration();
125         }
126 }