/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.ast; import net.sourceforge.phpdt.internal.compiler.ASTVisitor; import net.sourceforge.phpdt.internal.compiler.codegen.Label; import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; public class Block extends Statement { public Statement[] statements; // The array of statements found with this block public int explicitDeclarations; public BlockScope scope; // The number of explicit declaration , used to create scope public static final Block None = new Block(0); public Block(int explicitDeclarations) { this.explicitDeclarations = explicitDeclarations; } public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { // empty block if (statements == null) return flowInfo; boolean didAlreadyComplain = false; for (int i = 0, max = statements.length; i < max; i++) { Statement stat; if (!flowInfo.complainIfUnreachable(stat = statements[i], scope, didAlreadyComplain)) { flowInfo = stat.analyseCode(scope, flowContext, flowInfo); } else { didAlreadyComplain = true; } } return flowInfo; } public static final Block EmptyWith(int sourceStart, int sourceEnd) { // return an empty block which position is s and e Block bk = new Block(0); bk.sourceStart = sourceStart; bk.sourceEnd = sourceEnd; return bk; } /** * Code generation for a block */ // public void generateCode(BlockScope currentScope, CodeStream codeStream) // { // // if ((bits & IsReachableMASK) == 0) { // return; // } // int pc = codeStream.position; // if (statements != null) { // for (int i = 0, max = statements.length; i < max; i++) { // statements[i].generateCode(scope, codeStream); // } // } // for local variable debug attributes // if (scope != currentScope) { // was really associated with its own scope // codeStream.exitUserScope(scope); // } // codeStream.recordPositionsFrom(pc, this.sourceStart); // } public boolean isEmptyBlock() { return statements == null; } public StringBuffer printBody(int indent, StringBuffer output) { if (this.statements == null) return output; for (int i = 0; i < statements.length; i++) { statements[i].printStatement(indent + 1, output); output.append('\n'); } return output; } public StringBuffer printStatement(int indent, StringBuffer output) { printIndent(indent, output); output.append("{\n"); //$NON-NLS-1$ printBody(indent, output); return printIndent(indent, output).append('}'); } public void resolve(BlockScope upperScope) { if (statements != null) { scope = explicitDeclarations == 0 ? upperScope : new BlockScope( upperScope, explicitDeclarations); int i = 0, length = statements.length; while (i < length) statements[i++].resolve(scope); } } public void resolveUsing(BlockScope givenScope) { // this optimized resolve(...) is sent only on none empty blocks scope = givenScope; if (statements != null) { int i = 0, length = statements.length; while (i < length) statements[i++].resolve(scope); } } public String toString(int tab) { String s = tabString(tab); if (this.statements == null) { s += "{\n"; //$NON-NLS-1$ s += tabString(tab); s += "}"; //$NON-NLS-1$ return s; } s += "{\n"; //$NON-NLS-1$ s += this.toStringStatements(tab); s += tabString(tab); s += "}"; //$NON-NLS-1$ return s; } public String toStringStatements(int tab) { if (this.statements == null) return ""; //$NON-NLS-1$ StringBuffer buffer = new StringBuffer(); for (int i = 0; i < statements.length; i++) { buffer.append(statements[i].toString(tab + 1)); if (statements[i] instanceof Block) { buffer.append("\n"); //$NON-NLS-1$ } else { buffer.append(";\n"); //$NON-NLS-1$ } } ; return buffer.toString(); } public void traverse(ASTVisitor visitor, BlockScope blockScope) { if (visitor.visit(this, blockScope)) { if (statements != null) { int statementLength = statements.length; for (int i = 0; i < statementLength; i++) statements[i].traverse(visitor, scope); } } visitor.endVisit(this, blockScope); } /** * Dispatch the call on its last statement. */ public void branchChainTo(Label label) { if (this.statements != null) { this.statements[statements.length - 1].branchChainTo(label); } } }