Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2000, 2012 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: IBM Corporation - initial API and implementation Stephan Herrmann - contributions for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment bug 186342 - [compiler][null] Using annotations for null checking bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults /
  
  package org.eclipse.jdt.internal.compiler.lookup;
  
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map;
  import java.util.Set;
  
  
  public class LookupEnvironment implements ProblemReasonsTypeConstants {

Map from typeBinding -> accessRestriction rule
  
  	private Map accessRestrictions;
  	private int lastCompletedUnitIndex = -1;
  	private int lastUnitIndex = -1;
  
  
  	// indicate in which step on the compilation we are.
  	// step 1 : build the reference binding
  	// step 2 : conect the hierarchy (connect bindings)
  	// step 3 : build fields and method bindings.
  	private int stepCompleted;
  
  	
  	// key is a string with the method selector value is an array of method bindings
  	private SimpleLookupTable uniqueGetClassMethodBinding// https://bugs.eclipse.org/bugs/show_bug.cgi?id=300734
  
  	public CompilationUnitDeclaration unitBeingCompleted = null// only set while completing units
  	public Object missingClassFileLocation = null// only set when resolving certain references, to help locating problems
  	private MethodVerifier verifier;
  
  
  	private ArrayList missingTypes;
  	public boolean isProcessingAnnotations = false;
  	public boolean mayTolerateMissingType = false;
  
  	PackageBinding nullableAnnotationPackage;			// the package supposed to contain the Nullable annotation type
  	PackageBinding nonnullAnnotationPackage;			// the package supposed to contain the NonNull annotation type
  	PackageBinding nonnullByDefaultAnnotationPackage;	// the package supposed to contain the NonNullByDefault annotation type
  
  	final static int BUILD_FIELDS_AND_METHODS = 4;
  	final static int BUILD_TYPE_HIERARCHY = 1;
  	final static int CHECK_AND_SET_IMPORTS = 2;
  	final static int CONNECT_TYPE_HIERARCHY = 3;
  
  
  
  public LookupEnvironment(ITypeRequestor typeRequestorCompilerOptions globalOptionsProblemReporter problemReporterINameEnvironment nameEnvironment) {
  	this. = typeRequestor;
  	this. = globalOptions;
  	this. = problemReporter;
  	this. = new PackageBinding(this); // assume the default package always exists
 	this. = null;
 	this. = nameEnvironment;
 	this. = new ArrayBinding[5][];
 	this.[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
 	this. = null;
 	this. = new HashMap(3);
 	this. = ClassFilePool.newInstance();
 	this. = new HashSet();
 }

Ask the name environment for a type which corresponds to the compoundName. Answer null if the name cannot be found.
 
 
 public ReferenceBinding askForType(char[][] compoundName) {
 	NameEnvironmentAnswer answer = this..findType(compoundName);
 	if (answer == nullreturn null;
 
 	if (answer.isBinaryType()) {
 		// the type was found as a .class file
 		this..accept(answer.getBinaryType(), computePackageFrom(compoundNamefalse /* valid pkg */), answer.getAccessRestriction());
 	} else if (answer.isCompilationUnit()) {
 		// the type was found as a .java file, try to build it then search the cache
 	} else if (answer.isSourceType()) {
 		// the type was found as a source model
 		this..accept(answer.getSourceTypes(), computePackageFrom(compoundNamefalse /* valid pkg */), answer.getAccessRestriction());
 	}
 	return getCachedType(compoundName);
 }
 /* Ask the oracle for a type named name in the packageBinding.
 * Answer null if the name cannot be found.
 */
 
 ReferenceBinding askForType(PackageBinding packageBindingchar[] name) {
 	if (packageBinding == null) {
 		packageBinding = this.;
 	}
 	NameEnvironmentAnswer answer = this..findType(namepackageBinding.compoundName);
 	if (answer == null)
 		return null;
 
 	if (answer.isBinaryType()) {
 		// the type was found as a .class file
 		this..accept(answer.getBinaryType(), packageBindinganswer.getAccessRestriction());
 	} else if (answer.isCompilationUnit()) {
 		// the type was found as a .java file, try to build it then search the cache
 		try {
 		} catch (AbortCompilation abort) {
 			if (CharOperation.equals(name.))
 				return null// silently, requestor may not be able to handle compilation units (HierarchyResolver)
 			throw abort;
 		}
 	} else if (answer.isSourceType()) {
 		// the type was found as a source model
 		this..accept(answer.getSourceTypes(), packageBindinganswer.getAccessRestriction());
 	}
 	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 unitAccessRestriction accessRestriction) {
 	CompilationUnitScope scope = new CompilationUnitScope(unitthis);
 	scope.buildTypeBindings(accessRestriction);
 	int unitsLength = this..length;
 	if (++this. >= unitsLength)
 		System.arraycopy(this., 0, this. = new CompilationUnitDeclaration[2 * unitsLength], 0, unitsLength);
 	this.[this.] = 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.
 */
 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryTypeAccessRestriction accessRestriction) {
 	return cacheBinaryType(binaryTypetrueaccessRestriction);
 }
 
 /* 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 binaryTypeboolean needFieldsAndMethodsAccessRestriction accessRestriction) {
 	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(binaryTypecomputePackageFrom(compoundNamefalse /* valid pkg */), needFieldsAndMethodsaccessRestriction);
 	return null// the type already exists & can be retrieved from the cache
 }
 
 public void completeTypeBindings() {
 
 	for (int i = this. + 1; i <= this.i++) {
 	    (this. = this.[i])..checkAndSetImports();
 	}
 
 	for (int i = this. + 1; i <= this.i++) {
 	    (this. = this.[i])..connectTypeHierarchy();
 	}
 
 	for (int i = this. + 1; i <= this.i++) {
 		CompilationUnitScope unitScope = (this. = this.[i]).;
 		unitScope.buildFieldsAndMethods();
 		this.[i] = null// release unnecessary reference to the parsed unit
 	}
 	this. = null;
 }
 
 /*
 * 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(CompilationUnitDeclaration parsedUnit) {
 		// 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.
 	} else {
 		if (parsedUnit.scope == nullreturn// parsing errors were too severe
 
 			(this. = parsedUnit)..checkAndSetImports();
 
 
 		this. = null;
 	}
 }
 
 /*
 * 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
 */
 
 /*
 * 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 parsedUnitboolean buildFieldsAndMethods) {
 	if (parsedUnit.scope == nullreturn// parsing errors were too severe
 
 	(this. = parsedUnit)..checkAndSetImports();
 	parsedUnit.scope.connectTypeHierarchy();
 	parsedUnit.scope.checkParameterizedTypes();
 	if (buildFieldsAndMethods)
 		parsedUnit.scope.buildFieldsAndMethods();
 	this. = null;
 }
 
 /*
 * Used by other compiler tools which do not start by calling completeTypeBindings()
 * and have more than 1 unit to complete.
 *
 * 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[] parsedUnitsboolean[] buildFieldsAndMethodsint unitCount) {
 	for (int i = 0; i < unitCounti++) {
 		CompilationUnitDeclaration parsedUnit = parsedUnits[i];
 		if (parsedUnit.scope != null)
 			(this. = parsedUnit)..checkAndSetImports();
 	}
 
 	for (int i = 0; i < unitCounti++) {
 		CompilationUnitDeclaration parsedUnit = parsedUnits[i];
 		if (parsedUnit.scope != null)
 	}
 
 	for (int i = 0; i < unitCounti++) {
 		CompilationUnitDeclaration parsedUnit = parsedUnits[i];
 		if (parsedUnit.scope != null) {
 			if (buildFieldsAndMethods[i])
 				parsedUnit.scope.buildFieldsAndMethods();
 		}
 	}
 
 	this. = null;
 }
 	if (this. == null) {
 		this. = new MethodBinding(
 				(objectClone.modifiers & ~.) | .,
 				objectClone.returnType,
 				.// no exception for array specific method
 				(ReferenceBinding)objectClone.returnType);
 	}
 	return this.;
 	
 }
 	TypeBinding boxedType;
 	switch (type.id) {
 			return .;
 			return .;
 			return .;
 			return .;
 			return .;
 			return .;
 
 		case . :
 			boxedType = getType();
 			if (boxedType != nullreturn boxedType;
 		case . :
 			boxedType = getType();
 			if (boxedType != nullreturn boxedType;
 		case . :
 			boxedType = getType();
 			if (boxedType != nullreturn boxedType;
 		case . :
 			boxedType = getType();
 			if (boxedType != nullreturn boxedType;
 		case . :
 			boxedType = getType();
 			if (boxedType != nullreturn boxedType;
 		case . :
 			boxedType = getType();
 			if (boxedType != nullreturn boxedType;
 		case . :
 			boxedType = getType();
 			if (boxedType != nullreturn boxedType;
 		case . :
 			boxedType = getType();
 			if (boxedType != nullreturn boxedType;
 //		case TypeIds.T_int :
 //			return getResolvedType(JAVA_LANG_INTEGER, null);
 //		case TypeIds.T_byte :
 //			return getResolvedType(JAVA_LANG_BYTE, null);
 //		case TypeIds.T_short :
 //			return getResolvedType(JAVA_LANG_SHORT, null);
 //		case TypeIds.T_char :
 //			return getResolvedType(JAVA_LANG_CHARACTER, null);
 //		case TypeIds.T_long :
 //			return getResolvedType(JAVA_LANG_LONG, null);
 //		case TypeIds.T_float :
 //			return getResolvedType(JAVA_LANG_FLOAT, null);
 //		case TypeIds.T_double :
 //			return getResolvedType(JAVA_LANG_DOUBLE, null);
 //		case TypeIds.T_boolean :
 //			return getResolvedType(JAVA_LANG_BOOLEAN, null);
 	}
 	// allow indirect unboxing conversion for wildcards and type parameters
 	switch (type.kind()) {
 			switch (type.erasure().) {
 					return .;
 					return .;
 					return .;
 					return .;
 					return .;
 					return .;
 			}
 	}
 	return type;
 }
 
 private PackageBinding computePackageFrom(char[][] constantPoolNameboolean isMissing) {
 	if (constantPoolName.length == 1)
 		return this.;
 
 	PackageBinding packageBinding = getPackage0(constantPoolName[0]);
 	if (packageBinding == null || packageBinding == ) {
 		packageBinding = new PackageBinding(constantPoolName[0], this);
 		if (isMissingpackageBinding.tagBits |= .;
 		this..put(constantPoolName[0], packageBinding);
 	}
 
 	for (int i = 1, length = constantPoolName.length - 1; i < lengthi++) {
 		PackageBinding parent = packageBinding;
 		if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == ) {
 			packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parentthis);
 			if (isMissing) {
 				packageBinding.tagBits |= .;
 			}
 			parent.addPackage(packageBinding);
 		}
 	}
 	return packageBinding;
 }

Convert a given source type into a parameterized form if generic. generic X<E> --> param X<E>
 
 	if (originalType != null) {
 		boolean isGeneric = originalType.isGenericType();
 		ReferenceBinding originalEnclosingType = originalType.enclosingType();
 		ReferenceBinding convertedEnclosingType = originalEnclosingType;
 		boolean needToConvert = isGeneric;
 		if (originalEnclosingType != null) {
 			convertedEnclosingType = originalType.isStatic()
 				? (ReferenceBindingconvertToRawType(originalEnclosingTypefalse /*do not force conversion of enclosing types*/)
 				: convertToParameterizedType(originalEnclosingType);
 			needToConvert |= originalEnclosingType != convertedEnclosingType;
 		}
 		if (needToConvert) {
 			return createParameterizedType(originalTypeisGeneric ? originalType.typeVariables() : nullconvertedEnclosingType);
 		}
 	}
 	return originalType;
 }

