A massive organize imports and formatting of the sources using default Eclipse code...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / LookupEnvironment.java
index 54e6de2..bbe5a89 100644 (file)
@@ -20,23 +20,35 @@ import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 import net.sourceforge.phpdt.internal.compiler.util.HashtableOfPackage;
 import net.sourceforge.phpdt.internal.compiler.util.Util;
 
-public class LookupEnvironment implements BaseTypes, ProblemReasons, TypeConstants {
-//     public CompilerOptions options;
+public class LookupEnvironment implements BaseTypes, ProblemReasons,
+               TypeConstants {
+       // public CompilerOptions options;
        public ProblemReporter problemReporter;
+
        public ITypeRequestor typeRequestor;
 
        PackageBinding defaultPackage;
+
        ImportBinding[] defaultImports;
+
        HashtableOfPackage knownPackages;
-       static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound);
-       static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR, NotFound);
+
+       static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(
+                       CharOperation.NO_CHAR, NotFound);
+
+       static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(
+                       CharOperation.NO_CHAR, NotFound);
 
        private INameEnvironment nameEnvironment;
+
        private MethodVerifier verifier;
+
        private ArrayBinding[][] uniqueArrayBindings;
 
        private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4];
+
        private int lastUnitIndex = -1;
+
        private int lastCompletedUnitIndex = -1;
 
        // indicate in which step on the compilation we are.
@@ -44,542 +56,655 @@ public class LookupEnvironment implements BaseTypes, ProblemReasons, TypeConstan
        // step 2 : conect the hierarchy (connect bindings)
        // step 3 : build fields and method bindings.
        private int stepCompleted;
+
        final static int BUILD_TYPE_HIERARCHY = 1;
+
        final static int CHECK_AND_SET_IMPORTS = 2;
+
        final static int CONNECT_TYPE_HIERARCHY = 3;
+
        final static int BUILD_FIELDS_AND_METHODS = 4;
-public LookupEnvironment(ITypeRequestor typeRequestor,ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
-// CompilerOptions options, ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
-       this.typeRequestor = typeRequestor;
-//     this.options = options;
-       this.problemReporter = problemReporter;
-       this.defaultPackage = new PackageBinding(this); // assume the default package always exists
-       this.defaultImports = null;
-       this.nameEnvironment = nameEnvironment;
-       this.knownPackages = new HashtableOfPackage();
-       this.uniqueArrayBindings = new ArrayBinding[5][];
-       this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
-}
-/* Ask the oracle for a type which corresponds to the compoundName.
-* Answer null if the name cannot be found.
-*/
 
-public ReferenceBinding askForType(char[][] compoundName) {
-       NameEnvironmentAnswer answer = nameEnvironment.findType(compoundName);
-       if (answer == null)
-               return null;
+       public LookupEnvironment(ITypeRequestor typeRequestor,
+                       ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
+               // CompilerOptions options, ProblemReporter problemReporter,
+               // INameEnvironment nameEnvironment) {
+               this.typeRequestor = typeRequestor;
+               // this.options = options;
+               this.problemReporter = problemReporter;
+               this.defaultPackage = new PackageBinding(this); // assume the default
+                                                                                                               // package always exists
+               this.defaultImports = null;
+               this.nameEnvironment = nameEnvironment;
+               this.knownPackages = new HashtableOfPackage();
+               this.uniqueArrayBindings = new ArrayBinding[5][];
+               this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the
+                                                                                                                       // most common 1
+                                                                                                                       // dimension array @
+                                                                                                                       // 50
+       }
 
-       if (answer.isBinaryType())
-               // the type was found as a .class file
-               typeRequestor.accept(answer.getBinaryType(), computePackageFrom(compoundName));
-       else if (answer.isCompilationUnit())
-               // the type was found as a .java file, try to build it then search the cache
-               typeRequestor.accept(answer.getCompilationUnit());
-       else if (answer.isSourceType())
-               // the type was found as a source model
-               typeRequestor.accept(answer.getSourceTypes(), computePackageFrom(compoundName));
-
-       return getCachedType(compoundName);
-}
-/* Ask the oracle for a type named name in the packageBinding.
-* Answer null if the name cannot be found.
-*/
+       /*
+        * Ask the oracle for a type which corresponds to the compoundName. Answer
+        * null if the name cannot be found.
+        */
 
