/******************************************************************************* | |
* Copyright (c) 2000, 2004 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 org.eclipse.wst.jsdt.internal.compiler.ast; | |
import org.eclipse.wst.jsdt.internal.compiler.ASTVisitor; | |
import org.eclipse.wst.jsdt.internal.compiler.codegen.*; | |
import org.eclipse.wst.jsdt.internal.compiler.flow.*; | |
import org.eclipse.wst.jsdt.internal.compiler.lookup.*; | |
public class Block extends Statement { | |
public Statement[] statements; | |
public int explicitDeclarations; | |
// the number of explicit declaration , used to create scope | |
public BlockScope scope; | |
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 = statements[i]; | |
if (!stat.complainIfUnreachable(flowInfo, scope, didAlreadyComplain)) { | |
flowInfo = stat.analyseCode(scope, flowContext, flowInfo); | |
} else { | |
didAlreadyComplain = true; | |
} | |
} | |
return flowInfo; | |
} | |
/** | |
* 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 ((this.bits & UndocumentedEmptyBlockMASK) != 0) { | |
upperScope.problemReporter().undocumentedEmptyBlock(this.sourceStart, this.sourceEnd); | |
} | |
if (statements != null) { | |
scope = | |
explicitDeclarations == 0 | |
? upperScope | |
: new BlockScope(upperScope, explicitDeclarations); | |
for (int i = 0, length = statements.length; i < length; i++) { | |
statements[i].resolve(scope); | |
} | |
} | |
} | |
public void resolveUsing(BlockScope givenScope) { | |
if ((this.bits & UndocumentedEmptyBlockMASK) != 0) { | |
givenScope.problemReporter().undocumentedEmptyBlock(this.sourceStart, this.sourceEnd); | |
} | |
// this optimized resolve(...) is sent only on none empty blocks | |
scope = givenScope; | |
if (statements != null) { | |
for (int i = 0, length = statements.length; i < length; i++) { | |
statements[i].resolve(scope); | |
} | |
} | |
} | |
public void traverse( | |
ASTVisitor visitor, | |
BlockScope blockScope) { | |
if (visitor.visit(this, blockScope)) { | |
if (statements != null) { | |
for (int i = 0, length = statements.length; i < length; 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); | |
} | |
} | |
} |