return null;
if (receiverType.isArrayType()) {
TypeBinding leafType = receiverType.leafComponentType();
if (leafType instanceof ReferenceBinding)
if (!((ReferenceBinding)leafType).canBeSeenBy(this)) {
return new ProblemFieldBinding((ReferenceBinding)leafType, fieldName, ProblemReasons.ReceiverTypeNotVisible);
}
if (CharOperation.equals(fieldName, TypeConstants.LENGTH))
return ArrayBinding.ArrayLength;
return null;
}
ReferenceBinding currentType = (ReferenceBinding) receiverType;
if (!currentType.canBeSeenBy(this))
return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.ReceiverTypeNotVisible);
FieldBinding field = currentType.getField(fieldName, true /*resolve*/);
if (field != null) {
if (canBeSeenByForCodeSnippet(field, currentType, invocationSite, this))
return field;
else
return new ProblemFieldBinding(field /* closest match*/, field.declaringClass, fieldName, ProblemReasons.NotVisible);
}
// collect all superinterfaces of receiverType until the field is found in a supertype
ReferenceBinding[][] interfacesToVisit = null;
int lastPosition = -1;
FieldBinding visibleField = null;
boolean keepLooking = true;
boolean notVisible = false; // we could hold onto the not visible field for extra error reporting
while (keepLooking) {
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
if (interfacesToVisit == null)
interfacesToVisit = new ReferenceBinding[5][];
if (++lastPosition == interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
interfacesToVisit[lastPosition] = itsInterfaces;
}
if ((currentType = currentType.superclass()) == null)
break;
if ((field = currentType.getField(fieldName, true /*resolve*/)) != null) {
keepLooking = false;
if (canBeSeenByForCodeSnippet(field, receiverType, invocationSite, this)) {
if (visibleField == null)
visibleField = field;
else
return new ProblemFieldBinding(visibleField, visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
} else {
notVisible = true;
}
}
}
// walk all visible interfaces to find ambiguous references
if (interfacesToVisit != null) {
ProblemFieldBinding ambiguous = null;
org.eclipse.jdt.internal.compiler.util.SimpleSet interfacesSeen = new org.eclipse.jdt.internal.compiler.util.SimpleSet(lastPosition * 2);
done : for (int i = 0; i <= lastPosition; i++) {
ReferenceBinding[] interfaces = interfacesToVisit[i];
for (int j = 0, length = interfaces.length; j < length; j++) {
ReferenceBinding anInterface = interfaces[j];
if (interfacesSeen.addIfNotIncluded(anInterface) == anInterface) {
// if interface as not already been visited
if ((field = anInterface.getField(fieldName, true /*resolve*/)) != null) {
if (visibleField == null) {
visibleField = field;
} else {
ambiguous = new ProblemFieldBinding(visibleField, visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
break done;
}
} else {
ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
if (++lastPosition == interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
interfacesToVisit[lastPosition] = itsInterfaces;
}
}
}
}
}
if (ambiguous != null) return ambiguous;
}
if (visibleField != null)
return visibleField;
if (notVisible)
return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.NotVisible);
return null;
}