-ReferenceBinding askForType(PackageBinding packageBinding, char[] name) {
-       if (packageBinding == null) {
-               if (defaultPackage == null)
+       public ReferenceBinding askForType(char[][] compoundName) {
+               NameEnvironmentAnswer answer = nameEnvironment.findType(compoundName);
+               if (answer == null)
                        return null;
-               packageBinding = defaultPackage;
+
+               if (answer.isBinaryType())
+                       // the type was found as a .class file
+                       typeRequestor.accept(answer.getBinaryType(),
+                                       computePackageFrom(compoundName));
+               else if (answer.isCompilationUnit())
+                       // the type was found as a .java file, try to build it then search
+                       // the cache
+                       typeRequestor.accept(answer.getCompilationUnit());
+               else if (answer.isSourceType())
+                       // the type was found as a source model
+                       typeRequestor.accept(answer.getSourceTypes(),
+                                       computePackageFrom(compoundName));
+
+               return getCachedType(compoundName);
        }
-       NameEnvironmentAnswer answer = nameEnvironment.findType(name, packageBinding.compoundName);
-       if (answer == null)
-               return null;
 
-       if (answer.isBinaryType())
-               // the type was found as a .class file
-               typeRequestor.accept(answer.getBinaryType(), packageBinding);
-       else if (answer.isCompilationUnit())
-               // the type was found as a .java file, try to build it then search the cache
-               typeRequestor.accept(answer.getCompilationUnit());
-       else if (answer.isSourceType())
-               // the type was found as a source model
-               typeRequestor.accept(answer.getSourceTypes(), packageBinding);
-
-       return packageBinding.getType0(name);
-}
-/* Create the initial type bindings for the compilation unit.
-*
-* See completeTypeBindings() for a description of the remaining steps
-*
-* NOTE: This method can be called multiple times as additional source files are needed
-*/
-
-public void buildTypeBindings(CompilationUnitDeclaration unit) {
-       CompilationUnitScope scope = new CompilationUnitScope(unit, this);
-       scope.buildTypeBindings();
-
-       int unitsLength = units.length;
-       if (++lastUnitIndex >= unitsLength)
-               System.arraycopy(units, 0, units = new CompilationUnitDeclaration[2 * unitsLength], 0, unitsLength);
-       units[lastUnitIndex] = unit;
-}
-/* Cache the binary type since we know it is needed during this compile.
-*
-* Answer the created BinaryTypeBinding or null if the type is already in the cache.
-*/
+       /*
+        * Ask the oracle for a type named name in the packageBinding. Answer null
+        * if the name cannot be found.
+        */
 
-public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType) {
-       return cacheBinaryType(binaryType, true);
-}
-/* Cache the binary type since we know it is needed during this compile.
-*
-* Answer the created BinaryTypeBinding or null if the type is already in the cache.
-*/
-
-public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, boolean needFieldsAndMethods) {
-       char[][] compoundName = CharOperation.splitOn('/', binaryType.getName());
-       ReferenceBinding existingType = getCachedType(compoundName);
-
-       if (existingType == null || existingType instanceof UnresolvedReferenceBinding)
-               // only add the binary type if its not already in the cache
-               return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName), needFieldsAndMethods);
-       return null; // the type already exists & can be retrieved from the cache
-}
-/*
-* 1. Connect the type hierarchy for the type bindings created for parsedUnits.
-* 2. Create the field bindings
-* 3. Create the method bindings
-*/
-
-/* We know each known compilationUnit is free of errors at this point...
-*
-* Each step will create additional bindings unless a problem is detected, in which
-* case either the faulty import/superinterface/field/method will be skipped or a
-* suitable replacement will be substituted (such as Object for a missing superclass)
-*/
-
-public void completeTypeBindings() {
-       stepCompleted = BUILD_TYPE_HIERARCHY;
-       
-//     for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
-//             units[i].scope.checkAndSetImports();
-//     }
-       stepCompleted = CHECK_AND_SET_IMPORTS;
-
-//     for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
-//             units[i].scope.connectTypeHierarchy();
-//     }
-       stepCompleted = CONNECT_TYPE_HIERARCHY;
-
-       for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
-//             units[i].scope.buildFieldsAndMethods();
-               units[i] = null; // release unnecessary reference to the parsed unit
+       ReferenceBinding askForType(PackageBinding packageBinding, char[] name) {
+               if (packageBinding == null) {
+                       if (defaultPackage == null)
+                               return null;
+                       packageBinding = defaultPackage;
+               }
+               NameEnvironmentAnswer answer = nameEnvironment.findType(name,
+                               packageBinding.compoundName);
+               if (answer == null)
+                       return null;
+
+               if (answer.isBinaryType())
+                       // the type was found as a .class file
+                       typeRequestor.accept(answer.getBinaryType(), packageBinding);
+               else if (answer.isCompilationUnit())
+                       // the type was found as a .java file, try to build it then search
+                       // the cache
+                       typeRequestor.accept(answer.getCompilationUnit());
+               else if (answer.isSourceType())
+                       // the type was found as a source model
+                       typeRequestor.accept(answer.getSourceTypes(), packageBinding);
+
+               return packageBinding.getType0(name);
        }
-       stepCompleted = BUILD_FIELDS_AND_METHODS;
-       lastCompletedUnitIndex = lastUnitIndex;
-}
-/*
-* 1. Connect the type hierarchy for the type bindings created for parsedUnits.
-* 2. Create the field bindings
-* 3. Create the method bindings
-*/
-
-/*
-* Each step will create additional bindings unless a problem is detected, in which
-* case either the faulty import/superinterface/field/method will be skipped or a
-* suitable replacement will be substituted (such as Object for a missing superclass)
-*/
-
-public void completeTypeBindings(CompilationUnitDeclaration parsedUnit) {
-       if (stepCompleted == BUILD_FIELDS_AND_METHODS) {
-               // This can only happen because the original set of units are completely built and
-               // are now being processed, so we want to treat all the additional units as a group
-               // until they too are completely processed.
-               completeTypeBindings();
-       } else {
-               if (parsedUnit.scope == null) return; // parsing errors were too severe
-
-//             if (stepCompleted >= CHECK_AND_SET_IMPORTS)
-//                     parsedUnit.scope.checkAndSetImports();
-
-               if (stepCompleted >= CONNECT_TYPE_HIERARCHY)
-                       parsedUnit.scope.connectTypeHierarchy();
+
+       /*
+        * Create the initial type bindings for the compilation unit.
+        * 
+        * See completeTypeBindings() for a description of the remaining steps
+        * 
+        * NOTE: This method can be called multiple times as additional source files
+        * are needed
+        */
+
+       public void buildTypeBindings(CompilationUnitDeclaration unit) {
+               CompilationUnitScope scope = new CompilationUnitScope(unit, this);
+               scope.buildTypeBindings();
+
+               int unitsLength = units.length;
+               if (++lastUnitIndex >= unitsLength)
+                       System.arraycopy(units, 0,
+                                       units = new CompilationUnitDeclaration[2 * unitsLength], 0,
+                                       unitsLength);
+               units[lastUnitIndex] = unit;
        }
-}
-/*
-* Used by other compiler tools which do not start by calling completeTypeBindings().
-*
-* 1. Connect the type hierarchy for the type bindings created for parsedUnits.
-* 2. Create the field bindings
-* 3. Create the method bindings
-*/
-
-public void completeTypeBindings(CompilationUnitDeclaration parsedUnit, boolean buildFieldsAndMethods) {
-       if (parsedUnit.scope == null) return; // parsing errors were too severe
-
-       parsedUnit.scope.checkAndSetImports();
-       parsedUnit.scope.connectTypeHierarchy();
-
-       if (buildFieldsAndMethods)
-               parsedUnit.scope.buildFieldsAndMethods();
-}
 
-private PackageBinding computePackageFrom(char[][] constantPoolName) {
-       if (constantPoolName.length == 1)
-               return defaultPackage;
+       /*
+        * Cache the binary type since we know it is needed during this compile.
+        * 
+        * Answer the created BinaryTypeBinding or null if the type is already in
+        * the cache.
+        */
 
-       PackageBinding packageBinding = getPackage0(constantPoolName[0]);
-       if (packageBinding == null || packageBinding == TheNotFoundPackage) {
-               packageBinding = new PackageBinding(constantPoolName[0], this);
-               knownPackages.put(constantPoolName[0], packageBinding);
+       public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType) {
+               return cacheBinaryType(binaryType, true);
        }
 
-       for (int i = 1, length = constantPoolName.length - 1; i < length; i++) {
-               PackageBinding parent = packageBinding;
-               if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == TheNotFoundPackage) {
-                       packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parent, this);
-                       parent.addPackage(packageBinding);
-               }
+       /*
+        * Cache the binary type since we know it is needed during this compile.
+        * 
+        * Answer the created BinaryTypeBinding or null if the type is already in
+        * the cache.
+        */
+
+       public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType,
+                       boolean needFieldsAndMethods) {
+               char[][] compoundName = CharOperation
+                               .splitOn('/', binaryType.getName());
+               ReferenceBinding existingType = getCachedType(compoundName);
+
+               if (existingType == null
+                               || existingType instanceof UnresolvedReferenceBinding)
+                       // only add the binary type if its not already in the cache
+                       return createBinaryTypeFrom(binaryType,
+                                       computePackageFrom(compoundName), needFieldsAndMethods);
+               return null; // the type already exists & can be retrieved from the
+                                               // cache
        }
