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 155-161
Link Here
|
155 |
MethodBinding compareMethod = inheritedMethod instanceof ParameterizedGenericMethodBinding |
155 |
MethodBinding compareMethod = inheritedMethod instanceof ParameterizedGenericMethodBinding |
156 |
? ((ParameterizedGenericMethodBinding) inheritedMethod).originalMethod |
156 |
? ((ParameterizedGenericMethodBinding) inheritedMethod).originalMethod |
157 |
: inheritedMethod; |
157 |
: inheritedMethod; |
158 |
MethodBinding substitute = computeSubstituteMethod(otherInheritedMethod, compareMethod); |
158 |
MethodBinding substitute = computeSubstituteMethod(otherInheritedMethod, compareMethod, false); |
159 |
if (substitute == null || doesSubstituteMethodOverride(compareMethod, substitute)) |
159 |
if (substitute == null || doesSubstituteMethodOverride(compareMethod, substitute)) |
160 |
continue; |
160 |
continue; |
161 |
if (detectInheritedNameClash(originalInherited, otherOriginal)) |
161 |
if (detectInheritedNameClash(originalInherited, otherOriginal)) |
Lines 238-244
Link Here
|
238 |
while (superType != null && superType.isValidBinding()) { |
238 |
while (superType != null && superType.isValidBinding()) { |
239 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
239 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
240 |
for (int m = 0, n = methods.length; m < n; m++) { |
240 |
for (int m = 0, n = methods.length; m < n; m++) { |
241 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); |
241 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod, false); |
242 |
if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
242 |
if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
243 |
return; |
243 |
return; |
244 |
} |
244 |
} |
Lines 266-272
Link Here
|
266 |
if (superType.isValidBinding()) { |
266 |
if (superType.isValidBinding()) { |
267 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
267 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
268 |
for (int m = 0, n = methods.length; m < n; m++){ |
268 |
for (int m = 0, n = methods.length; m < n; m++){ |
269 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); |
269 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod, false); |
270 |
if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
270 |
if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
271 |
return; |
271 |
return; |
272 |
} |
272 |
} |
Lines 360-366
Link Here
|
360 |
MethodBinding inheritedMethod; |
360 |
MethodBinding inheritedMethod; |
361 |
if (i != j && (inheritedMethod = methodsToCheck[j]) != null && |
361 |
if (i != j && (inheritedMethod = methodsToCheck[j]) != null && |
362 |
existingMethod.declaringClass.implementsInterface(inheritedMethod.declaringClass, true)) { |
362 |
existingMethod.declaringClass.implementsInterface(inheritedMethod.declaringClass, true)) { |
363 |
MethodBinding substitute = computeSubstituteMethod(inheritedMethod, existingMethod); |
363 |
MethodBinding substitute = computeSubstituteMethod(inheritedMethod, existingMethod, false); |
364 |
if (substitute != null && |
364 |
if (substitute != null && |
365 |
doesSubstituteMethodOverride(existingMethod, substitute) && |
365 |
doesSubstituteMethodOverride(existingMethod, substitute) && |
366 |
(existingMethod.returnType.isCompatibleWith(substitute.returnType) || |
366 |
(existingMethod.returnType.isCompatibleWith(substitute.returnType) || |
Lines 426-432
Link Here
|
426 |
for (int i = 0, length1 = current.length; i < length1; i++) { |
426 |
for (int i = 0, length1 = current.length; i < length1; i++) { |
427 |
MethodBinding currentMethod = current[i]; |
427 |
MethodBinding currentMethod = current[i]; |
428 |
for (int j = 0, length2 = inherited.length; j < length2; j++) { |
428 |
for (int j = 0, length2 = inherited.length; j < length2; j++) { |
429 |
MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod); |
429 |
MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod, true); |
430 |
if (inheritedMethod != null) { |
430 |
if (inheritedMethod != null) { |
431 |
if (foundMatch[j] == 0 && doesSubstituteMethodOverride(currentMethod, inheritedMethod)) { |
431 |
if (foundMatch[j] == 0 && doesSubstituteMethodOverride(currentMethod, inheritedMethod)) { |
432 |
matchingInherited[++index] = inheritedMethod; |
432 |
matchingInherited[++index] = inheritedMethod; |
Lines 455-461
Link Here
|
455 |
MethodBinding otherInheritedMethod = inherited[j]; |
455 |
MethodBinding otherInheritedMethod = inherited[j]; |
456 |
if (foundMatch[j] == 1 || canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) |
456 |
if (foundMatch[j] == 1 || canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) |
457 |
continue; |
457 |
continue; |
458 |
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); |
458 |
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod, false); |
459 |
if (otherInheritedMethod != null) { |
459 |
if (otherInheritedMethod != null) { |
460 |
if (doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { |
460 |
if (doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { |
461 |
matchingInherited[++index] = otherInheritedMethod; |
461 |
matchingInherited[++index] = otherInheritedMethod; |
Lines 493-499
Link Here
|
493 |
MethodBinding otherInheritedMethod = inherited[j]; |
493 |
MethodBinding otherInheritedMethod = inherited[j]; |
494 |
if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) |
494 |
if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) |
495 |
continue; |
495 |
continue; |
496 |
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); |
496 |
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod, false); |
497 |
if (otherInheritedMethod != null && doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { |
497 |
if (otherInheritedMethod != null && doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { |
498 |
matchingInherited[++index] = otherInheritedMethod; |
498 |
matchingInherited[++index] = otherInheritedMethod; |
499 |
inherited[j] = null; // do not want to find it again |
499 |
inherited[j] = null; // do not want to find it again |
Lines 512-518
Link Here
|
512 |
} |
512 |
} |
513 |
} |
513 |
} |
514 |
} |
514 |
} |
515 |
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) { |
515 |
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, boolean eraseIfTypeParametersNbMismatch) { |
516 |
if (inheritedMethod == null) return null; |
516 |
if (inheritedMethod == null) return null; |
517 |
if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match |
517 |
if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match |
518 |
|
518 |
|
Lines 527-540
Link Here
|
527 |
int inheritedLength = inheritedTypeVariables.length; |
527 |
int inheritedLength = inheritedTypeVariables.length; |
528 |
TypeVariableBinding[] typeVariables = currentMethod.typeVariables; |
528 |
TypeVariableBinding[] typeVariables = currentMethod.typeVariables; |
529 |
int length = typeVariables.length; |
529 |
int length = typeVariables.length; |
530 |
if (length > 0 && inheritedLength != length) return inheritedMethod; |
530 |
if (length > 0 && inheritedLength != length) return inheritedMethod; // no match JLS 8.4.2 |
531 |
TypeBinding[] arguments = new TypeBinding[inheritedLength]; |
531 |
TypeBinding[] arguments = new TypeBinding[inheritedLength]; |
532 |
if (inheritedLength <= length) { |
532 |
if (length != 0) { |
533 |
System.arraycopy(typeVariables, 0, arguments, 0, inheritedLength); |
533 |
System.arraycopy(typeVariables, 0, arguments, 0, inheritedLength); |
|
|
534 |
} else if (eraseIfTypeParametersNbMismatch) { |
535 |
// length is null |
536 |
for (int i = 0; i < inheritedLength; i++) { |
537 |
arguments[i] = inheritedTypeVariables[i].erasure(); |
538 |
} |
539 |
return this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); // erasure |
534 |
} else { |
540 |
} else { |
535 |
System.arraycopy(typeVariables, 0, arguments, 0, length); |
541 |
// length is null |
536 |
for (int i = length; i < inheritedLength; i++) |
542 |
for (int i = 0; i < inheritedLength; i++) { |
537 |
arguments[i] = inheritedTypeVariables[i].upperBound(); |
543 |
arguments[i] = inheritedTypeVariables[i].upperBound(); |
|
|
544 |
} |
538 |
} |
545 |
} |
539 |
ParameterizedGenericMethodBinding substitute = |
546 |
ParameterizedGenericMethodBinding substitute = |
540 |
this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); |
547 |
this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); |
Lines 589-595
Link Here
|
589 |
return true; |
596 |
return true; |
590 |
} |
597 |
} |
591 |
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { |
598 |
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { |
592 |
MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method); |
599 |
MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method, false); |
593 |
return substitute != null && doesSubstituteMethodOverride(method, substitute); |
600 |
return substitute != null && doesSubstituteMethodOverride(method, substitute); |
594 |
} |
601 |
} |
595 |
boolean doesSubstituteMethodOverride(MethodBinding method, MethodBinding substituteMethod) { |
602 |
boolean doesSubstituteMethodOverride(MethodBinding method, MethodBinding substituteMethod) { |
Lines 627-633
Link Here
|
627 |
if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) |
634 |
if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) |
628 |
return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary |
635 |
return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary |
629 |
|
636 |
|
630 |
inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod); |
637 |
inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod, false); |
631 |
return inheritedMethod != null |
638 |
return inheritedMethod != null |
632 |
&& inheritedMethod.returnType == existingMethod.returnType |
639 |
&& inheritedMethod.returnType == existingMethod.returnType |
633 |
&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType); |
640 |
&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType); |