Returns the given binding's raw type binding.

Parameters:
type the TypeBinding to raw convert
forceRawEnclosingType forces recursive raw conversion of enclosing types (used in Javadoc references only)
Returns:
TypeBinding the raw converted TypeBinding
 
 public TypeBinding convertToRawType(TypeBinding typeboolean forceRawEnclosingType) {
 	int dimension;
 	TypeBinding originalType;
 	switch(type.kind()) {
 		case . :
 			return type;
 			dimension = type.dimensions();
 			originalType = type.leafComponentType();
 			break;
 		default:
 			if (type.id == .)
 				return type// Object is not generic
 			dimension = 0;
 			originalType = type;
 	}
 	boolean needToConvert;
 	switch (originalType.kind()) {
 		case . :
 			return type;
 			needToConvert = true;
 			break;
 			ParameterizedTypeBinding paramType = (ParameterizedTypeBindingoriginalType;
 			needToConvert = paramType.genericType().isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
 			break;
 		default :
 			needToConvert = false;
 			break;
 	}
 	ReferenceBinding originalEnclosing = originalType.enclosingType();
 	TypeBinding convertedType;
 	if (originalEnclosing == null) {
 		convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
 	} else {
 		ReferenceBinding convertedEnclosing;
 		if (originalEnclosing.kind() == .) {
 			needToConvert |= !((ReferenceBinding)originalType).isStatic();
 			convertedEnclosing = originalEnclosing;
 		} else if (forceRawEnclosingType && !needToConvert/*stop recursion when conversion occurs*/) {
 			convertedEnclosing = (ReferenceBindingconvertToRawType(originalEnclosingforceRawEnclosingType);
 			needToConvert = originalEnclosing != convertedEnclosing// only convert generic or parameterized types
 		} else if (needToConvert || ((ReferenceBinding)originalType).isStatic()) {
 			convertedEnclosing = (ReferenceBindingconvertToRawType(originalEnclosingfalse);
 		} else {
 			convertedEnclosing = convertToParameterizedType(originalEnclosing);
 		}
 		if (needToConvert) {
 			convertedType = createRawType((ReferenceBindingoriginalType.erasure(), convertedEnclosing);
 		} else if (originalEnclosing != convertedEnclosing) {
 			convertedType = createParameterizedType((ReferenceBindingoriginalType.erasure(), nullconvertedEnclosing);
 		} else {
 			convertedType = originalType;
 		}
 	}
 	if (originalType != convertedType) {
 		return dimension > 0 ? (TypeBinding)createArrayType(convertedTypedimension) : convertedType;
 	}
 	return type;
 }

Convert an array of types in raw forms. Only allocate an array if anything is different.
 
 public ReferenceBinding[] convertToRawTypes(ReferenceBinding[] originalTypesboolean forceErasureboolean forceRawEnclosingType) {
 	if (originalTypes == nullreturn null;
     ReferenceBinding[] convertedTypes = originalTypes;
     for (int i = 0, length = originalTypes.lengthi < lengthi++) {
         ReferenceBinding originalType = originalTypes[i];
         ReferenceBinding convertedType = (ReferenceBindingconvertToRawType(forceErasure ? originalType.erasure() : originalTypeforceRawEnclosingType);
         if (convertedType != originalType) {        
             if (convertedTypes == originalTypes) {
                 System.arraycopy(originalTypes, 0, convertedTypes = new ReferenceBinding[length], 0, i);
             }
             convertedTypes[i] = convertedType;
         } else if (convertedTypes != originalTypes) {
             convertedTypes[i] = originalType;
         }
     }
     return convertedTypes;
 }
 
 // variation for unresolved types in binaries (consider generic type as raw)
 	int dimension;
 	TypeBinding originalType;
 	switch(type.kind()) {
 		case . :
 			return type;
 			dimension = type.dimensions();
 			originalType = type.leafComponentType();
 			break;
 		default:
 			if (type.id == .)
 				return type// Object is not generic
 			dimension = 0;
 			originalType = type;
 	}
 	boolean needToConvert;
 	switch (originalType.kind()) {
 		case . :
 			return type;
 			needToConvert = true;
 			break;
 			ParameterizedTypeBinding paramType = (ParameterizedTypeBindingoriginalType;
 			needToConvert = paramType.genericType().isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
 			break;
 		default :
 			needToConvert = false;
 			break;
 	}
 	ReferenceBinding originalEnclosing = originalType.enclosingType();
 	TypeBinding convertedType;
 	if (originalEnclosing == null) {
 		convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
 	} else {
 		ReferenceBinding convertedEnclosing = (ReferenceBindingconvertUnresolvedBinaryToRawType(originalEnclosing);
 		if (convertedEnclosing != originalEnclosing) {
 			needToConvert |= !((ReferenceBinding)originalType).isStatic();
 		}
 		if (needToConvert) {
 			convertedType = createRawType((ReferenceBindingoriginalType.erasure(), convertedEnclosing);
 		} else if (originalEnclosing != convertedEnclosing) {
 			convertedType = createParameterizedType((ReferenceBindingoriginalType.erasure(), nullconvertedEnclosing);
 		} else {
 			convertedType = originalType;
 		}
 	}
 	if (originalType != convertedType) {
 		return dimension > 0 ? (TypeBinding)createArrayType(convertedTypedimension) : convertedType;
 	}
 	return type;
 }
 /*
  *  Used to guarantee annotation identity.
  */
 	if (pairs.length != 0) {
 		AnnotationBinding.setMethodBindings(annotationTypepairs);
 	}
 	return new AnnotationBinding(annotationTypepairs);
 }
 
 /*
  *  Used to guarantee array type identity.
  */
 public ArrayBinding createArrayType(TypeBinding leafComponentTypeint dimensionCount) {
 	if (leafComponentType instanceof LocalTypeBinding// cache local type arrays with the local type itself
 		return ((LocalTypeBindingleafComponentType).createArrayType(dimensionCountthis);
 
 	// find the array binding cache for this dimension
 	int dimIndex = dimensionCount - 1;
 	int length = this..length;
 	ArrayBinding[] arrayBindings;
 	if (dimIndex < length) {
 		if ((arrayBindings = this.[dimIndex]) == null)
 			this.[dimIndex] = arrayBindings = new ArrayBinding[10];
 	} else {
 		System.arraycopy(
 			this. = new ArrayBinding[dimensionCount][], 0,
 			length);
 		this.[dimIndex] = arrayBindings = new ArrayBinding[10];
 	}
 
 	// 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(leafComponentTypedimensionCountthis);
 		if (currentBinding.leafComponentType == leafComponentType)
 			return currentBinding;
 	}
 
 	// no matching array, no space left
 	System.arraycopy(
 		arrayBindings, 0,
 		(arrayBindings = new ArrayBinding[length * 2]), 0,
 		length);
 	this.[dimIndex] = arrayBindings;
 	return arrayBindings[length] = new ArrayBinding(leafComponentTypedimensionCountthis);
 }
 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryTypePackageBinding packageBindingAccessRestriction accessRestriction) {
 	return createBinaryTypeFrom(binaryTypepackageBindingtrueaccessRestriction);
 }
 
 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryTypePackageBinding packageBindingboolean needFieldsAndMethodsAccessRestriction accessRestriction) {
 	BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBindingbinaryTypethis);
 
 	// resolve any array bindings which reference the unresolvedType
 	ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
 	if (cachedType != null) { // update reference to unresolved binding after having read classfile (knows whether generic for raw conversion)
 		if (cachedType instanceof UnresolvedReferenceBinding) {
 			((UnresolvedReferenceBindingcachedType).setResolvedType(binaryBindingthis);
 		} else {
 			if (cachedType.isBinaryBinding()) // sanity check... at this point the cache should ONLY contain unresolved types
 				return (BinaryTypeBindingcachedType;
 			// it is possible with a large number of source files (exceeding AbstractImageBuilder.MAX_AT_ONCE) that a member type can be in the cache as an UnresolvedType,
 			// but because its enclosingType is resolved while its created (call to BinaryTypeBinding constructor), its replaced with a source type
 			return null;
 		}
 	}
 	packageBinding.addType(binaryBinding);
 	setAccessRestriction(binaryBindingaccessRestriction);
 	// need type annotations before processing methods (for @NonNullByDefault)
 		binaryBinding.scanTypeForNullDefaultAnnotation(binaryTypepackageBindingbinaryBinding);
 	binaryBinding.cachePartsFrom(binaryTypeneedFieldsAndMethods);
 	return binaryBinding;
 }
 
 /*
  * Used to create types denoting missing types.
  * If package is given, then reuse the package; if not then infer a package from compound name.
  * If the package is existing, then install the missing type in type cache
 */
 public MissingTypeBinding createMissingType(PackageBinding packageBindingchar[][] compoundName) {
 	// create a proxy for the missing BinaryType
 	if (packageBinding == null) {
 		packageBinding = computePackageFrom(compoundNametrue /* missing */);
 		if (packageBinding == packageBinding = this.;
 	}
 	MissingTypeBinding missingType = new MissingTypeBinding(packageBindingcompoundNamethis);
 	if (missingType.id != .) {
 		// make Object be its superclass - it could in turn be missing as well
 		if (objectType == null) {
 			objectType = createMissingType(null.);	// create a proxy for the missing Object type
 		}
 		missingType.setMissingSuperclass(objectType);
 	}
 	packageBinding.addType(missingType);
 	if (this. == null)
 		this. = new ArrayList(3);
 	this..add(missingType);
 	return missingType;
 }
 
 /*
 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
 * 2. Create the field bindings
 * 3. Create the method bindings
 */
 public PackageBinding createPackage(char[][] compoundName) {
 	PackageBinding packageBinding = getPackage0(compoundName[0]);
 	if (packageBinding == null || packageBinding == ) {
 		packageBinding = new PackageBinding(compoundName[0], this);
 		this..put(compoundName[0], packageBinding);
 	}
 
 	for (int i = 1, length = compoundName.lengthi < lengthi++) {
 		// 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
 		// NOTE: empty packages are not packages according to changes in JLS v2, 7.4.3
 		// so not all types cause collision errors when they're created even though the package did exist
 		ReferenceBinding type = packageBinding.getType0(compoundName[i]);
 		if (type != null && type !=  && !(type instanceof UnresolvedReferenceBinding))
 			return null;
 
 		PackageBinding parent = packageBinding;
 		if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == ) {
 			// 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 to check whenever a package is created
 			if (this..findType(compoundName[i], parent.compoundName) != null)
 				return null;
 
 			packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parentthis);
 			parent.addPackage(packageBinding);
 		}
 	}
 	return packageBinding;
 }
 
 	// cached info is array of already created parameterized types for this type
 	boolean needToGrow = false;
 	int index = 0;
 	if (cachedInfo != null){
 		nextCachedMethod :
 			// iterate existing parameterized for reusing one with same type arguments if any
 			for (int max = cachedInfo.lengthindex < maxindex++){
 				ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index];
 				if (cachedMethod == nullbreak nextCachedMethod;
 				if (!cachedMethod.isRawcontinue nextCachedMethod;
 				if (cachedMethod.declaringClass != (rawType == null ? genericMethod.declaringClass : rawType)) continue nextCachedMethod;
 				return cachedMethod;
 		}
 		needToGrow = true;
 	} else {
 		cachedInfo = new ParameterizedGenericMethodBinding[5];
 		this..put(genericMethodcachedInfo);
 	}
 	// grow cache ?
 	int length = cachedInfo.length;
 	if (needToGrow && index == length){
 		System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedGenericMethodBinding[length*2], 0, length);
 		this..put(genericMethodcachedInfo);
 	}
 	// add new binding
 	ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethodrawTypethis);
 	cachedInfo[index] = parameterizedGenericMethod;
 	return parameterizedGenericMethod;
 }
 
 	// cached info is array of already created parameterized types for this type
 	int argLength = typeArguments == null ? 0: typeArguments.length;
 	boolean needToGrow = false;
 	int index = 0;
 	if (cachedInfo != null){
 		nextCachedMethod :
 			// iterate existing parameterized for reusing one with same type arguments if any
 			for (int max = cachedInfo.lengthindex < maxindex++){
 				ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index];
 				if (cachedMethod == nullbreak nextCachedMethod;
 				if (cachedMethod.isRawcontinue nextCachedMethod;
 				TypeBinding[] cachedArguments = cachedMethod.typeArguments;
 				int cachedArgLength = cachedArguments == null ? 0 : cachedArguments.length;
 				if (argLength != cachedArgLengthcontinue nextCachedMethod;
 				for (int j = 0; j < cachedArgLengthj++){
 					if (typeArguments[j] != cachedArguments[j]) continue nextCachedMethod;
 				}
 				// all arguments match, reuse current
 				return cachedMethod;
 		}
 		needToGrow = true;
 	} else {
 		cachedInfo = new ParameterizedGenericMethodBinding[5];
 		this..put(genericMethodcachedInfo);
 	}
 	// grow cache ?
 	int length = cachedInfo.length;
 	if (needToGrow && index == length){
 		System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedGenericMethodBinding[length*2], 0, length);
 		this..put(genericMethodcachedInfo);
 	}
 	// add new binding
 	ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethodtypeArgumentsthis);
 	cachedInfo[index] = parameterizedGenericMethod;
 	return parameterizedGenericMethod;
 }
 public PolymorphicMethodBinding createPolymorphicMethod(MethodBinding originalPolymorphicMethodTypeBinding[] parameters) {
 	// cached info is array of already created polymorphic methods for this type
 	String key = new String(originalPolymorphicMethod.selector);
 	int parametersLength = parameters == null ? 0: parameters.length;
 	TypeBinding[] parametersTypeBinding = new TypeBinding[parametersLength]; 
 	for (int i = 0; i < parametersLengthi++) {
 		TypeBinding parameterTypeBinding = parameters[i];
 		if (parameterTypeBinding.id == .) {
 			parametersTypeBinding[i] = getType();
 		} else {
 			parametersTypeBinding[i] = parameterTypeBinding.erasure();
 		}
 	}
 	boolean needToGrow = false;
 	int index = 0;
 	if (cachedInfo != null) {
 		nextCachedMethod :
 			// iterate existing polymorphic method for reusing one with same type arguments if any
 			for (int max = cachedInfo.lengthindex < maxindex++) {
 				PolymorphicMethodBinding cachedMethod = cachedInfo[index];
 				if (cachedMethod == null) {
 					break nextCachedMethod;
 				}
 				if (cachedMethod.matches(parametersTypeBindingoriginalPolymorphicMethod.returnType)) {
 					return cachedMethod;
 				}
 		}
 		needToGrow = true;
 	} else {
 		cachedInfo = new PolymorphicMethodBinding[5];
 		this..put(keycachedInfo);
 	}
 	// grow cache ?
 	int length = cachedInfo.length;
 	if (needToGrow && index == length) {
 		System.arraycopy(cachedInfo, 0, cachedInfo = new PolymorphicMethodBinding[length*2], 0, length);
 		this..put(keycachedInfo);
 	}
 	// add new binding
 			originalPolymorphicMethod,
 			parametersTypeBinding);
 	cachedInfo[index] = polymorphicMethod;
 	return polymorphicMethod;
 }
 	// update the return type to be the given return type, but reuse existing binding if one can match
 	String key = new String(binding.selector);
 	boolean needToGrow = false;
 	int index = 0;
 	TypeBinding[] parameters = binding.parameters;
 	if (cachedInfo != null) {
 		nextCachedMethod :
 			// iterate existing polymorphic method for reusing one with same type arguments if any
 			for (int max = cachedInfo.lengthindex < maxindex++) {
 				PolymorphicMethodBinding cachedMethod = cachedInfo[index];
 				if (cachedMethod == null) {
 					break nextCachedMethod;
 				}
 				if (cachedMethod.matches(parameterstypeBinding)) {
 					return cachedMethod;
 				}
 		}
 		needToGrow = true;
 	} else {
 		cachedInfo = new PolymorphicMethodBinding[5];
 		this..put(keycachedInfo);
 	}
 	// grow cache ?
 	int length = cachedInfo.length;
 	if (needToGrow && index == length) {
 		System.arraycopy(cachedInfo, 0, cachedInfo = new PolymorphicMethodBinding[length*2], 0, length);
 		this..put(keycachedInfo);
 	}
 	// add new binding
 			binding.original(),
 			typeBinding,
 			parameters);
 	cachedInfo[index] = polymorphicMethod;
 	return polymorphicMethod;
 }
 public ParameterizedMethodBinding createGetClassMethod(TypeBinding receiverTypeMethodBinding originalMethodScope scope) {
 	// see if we have already cached this method for the given receiver type.
 	ParameterizedMethodBinding retVal = null;
 	if (this. == null) {
 	} else {
 	}
 	if (retVal == null) {
 		retVal = ParameterizedMethodBinding.instantiateGetClass(receiverTypeoriginalMethodscope);
 		this..put(receiverTyperetVal);
 	}
 	return retVal;
 }
 
 public ParameterizedTypeBinding createParameterizedType(ReferenceBinding genericTypeTypeBinding[] typeArgumentsReferenceBinding enclosingType) {
 	// cached info is array of already created parameterized types for this type
 	int argLength = typeArguments == null ? 0: typeArguments.length;
 	boolean needToGrow = false;
 	int index = 0;
 	if (cachedInfo != null){
 		nextCachedType :
 			// iterate existing parameterized for reusing one with same type arguments if any
 			for (int max = cachedInfo.lengthindex < maxindex++){
 			    ParameterizedTypeBinding cachedType = cachedInfo[index];
 			    if (cachedType == nullbreak nextCachedType;
 			    if (cachedType.actualType() != genericTypecontinue nextCachedType; // remain of unresolved type
 			    if (cachedType.enclosingType() != enclosingTypecontinue nextCachedType;
 				TypeBinding[] cachedArguments = cachedType.arguments;
 				int cachedArgLength = cachedArguments == null ? 0 : cachedArguments.length;
 				if (argLength != cachedArgLengthcontinue nextCachedType; // would be an error situation (from unresolved binaries)
 				for (int j = 0; j < cachedArgLengthj++){
 					if (typeArguments[j] != cachedArguments[j]) continue nextCachedType;
 				}
 				// all arguments match, reuse current
 				return cachedType;
 		}
 		needToGrow = true;
 	} else {
 		cachedInfo = new ParameterizedTypeBinding[5];
 		this..put(genericTypecachedInfo);
 	}
 	// grow cache ?
 	int length = cachedInfo.length;
 	if (needToGrow && index == length){
 		System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedTypeBinding[length*2], 0, length);
 		this..put(genericTypecachedInfo);
 	}
 	// add new binding
 	ParameterizedTypeBinding parameterizedType = new ParameterizedTypeBinding(genericType,typeArgumentsenclosingTypethis);
 	cachedInfo[index] = parameterizedType;
 	return parameterizedType;
 }
 
 public RawTypeBinding createRawType(ReferenceBinding genericTypeReferenceBinding enclosingType) {
 	// cached info is array of already created raw types for this type
 	RawTypeBinding[] cachedInfo = (RawTypeBinding[])this..get(genericType);
 	boolean needToGrow = false;
 	int index = 0;
 	if (cachedInfo != null){
 		nextCachedType :
 			// iterate existing parameterized for reusing one with same type arguments if any
 			for (int max = cachedInfo.lengthindex < maxindex++){
 			    RawTypeBinding cachedType = cachedInfo[index];
 			    if (cachedType == nullbreak nextCachedType;
 			    if (cachedType.actualType() != genericTypecontinue nextCachedType; // remain of unresolved type
 			    if (cachedType.enclosingType() != enclosingTypecontinue nextCachedType;
 				// all enclosing type match, reuse current
 				return cachedType;
 		}
 		needToGrow = true;
 	} else {
 		cachedInfo = new RawTypeBinding[1];
 		this..put(genericTypecachedInfo);
 	}
	// grow cache ?
	int length = cachedInfo.length;
	if (needToGrow && index == length){
		System.arraycopy(cachedInfo, 0, cachedInfo = new RawTypeBinding[length*2], 0, length);
		this..put(genericTypecachedInfo);
	// add new binding