private Binding findSingleStaticImport(char[][] compoundName, int mask) { Binding binding = findImport(compoundName, compoundName.length - 1); if (!binding.isValidBinding()) return binding; char[] name = compoundName[compoundName.length - 1]; if (binding instanceof PackageBinding) { Binding temp = ((PackageBinding) binding).getTypeOrPackage(name); if (temp != null && temp instanceof ReferenceBinding) // must resolve to a member type or field, not a top level type return new ProblemReferenceBinding( compoundName, (ReferenceBinding) temp, ProblemReasons.InvalidTypeForStaticImport); return binding; // cannot be a package, error is caught in sender } // look to see if its a static field first ReferenceBinding type = (ReferenceBinding) binding; FieldBinding field = (mask & Binding.FIELD) != 0 ? findField(type, name, null, true) : null; if (field != null) { if (field.problemId() == ProblemReasons.Ambiguous && ((ProblemFieldBinding) field).closestMatch.isStatic()) return field; // keep the ambiguous field instead of a possible method match if (field.isValidBinding() && field.isStatic() && field.canBeSeenBy(type, null, this)) return field; } // look to see if there is a static method with the same selector MethodBinding method = (mask & Binding.METHOD) != 0 ? findStaticMethod(type, name) : null; if (method != null) return method; type = findMemberType(name, type); if (type == null || !type.isStatic()) { if (field != null && !field.isValidBinding() && field.problemId() != ProblemReasons.NotFound) return field; return new ProblemReferenceBinding(compoundName, type, ProblemReasons.NotFound); } if (type.isValidBinding() && !type.canBeSeenBy(this.fPackage)) return new ProblemReferenceBinding(compoundName, type, ProblemReasons.NotVisible); if (type.problemId() == ProblemReasons.NotVisible) // ensure compoundName is correct return new ProblemReferenceBinding( compoundName, ((ProblemReferenceBinding) type).closestMatch, ProblemReasons.NotVisible); return type; }
/** * Checks for duplicates. If all ok, records the importBinding returns -1 when this import is * flagged as duplicate. * * @param importBinding * @param typesBySimpleNames * @param importReference * @param compoundName * @return -1 when this import is flagged as duplicate, importPtr otherwise. */ private int checkAndRecordImportBinding( Binding importBinding, HashtableOfType typesBySimpleNames, ImportReference importReference, char[][] compoundName) { ReferenceBinding conflictingType = null; if (importBinding instanceof MethodBinding) { conflictingType = (ReferenceBinding) getType(compoundName, compoundName.length); if (!conflictingType.isValidBinding() || (importReference.isStatic() && !conflictingType.isStatic())) conflictingType = null; } // collisions between an imported static field & a type should be checked according to spec... // but currently not by javac final char[] name = compoundName[compoundName.length - 1]; if (importBinding instanceof ReferenceBinding || conflictingType != null) { ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding : conflictingType; ReferenceBinding typeToCheck = referenceBinding.problemId() == ProblemReasons.Ambiguous ? ((ProblemReferenceBinding) referenceBinding).closestMatch : referenceBinding; if (importReference.isTypeUseDeprecated(typeToCheck, this)) problemReporter().deprecatedType(typeToCheck, importReference); ReferenceBinding existingType = typesBySimpleNames.get(name); if (existingType != null) { // duplicate test above should have caught this case, but make sure if (TypeBinding.equalsEquals(existingType, referenceBinding)) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=302865 // Check all resolved imports to see if this import qualifies as a duplicate for (int j = 0; j < this.importPtr; j++) { ImportBinding resolved = this.tempImports[j]; if (resolved instanceof ImportConflictBinding) { ImportConflictBinding importConflictBinding = (ImportConflictBinding) resolved; if (TypeBinding.equalsEquals( importConflictBinding.conflictingTypeBinding, referenceBinding)) { if (!importReference.isStatic()) { // resolved is implicitly static problemReporter().duplicateImport(importReference); recordImportBinding( new ImportBinding(compoundName, false, importBinding, importReference)); } } } else if (resolved.resolvedImport == referenceBinding) { if (importReference.isStatic() != resolved.isStatic()) { problemReporter().duplicateImport(importReference); recordImportBinding( new ImportBinding(compoundName, false, importBinding, importReference)); } } } return -1; } // either the type collides with a top level type or another imported type for (int j = 0, length = this.topLevelTypes.length; j < length; j++) { if (CharOperation.equals(this.topLevelTypes[j].sourceName, existingType.sourceName)) { problemReporter().conflictingImport(importReference); return -1; } } if (importReference.isStatic() && importBinding instanceof ReferenceBinding && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) { // 7.5.3 says nothing about collision of single static imports and JDK8 tolerates them, // though use is flagged. for (int j = 0; j < this.importPtr; j++) { ImportBinding resolved = this.tempImports[j]; if (resolved.isStatic() && resolved.resolvedImport instanceof ReferenceBinding && importBinding != resolved.resolvedImport) { if (CharOperation.equals( name, resolved.compoundName[resolved.compoundName.length - 1])) { ReferenceBinding type = (ReferenceBinding) resolved.resolvedImport; resolved.resolvedImport = new ProblemReferenceBinding( new char[][] {name}, type, ProblemReasons.Ambiguous); return -1; } } } } problemReporter().duplicateImport(importReference); return -1; } typesBySimpleNames.put(name, referenceBinding); } else if (importBinding instanceof FieldBinding) { for (int j = 0; j < this.importPtr; j++) { ImportBinding resolved = this.tempImports[j]; // find other static fields with the same name if (resolved.isStatic() && resolved.resolvedImport instanceof FieldBinding && importBinding != resolved.resolvedImport) { if (CharOperation.equals(name, resolved.compoundName[resolved.compoundName.length - 1])) { if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) { // 7.5.3 says nothing about collision of single static imports and JDK8 tolerates // them, though use is flagged. FieldBinding field = (FieldBinding) resolved.resolvedImport; resolved.resolvedImport = new ProblemFieldBinding( field, field.declaringClass, name, ProblemReasons.Ambiguous); return -1; } else { problemReporter().duplicateImport(importReference); return -1; } } } } } if (conflictingType == null) { recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference)); } else { recordImportBinding( new ImportConflictBinding(compoundName, importBinding, conflictingType, importReference)); } return this.importPtr; }