Lines 313-321
Link Here
|
313 |
|
313 |
|
314 |
super.checkInheritedMethods(methods, length); |
314 |
super.checkInheritedMethods(methods, length); |
315 |
} |
315 |
} |
|
|
316 |
class OneOneSubstitution implements Substitution { |
317 |
TypeBinding replaced, replacer; |
318 |
OneOneSubstitution(TypeBinding replaced, TypeBinding replacer) { |
319 |
this.replaced = replaced; |
320 |
this.replacer = replacer; |
321 |
} |
322 |
public LookupEnvironment environment() { |
323 |
return environment; |
324 |
} |
325 |
public boolean isRawSubstitution() { |
326 |
return false; |
327 |
} |
328 |
public TypeBinding substitute(TypeVariableBinding typeVariable) { |
329 |
return typeVariable == replaced ? replacer : typeVariable; |
330 |
} |
331 |
} |
316 |
boolean checkInheritedReturnTypes(MethodBinding[] methods, int length) { |
332 |
boolean checkInheritedReturnTypes(MethodBinding[] methods, int length) { |
317 |
if (methods[0].declaringClass.isClass()) |
333 |
if (methods[0].declaringClass.isClass()) |
318 |
return super.checkInheritedReturnTypes(methods, length); |
334 |
return super.checkInheritedReturnTypes(methods, length); |
|
|
335 |
if (length <= 1) { |
336 |
return true; // no need to continue since only 1 inherited method is left |
337 |
} |
338 |
// get rid of overriden methods coming from interfaces - if any |
339 |
MethodBinding methodsToCheck[] = new MethodBinding[length]; // must not nullify methods slots in place |
340 |
int count = length; |
341 |
for (int i = 0; i < length; i++) { |
342 |
methodsToCheck[i] = methods[i]; |
343 |
} |
344 |
MethodBinding existingMethod, inheritedMethod, substitute; |
345 |
for (int i = 0; i < length; i++) { |
346 |
if ((existingMethod = methodsToCheck[i]) != null) { |
347 |
for (int j = 0; j < length; j++) { |
348 |
if (i != j && (inheritedMethod = methodsToCheck[j]) != null && |
349 |
existingMethod.declaringClass.implementsInterface(inheritedMethod.declaringClass, true)) { |
350 |
substitute = computeSubstituteMethod(inheritedMethod, existingMethod); |
351 |
if (substitute != null && doesSubstituteMethodOverride(existingMethod, substitute) && |
352 |
(existingMethod.returnType.isCompatibleWith(substitute.returnType) || |
353 |
substitute.returnType instanceof TypeVariableBinding && |
354 |
((TypeVariableBinding) substitute.returnType). |
355 |
boundCheck( |
356 |
new OneOneSubstitution(substitute.returnType, existingMethod.returnType), |
357 |
existingMethod.returnType) == TypeConstants.OK)) { |
358 |
count--; |
359 |
methodsToCheck[j] = null; |
360 |
} |
361 |
} |
362 |
} |
363 |
} |
364 |
} |
365 |
if (count < length) { |
366 |
if (count == 1) { |
367 |
return true; // no need to continue since only 1 inherited method is left |
368 |
} |
369 |
for (int i = 0, j = 0; j < count; i++) { |
370 |
if (methodsToCheck[i] != null) { |
371 |
methodsToCheck[j++] = methodsToCheck[i]; |
372 |
} |
373 |
} |
374 |
methods = methodsToCheck; |
375 |
length = count; |
376 |
} // else keep methods unchanged for further checks |
319 |
|
377 |
|
320 |
// its possible in 1.5 that A is compatible with B & C, but B is not compatible with C |
378 |
// its possible in 1.5 that A is compatible with B & C, but B is not compatible with C |
321 |
for (int i = 0, l = length - 1; i < l;) { |
379 |
for (int i = 0, l = length - 1; i < l;) { |
Lines 552-565
Link Here
|
552 |
// one has type variables and substituteTwo did not pass bounds check in computeSubstituteMethod() |
610 |
// one has type variables and substituteTwo did not pass bounds check in computeSubstituteMethod() |
553 |
return one.typeVariables != Binding.NO_TYPE_VARIABLES && !(substituteTwo instanceof ParameterizedGenericMethodBinding); |
611 |
return one.typeVariables != Binding.NO_TYPE_VARIABLES && !(substituteTwo instanceof ParameterizedGenericMethodBinding); |
554 |
} |
612 |
} |
|
|
613 |
// caveat: returns false if a method is implemented but needs that a bridge |
614 |
// method be generated |
555 |
boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) { |
615 |
boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) { |
556 |
if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) |
616 |
if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) |
557 |
return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary |
617 |
return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary |
558 |
|
618 |
|
559 |
inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod); |
619 |
inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod); |
560 |
return inheritedMethod != null |
620 |
return inheritedMethod != null |
561 |
&& (inheritedMethod.returnType == existingMethod.returnType || |
621 |
&& inheritedMethod.returnType == existingMethod.returnType |
562 |
inheritedMethod.returnType.isCompatibleWith(inheritedMethod.returnType)) |
|
|
563 |
&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType); |
622 |
&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType); |
564 |
} |
623 |
} |
565 |
SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) { |
624 |
SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) { |