1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.ast;
13 import net.sourceforge.phpdt.internal.compiler.*;
14 import net.sourceforge.phpdt.internal.compiler.impl.*;
15 import net.sourceforge.phpdt.internal.compiler.lookup.*;
16 import net.sourceforge.phpdt.internal.compiler.problem.*;
17 import net.sourceforge.phpdt.internal.compiler.util.*;
19 public class CompilationUnitDeclaration
21 implements ProblemSeverities, ReferenceContext {
23 public ImportReference currentPackage;
24 public ImportReference[] imports;
25 public TypeDeclaration[] types;
26 //public char[][] name;
28 public boolean ignoreFurtherInvestigation = false; // once pointless to investigate due to errors
29 public boolean ignoreMethodBodies = false;
30 public CompilationUnitScope scope;
31 public ProblemReporter problemReporter;
32 public CompilationResult compilationResult;
34 private LocalTypeBinding[] allLocalTypes;
35 public boolean isPropagatingInnerClassEmulation;
37 public CompilationUnitDeclaration(
38 ProblemReporter problemReporter,
39 CompilationResult compilationResult,
42 this.problemReporter = problemReporter;
43 this.compilationResult = compilationResult;
45 //by definition of a compilation unit....
47 sourceEnd = sourceLength - 1;
52 * We cause the compilation task to abort to a given extent.
54 public void abort(int abortLevel) {
58 throw new AbortType(compilationResult);
60 throw new AbortMethod(compilationResult);
62 throw new AbortCompilationUnit(compilationResult);
67 * Dispatch code analysis AND request saturation of inner emulation
69 public void analyseCode() {
71 if (ignoreFurtherInvestigation)
75 for (int i = 0, count = types.length; i < count; i++) {
76 types[i].analyseCode(scope);
79 // request inner emulation propagation
80 propagateInnerEmulationForAllLocalTypes();
81 } catch (AbortCompilationUnit e) {
82 this.ignoreFurtherInvestigation = true;
88 * When unit result is about to be accepted, removed back pointers
89 * to compiler structures.
91 public void cleanUp() {
93 ClassFile[] classFiles = compilationResult.getClassFiles();
94 for (int i = 0, max = classFiles.length; i < max; i++) {
95 // clear the classFile back pointer to the bindings
96 ClassFile classFile = classFiles[i];
97 // null out the type's scope backpointers
98 ((SourceTypeBinding) classFile.referenceBinding).scope = null;
99 // null out the classfile backpointer to a type binding
100 classFile.referenceBinding = null;
101 classFile.codeStream = null; // codeStream holds onto ast and scopes
102 classFile.innerClassesBindings = null;
106 public void checkUnusedImports(){
108 if (this.scope.imports != null){
109 for (int i = 0, max = this.scope.imports.length; i < max; i++){
110 ImportBinding importBinding = this.scope.imports[i];
111 ImportReference importReference = importBinding.reference;
112 if (importReference != null && !importReference.used){
113 scope.problemReporter().unusedImport(importReference);
119 public CompilationResult compilationResult() {
120 return compilationResult;
124 * Finds the matching type amoung this compilation unit types.
125 * Returns null if no type with this name is found.
126 * The type name is a compound name
127 * eg. if we're looking for X.A.B then a type name would be {X, A, B}
129 public TypeDeclaration declarationOfType(char[][] typeName) {
131 for (int i = 0; i < this.types.length; i++) {
132 TypeDeclaration typeDecl = this.types[i].declarationOfType(typeName);
133 if (typeDecl != null) {
141 * Bytecode generation
143 public void generateCode() {
145 if (ignoreFurtherInvestigation) {
147 for (int i = 0, count = types.length; i < count; i++) {
148 types[i].ignoreFurtherInvestigation = true;
149 // propagate the flag to request problem type creation
150 types[i].generateCode(scope);
157 for (int i = 0, count = types.length; i < count; i++)
158 types[i].generateCode(scope);
160 } catch (AbortCompilationUnit e) {
164 public char[] getFileName() {
166 return compilationResult.getFileName();
169 public char[] getMainTypeName() {
171 if (compilationResult.compilationUnit == null) {
172 char[] fileName = compilationResult.getFileName();
174 int start = CharOperation.lastIndexOf('/', fileName) + 1;
175 if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName))
176 start = CharOperation.lastIndexOf('\\', fileName) + 1;
178 int end = CharOperation.lastIndexOf('.', fileName);
180 end = fileName.length;
182 return CharOperation.subarray(fileName, start, end);
184 return compilationResult.compilationUnit.getMainTypeName();
188 public boolean isEmpty() {
190 return (currentPackage == null) && (imports == null) && (types == null);
193 public boolean hasErrors() {
194 return this.ignoreFurtherInvestigation;
198 * Force inner local types to update their innerclass emulation
200 public void propagateInnerEmulationForAllLocalTypes() {
202 isPropagatingInnerClassEmulation = true;
203 if (allLocalTypes != null) {
204 for (int i = 0, max = allLocalTypes.length; i < max; i++) {
205 allLocalTypes[i].updateInnerEmulationDependents();
211 * Keep track of all local types, so as to update their innerclass
212 * emulation later on.
214 public void record(LocalTypeBinding localType) {
216 if (allLocalTypes == null) {
217 allLocalTypes = new LocalTypeBinding[] { localType };
219 int length = allLocalTypes.length;
223 (allLocalTypes = new LocalTypeBinding[length + 1]),
226 allLocalTypes[length] = localType;
230 public void resolve() {
234 for (int i = 0, count = types.length; i < count; i++) {
235 types[i].resolve(scope);
238 checkUnusedImports();
239 } catch (AbortCompilationUnit e) {
240 this.ignoreFurtherInvestigation = true;
245 public void tagAsHavingErrors() {
246 ignoreFurtherInvestigation = true;
249 public String toString(int tab) {
251 String s = ""; //$NON-NLS-1$
252 if (currentPackage != null)
253 s = tabString(tab) + "package " + currentPackage.toString(0, false) + ";\n"; //$NON-NLS-1$ //$NON-NLS-2$
256 for (int i = 0; i < imports.length; i++) {
257 s += tabString(tab) + "import " + imports[i].toString() + ";\n"; //$NON-NLS-1$ //$NON-NLS-2$
261 for (int i = 0; i < types.length; i++) {
262 s += types[i].toString(tab) + "\n"; //$NON-NLS-1$
267 public void traverse(
268 IAbstractSyntaxTreeVisitor visitor,
269 CompilationUnitScope scope) {
271 if (ignoreFurtherInvestigation)
274 if (visitor.visit(this, scope)) {
275 if (imports != null) {
276 int importLength = imports.length;
277 for (int i = 0; i < importLength; i++)
278 imports[i].traverse(visitor, scope);
281 int typesLength = types.length;
282 for (int i = 0; i < typesLength; i++)
283 types[i].traverse(visitor, scope);
286 visitor.endVisit(this, scope);
287 } catch (AbortCompilationUnit e) {