-       return packageBinding;
-}
-/* Used to guarantee array type identity.
-*/
-
-ArrayBinding createArrayType(TypeBinding type, int dimensionCount) {
-       if (type instanceof LocalTypeBinding) // cache local type arrays with the local type itself
-               return ((LocalTypeBinding) type).createArrayType(dimensionCount);
-
-       // find the array binding cache for this dimension
-       int dimIndex = dimensionCount - 1;
-       int length = uniqueArrayBindings.length;
-       ArrayBinding[] arrayBindings;
-       if (dimIndex < length) {
-               if ((arrayBindings = uniqueArrayBindings[dimIndex]) == null)
-                       uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
-       } else {
-               System.arraycopy(
-                       uniqueArrayBindings, 0, 
-                       uniqueArrayBindings = new ArrayBinding[dimensionCount][], 0, 
-                       length); 
-               uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
+
+       /*
+        * 1. Connect the type hierarchy for the type bindings created for
+        * parsedUnits. 2. Create the field bindings 3. Create the method bindings
+        */
+
+       /*
+        * We know each known compilationUnit is free of errors at this point...
+        * 
+        * Each step will create additional bindings unless a problem is detected,
+        * in which case either the faulty import/superinterface/field/method will
+        * be skipped or a suitable replacement will be substituted (such as Object
+        * for a missing superclass)
+        */
+
+       public void completeTypeBindings() {
+               stepCompleted = BUILD_TYPE_HIERARCHY;
+
+               // for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
+               // units[i].scope.checkAndSetImports();
+               // }
+               stepCompleted = CHECK_AND_SET_IMPORTS;
+
+               // for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
+               // units[i].scope.connectTypeHierarchy();
+               // }
+               stepCompleted = CONNECT_TYPE_HIERARCHY;
+
+               for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
+                       // units[i].scope.buildFieldsAndMethods();
+                       units[i] = null; // release unnecessary reference to the parsed
+                                                               // unit
+               }
+               stepCompleted = BUILD_FIELDS_AND_METHODS;
+               lastCompletedUnitIndex = lastUnitIndex;
        }
 
-       // find the cached array binding for this leaf component type (if any)
-       int index = -1;
-       length = arrayBindings.length;
-       while (++index < length) {
-               ArrayBinding currentBinding = arrayBindings[index];
-               if (currentBinding == null) // no matching array, but space left
-                       return arrayBindings[index] = new ArrayBinding(type, dimensionCount);
-               if (currentBinding.leafComponentType == type)
-                       return currentBinding;
+       /*
+        * 1. Connect the type hierarchy for the type bindings created for
+        * parsedUnits. 2. Create the field bindings 3. Create the method bindings
+        */
+
+       /*
+        * Each step will create additional bindings unless a problem is detected,
+        * in which case either the faulty import/superinterface/field/method will
+        * be skipped or a suitable replacement will be substituted (such as Object
+        * for a missing superclass)
+        */
+
+       public void completeTypeBindings(CompilationUnitDeclaration parsedUnit) {
+               if (stepCompleted == BUILD_FIELDS_AND_METHODS) {
+                       // This can only happen because the original set of units are
+                       // completely built and
+                       // are now being processed, so we want to treat all the additional
+                       // units as a group
+                       // until they too are completely processed.
+                       completeTypeBindings();
+               } else {
+                       if (parsedUnit.scope == null)
+                               return; // parsing errors were too severe
+
+                       // if (stepCompleted >= CHECK_AND_SET_IMPORTS)
+                       // parsedUnit.scope.checkAndSetImports();
+
+                       if (stepCompleted >= CONNECT_TYPE_HIERARCHY)
+                               parsedUnit.scope.connectTypeHierarchy();
+               }
        }
 
-       // no matching array, no space left
-       System.arraycopy(
-               arrayBindings, 0,
-               (arrayBindings = new ArrayBinding[length * 2]), 0,
-               length); 
-       uniqueArrayBindings[dimIndex] = arrayBindings;
-       return arrayBindings[length] = new ArrayBinding(type, dimensionCount);
-}
-public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding) {
-       return createBinaryTypeFrom(binaryType, packageBinding, true);
-}
-public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, boolean needFieldsAndMethods) {
-       BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBinding, binaryType, this);
-
-       // resolve any array bindings which reference the unresolvedType
-       ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
-       if (cachedType != null) {
-               if (cachedType.isBinaryBinding()) // sanity check before the cast... at this point the cache should ONLY contain unresolved types
-                       return (BinaryTypeBinding) cachedType;
-
-               UnresolvedReferenceBinding unresolvedType = (UnresolvedReferenceBinding) cachedType;
-               unresolvedType.resolvedType = binaryBinding;
-               updateArrayCache(unresolvedType, binaryBinding);
+       /*
+        * Used by other compiler tools which do not start by calling
+        * completeTypeBindings().
+        * 
+        * 1. Connect the type hierarchy for the type bindings created for
+        * parsedUnits. 2. Create the field bindings 3. Create the method bindings
+        */
+
+       public void completeTypeBindings(CompilationUnitDeclaration parsedUnit,
+                       boolean buildFieldsAndMethods) {
+               if (parsedUnit.scope == null)
+                       return; // parsing errors were too severe
+
+               parsedUnit.scope.checkAndSetImports();
+               parsedUnit.scope.connectTypeHierarchy();
+
+               if (buildFieldsAndMethods)
+                       parsedUnit.scope.buildFieldsAndMethods();
        }
 
-       packageBinding.addType(binaryBinding);
-       binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods);
-       return binaryBinding;
-}
-/* Used to create packages from the package statement.
-*/
-
-PackageBinding createPackage(char[][] compoundName) {
-    return null;
-//     PackageBinding packageBinding = getPackage0(compoundName[0]);
-//     if (packageBinding == null || packageBinding == TheNotFoundPackage) {
-//             packageBinding = new PackageBinding(compoundName[0], this);
-//             knownPackages.put(compoundName[0], packageBinding);
-//     }
-//
-//     for (int i = 1, length = compoundName.length; i < length; i++) {
-//             // check to see if it collides with a known type...
-//             // this case can only happen if the package does not exist as a directory in the file system
-//             // otherwise when the source type was defined, the correct error would have been reported
-//             // unless its an unresolved type which is referenced from an inconsistent class file
-//             ReferenceBinding type = packageBinding.getType0(compoundName[i]);
-//             if (type != null && type != TheNotFoundType && !(type instanceof UnresolvedReferenceBinding))
-//                     return null;
-//
-//             PackageBinding parent = packageBinding;
-//             if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) {
-//                     // if the package is unknown, check to see if a type exists which would collide with the new package
-//                     // catches the case of a package statement of: package java.lang.Object;
-//                     // since the package can be added after a set of source files have already been compiled, we need
-//                     // whenever a package statement is encountered
-//                     if (nameEnvironment.findType(compoundName[i], parent.compoundName) != null)
-//                             return null;
-//
-//                     packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parent, this);
-//                     parent.addPackage(packageBinding);
-//             }
-//     }
-//     return packageBinding;
-}
-/* Answer the type for the compoundName if it exists in the cache.
-* Answer theNotFoundType if it could not be resolved the first time
-* it was looked up, otherwise answer null.
-*
-* NOTE: Do not use for nested types... the answer is NOT the same for a.b.C or a.b.C.D.E
-* assuming C is a type in both cases. In the a.b.C.D.E case, null is the answer.
-*/
-
-public ReferenceBinding getCachedType(char[][] compoundName) {
-       if (compoundName.length == 1) {
-               if (defaultPackage == null)
-                       return null;
-               return defaultPackage.getType0(compoundName[0]);
+       private PackageBinding computePackageFrom(char[][] constantPoolName) {
+               if (constantPoolName.length == 1)
+                       return defaultPackage;
+
+               PackageBinding packageBinding = getPackage0(constantPoolName[0]);
+               if (packageBinding == null || packageBinding == TheNotFoundPackage) {
+                       packageBinding = new PackageBinding(constantPoolName[0], this);
+                       knownPackages.put(constantPoolName[0], packageBinding);
+               }
+
+               for (int i = 1, length = constantPoolName.length - 1; i < length; i++) {
+                       PackageBinding parent = packageBinding;
+                       if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null
+                                       || packageBinding == TheNotFoundPackage) {
+                               packageBinding = new PackageBinding(CharOperation.subarray(
+                                               constantPoolName, 0, i + 1), parent, this);
+                               parent.addPackage(packageBinding);
+                       }
+               }
+               return packageBinding;
        }
 
-       PackageBinding packageBinding = getPackage0(compoundName[0]);
-       if (packageBinding == null || packageBinding == TheNotFoundPackage)
-               return null;
+       /*
+        * Used to guarantee array type identity.
+        */
+
+       ArrayBinding createArrayType(TypeBinding type, int dimensionCount) {
+               if (type instanceof LocalTypeBinding) // cache local type arrays with
+                                                                                               // the local type itself
+                       return ((LocalTypeBinding) type).createArrayType(dimensionCount);
+
+               // find the array binding cache for this dimension
+               int dimIndex = dimensionCount - 1;
+               int length = uniqueArrayBindings.length;
+               ArrayBinding[] arrayBindings;
+               if (dimIndex < length) {
+                       if ((arrayBindings = uniqueArrayBindings[dimIndex]) == null)
+                               uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
+               } else {
+                       System.arraycopy(uniqueArrayBindings, 0,
+                                       uniqueArrayBindings = new ArrayBinding[dimensionCount][],
+                                       0, length);
+                       uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
+               }
 
-       for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++)
-               if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage)
-                       return null;
-       return packageBinding.getType0(compoundName[compoundName.length - 1]);
-}
-/* Answer the top level package named name if it exists in the cache.
-* Answer theNotFoundPackage if it could not be resolved the first time
-* it was looked up, otherwise answer null.
-*
-* NOTE: Senders must convert theNotFoundPackage into a real problem
-* package if its to returned.
-*/
-
-PackageBinding getPackage0(char[] name) {
-       return knownPackages.get(name);
-}
-/* Answer the top level package named name.
-* Ask the oracle for the package if its not in the cache.
-* Answer null if the package cannot be found.
-*/
-
-PackageBinding getTopLevelPackage(char[] name) {
-       PackageBinding packageBinding = getPackage0(name);
-       if (packageBinding != null) {
-               if (packageBinding == TheNotFoundPackage)
-                       return null;
-               else
-                       return packageBinding;
+               // find the cached array binding for this leaf component type (if any)
+               int index = -1;
+               length = arrayBindings.length;
+               while (++index < length) {
+                       ArrayBinding currentBinding = arrayBindings[index];
+                       if (currentBinding == null) // no matching array, but space left
+                               return arrayBindings[index] = new ArrayBinding(type,
+                                               dimensionCount);
+                       if (currentBinding.leafComponentType == type)
+                               return currentBinding;
+               }
+
+               // no matching array, no space left
+               System.arraycopy(arrayBindings, 0,
+                               (arrayBindings = new ArrayBinding[length * 2]), 0, length);
+               uniqueArrayBindings[dimIndex] = arrayBindings;
+               return arrayBindings[length] = new ArrayBinding(type, dimensionCount);
        }
 
-       if (nameEnvironment.isPackage(null, name)) {
-               knownPackages.put(name, packageBinding = new PackageBinding(name, this));
-               return packageBinding;
+       public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType,
+                       PackageBinding packageBinding) {
+               return createBinaryTypeFrom(binaryType, packageBinding, true);
        }
 
-       knownPackages.put(name, TheNotFoundPackage); // saves asking the oracle next time
-       return null;
-}
-/* Answer the type corresponding to the compoundName.
-* Ask the oracle for the type if its not in the cache.
-* Answer null if the type cannot be found... likely a fatal error.
-*/
+       public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType,
+                       PackageBinding packageBinding, boolean needFieldsAndMethods) {
+               BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBinding,
+                               binaryType, this);
+
+               // resolve any array bindings which reference the unresolvedType
+               ReferenceBinding cachedType = packageBinding
+                               .getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
+               if (cachedType != null) {
+                       if (cachedType.isBinaryBinding()) // sanity check before the
+                                                                                               // cast... at this point the
+                                                                                               // cache should ONLY contain
+                                                                                               // unresolved types
+                               return (BinaryTypeBinding) cachedType;
+
+                       UnresolvedReferenceBinding unresolvedType = (UnresolvedReferenceBinding) cachedType;
+                       unresolvedType.resolvedType = binaryBinding;
+                       updateArrayCache(unresolvedType, binaryBinding);
+               }
 
