1) Fixed issue #779: PHPEclipse reports error with a correct try/catch block
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / Block.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.lookup.BlockScope;
18
19 public class Block extends Statement {
20         public Statement[] statements;         // The array of statements found with this block
21
22         public int explicitDeclarations;
23
24         public BlockScope scope;               // The number of explicit declaration , used to create scope
25
26         public static final Block None = new Block(0);
27
28         public Block(int explicitDeclarations) {
29                 this.explicitDeclarations = explicitDeclarations;
30         }
31
32         public FlowInfo analyseCode(BlockScope currentScope,
33                         FlowContext flowContext, FlowInfo flowInfo) {
34
35                 // empty block
36                 if (statements == null)
37                         return flowInfo;
38                 boolean didAlreadyComplain = false;
39                 for (int i = 0, max = statements.length; i < max; i++) {
40                         Statement stat;
41                         if (!flowInfo.complainIfUnreachable(stat = statements[i], scope,
42                                         didAlreadyComplain)) {
43                                 flowInfo = stat.analyseCode(scope, flowContext, flowInfo);
44                         } else {
45                                 didAlreadyComplain = true;
46                         }
47                 }
48                 return flowInfo;
49         }
50
51         public static final Block EmptyWith(int sourceStart, int sourceEnd) {
52
53                 // return an empty block which position is s and e
54                 Block bk = new Block(0);
55                 bk.sourceStart = sourceStart;
56                 bk.sourceEnd = sourceEnd;
57                 return bk;
58         }
59
60         /**
61          * Code generation for a block
62          */
63         // public void generateCode(BlockScope currentScope, CodeStream codeStream)
64         // {
65         //
66         // if ((bits & IsReachableMASK) == 0) {
67         // return;
68         // }
69         // int pc = codeStream.position;
70         // if (statements != null) {
71         // for (int i = 0, max = statements.length; i < max; i++) {
72         // statements[i].generateCode(scope, codeStream);
73         // }
74         // } // for local variable debug attributes
75         // if (scope != currentScope) { // was really associated with its own scope
76         // codeStream.exitUserScope(scope);
77         // }
78         // codeStream.recordPositionsFrom(pc, this.sourceStart);
79         // }
80         public boolean isEmptyBlock() {
81
82                 return statements == null;
83         }
84
85         public StringBuffer printBody(int indent, StringBuffer output) {
86
87                 if (this.statements == null)
88                         return output;
89                 for (int i = 0; i < statements.length; i++) {
90                         statements[i].printStatement(indent + 1, output);
91                         output.append('\n');
92                 }
93                 return output;
94         }
95
96         public StringBuffer printStatement(int indent, StringBuffer output) {
97
98                 printIndent(indent, output);
99                 output.append("{\n"); //$NON-NLS-1$
100                 printBody(indent, output);
101                 return printIndent(indent, output).append('}');
102         }
103
104         public void resolve(BlockScope upperScope) {
105
106                 if (statements != null) {
107                         scope = explicitDeclarations == 0 ? upperScope : new BlockScope(
108                                         upperScope, explicitDeclarations);
109                         int i = 0, length = statements.length;
110                         while (i < length)
111                                 statements[i++].resolve(scope);
112                 }
113         }
114
115         public void resolveUsing(BlockScope givenScope) {
116
117                 // this optimized resolve(...) is sent only on none empty blocks
118                 scope = givenScope;
119                 if (statements != null) {
120                         int i = 0, length = statements.length;
121                         while (i < length)
122                                 statements[i++].resolve(scope);
123                 }
124         }
125
126         public String toString(int tab) {
127
128                 String s = tabString(tab);
129                 if (this.statements == null) {
130                         s += "{\n"; //$NON-NLS-1$
131                         s += tabString(tab);
132                         s += "}"; //$NON-NLS-1$
133                         return s;
134                 }
135                 s += "{\n"; //$NON-NLS-1$
136                 s += this.toStringStatements(tab);
137                 s += tabString(tab);
138                 s += "}"; //$NON-NLS-1$
139                 return s;
140         }
141
142         public String toStringStatements(int tab) {
143
144                 if (this.statements == null)
145                         return ""; //$NON-NLS-1$
146                 StringBuffer buffer = new StringBuffer();
147                 for (int i = 0; i < statements.length; i++) {
148                         buffer.append(statements[i].toString(tab + 1));
149                         if (statements[i] instanceof Block) {
150                                 buffer.append("\n"); //$NON-NLS-1$
151                         } else {
152                                 buffer.append(";\n"); //$NON-NLS-1$
153                         }
154                 }
155                 ;
156                 return buffer.toString();
157         }
158
159         public void traverse(ASTVisitor visitor, BlockScope blockScope) {
160
161                 if (visitor.visit(this, blockScope)) {
162                         if (statements != null) {
163                                 int statementLength = statements.length;
164                                 for (int i = 0; i < statementLength; i++)
165                                         statements[i].traverse(visitor, scope);
166                         }
167                 }
168                 visitor.endVisit(this, blockScope);
169         }
170
171         /**
172          * Dispatch the call on its last statement.
173          */
174         public void branchChainTo(Label label) {
175                 if (this.statements != null) {
176                         this.statements[statements.length - 1].branchChainTo(label);
177                 }
178         }
179
180 }