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.
// 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;
+ }
}
}
}
}
}
-}