-public ReferenceBinding getType(char[][] compoundName) {
-       ReferenceBinding referenceBinding;
+               packageBinding.addType(binaryBinding);
+               binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods);
+               return binaryBinding;
+       }
 
-       if (compoundName.length == 1) {
-               if (defaultPackage == null)
-                       return null;
+       /*
+        * Used to create packages from the package statement.
+        */
 
-               if ((referenceBinding = defaultPackage.getType0(compoundName[0])) == null) {
-                       PackageBinding packageBinding = getPackage0(compoundName[0]);
-                       if (packageBinding != null && packageBinding != TheNotFoundPackage)
-                               return null; // collides with a known package... should not call this method in such a case
-                       referenceBinding = askForType(defaultPackage, compoundName[0]);
+       PackageBinding createPackage(char[][] compoundName) {
+               return null;
+               // PackageBinding packageBinding = getPackage0(compoundName[0]);
+               // if (packageBinding == null || packageBinding == TheNotFoundPackage) {
+               // packageBinding = new PackageBinding(compoundName[0], this);
+               // knownPackages.put(compoundName[0], packageBinding);
+               // }
+               //
+               // for (int i = 1, length = compoundName.length; i < length; i++) {
+               // // check to see if it collides with a known type...
+               // // this case can only happen if the package does not exist as a
+               // directory in the file system
+               // // otherwise when the source type was defined, the correct error
+               // would have been reported
+               // // unless its an unresolved type which is referenced from an
+               // inconsistent class file
+               // ReferenceBinding type = packageBinding.getType0(compoundName[i]);
+               // if (type != null && type != TheNotFoundType && !(type instanceof
+               // UnresolvedReferenceBinding))
+               // return null;
+               //
+               // PackageBinding parent = packageBinding;
+               // if ((packageBinding = parent.getPackage0(compoundName[i])) == null ||
+               // packageBinding == TheNotFoundPackage) {
+               // // if the package is unknown, check to see if a type exists which
+               // would collide with the new package
+               // // catches the case of a package statement of: package
+               // java.lang.Object;
+               // // since the package can be added after a set of source files have
+               // already been compiled, we need
+               // // whenever a package statement is encountered
+               // if (nameEnvironment.findType(compoundName[i], parent.compoundName) !=
+               // null)
+               // return null;
+               //
+               // packageBinding = new
+               // PackageBinding(CharOperation.subarray(compoundName, 0, i + 1),
+               // parent, this);
+               // parent.addPackage(packageBinding);
+               // }
+               // }
+               // return packageBinding;
+       }
+
+       /*
+        * Answer the type for the compoundName if it exists in the cache. Answer
+        * theNotFoundType if it could not be resolved the first time it was looked
+        * up, otherwise answer null.
+        * 
+        * NOTE: Do not use for nested types... the answer is NOT the same for a.b.C
+        * or a.b.C.D.E assuming C is a type in both cases. In the a.b.C.D.E case,
+        * null is the answer.
+        */
+
+       public ReferenceBinding getCachedType(char[][] compoundName) {
+               if (compoundName.length == 1) {
+                       if (defaultPackage == null)
+                               return null;
+                       return defaultPackage.getType0(compoundName[0]);
                }
-       } else {
+
                PackageBinding packageBinding = getPackage0(compoundName[0]);
-               if (packageBinding == TheNotFoundPackage)
+               if (packageBinding == null || packageBinding == TheNotFoundPackage)
                        return null;
 
+               for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++)
+                       if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null
+                                       || packageBinding == TheNotFoundPackage)
+                               return null;
+               return packageBinding.getType0(compoundName[compoundName.length - 1]);
+       }
+
+       /*
+        * Answer the top level package named name if it exists in the cache. Answer
+        * theNotFoundPackage if it could not be resolved the first time it was
+        * looked up, otherwise answer null.
+        * 
+        * NOTE: Senders must convert theNotFoundPackage into a real problem package
+        * if its to returned.
+        */
+
+       PackageBinding getPackage0(char[] name) {
+               return knownPackages.get(name);
+       }
+
+       /*
+        * Answer the top level package named name. Ask the oracle for the package
+        * if its not in the cache. Answer null if the package cannot be found.
+        */
+
+       PackageBinding getTopLevelPackage(char[] name) {
+               PackageBinding packageBinding = getPackage0(name);
                if (packageBinding != null) {
-                       for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) {
-                               if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null)
-                                       break;
-                               if (packageBinding == TheNotFoundPackage)
-                                       return null;
-                       }
+                       if (packageBinding == TheNotFoundPackage)
+                               return null;
+                       else
+                               return packageBinding;
                }
 
