001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
011:
012: import org.eclipse.jdt.internal.compiler.ASTVisitor;
013: import org.eclipse.jdt.internal.compiler.codegen.*;
014: import org.eclipse.jdt.internal.compiler.flow.*;
015: import org.eclipse.jdt.internal.compiler.lookup.*;
016:
017: public class Block extends Statement {
018:
019: public Statement[] statements;
020: public int explicitDeclarations;
021: // the number of explicit declaration , used to create scope
022: public BlockScope scope;
023:
024: public Block(int explicitDeclarations) {
025: this .explicitDeclarations = explicitDeclarations;
026: }
027:
028: public FlowInfo analyseCode(BlockScope currentScope,
029: FlowContext flowContext, FlowInfo flowInfo) {
030:
031: // empty block
032: if (statements == null)
033: return flowInfo;
034: boolean didAlreadyComplain = false;
035: for (int i = 0, max = statements.length; i < max; i++) {
036: Statement stat = statements[i];
037: if (!stat.complainIfUnreachable(flowInfo, scope,
038: didAlreadyComplain)) {
039: flowInfo = stat.analyseCode(scope, flowContext,
040: flowInfo);
041: } else {
042: didAlreadyComplain = true;
043: }
044: }
045: return flowInfo;
046: }
047:
048: /**
049: * Code generation for a block
050: */
051: public void generateCode(BlockScope currentScope,
052: CodeStream codeStream) {
053:
054: if ((bits & IsReachable) == 0) {
055: return;
056: }
057: int pc = codeStream.position;
058: if (statements != null) {
059: for (int i = 0, max = statements.length; i < max; i++) {
060: statements[i].generateCode(scope, codeStream);
061: }
062: } // for local variable debug attributes
063: if (scope != currentScope) { // was really associated with its own scope
064: codeStream.exitUserScope(scope);
065: }
066: codeStream.recordPositionsFrom(pc, this .sourceStart);
067: }
068:
069: public boolean isEmptyBlock() {
070:
071: return statements == null;
072: }
073:
074: public StringBuffer printBody(int indent, StringBuffer output) {
075:
076: if (this .statements == null)
077: return output;
078: for (int i = 0; i < statements.length; i++) {
079: statements[i].printStatement(indent + 1, output);
080: output.append('\n');
081: }
082: return output;
083: }
084:
085: public StringBuffer printStatement(int indent, StringBuffer output) {
086:
087: printIndent(indent, output);
088: output.append("{\n"); //$NON-NLS-1$
089: printBody(indent, output);
090: return printIndent(indent, output).append('}');
091: }
092:
093: public void resolve(BlockScope upperScope) {
094:
095: if ((this .bits & UndocumentedEmptyBlock) != 0) {
096: upperScope.problemReporter().undocumentedEmptyBlock(
097: this .sourceStart, this .sourceEnd);
098: }
099: if (statements != null) {
100: scope = explicitDeclarations == 0 ? upperScope
101: : new BlockScope(upperScope, explicitDeclarations);
102: for (int i = 0, length = statements.length; i < length; i++) {
103: statements[i].resolve(scope);
104: }
105: }
106: }
107:
108: public void resolveUsing(BlockScope givenScope) {
109:
110: if ((this .bits & UndocumentedEmptyBlock) != 0) {
111: givenScope.problemReporter().undocumentedEmptyBlock(
112: this .sourceStart, this .sourceEnd);
113: }
114: // this optimized resolve(...) is sent only on none empty blocks
115: scope = givenScope;
116: if (statements != null) {
117: for (int i = 0, length = statements.length; i < length; i++) {
118: statements[i].resolve(scope);
119: }
120: }
121: }
122:
123: public void traverse(ASTVisitor visitor, BlockScope blockScope) {
124:
125: if (visitor.visit(this , blockScope)) {
126: if (statements != null) {
127: for (int i = 0, length = statements.length; i < length; i++)
128: statements[i].traverse(visitor, scope);
129: }
130: }
131: visitor.endVisit(this , blockScope);
132: }
133:
134: /**
135: * Dispatch the call on its last statement.
136: */
137: public void branchChainTo(BranchLabel label) {
138: if (this .statements != null) {
139: this .statements[statements.length - 1].branchChainTo(label);
140: }
141: }
142:
143: }
|