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) {