-               if (packageBinding == null)
-                       referenceBinding = askForType(compoundName);
-               else if ((referenceBinding = packageBinding.getType0(compoundName[compoundName.length - 1])) == null)
-                       referenceBinding = askForType(packageBinding, compoundName[compoundName.length - 1]);
-       }
+               if (nameEnvironment.isPackage(null, name)) {
+                       knownPackages.put(name, packageBinding = new PackageBinding(name,
+                                       this));
+                       return packageBinding;
+               }
 
-       if (referenceBinding == null || referenceBinding == TheNotFoundType)
+               knownPackages.put(name, TheNotFoundPackage); // saves asking the
+                                                                                                               // oracle next time
                return null;
-       if (referenceBinding instanceof UnresolvedReferenceBinding)
-               referenceBinding = ((UnresolvedReferenceBinding) referenceBinding).resolve(this);
-
-       // compoundName refers to a nested type incorrectly (for example, package1.A$B)
-       if (referenceBinding.isNestedType())
-               return new ProblemReferenceBinding(compoundName, InternalNameProvided);
-       else
-               return referenceBinding;
-}
-/* Answer the type corresponding to the name from the binary file.
-* Does not ask the oracle for the type if its not found in the cache... instead an
-* unresolved type is returned which must be resolved before used.
-*
-* NOTE: Does NOT answer base types nor array types!
-*
-* NOTE: Aborts compilation if the class file cannot be found.
-*/
-
-ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end) {
-       if (end == -1)
-               end = signature.length;
-
-       char[][] compoundName = CharOperation.splitOn('/', signature, start, end);
-       ReferenceBinding binding = getCachedType(compoundName);
-       if (binding == null) {
-               PackageBinding packageBinding = computePackageFrom(compoundName);
-               binding = new UnresolvedReferenceBinding(compoundName, packageBinding);
-               packageBinding.addType(binding);
-       } else if (binding == TheNotFoundType) {
-               problemReporter.isClassPathCorrect(compoundName, null);
-               return null; // will not get here since the above error aborts the compilation
        }
-       return binding;
-}
-/* Answer the type corresponding to the signature from the binary file.
-* Does not ask the oracle for the type if its not found in the cache... instead an
-* unresolved type is returned which must be resolved before used.
-*
-* NOTE: Does answer base types & array types.
-*
-* NOTE: Aborts compilation if the class file cannot be found.
-*/
-
-TypeBinding getTypeFromSignature(char[] signature, int start, int end) {
-       int dimension = 0;
-       while (signature[start] == '[') {
-               start++;
-               dimension++;
+
+       /*
+        * Answer the type corresponding to the compoundName. Ask the oracle for the
+        * type if its not in the cache. Answer null if the type cannot be found...
+        * likely a fatal error.
+        */
+
+       public ReferenceBinding getType(char[][] compoundName) {
+               ReferenceBinding referenceBinding;
+
+               if (compoundName.length == 1) {
+                       if (defaultPackage == null)
+                               return null;
+
+                       if ((referenceBinding = defaultPackage.getType0(compoundName[0])) == null) {
+                               PackageBinding packageBinding = getPackage0(compoundName[0]);
+                               if (packageBinding != null
+                                               && packageBinding != TheNotFoundPackage)
+                                       return null; // collides with a known package... should
+                                                                       // not call this method in such a case
+                               referenceBinding = askForType(defaultPackage, compoundName[0]);
+                       }
+               } else {
+                       PackageBinding packageBinding = getPackage0(compoundName[0]);
+                       if (packageBinding == TheNotFoundPackage)
+                               return null;
+
+                       if (packageBinding != null) {
+                               for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) {
+                                       if ((packageBinding = packageBinding
+                                                       .getPackage0(compoundName[i])) == null)
+                                               break;
+                                       if (packageBinding == TheNotFoundPackage)
+                                               return null;
+                               }
+                       }
+
+                       if (packageBinding == null)
+                               referenceBinding = askForType(compoundName);
+                       else if ((referenceBinding = packageBinding
+                                       .getType0(compoundName[compoundName.length - 1])) == null)
+                               referenceBinding = askForType(packageBinding,
+                                               compoundName[compoundName.length - 1]);
+               }
+
+               if (referenceBinding == null || referenceBinding == TheNotFoundType)
+                       return null;
+               if (referenceBinding instanceof UnresolvedReferenceBinding)
+                       referenceBinding = ((UnresolvedReferenceBinding) referenceBinding)
+                                       .resolve(this);
+
+               // compoundName refers to a nested type incorrectly (for example,
+               // package1.A$B)
+               if (referenceBinding.isNestedType())
+                       return new ProblemReferenceBinding(compoundName,
+                                       InternalNameProvided);
+               else
+                       return referenceBinding;
+       }
+
+       /*
+        * Answer the type corresponding to the name from the binary file. Does not
+        * ask the oracle for the type if its not found in the cache... instead an
+        * unresolved type is returned which must be resolved before used.
+        * 
+        * NOTE: Does NOT answer base types nor array types!
+        * 
+        * NOTE: Aborts compilation if the class file cannot be found.
+        */
+
+       ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start,
+                       int end) {
+               if (end == -1)
+                       end = signature.length;
+
+               char[][] compoundName = CharOperation.splitOn('/', signature, start,
+                               end);
+               ReferenceBinding binding = getCachedType(compoundName);
+               if (binding == null) {
+                       PackageBinding packageBinding = computePackageFrom(compoundName);
+                       binding = new UnresolvedReferenceBinding(compoundName,
+                                       packageBinding);
+                       packageBinding.addType(binding);
+               } else if (binding == TheNotFoundType) {
+                       problemReporter.isClassPathCorrect(compoundName, null);
+                       return null; // will not get here since the above error aborts
+                                                       // the compilation
+               }
+               return binding;
        }
