merged src/java and src/rsc
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / ast / CompilationUnitDeclaration.java
diff --git a/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
new file mode 100644 (file)
index 0000000..d736614
--- /dev/null
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * 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.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+
+public class CompilationUnitDeclaration
+       extends ASTNode
+       implements ProblemSeverities, ReferenceContext {
+               
+       public ImportReference currentPackage;
+       public ImportReference[] imports;
+       public TypeDeclaration[] types;
+       public int[][] comments;
+
+       public boolean ignoreFurtherInvestigation = false;      // once pointless to investigate due to errors
+       public boolean ignoreMethodBodies = false;
+       public CompilationUnitScope scope;
+       public ProblemReporter problemReporter;
+       public CompilationResult compilationResult;
+
+       public LocalTypeBinding[] localTypes;
+       public int localTypeCount = 0;
+       
+       public boolean isPropagatingInnerClassEmulation;
+
+       public CompilationUnitDeclaration(
+               ProblemReporter problemReporter,
+               CompilationResult compilationResult,
+               int sourceLength) {
+
+               this.problemReporter = problemReporter;
+               this.compilationResult = compilationResult;
+
+               //by definition of a compilation unit....
+               sourceStart = 0;
+               sourceEnd = sourceLength - 1;
+
+       }
+
+       /*
+        *      We cause the compilation task to abort to a given extent.
+        */
+       public void abort(int abortLevel, IProblem problem) {
+
+               switch (abortLevel) {
+                       case AbortType :
+                               throw new AbortType(this.compilationResult, problem);
+                       case AbortMethod :
+                               throw new AbortMethod(this.compilationResult, problem);
+                       default :
+                               throw new AbortCompilationUnit(this.compilationResult, problem);
+               }
+       }
+
+       /*
+        * Dispatch code analysis AND request saturation of inner emulation
+        */
+       public void analyseCode() {
+
+               if (ignoreFurtherInvestigation)
+                       return;
+               try {
+                       if (types != null) {
+                               for (int i = 0, count = types.length; i < count; i++) {
+                                       types[i].analyseCode(scope);
+                               }
+                       }
+                       // request inner emulation propagation
+                       propagateInnerEmulationForAllLocalTypes();
+               } catch (AbortCompilationUnit e) {
+                       this.ignoreFurtherInvestigation = true;
+                       return;
+               }
+       }
+
+       /*
+        * When unit result is about to be accepted, removed back pointers
+        * to compiler structures.
+        */
+       public void cleanUp() {
+               if (this.types != null) {
+                       for (int i = 0, max = this.types.length; i < max; i++) {
+                               cleanUp(this.types[i]);
+                       }
+                       for (int i = 0, max = this.localTypeCount; i < max; i++) {
+                           LocalTypeBinding localType = localTypes[i];
+                               // null out the type's scope backpointers
+                               localType.scope = null; // local members are already in the list
+                       }
+               }
+               ClassFile[] classFiles = compilationResult.getClassFiles();
+               for (int i = 0, max = classFiles.length; i < max; i++) {
+                       // clear the classFile back pointer to the bindings
+                       ClassFile classFile = classFiles[i];
+                       // null out the classfile backpointer to a type binding
+                       classFile.referenceBinding = null;
+                       classFile.codeStream = null; // codeStream holds onto ast and scopes
+                       classFile.innerClassesBindings = null;
+               }
+       }
+       private void cleanUp(TypeDeclaration type) {
+               if (type.memberTypes != null) {
+                       for (int i = 0, max = type.memberTypes.length; i < max; i++){
+                               cleanUp(type.memberTypes[i]);
+                       }
+               }
+               if (type.binding != null) {
+                       // null out the type's scope backpointers
+                       type.binding.scope = null;
+               }
+       }
+
+       public void checkUnusedImports(){
+               
+               if (this.scope.imports != null){
+                       for (int i = 0, max = this.scope.imports.length; i < max; i++){
+                               ImportBinding importBinding = this.scope.imports[i];
+                               ImportReference importReference = importBinding.reference;
+                               if (importReference != null && !importReference.used){
+                                       scope.problemReporter().unusedImport(importReference);
+                               }
+                       }
+               }
+       }
+       
+       public CompilationResult compilationResult() {
+               return compilationResult;
+       }
+       
+       /*
+        * Finds the matching type amoung this compilation unit types.
+        * Returns null if no type with this name is found.
+        * The type name is a compound name
+        * eg. if we're looking for X.A.B then a type name would be {X, A, B}
+        */
+       public TypeDeclaration declarationOfType(char[][] typeName) {
+
+               for (int i = 0; i < this.types.length; i++) {
+                       TypeDeclaration typeDecl = this.types[i].declarationOfType(typeName);
+                       if (typeDecl != null) {
+                               return typeDecl;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Bytecode generation
+        */
+       public void generateCode() {
+
+               if (ignoreFurtherInvestigation) {
+                       if (types != null) {
+                               for (int i = 0, count = types.length; i < count; i++) {
+                                       types[i].ignoreFurtherInvestigation = true;
+                                       // propagate the flag to request problem type creation
+                                       types[i].generateCode(scope);
+                               }
+                       }
+                       return;
+               }
+               try {
+                       if (types != null) {
+                               for (int i = 0, count = types.length; i < count; i++)
+                                       types[i].generateCode(scope);
+                       }
+               } catch (AbortCompilationUnit e) {
+                       // ignore
+               }
+       }
+
+       public char[] getFileName() {
+
+               return compilationResult.getFileName();
+       }
+
+       public char[] getMainTypeName() {
+
+               if (compilationResult.compilationUnit == null) {
+                       char[] fileName = compilationResult.getFileName();
+
+                       int start = CharOperation.lastIndexOf('/', fileName) + 1;
+                       if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName))
+                               start = CharOperation.lastIndexOf('\\', fileName) + 1;
+
+                       int end = CharOperation.lastIndexOf('.', fileName);
+                       if (end == -1)
+                               end = fileName.length;
+
+                       return CharOperation.subarray(fileName, start, end);
+               } else {
+                       return compilationResult.compilationUnit.getMainTypeName();
+               }
+       }
+
+       public boolean isEmpty() {
+
+               return (currentPackage == null) && (imports == null) && (types == null);
+       }
+
+       public boolean hasErrors() {
+               return this.ignoreFurtherInvestigation;
+       }
+
+       public StringBuffer print(int indent, StringBuffer output) {
+
+               if (currentPackage != null) {
+                       printIndent(indent, output).append("package "); //$NON-NLS-1$
+                       currentPackage.print(0, output, false).append(";\n"); //$NON-NLS-1$
+               }
+               if (imports != null)
+                       for (int i = 0; i < imports.length; i++) {
+                               printIndent(indent, output).append("import "); //$NON-NLS-1$
+                               imports[i].print(0, output).append(";\n"); //$NON-NLS-1$ 
+                       }
+
+               if (types != null) {
+                       for (int i = 0; i < types.length; i++) {
+                               types[i].print(indent, output).append("\n"); //$NON-NLS-1$
+                       }
+               }
+               return output;
+       }
+       
+       /*
+        * Force inner local types to update their innerclass emulation
+        */
+       public void propagateInnerEmulationForAllLocalTypes() {
+
+               isPropagatingInnerClassEmulation = true;
+               for (int i = 0, max = this.localTypeCount; i < max; i++) {
+                               
+                       LocalTypeBinding localType = localTypes[i];
+                       // only propagate for reachable local types
+                       if ((localType.scope.referenceType().bits & IsReachableMASK) != 0) {
+                               localType.updateInnerEmulationDependents();
+                       }
+               }
+       }
+
+       /*
+        * Keep track of all local types, so as to update their innerclass
+        * emulation later on.
+        */
+       public void record(LocalTypeBinding localType) {
+
+               if (this.localTypeCount == 0) {
+                       this.localTypes = new LocalTypeBinding[5];
+               } else if (this.localTypeCount == this.localTypes.length) {
+                       System.arraycopy(this.localTypes, 0, (this.localTypes = new LocalTypeBinding[this.localTypeCount * 2]), 0, this.localTypeCount);
+               }
+               this.localTypes[this.localTypeCount++] = localType;
+       }
+
+       public void resolve() {
+
+               try {
+                       if (types != null) {
+                               for (int i = 0, count = types.length; i < count; i++) {
+                                       types[i].resolve(scope);
+                               }
+                       }
+                       if (!this.compilationResult.hasSyntaxError()) checkUnusedImports();
+               } catch (AbortCompilationUnit e) {
+                       this.ignoreFurtherInvestigation = true;
+                       return;
+               }
+       }
+
+       public void tagAsHavingErrors() {
+               ignoreFurtherInvestigation = true;
+       }
+
+       public void traverse(
+               ASTVisitor visitor,
+               CompilationUnitScope unitScope) {
+
+               if (ignoreFurtherInvestigation)
+                       return;
+               try {
+                       if (visitor.visit(this, this.scope)) {
+                               if (currentPackage != null) {
+                                       currentPackage.traverse(visitor, this.scope);
+                               }
+                               if (imports != null) {
+                                       int importLength = imports.length;
+                                       for (int i = 0; i < importLength; i++) {
+                                               imports[i].traverse(visitor, this.scope);
+                                       }
+                               }
+                               if (types != null) {
+                                       int typesLength = types.length;
+                                       for (int i = 0; i < typesLength; i++) {
+                                               types[i].traverse(visitor, this.scope);
+                                       }
+                               }
+                       }
+                       visitor.endVisit(this, this.scope);
+               } catch (AbortCompilationUnit e) {
+                       // ignore
+               }
+       }
+}