receiverType = receiverType instanceof CaptureBinding ? receiverType : (ReferenceBinding) receiverType.erasure();
nextSpecific : for (int i = 0; i < visibleSize; i++) {
MethodBinding current = moreSpecific[i];
if (current != null) {
ReferenceBinding[] mostSpecificExceptions = null;
SimpleSet possibleMethods = null;
MethodBinding original = current.original();
for (int j = 0; j < visibleSize; j++) {
MethodBinding next = moreSpecific[j];
if (next == null || i == j) continue;
MethodBinding original2 = next.original();
if (original.getOwningClass() == original2.getOwningClass()) // AspectJ Extension - was (original.declaringClass == original2.declaringClass)
break nextSpecific; // duplicates thru substitution
if (!original.isAbstract()) {
if (original2.isAbstract())
continue; // only compare current against other concrete methods
// AspectJ Extension - move superType test inside - causes problems (pr233838)
if (current.hasSubstitutedParameters() || original.typeVariables != Binding.NO_TYPE_VARIABLES) {
TypeBinding superType = original.getOwningClass().findSuperTypeWithSameErasure(original2.getOwningClass().erasure()); // AspectJ Extension - was declaringClass, now getOwningClass()
if (superType == null)
continue nextSpecific; // current's declaringClass is not a subtype of next's declaringClass
if (original2.declaringClass != superType) {
// must find inherited method with the same substituted variables
MethodBinding[] superMethods = ((ReferenceBinding) superType).getMethods(original2.selector);
for (int m = 0, l = superMethods.length; m < l; m++) {
if (superMethods[m].original() == original2) {
original2 = superMethods[m];
break;
}
}
}
if (!environment().methodVerifier().doesMethodOverride(original, original2))
continue nextSpecific; // current does not override next
}
} else if (receiverType != null) { // should not be null if original isAbstract, but be safe
TypeBinding superType = receiverType.findSuperTypeWithSameErasure(original.getOwningClass().erasure());// AspectJ Extension - was declaringClass, now getOwningClass()
if (original.declaringClass == superType || !(superType instanceof ReferenceBinding)) {
// keep original
} else {
// must find inherited method with the same substituted variables
MethodBinding[] superMethods = ((ReferenceBinding) superType).getMethods(original.selector);
for (int m = 0, l = superMethods.length; m < l; m++) {
if (superMethods[m].original() == original) {
original = superMethods[m];
break;
}
}
}
superType = receiverType.findSuperTypeWithSameErasure(original2.getOwningClass().erasure());// AspectJ Extension - was declaringClass, now getOwningClass()
if (original2.declaringClass == superType || !(superType instanceof ReferenceBinding)) {
// keep original2
} else {
// must find inherited method with the same substituted variables
MethodBinding[] superMethods = ((ReferenceBinding) superType).getMethods(original2.selector);
for (int m = 0, l = superMethods.length; m < l; m++) {
if (superMethods[m].original() == original2) {
original2 = superMethods[m];
break;
}
}
}
if (original.typeVariables != Binding.NO_TYPE_VARIABLES)
original2 = original.computeSubstitutedMethod(original2, environment());
if (original2 == null || !original.areParameterErasuresEqual(original2))
continue nextSpecific; // current does not override next
if (!original.returnType.isCompatibleWith(original2.returnType) &&
!original.returnType.erasure().isCompatibleWith(original2.returnType.erasure())) {
// 15.12.2
continue nextSpecific; // choose original2 instead
}
if (original.thrownExceptions != original2.thrownExceptions) {
if (mostSpecificExceptions == null)
mostSpecificExceptions = original.thrownExceptions;
if (possibleMethods == null)
possibleMethods = new SimpleSet(3);
int mostSpecificLength = mostSpecificExceptions.length;
int original2Length = original2.thrownExceptions.length;
SimpleSet temp = new SimpleSet(mostSpecificLength);
nextException : for (int t = 0; t < mostSpecificLength; t++) {
ReferenceBinding exception = mostSpecificExceptions[t];
for (int s = 0; s < original2Length; s++) {
if (exception.isCompatibleWith(original2.thrownExceptions[s])) {
possibleMethods.add(current);
temp.add(exception);
continue nextException;
} else if (original2.thrownExceptions[s].isCompatibleWith(exception)) {
possibleMethods.add(next);
temp.add(original2.thrownExceptions[s]);
continue nextException;
}
}
}
mostSpecificExceptions = temp.elementSize == 0 ? Binding.NO_EXCEPTIONS : new ReferenceBinding[temp.elementSize];
temp.asArray(mostSpecificExceptions);
}
}
}
if (mostSpecificExceptions != null) {
Object[] values = possibleMethods.values;