-       if (end == -1)
-               end = signature.length - 1;
-
-       // Just switch on signature[start] - the L case is the else
-       TypeBinding binding = null;
-       if (start == end) {
-               switch (signature[start]) {
-                       case 'I' :
+
+       /*
+        * Answer the type corresponding to the signature from the binary file. Does
+        * not ask the oracle for the type if its not found in the cache... instead
+        * an unresolved type is returned which must be resolved before used.
+        * 
+        * NOTE: Does answer base types & array types.
+        * 
+        * NOTE: Aborts compilation if the class file cannot be found.
+        */
+
+       TypeBinding getTypeFromSignature(char[] signature, int start, int end) {
+               int dimension = 0;
+               while (signature[start] == '[') {
+                       start++;
+                       dimension++;
+               }
+               if (end == -1)
+                       end = signature.length - 1;
+
+               // Just switch on signature[start] - the L case is the else
+               TypeBinding binding = null;
+               if (start == end) {
+                       switch (signature[start]) {
+                       case 'I':
                                binding = IntBinding;
                                break;
-                       case 'Z' :
+                       case 'Z':
                                binding = BooleanBinding;
                                break;
-                       case 'V' :
+                       case 'V':
                                binding = VoidBinding;
                                break;
-                       case 'C' :
+                       case 'C':
                                binding = CharBinding;
                                break;
-                       case 'D' :
+                       case 'D':
                                binding = DoubleBinding;
                                break;
-                       case 'B' :
+                       case 'B':
                                binding = ByteBinding;
                                break;
-                       case 'F' :
+                       case 'F':
                                binding = FloatBinding;
                                break;
-                       case 'J' :
+                       case 'J':
                                binding = LongBinding;
                                break;
-                       case 'S' :
+                       case 'S':
                                binding = ShortBinding;
                                break;
-                       default :
-                               throw new Error(Util.bind("error.undefinedBaseType",String.valueOf(signature[start]))); //$NON-NLS-1$
+                       default:
+                               throw new Error(
+                                               Util
+                                                               .bind(
+                                                                               "error.undefinedBaseType", String.valueOf(signature[start]))); //$NON-NLS-1$
+                       }
+               } else {
+                       binding = getTypeFromConstantPoolName(signature, start + 1, end);
                }
-       } else {
-               binding = getTypeFromConstantPoolName(signature, start + 1, end);
+
+               if (dimension == 0)
+                       return binding;
+               else
+                       return createArrayType(binding, dimension);
        }
 
-       if (dimension == 0)
-               return binding;
-       else
-               return createArrayType(binding, dimension);
-}
-/* Ask the oracle if a package exists named name in the package named compoundName.
-*/
-
-boolean isPackage(char[][] compoundName, char[] name) {
-       if (compoundName == null || compoundName.length == 0)
-               return nameEnvironment.isPackage(null, name);
-       else
-               return nameEnvironment.isPackage(compoundName, name);
-}
-// The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready.
+       /*
+        * Ask the oracle if a package exists named name in the package named
+        * compoundName.
+        */
 
-public MethodVerifier methodVerifier() {
-       if (verifier == null)
-               verifier = new MethodVerifier(this);
-       return verifier;
-}
-public void reset() {
-       this.defaultPackage = new PackageBinding(this); // assume the default package always exists
-       this.defaultImports = null;
-       this.knownPackages = new HashtableOfPackage();
-
-       this.verifier = null;
-       for (int i = this.uniqueArrayBindings.length; --i >= 0;)
-               this.uniqueArrayBindings[i] = null;
-       this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
-
-       for (int i = this.units.length; --i >= 0;)
-               this.units[i] = null;
-       this.lastUnitIndex = -1;
-       this.lastCompletedUnitIndex = -1;
-       
-       // name environment has a longer life cycle, and must be reset in
-       // the code which created it.
-}
-void updateArrayCache(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
-       nextDimension : for (int i = 0, length = uniqueArrayBindings.length; i < length; i++) {
-               ArrayBinding[] arrayBindings = uniqueArrayBindings[i];
-               if (arrayBindings != null) {
-                       for (int j = 0, max = arrayBindings.length; j < max; j++) {
-                               ArrayBinding currentBinding = arrayBindings[j];
-                               if (currentBinding == null)
-                                       continue nextDimension;
-                               if (currentBinding.leafComponentType == unresolvedType) {
-                                       currentBinding.leafComponentType = resolvedType;
-                                       continue nextDimension;
+       boolean isPackage(char[][] compoundName, char[] name) {
+               if (compoundName == null || compoundName.length == 0)
+                       return nameEnvironment.isPackage(null, name);
+               else
+                       return nameEnvironment.isPackage(compoundName, name);
+       }
+
+       // The method verifier is lazily initialized to guarantee the receiver, the
+       // compiler & the oracle are ready.
+
+       public MethodVerifier methodVerifier() {
+               if (verifier == null)
+                       verifier = new MethodVerifier(this);
+               return verifier;
+       }
+
+       public void reset() {
+               this.defaultPackage = new PackageBinding(this); // assume the default
+                                                                                                               // package always exists
+               this.defaultImports = null;
+               this.knownPackages = new HashtableOfPackage();
+
+               this.verifier = null;
+               for (int i = this.uniqueArrayBindings.length; --i >= 0;)
+                       this.uniqueArrayBindings[i] = null;
+               this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the
+                                                                                                                       // most common 1
+                                                                                                                       // dimension array @
+                                                                                                                       // 50
+
+               for (int i = this.units.length; --i >= 0;)
+                       this.units[i] = null;
+               this.lastUnitIndex = -1;
+               this.lastCompletedUnitIndex = -1;
+
+               // name environment has a longer life cycle, and must be reset in
+               // the code which created it.
+       }
+
+       void updateArrayCache(UnresolvedReferenceBinding unresolvedType,
+                       ReferenceBinding resolvedType) {
+               nextDimension: for (int i = 0, length = uniqueArrayBindings.length; i < length; i++) {
+                       ArrayBinding[] arrayBindings = uniqueArrayBindings[i];
+                       if (arrayBindings != null) {
+                               for (int j = 0, max = arrayBindings.length; j < max; j++) {
+                                       ArrayBinding currentBinding = arrayBindings[j];
+                                       if (currentBinding == null)
+                                               continue nextDimension;
+                                       if (currentBinding.leafComponentType == unresolvedType) {
+                                               currentBinding.leafComponentType = resolvedType;
+                                               continue nextDimension;
+                                       }
                                }
                        }
                }
        }
 }
-}