Makefile fixup
[org.ibex.tool.git] / repo / org.ibex.tool / src / org / eclipse / jdt / internal / compiler / ast / LabeledStatement.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 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 org.eclipse.jdt.internal.compiler.ast;
12
13 import org.eclipse.jdt.internal.compiler.ASTVisitor;
14 import org.eclipse.jdt.internal.compiler.codegen.*;
15 import org.eclipse.jdt.internal.compiler.flow.*;
16 import org.eclipse.jdt.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[] label, Statement statement, int sourceStart, int sourceEnd) {
31                 
32                 this.statement = statement;
33                 // remember useful empty statement
34                 if (statement instanceof EmptyStatement) statement.bits |= IsUsefulEmptyStatementMASK;
35                 this.label = label;
36                 this.sourceStart = sourceStart;
37                 this.sourceEnd = sourceEnd;
38         }
39         
40         public FlowInfo analyseCode(
41                 BlockScope currentScope,
42                 FlowContext flowContext,
43                 FlowInfo flowInfo) {
44
45                 // need to stack a context to store explicit label, answer inits in case of normal completion merged
46                 // with those relative to the exit path from break statement occurring inside the labeled statement.
47                 if (statement == null) {
48                         return flowInfo;
49                 } else {
50                         LabelFlowContext labelContext;
51                         FlowInfo mergedInfo =
52                                 statement
53                                         .analyseCode(
54                                                 currentScope,
55                                                 (labelContext =
56                                                         new LabelFlowContext(
57                                                                 flowContext,
58                                                                 this,
59                                                                 label,
60                                                                 (targetLabel = new Label()),
61                                                                 currentScope)),
62                                                 flowInfo)
63                                         .mergedWith(labelContext.initsOnBreak);
64                         mergedInitStateIndex =
65                                 currentScope.methodScope().recordInitializationStates(mergedInfo);
66                         return mergedInfo;
67                 }
68         }
69         
70         public ASTNode concreteStatement() {
71                 
72                 // return statement.concreteStatement(); // for supporting nested labels:   a:b:c: someStatement (see 21912)
73                 return statement;
74         }
75         
76         /**
77          * Code generation for labeled statement
78          *
79          * may not need actual source positions recording
80          *
81          * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
82          * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
83          */
84         public void generateCode(BlockScope currentScope, CodeStream codeStream) {
85                 
86                 int pc = codeStream.position;
87                 if (targetLabel != null) {
88                         targetLabel.initialize(codeStream);
89                         if (statement != null) {
90                                 statement.generateCode(currentScope, codeStream);
91                         }
92                         targetLabel.place();
93                 }
94                 // May loose some local variable initializations : affecting the local variable attributes
95                 if (mergedInitStateIndex != -1) {
96                         codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
97                         codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
98                 }
99                 codeStream.recordPositionsFrom(pc, this.sourceStart);
100         }
101         
102         public StringBuffer printStatement(int tab, StringBuffer output) {
103
104                 printIndent(tab, output).append(label).append(": "); //$NON-NLS-1$
105                 if (this.statement == null) 
106                         output.append(';');
107                 else 
108                         this.statement.printStatement(0, output); 
109                 return output;
110         }
111         
112         public void resolve(BlockScope scope) {
113                 
114                 if (this.statement != null) {
115                         this.statement.resolve(scope);
116                 }
117         }
118
119
120         public void traverse(
121                 ASTVisitor visitor,
122                 BlockScope blockScope) {
123
124                 if (visitor.visit(this, blockScope)) {
125                         if (this.statement != null) this.statement.traverse(visitor, blockScope);
126                 }
127                 visitor.endVisit(this, blockScope);
128         }
129 }