/** * Checks additional bindings (methods or types) imported from a single static import. Method is * tried first, followed by type. If found, records them. If in the process, import is flagged as * duplicate, -1 is returned. * * @param compoundName * @param typesBySimpleNames * @param mask * @param importReference */ private void checkMoreStaticBindings( char[][] compoundName, HashtableOfType typesBySimpleNames, int mask, ImportReference importReference) { Binding importBinding = findSingleStaticImport(compoundName, mask); if (!importBinding.isValidBinding()) { // only continue if the same kind's ambiguous binding is returned // may have found an ambiguous type when looking for field or method. Don't continue in that // case if (importBinding.problemId() == ProblemReasons.Ambiguous) { // keep it unless a duplicate can be found below checkAndRecordImportBinding( importBinding, typesBySimpleNames, importReference, compoundName); } } else { checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); } if (((mask & Binding.METHOD) != 0) && (importBinding.kind() == Binding.METHOD)) { // found method // type is left to be looked for // reset METHOD bit to enable lookup for only type mask &= ~Binding.METHOD; // now search for a type binding checkMoreStaticBindings(compoundName, typesBySimpleNames, mask, importReference); } }
void faultInImports() { boolean unresolvedFound = false; // should report unresolved only if we are not suppressing caching of failed resolutions boolean reportUnresolved = !this.suppressImportErrors; if (this.typeOrPackageCache != null && !this.skipCachingImports) return; // can be called when a field constant is resolved before static imports if (this.referenceContext.imports == null) { this.typeOrPackageCache = new HashtableOfObject(1); return; } // collect the top level type names if a single type import exists int numberOfStatements = this.referenceContext.imports.length; HashtableOfType typesBySimpleNames = null; for (int i = 0; i < numberOfStatements; i++) { if ((this.referenceContext.imports[i].bits & ASTNode.OnDemand) == 0) { typesBySimpleNames = new HashtableOfType(this.topLevelTypes.length + numberOfStatements); for (int j = 0, length = this.topLevelTypes.length; j < length; j++) typesBySimpleNames.put(this.topLevelTypes[j].sourceName, this.topLevelTypes[j]); break; } } // allocate the import array, add java.lang.* by default int numberOfImports = numberOfStatements + 1; for (int i = 0; i < numberOfStatements; i++) { ImportReference importReference = this.referenceContext.imports[i]; if (((importReference.bits & ASTNode.OnDemand) != 0) && CharOperation.equals(TypeConstants.JAVA_LANG, importReference.tokens) && !importReference.isStatic()) { numberOfImports--; break; } } this.tempImports = new ImportBinding[numberOfImports]; this.tempImports[0] = getDefaultImports()[0]; this.importPtr = 1; // keep static imports with normal imports until there is a reason to split them up // on demand imports continue to be packages & types. need to check on demand type imports for // fields/methods // single imports change from being just types to types or fields nextImport: for (int i = 0; i < numberOfStatements; i++) { ImportReference importReference = this.referenceContext.imports[i]; char[][] compoundName = importReference.tokens; // skip duplicates or imports of the current package for (int j = 0; j < this.importPtr; j++) { ImportBinding resolved = this.tempImports[j]; if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0) && resolved.isStatic() == importReference.isStatic()) { if (CharOperation.equals(compoundName, resolved.compoundName)) { problemReporter().unusedImport(importReference); // since skipped, must be reported now continue nextImport; } } } if ((importReference.bits & ASTNode.OnDemand) != 0) { if (CharOperation.equals(compoundName, this.currentPackageName)) { problemReporter().unusedImport(importReference); // since skipped, must be reported now continue nextImport; } Binding importBinding = findImport(compoundName, compoundName.length); if (!importBinding.isValidBinding()) { problemReporter().importProblem(importReference, importBinding); continue nextImport; } if (importReference.isStatic() && importBinding instanceof PackageBinding) { problemReporter().cannotImportPackage(importReference); continue nextImport; } recordImportBinding(new ImportBinding(compoundName, true, importBinding, importReference)); } else { Binding importBinding = findSingleImport( compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, importReference.isStatic()); if (!importBinding.isValidBinding()) { if (importBinding.problemId() == ProblemReasons.Ambiguous) { // keep it unless a duplicate can be found below } else { unresolvedFound = true; if (reportUnresolved) { problemReporter().importProblem(importReference, importBinding); } continue nextImport; } } if (importBinding instanceof PackageBinding) { problemReporter().cannotImportPackage(importReference); continue nextImport; } // all the code here which checks for valid bindings have been moved to the method // checkAndRecordImportBinding() since bug 361327 if (checkAndRecordImportBinding( importBinding, typesBySimpleNames, importReference, compoundName) == -1) continue nextImport; if (importReference.isStatic()) { // look for more static bindings being imported by single static import(bug 361327). // findSingleImport() finds fields first, followed by method and then type // So if a type is found, no fields and methods are available anyway // similarly when method is found, type may be available but no field available for sure if (importBinding.kind() == Binding.FIELD) { checkMoreStaticBindings( compoundName, typesBySimpleNames, Binding.TYPE | Binding.METHOD, importReference); } else if (importBinding.kind() == Binding.METHOD) { checkMoreStaticBindings( compoundName, typesBySimpleNames, Binding.TYPE, importReference); } } } } // shrink resolvedImports... only happens if an error was reported if (this.tempImports.length > this.importPtr) System.arraycopy( this.tempImports, 0, this.tempImports = new ImportBinding[this.importPtr], 0, this.importPtr); this.imports = this.tempImports; int length = this.imports.length; this.typeOrPackageCache = new HashtableOfObject(length); for (int i = 0; i < length; i++) { ImportBinding binding = this.imports[i]; if (!binding.onDemand && binding.resolvedImport instanceof ReferenceBinding || binding instanceof ImportConflictBinding) this.typeOrPackageCache.put(binding.compoundName[binding.compoundName.length - 1], binding); } this.skipCachingImports = this.suppressImportErrors && unresolvedFound; }