|
Lines 138-148
Link Here
|
| 138 |
if (!isAcceptableReturnTypeOverride(currentMethod, inheritedMethod)) |
138 |
if (!isAcceptableReturnTypeOverride(currentMethod, inheritedMethod)) |
| 139 |
problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, this.type); |
139 |
problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, this.type); |
| 140 |
|
140 |
|
| 141 |
if (this.type.addSyntheticBridgeMethod(originalInherited, currentMethod.original()) != null) { |
141 |
MethodBinding bridge = this.type.addSyntheticBridgeMethod(originalInherited, currentMethod.original()); |
|
|
142 |
if (bridge != null) { |
| 142 |
for (int i = 0, l = allInheritedMethods == null ? 0 : allInheritedMethods.length; i < l; i++) { |
143 |
for (int i = 0, l = allInheritedMethods == null ? 0 : allInheritedMethods.length; i < l; i++) { |
| 143 |
if (allInheritedMethods[i] != null && detectInheritedNameClash(originalInherited, allInheritedMethods[i].original())) |
144 |
if (allInheritedMethods[i] != null && detectInheritedNameClash(originalInherited, allInheritedMethods[i].original())) |
| 144 |
return; |
145 |
return; |
| 145 |
} |
146 |
} |
|
|
147 |
// See if the new bridge clashes with any of the user methods of the class. For this check |
| 148 |
// we should check for "method descriptor clash" and not just "method signature clash". Really |
| 149 |
// what we are checking is whether there is a contention for the method dispatch table slot. |
| 150 |
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=293615. |
| 151 |
MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(bridge.selector); |
| 152 |
for (int i = current.length - 1; i >= 0; --i) { |
| 153 |
final MethodBinding thisMethod = current[i]; |
| 154 |
if (thisMethod.areParameterErasuresEqual(bridge) && thisMethod.returnType.erasure() == bridge.returnType.erasure()) { |
| 155 |
// use inherited method for problem reporting. |
| 156 |
problemReporter(thisMethod).methodNameClash(thisMethod, inheritedMethod.declaringClass.isRawType() ? inheritedMethod : inheritedMethod.original()); |
| 157 |
return; |
| 158 |
} |
| 159 |
} |
| 146 |
} |
160 |
} |
| 147 |
} |
161 |
} |
| 148 |
void checkForNameClash(MethodBinding currentMethod, MethodBinding inheritedMethod) { |
162 |
void checkForNameClash(MethodBinding currentMethod, MethodBinding inheritedMethod) { |
|
Lines 180-186
Link Here
|
| 180 |
|
194 |
|
| 181 |
if (currentMethod.declaringClass.isInterface() || inheritedMethod.isStatic()) return; |
195 |
if (currentMethod.declaringClass.isInterface() || inheritedMethod.isStatic()) return; |
| 182 |
|
196 |
|
| 183 |
if (!detectNameClash(currentMethod, inheritedMethod)) { // check up the hierarchy for skipped inherited methods |
197 |
if (!detectNameClash(currentMethod, inheritedMethod, false)) { // check up the hierarchy for skipped inherited methods |
| 184 |
TypeBinding[] currentParams = currentMethod.parameters; |
198 |
TypeBinding[] currentParams = currentMethod.parameters; |
| 185 |
TypeBinding[] inheritedParams = inheritedMethod.parameters; |
199 |
TypeBinding[] inheritedParams = inheritedMethod.parameters; |
| 186 |
int length = currentParams.length; |
200 |
int length = currentParams.length; |
|
Lines 204-210
Link Here
|
| 204 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
218 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
| 205 |
for (int m = 0, n = methods.length; m < n; m++) { |
219 |
for (int m = 0, n = methods.length; m < n; m++) { |
| 206 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); |
220 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); |
| 207 |
if (substitute != null && !isSubstituteParameterSubsignature(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
221 |
if (substitute != null && !isSubstituteParameterSubsignature(currentMethod, substitute) && detectNameClash(currentMethod, substitute, true)) |
| 208 |
return; |
222 |
return; |
| 209 |
} |
223 |
} |
| 210 |
if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { |
224 |
if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { |
|
Lines 232-238
Link Here
|
| 232 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
246 |
MethodBinding[] methods = superType.getMethods(currentMethod.selector); |
| 233 |
for (int m = 0, n = methods.length; m < n; m++){ |
247 |
for (int m = 0, n = methods.length; m < n; m++){ |
| 234 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); |
248 |
MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); |
| 235 |
if (substitute != null && !isSubstituteParameterSubsignature(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) |
249 |
if (substitute != null && !isSubstituteParameterSubsignature(currentMethod, substitute) && detectNameClash(currentMethod, substitute, true)) |
| 236 |
return; |
250 |
return; |
| 237 |
} |
251 |
} |
| 238 |
if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { |
252 |
if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { |
|
Lines 555-565
Link Here
|
| 555 |
problemReporter().inheritedMethodsHaveNameClash(this.type, inherited, otherInherited); |
569 |
problemReporter().inheritedMethodsHaveNameClash(this.type, inherited, otherInherited); |
| 556 |
return true; |
570 |
return true; |
| 557 |
} |
571 |
} |
| 558 |
boolean detectNameClash(MethodBinding current, MethodBinding inherited) { |
572 |
boolean detectNameClash(MethodBinding current, MethodBinding inherited, boolean treatAsSynthetic) { |
| 559 |
MethodBinding original = inherited.original(); // can be the same as inherited |
573 |
MethodBinding methodToCheck = inherited; |
|
|
574 |
if (!treatAsSynthetic) { |
| 575 |
// For a user method, see if current class overrides the inherited method. If it does, |
| 576 |
// then any grievance we may have ought to be against the current class's method and |
| 577 |
// NOT against any super implementations. https://bugs.eclipse.org/bugs/show_bug.cgi?id=293615 |
| 578 |
MethodBinding[] currentNamesakes = (MethodBinding[]) this.currentMethods.get(inherited.selector); |
| 579 |
if (currentNamesakes.length > 1) { // we know it ought to at least one and that current is NOT the override |
| 580 |
for (int i = 0, length = currentNamesakes.length; i < length; i++) { |
| 581 |
MethodBinding currentMethod = currentNamesakes[i]; |
| 582 |
if (currentMethod != current && doesMethodOverride(currentMethod, inherited)) { |
| 583 |
methodToCheck = currentMethod; |
| 584 |
break; |
| 585 |
} |
| 586 |
} |
| 587 |
} |
| 588 |
} |
| 589 |
MethodBinding original = methodToCheck.original(); // can be the same as inherited |
| 560 |
if (!current.areParameterErasuresEqual(original)) |
590 |
if (!current.areParameterErasuresEqual(original)) |
| 561 |
return false; |
591 |
return false; |
| 562 |
|
592 |
original = inherited.original(); // For error reporting use, inherited.original() |
| 563 |
problemReporter(current).methodNameClash(current, inherited.declaringClass.isRawType() ? inherited : original); |
593 |
problemReporter(current).methodNameClash(current, inherited.declaringClass.isRawType() ? inherited : original); |
| 564 |
return true; |
594 |
return true; |
| 565 |
} |
595 |
} |