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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.ast;
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;
19 public class Block extends Statement {
21 public Statement[] statements;
23 public int explicitDeclarations;
25 // the number of explicit declaration , used to create scope
26 public BlockScope scope;
28 public static final Block None = new Block(0);
30 public Block(int explicitDeclarations) {
31 this.explicitDeclarations = explicitDeclarations;
34 public FlowInfo analyseCode(BlockScope currentScope,
35 FlowContext flowContext, FlowInfo flowInfo) {
38 if (statements == null)
40 boolean didAlreadyComplain = false;
41 for (int i = 0, max = statements.length; i < max; i++) {
43 if (!flowInfo.complainIfUnreachable(stat = statements[i], scope,
44 didAlreadyComplain)) {
45 flowInfo = stat.analyseCode(scope, flowContext, flowInfo);
47 didAlreadyComplain = true;
53 public static final Block EmptyWith(int sourceStart, int sourceEnd) {
55 // return an empty block which position is s and e
56 Block bk = new Block(0);
57 bk.sourceStart = sourceStart;
58 bk.sourceEnd = sourceEnd;
63 * Code generation for a block
65 // public void generateCode(BlockScope currentScope, CodeStream codeStream)
68 // if ((bits & IsReachableMASK) == 0) {
71 // int pc = codeStream.position;
72 // if (statements != null) {
73 // for (int i = 0, max = statements.length; i < max; i++) {
74 // statements[i].generateCode(scope, codeStream);
76 // } // for local variable debug attributes
77 // if (scope != currentScope) { // was really associated with its own scope
78 // codeStream.exitUserScope(scope);
80 // codeStream.recordPositionsFrom(pc, this.sourceStart);
82 public boolean isEmptyBlock() {
84 return statements == null;
87 public StringBuffer printBody(int indent, StringBuffer output) {
89 if (this.statements == null)
91 for (int i = 0; i < statements.length; i++) {
92 statements[i].printStatement(indent + 1, output);
98 public StringBuffer printStatement(int indent, StringBuffer output) {
100 printIndent(indent, output);
101 output.append("{\n"); //$NON-NLS-1$
102 printBody(indent, output);
103 return printIndent(indent, output).append('}');
106 public void resolve(BlockScope upperScope) {
108 if (statements != null) {
109 scope = explicitDeclarations == 0 ? upperScope : new BlockScope(
110 upperScope, explicitDeclarations);
111 int i = 0, length = statements.length;
113 statements[i++].resolve(scope);
117 public void resolveUsing(BlockScope givenScope) {
119 // this optimized resolve(...) is sent only on none empty blocks
121 if (statements != null) {
122 int i = 0, length = statements.length;
124 statements[i++].resolve(scope);
128 public String toString(int tab) {
130 String s = tabString(tab);
131 if (this.statements == null) {
132 s += "{\n"; //$NON-NLS-1$
134 s += "}"; //$NON-NLS-1$
137 s += "{\n"; //$NON-NLS-1$
138 s += this.toStringStatements(tab);
140 s += "}"; //$NON-NLS-1$
144 public String toStringStatements(int tab) {
146 if (this.statements == null)
147 return ""; //$NON-NLS-1$
148 StringBuffer buffer = new StringBuffer();
149 for (int i = 0; i < statements.length; i++) {
150 buffer.append(statements[i].toString(tab + 1));
151 if (statements[i] instanceof Block) {
152 buffer.append("\n"); //$NON-NLS-1$
154 buffer.append(";\n"); //$NON-NLS-1$
158 return buffer.toString();
161 public void traverse(ASTVisitor visitor, BlockScope blockScope) {
163 if (visitor.visit(this, blockScope)) {
164 if (statements != null) {
165 int statementLength = statements.length;
166 for (int i = 0; i < statementLength; i++)
167 statements[i].traverse(visitor, scope);
170 visitor.endVisit(this, blockScope);
174 * Dispatch the call on its last statement.
176 public void branchChainTo(Label label) {
177 if (this.statements != null) {
178 this.statements[statements.length - 1].branchChainTo(label);