return foundType;
}
// at this point the scope is a compilation unit scope
CompilationUnitScope unitScope = (CompilationUnitScope) scope;
HashtableOfObject typeOrPackageCache = unitScope.typeOrPackageCache;
if (typeOrPackageCache != null) {
Binding cachedBinding = (Binding) typeOrPackageCache.get(name);
if (cachedBinding != null) { // can also include NotFound ProblemReferenceBindings if we already know this name is not found
if (cachedBinding instanceof ImportBinding) { // single type import cached in faultInImports(), replace it in the cache with the type
ImportReference importReference = ((ImportBinding) cachedBinding).reference;
if (importReference != null) {
importReference.bits |= ASTNode.Used;
}
if (cachedBinding instanceof ImportConflictBinding)
typeOrPackageCache.put(name, cachedBinding = ((ImportConflictBinding) cachedBinding).conflictingTypeBinding); // already know its visible
else
typeOrPackageCache.put(name, cachedBinding = ((ImportBinding) cachedBinding).resolvedImport); // already know its visible
}
if ((mask & Binding.TYPE) != 0) {
if (foundType != null && foundType.problemId() != ProblemReasons.NotVisible && cachedBinding.problemId() != ProblemReasons.Ambiguous)
return foundType; // problem type from above supercedes NotFound type but not Ambiguous import case
if (cachedBinding instanceof ReferenceBinding)
return cachedBinding; // cached type found in previous walk below
}
if ((mask & Binding.PACKAGE) != 0 && cachedBinding instanceof PackageBinding)
return cachedBinding; // cached package found in previous walk below
}
}
// ask for the imports + name
if ((mask & Binding.TYPE) != 0) {
ImportBinding[] imports = unitScope.imports;
if (imports != null && typeOrPackageCache == null) { // walk single type imports since faultInImports() has not run yet
nextImport : for (int i = 0, length = imports.length; i < length; i++) {
ImportBinding importBinding = imports[i];
if (!importBinding.onDemand) {
if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) {
Binding resolvedImport = unitScope.resolveSingleImport(importBinding, Binding.TYPE);
if (resolvedImport == null) continue nextImport;
if (resolvedImport instanceof TypeBinding) {
ImportReference importReference = importBinding.reference;
if (importReference != null)
importReference.bits |= ASTNode.Used;
return resolvedImport; // already know its visible
}
}
}
}
}
// check if the name is in the current package, skip it if its a sub-package
PackageBinding currentPackage = unitScope.fPackage;
unitScope.recordReference(currentPackage.compoundName, name);
Binding binding = currentPackage.getTypeOrPackage(name);
if (binding instanceof ReferenceBinding) {
ReferenceBinding referenceType = (ReferenceBinding) binding;
if ((referenceType.tagBits & TagBits.HasMissingType) == 0) {
if (typeOrPackageCache != null)
typeOrPackageCache.put(name, referenceType);
return referenceType; // type is always visible to its own package
}
}
// check on demand imports
if (imports != null) {
boolean foundInImport = false;
ReferenceBinding type = null;
for (int i = 0, length = imports.length; i < length; i++) {
ImportBinding someImport = imports[i];
if (someImport.onDemand) {
Binding resolvedImport = someImport.resolvedImport;
ReferenceBinding temp = null;
if (resolvedImport instanceof PackageBinding) {
temp = findType(name, (PackageBinding) resolvedImport, currentPackage);
} else if (someImport.isStatic()) {
temp = findMemberType(name, (ReferenceBinding) resolvedImport); // static imports are allowed to see inherited member types
if (temp != null && !temp.isStatic())
temp = null;
} else {
temp = findDirectMemberType(name, (ReferenceBinding) resolvedImport);
}
if (temp != type && temp != null) {
if (temp.isValidBinding()) {
ImportReference importReference = someImport.reference;
if (importReference != null) {
importReference.bits |= ASTNode.Used;
}
if (foundInImport) {
// Answer error binding -- import on demand conflict; name found in two import on demand packages.
temp = new ProblemReferenceBinding(new char[][]{name}, type, ProblemReasons.Ambiguous);
if (typeOrPackageCache != null)
typeOrPackageCache.put(name, temp);
return temp;
}
type = temp;
foundInImport = true;
} else if (foundType == null) {
foundType = temp;
}
}
}
}
if (type != null) {
if (typeOrPackageCache != null)
typeOrPackageCache.put(name, type);
return type;
}
}
}
unitScope.recordSimpleReference(name);
if ((mask & Binding.PACKAGE) != 0) {
PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name);
if (packageBinding != null) {
if (typeOrPackageCache != null)
typeOrPackageCache.put(name, packageBinding);
return packageBinding;
}
}
// Answer error binding -- could not find name
if (foundType == null) {
char[][] qName = new char[][] { name };
ReferenceBinding closestMatch = null;
if ((mask & Binding.PACKAGE) != 0) {
if (needResolve) {
closestMatch = environment().createMissingType(unitScope.fPackage, qName);
}
} else {
PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name);
if (packageBinding == null || !packageBinding.isValidBinding()) {
if (needResolve) {
closestMatch = environment().createMissingType(unitScope.fPackage, qName);
}
}
}
foundType = new ProblemReferenceBinding(qName, closestMatch, ProblemReasons.NotFound);
if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) { // only put NotFound type in cache if you know its not a package
typeOrPackageCache.put(name, foundType);
}
} else if ((foundType.tagBits & TagBits.HasMissingType) != 0) {
char[][] qName = new char[][] { name };
foundType = new ProblemReferenceBinding(qName, foundType, ProblemReasons.NotFound);
if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) // only put NotFound type in cache if you know its not a package
typeOrPackageCache.put(name, foundType);
}
return foundType;
}