Lines 20-26
Link Here
|
20 |
super(environment); |
20 |
super(environment); |
21 |
} |
21 |
} |
22 |
boolean areMethodsEqual(MethodBinding one, MethodBinding two) { |
22 |
boolean areMethodsEqual(MethodBinding one, MethodBinding two) { |
23 |
MethodBinding sub = computeSubstituteMethod(two, one); |
23 |
MethodBinding sub = computeSubstituteMethod(two, one, false); |
24 |
return sub != null && doesSubstituteMethodOverride(one, sub) && areReturnTypesEqual(one, sub); |
24 |
return sub != null && doesSubstituteMethodOverride(one, sub) && areReturnTypesEqual(one, sub); |
25 |
} |
25 |
} |
26 |
boolean areParametersEqual(MethodBinding one, MethodBinding two) { |
26 |
boolean areParametersEqual(MethodBinding one, MethodBinding two) { |
Lines 128-134
Link Here
|
128 |
MethodBinding compareMethod = inheritedMethod instanceof ParameterizedGenericMethodBinding |
128 |
MethodBinding compareMethod = inheritedMethod instanceof ParameterizedGenericMethodBinding |
129 |
? ((ParameterizedGenericMethodBinding) inheritedMethod).originalMethod |
129 |
? ((ParameterizedGenericMethodBinding) inheritedMethod).originalMethod |
130 |
: inheritedMethod; |
130 |
: inheritedMethod; |
131 |
MethodBinding substitute = computeSubstituteMethod(otherInheritedMethod, compareMethod); |
131 |
MethodBinding substitute = computeSubstituteMethod(otherInheritedMethod, compareMethod, false); |
132 |
if (substitute == null || doesSubstituteMethodOverride(compareMethod, substitute)) |
132 |
if (substitute == null || doesSubstituteMethodOverride(compareMethod, substitute)) |
133 |
continue; |
133 |
continue; |
134 |
if (detectInheritedNameClash(originalInherited, otherOriginal)) |
134 |
if (detectInheritedNameClash(originalInherited, otherOriginal)) |
Lines 211-217
Link Here
|
211 |
while (superType != null && superType.isValidBinding()) { |
211 |
while (superType != null && superType.isValidBinding()) { |
212 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
212 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
213 |
for (int m = 0, n = methods.length; m < n; m++) { |
213 |
for (int m = 0, n = methods.length; m < n; m++) { |
214 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); |
214 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod, false); |
215 |
if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
215 |
if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
216 |
return; |
216 |
return; |
217 |
} |
217 |
} |
Lines 239-245
Link Here
|
239 |
if (superType.isValidBinding()) { |
239 |
if (superType.isValidBinding()) { |
240 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
240 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
241 |
for (int m = 0, n = methods.length; m < n; m++){ |
241 |
for (int m = 0, n = methods.length; m < n; m++){ |
242 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); |
242 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod, false); |
243 |
if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
243 |
if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
244 |
return; |
244 |
return; |
245 |
} |
245 |
} |
Lines 333-339
Link Here
|
333 |
MethodBinding inheritedMethod; |
333 |
MethodBinding inheritedMethod; |
334 |
if (i != j && (inheritedMethod = methodsToCheck[j]) != null && |
334 |
if (i != j && (inheritedMethod = methodsToCheck[j]) != null && |
335 |
existingMethod.declaringClass.implementsInterface(inheritedMethod.declaringClass, true)) { |
335 |
existingMethod.declaringClass.implementsInterface(inheritedMethod.declaringClass, true)) { |
336 |
MethodBinding substitute = computeSubstituteMethod(inheritedMethod, existingMethod); |
336 |
MethodBinding substitute = computeSubstituteMethod(inheritedMethod, existingMethod, false); |
337 |
if (substitute != null && |
337 |
if (substitute != null && |
338 |
doesSubstituteMethodOverride(existingMethod, substitute) && |
338 |
doesSubstituteMethodOverride(existingMethod, substitute) && |
339 |
(existingMethod.returnType.isCompatibleWith(substitute.returnType) || |
339 |
(existingMethod.returnType.isCompatibleWith(substitute.returnType) || |
Lines 399-405
Link Here
|
399 |
for (int i = 0, length1 = current.length; i < length1; i++) { |
399 |
for (int i = 0, length1 = current.length; i < length1; i++) { |
400 |
MethodBinding currentMethod = current[i]; |
400 |
MethodBinding currentMethod = current[i]; |
401 |
for (int j = 0, length2 = inherited.length; j < length2; j++) { |
401 |
for (int j = 0, length2 = inherited.length; j < length2; j++) { |
402 |
MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod); |
402 |
MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod, true); |
403 |
if (inheritedMethod != null) { |
403 |
if (inheritedMethod != null) { |
404 |
if (foundMatch[j] == 0 && doesSubstituteMethodOverride(currentMethod, inheritedMethod)) { |
404 |
if (foundMatch[j] == 0 && doesSubstituteMethodOverride(currentMethod, inheritedMethod)) { |
405 |
matchingInherited[++index] = inheritedMethod; |
405 |
matchingInherited[++index] = inheritedMethod; |
Lines 428-434
Link Here
|
428 |
MethodBinding otherInheritedMethod = inherited[j]; |
428 |
MethodBinding otherInheritedMethod = inherited[j]; |
429 |
if (foundMatch[j] == 1 || canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) |
429 |
if (foundMatch[j] == 1 || canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) |
430 |
continue; |
430 |
continue; |
431 |
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); |
431 |
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod, false); |
432 |
if (otherInheritedMethod != null) { |
432 |
if (otherInheritedMethod != null) { |
433 |
if (doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { |
433 |
if (doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { |
434 |
matchingInherited[++index] = otherInheritedMethod; |
434 |
matchingInherited[++index] = otherInheritedMethod; |
Lines 466-472
Link Here
|
466 |
MethodBinding otherInheritedMethod = inherited[j]; |
466 |
MethodBinding otherInheritedMethod = inherited[j]; |
467 |
if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) |
467 |
if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) |
468 |
continue; |
468 |
continue; |
469 |
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); |
469 |
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod, false); |
470 |
if (otherInheritedMethod != null && doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { |
470 |
if (otherInheritedMethod != null && doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { |
471 |
matchingInherited[++index] = otherInheritedMethod; |
471 |
matchingInherited[++index] = otherInheritedMethod; |
472 |
inherited[j] = null; // do not want to find it again |
472 |
inherited[j] = null; // do not want to find it again |
Lines 485-491
Link Here
|
485 |
} |
485 |
} |
486 |
} |
486 |
} |
487 |
} |
487 |
} |
488 |
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) { |
488 |
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, boolean eraseIfTypeParametersNbMismatch) { |
489 |
if (inheritedMethod == null) return null; |
489 |
if (inheritedMethod == null) return null; |
490 |
if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match |
490 |
if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match |
491 |
|
491 |
|
Lines 500-513
Link Here
|
500 |
int inheritedLength = inheritedTypeVariables.length; |
500 |
int inheritedLength = inheritedTypeVariables.length; |
501 |
TypeVariableBinding[] typeVariables = currentMethod.typeVariables; |
501 |
TypeVariableBinding[] typeVariables = currentMethod.typeVariables; |
502 |
int length = typeVariables.length; |
502 |
int length = typeVariables.length; |
503 |
if (length > 0 && inheritedLength != length) return inheritedMethod; |
503 |
if (length > 0 && inheritedLength != length) return inheritedMethod; // no match JLS 8.4.2 |
504 |
TypeBinding[] arguments = new TypeBinding[inheritedLength]; |
504 |
TypeBinding[] arguments = new TypeBinding[inheritedLength]; |
505 |
if (inheritedLength <= length) { |
505 |
if (length != 0) { |
506 |
System.arraycopy(typeVariables, 0, arguments, 0, inheritedLength); |
506 |
System.arraycopy(typeVariables, 0, arguments, 0, inheritedLength); |
|
|
507 |
} else if (eraseIfTypeParametersNbMismatch) { |
508 |
// length is null |
509 |
for (int i = 0; i < inheritedLength; i++) { |
510 |
arguments[i] = inheritedTypeVariables[i].erasure(); |
511 |
} |
512 |
return this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); // erasure |
507 |
} else { |
513 |
} else { |
508 |
System.arraycopy(typeVariables, 0, arguments, 0, length); |
514 |
// length is null |
509 |
for (int i = length; i < inheritedLength; i++) |
515 |
for (int i = 0; i < inheritedLength; i++) { |
510 |
arguments[i] = inheritedTypeVariables[i].upperBound(); |
516 |
arguments[i] = inheritedTypeVariables[i].upperBound(); |
|
|
517 |
} |
511 |
} |
518 |
} |
512 |
ParameterizedGenericMethodBinding substitute = |
519 |
ParameterizedGenericMethodBinding substitute = |
513 |
this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); |
520 |
this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); |
Lines 562-568
Link Here
|
562 |
return true; |
569 |
return true; |
563 |
} |
570 |
} |
564 |
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { |
571 |
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { |
565 |
MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method); |
572 |
MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method, false); |
566 |
return substitute != null && doesSubstituteMethodOverride(method, substitute); |
573 |
return substitute != null && doesSubstituteMethodOverride(method, substitute); |
567 |
} |
574 |
} |
568 |
boolean doesSubstituteMethodOverride(MethodBinding method, MethodBinding substituteMethod) { |
575 |
boolean doesSubstituteMethodOverride(MethodBinding method, MethodBinding substituteMethod) { |
Lines 600-606
Link Here
|
600 |
if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) |
607 |
if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) |
601 |
return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary |
608 |
return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary |
602 |
|
609 |
|
603 |
inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod); |
610 |
inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod, false); |
604 |
return inheritedMethod != null |
611 |
return inheritedMethod != null |
605 |
&& inheritedMethod.returnType == existingMethod.returnType |
612 |
&& inheritedMethod.returnType == existingMethod.returnType |
606 |
&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType); |
613 |
&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType); |