View | Details | Raw Unified | Return to bug 111093 | Differences between
and this patch

Collapse All | Expand All

(-)dom/org/eclipse/jdt/core/dom/MethodBinding.java (-36 / +7 lines)
Lines 22-28 Link Here
22
import org.eclipse.jdt.core.compiler.CharOperation;
22
import org.eclipse.jdt.core.compiler.CharOperation;
23
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
23
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
24
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
24
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
25
import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
26
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
25
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
27
import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
26
import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
28
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
27
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
Lines 453-462 Link Here
453
452
454
	public boolean isSubsignature(IMethodBinding otherMethod) {
453
	public boolean isSubsignature(IMethodBinding otherMethod) {
455
		try {
454
		try {
456
			org.eclipse.jdt.internal.compiler.lookup.MethodBinding other = ((MethodBinding) otherMethod).binding;
455
			LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
457
			if (!CharOperation.equals(this.binding.selector, other.selector))
456
			return lookupEnvironment != null
458
				return false;
457
				&& lookupEnvironment.methodVerifier().isMethodSubsignature(this.binding, ((MethodBinding) otherMethod).binding);
459
			return this.binding.areParameterErasuresEqual(other) && this.binding.areTypeVariableErasuresEqual(other);
460
		} catch (AbortCompilation e) {
458
		} catch (AbortCompilation e) {
461
			// don't surface internal exception to clients
459
			// don't surface internal exception to clients
462
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
460
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
Lines 474-510 Link Here
474
	/**
472
	/**
475
	 * @see IMethodBinding#overrides(IMethodBinding)
473
	 * @see IMethodBinding#overrides(IMethodBinding)
476
	 */
474
	 */
477
	public boolean overrides(IMethodBinding overridenMethod) {
475
	public boolean overrides(IMethodBinding otherMethod) {
478
		try {
476
			LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
479
			org.eclipse.jdt.internal.compiler.lookup.MethodBinding overridenCompilerBinding = ((MethodBinding) overridenMethod).binding;
477
			return lookupEnvironment != null
480
			if (this.binding == overridenCompilerBinding
478
				&& lookupEnvironment.methodVerifier().doesMethodOverride(this.binding, ((MethodBinding) otherMethod).binding);
481
					|| overridenCompilerBinding.isStatic()
482
					|| overridenCompilerBinding.isPrivate()
483
					|| this.binding.isStatic())
484
				return false;
485
			char[] selector = this.binding.selector;
486
			if (!CharOperation.equals(selector, overridenCompilerBinding.selector))
487
				return false;
488
			TypeBinding match = this.binding.declaringClass.findSuperTypeOriginatingFrom(overridenCompilerBinding.declaringClass);
489
			if (!(match instanceof ReferenceBinding)) return false;
490
491
			org.eclipse.jdt.internal.compiler.lookup.MethodBinding[] superMethods = ((ReferenceBinding)match).getMethods(selector);
492
			for (int i = 0, length = superMethods.length; i < length; i++) {
493
				if (superMethods[i].original() == overridenCompilerBinding) {
494
					LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
495
					if (lookupEnvironment == null) return false;
496
					MethodVerifier methodVerifier = lookupEnvironment.methodVerifier();
497
					org.eclipse.jdt.internal.compiler.lookup.MethodBinding superMethod = superMethods[i];
498
					return !(superMethod.isDefault() && (superMethod.declaringClass.getPackage()) != this.binding.declaringClass.getPackage())
499
						&& methodVerifier.doesMethodOverride(this.binding, superMethod);
500
				}
501
			}
502
			return false;
503
		} catch (AbortCompilation e) {
504
			// don't surface internal exception to clients
505
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
506
			return false;
507
		}
508
	}
479
	}
509
480
510
	/**
481
	/**
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java (-25 / +58 lines)
Lines 21-27 Link Here
21
}
21
}
22
boolean areMethodsCompatible(MethodBinding one, MethodBinding two) {
22
boolean areMethodsCompatible(MethodBinding one, MethodBinding two) {
23
	MethodBinding sub = computeSubstituteMethod(two, one);
23
	MethodBinding sub = computeSubstituteMethod(two, one);
24
	return sub != null && doesSubstituteMethodOverride(one, sub) && areReturnTypesCompatible(one, sub);
24
	return sub != null && isSubstituteParameterSubsignature(one, sub) && areReturnTypesCompatible(one, sub);
25
}
25
}
26
boolean areParametersEqual(MethodBinding one, MethodBinding two) {
26
boolean areParametersEqual(MethodBinding one, MethodBinding two) {
27
	TypeBinding[] oneArgs = one.parameters;
27
	TypeBinding[] oneArgs = one.parameters;
Lines 224-230 Link Here
224
			MethodBinding[] methods = superType.getMethods(currentMethod.selector);
224
			MethodBinding[] methods = superType.getMethods(currentMethod.selector);
225
			for (int m = 0, n = methods.length; m < n; m++) {
225
			for (int m = 0, n = methods.length; m < n; m++) {
226
				MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod);
226
				MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod);
227
				if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute))
227
				if (substitute != null && !isSubstituteParameterSubsignature(currentMethod, substitute) && detectNameClash(currentMethod, substitute))
228
					return;
228
					return;
229
			}
229
			}
230
			if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
230
			if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
Lines 252-258 Link Here
252
				MethodBinding[] methods = superType.getMethods(currentMethod.selector);
252
				MethodBinding[] methods = superType.getMethods(currentMethod.selector);
253
				for (int m = 0, n = methods.length; m < n; m++){
253
				for (int m = 0, n = methods.length; m < n; m++){
254
					MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod);
254
					MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod);
255
					if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute))
255
					if (substitute != null && !isSubstituteParameterSubsignature(currentMethod, substitute) && detectNameClash(currentMethod, substitute))
256
						return;
256
						return;
257
				}
257
				}
258
				if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
258
				if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
Lines 424-430 Link Here
424
				for (int j = 0, length2 = inherited.length; j < length2; j++) {
424
				for (int j = 0, length2 = inherited.length; j < length2; j++) {
425
					MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod);
425
					MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod);
426
					if (inheritedMethod != null) {
426
					if (inheritedMethod != null) {
427
						if (foundMatch[j] == 0 && doesSubstituteMethodOverride(currentMethod, inheritedMethod)) {
427
						if (foundMatch[j] == 0 && isSubstituteParameterSubsignature(currentMethod, inheritedMethod)) {
428
							matchingInherited[++index] = inheritedMethod;
428
							matchingInherited[++index] = inheritedMethod;
429
							foundMatch[j] = 1; // cannot null out inherited methods
429
							foundMatch[j] = 1; // cannot null out inherited methods
430
						} else {
430
						} else {
Lines 454-460 Link Here
454
				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
454
				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
455
				if (otherInheritedMethod != null) {
455
				if (otherInheritedMethod != null) {
456
					if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass
456
					if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass
457
						&& doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) {
457
						&& isSubstituteParameterSubsignature(inheritedMethod, otherInheritedMethod)) {
458
							matchingInherited[++index] = otherInheritedMethod;
458
							matchingInherited[++index] = otherInheritedMethod;
459
							foundMatch[j] = 1; // cannot null out inherited methods
459
							foundMatch[j] = 1; // cannot null out inherited methods
460
					} else {
460
					} else {
Lines 491-497 Link Here
491
					if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
491
					if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
492
						continue;
492
						continue;
493
					otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
493
					otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
494
					if (otherInheritedMethod != null && doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) {
494
					if (otherInheritedMethod != null && isSubstituteParameterSubsignature(inheritedMethod, otherInheritedMethod)) {
495
						matchingInherited[++index] = otherInheritedMethod;
495
						matchingInherited[++index] = otherInheritedMethod;
496
						inherited[j] = null; // do not want to find it again
496
						inherited[j] = null; // do not want to find it again
497
					}
497
					}
Lines 586-614 Link Here
586
	return true;
586
	return true;
587
}
587
}
588
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
588
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
589
	MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method);
589
	if (!couldMethodOverride(method, inheritedMethod))
590
	return substitute != null && doesSubstituteMethodOverride(method, substitute);
591
}
592
// if method "overrides" substituteMethod then we can skip over substituteMethod while resolving a message send
593
// if it does not then a name clash error is likely
594
boolean doesSubstituteMethodOverride(MethodBinding method, MethodBinding substituteMethod) {
595
	if (!areParametersEqual(method, substituteMethod)) {
596
		// method can still override substituteMethod in cases like :
597
		// <U extends Number> void c(U u) {}
598
		// @Override void c(Number n) {}
599
		// but method cannot have a "generic-enabled" parameter type
600
		if (substituteMethod.hasSubstitutedParameters() && method.areParameterErasuresEqual(substituteMethod))
601
			return method.typeVariables == Binding.NO_TYPE_VARIABLES && !hasGenericParameter(method);
602
		return false;
590
		return false;
603
	}
604
591
605
	if (substituteMethod instanceof ParameterizedGenericMethodBinding) {
592
	inheritedMethod = inheritedMethod.original();
606
		// since substituteMethod has substituted type variables, method cannot have a generic signature AND no variables -> its a name clash if it does
593
	TypeBinding match = method.declaringClass.findSuperTypeOriginatingFrom(inheritedMethod.declaringClass);
607
		return ! (hasGenericParameter(method) && method.typeVariables == Binding.NO_TYPE_VARIABLES);
594
	if (!(match instanceof ReferenceBinding))
595
		return false; // method's declaringClass does not inherit from inheritedMethod's 
596
597
	if (match != inheritedMethod.declaringClass) {
598
		MethodBinding[] superMethods = ((ReferenceBinding) match).getMethods(inheritedMethod.selector);
599
		for (int i = 0, length = superMethods.length; i < length; i++)
600
			if (superMethods[i].original() == inheritedMethod)
601
				return isParameterSubsignature(method, superMethods[i]);
608
	}
602
	}
609
603
610
	// if method has its own variables, then substituteMethod failed bounds check in computeSubstituteMethod()
604
	return isParameterSubsignature(method, inheritedMethod);
611
	return method.typeVariables == Binding.NO_TYPE_VARIABLES;
612
}
605
}
613
boolean hasGenericParameter(MethodBinding method) {
606
boolean hasGenericParameter(MethodBinding method) {
614
	if (method.genericSignature() == null) return false;
607
	if (method.genericSignature() == null) return false;
Lines 708-713 Link Here
708
		&& inheritedMethod.returnType == existingMethod.returnType // keep around to produce bridge methods
701
		&& inheritedMethod.returnType == existingMethod.returnType // keep around to produce bridge methods
709
		&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType);
702
		&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType);
710
}
703
}
704
public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
705
	if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
706
		return false;
707
708
	inheritedMethod = inheritedMethod.original();
709
	TypeBinding match = method.declaringClass.findSuperTypeOriginatingFrom(inheritedMethod.declaringClass);
710
	if ((match instanceof ReferenceBinding) && match != inheritedMethod.declaringClass) {
711
		MethodBinding[] superMethods = ((ReferenceBinding) match).getMethods(inheritedMethod.selector);
712
		for (int i = 0, length = superMethods.length; i < length; i++)
713
			if (superMethods[i].original() == inheritedMethod)
714
				return isParameterSubsignature(method, superMethods[i]);
715
	}
716
717
	return isParameterSubsignature(method, inheritedMethod);
718
}
719
boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
720
	MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method);
721
	return substitute != null && isSubstituteParameterSubsignature(method, substitute);
722
}
723
// if method "overrides" substituteMethod then we can skip over substituteMethod while resolving a message send
724
// if it does not then a name clash error is likely
725
boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod) {
726
	if (!areParametersEqual(method, substituteMethod)) {
727
		// method can still override substituteMethod in cases like :
728
		// <U extends Number> void c(U u) {}
729
		// @Override void c(Number n) {}
730
		// but method cannot have a "generic-enabled" parameter type
731
		if (substituteMethod.hasSubstitutedParameters() && method.areParameterErasuresEqual(substituteMethod))
732
			return method.typeVariables == Binding.NO_TYPE_VARIABLES && !hasGenericParameter(method);
733
		return false;
734
	}
735
736
	if (substituteMethod instanceof ParameterizedGenericMethodBinding) {
737
		// since substituteMethod has substituted type variables, method cannot have a generic signature AND no variables -> its a name clash if it does
738
		return ! (hasGenericParameter(method) && method.typeVariables == Binding.NO_TYPE_VARIABLES);
739
	}
740
741
	// if method has its own variables, then substituteMethod failed bounds check in computeSubstituteMethod()
742
	return method.typeVariables == Binding.NO_TYPE_VARIABLES;
743
}
711
boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) {
744
boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) {
712
	// JLS 3 §8.4.5: more are accepted, with an unchecked conversion
745
	// JLS 3 §8.4.5: more are accepted, with an unchecked conversion
713
	if (currentMethod.returnType == inheritedMethod.returnType.erasure()) {
746
	if (currentMethod.returnType == inheritedMethod.returnType.erasure()) {
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java (-3 / +3 lines)
Lines 706-712 Link Here
706
				if (compatibleMethod != null) {
706
				if (compatibleMethod != null) {
707
					if (compatibleMethod.isValidBinding()) {
707
					if (compatibleMethod.isValidBinding()) {
708
						if (concreteMatch != null && concreteMatch.declaringClass.findSuperTypeOriginatingFrom(compatibleMethod.declaringClass) != null)
708
						if (concreteMatch != null && concreteMatch.declaringClass.findSuperTypeOriginatingFrom(compatibleMethod.declaringClass) != null)
709
							if (environment().methodVerifier().doesMethodOverride(concreteMatch, compatibleMethod))
709
							if (environment().methodVerifier().isParameterSubsignature(concreteMatch, compatibleMethod))
710
								continue; // can skip this method since concreteMatch overrides it
710
								continue; // can skip this method since concreteMatch overrides it
711
						if (candidatesCount == 0) {
711
						if (candidatesCount == 0) {
712
							candidates = new MethodBinding[foundSize - startFoundSize + 1];
712
							candidates = new MethodBinding[foundSize - startFoundSize + 1];
Lines 1086-1092 Link Here
1086
						// BUT we can also ignore any overridden method since we already know the better match (fixes 80028)
1086
						// BUT we can also ignore any overridden method since we already know the better match (fixes 80028)
1087
						for (int j = 0, max = found.size; j < max; j++) {
1087
						for (int j = 0, max = found.size; j < max; j++) {
1088
							MethodBinding matchingMethod = (MethodBinding) found.elementAt(j);
1088
							MethodBinding matchingMethod = (MethodBinding) found.elementAt(j);
1089
							if (verifier.doesMethodOverride(matchingMethod.original(), currentMethod.original())) {
1089
							if (verifier.isParameterSubsignature(matchingMethod.original(), currentMethod.original())) {
1090
								if (isCompliant15) {
1090
								if (isCompliant15) {
1091
									if (matchingMethod.isBridge() && !currentMethod.isBridge())
1091
									if (matchingMethod.isBridge() && !currentMethod.isBridge())
1092
										continue nextMethod; // keep inherited methods to find concrete method over a bridge method
1092
										continue nextMethod; // keep inherited methods to find concrete method over a bridge method
Lines 3420-3426 Link Here
3420
									}
3420
									}
3421
								}
3421
								}
3422
							}
3422
							}
3423
							if (!environment().methodVerifier().doesMethodOverride(original, original2))
3423
							if (!environment().methodVerifier().isParameterSubsignature(original, original2))
3424
								continue nextSpecific; // current does not override next
3424
								continue nextSpecific; // current does not override next
3425
						}
3425
						}
3426
					} else if (receiverType != null) { // should not be null if original isAbstract, but be safe
3426
					} else if (receiverType != null) { // should not be null if original isAbstract, but be safe
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java (-4 / +39 lines)
Lines 51-57 Link Here
51
			&& environment.globalOptions.sourceLevel < ClassFileConstants.JDK1_5;
51
			&& environment.globalOptions.sourceLevel < ClassFileConstants.JDK1_5;
52
}
52
}
53
boolean areMethodsCompatible(MethodBinding one, MethodBinding two) {
53
boolean areMethodsCompatible(MethodBinding one, MethodBinding two) {
54
	return doesMethodOverride(one, two) && areReturnTypesCompatible(one, two);
54
	return isParameterSubsignature(one, two) && areReturnTypesCompatible(one, two);
55
}
55
}
56
boolean areParametersEqual(MethodBinding one, MethodBinding two) {
56
boolean areParametersEqual(MethodBinding one, MethodBinding two) {
57
	TypeBinding[] oneArgs = one.parameters;
57
	TypeBinding[] oneArgs = one.parameters;
Lines 348-354 Link Here
348
				for (int j = 0, length2 = inherited.length; j < length2; j++) {
348
				for (int j = 0, length2 = inherited.length; j < length2; j++) {
349
					MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod);
349
					MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod);
350
					if (inheritedMethod != null) {
350
					if (inheritedMethod != null) {
351
						if (doesMethodOverride(currentMethod, inheritedMethod)) {
351
						if (isParameterSubsignature(currentMethod, inheritedMethod)) {
352
							matchingInherited[++index] = inheritedMethod;
352
							matchingInherited[++index] = inheritedMethod;
353
							inherited[j] = null; // do not want to find it again
353
							inherited[j] = null; // do not want to find it again
354
						}
354
						}
Lines 372-378 Link Here
372
					continue;
372
					continue;
373
				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
373
				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
374
				if (otherInheritedMethod != null) {
374
				if (otherInheritedMethod != null) {
375
					if (doesMethodOverride(inheritedMethod, otherInheritedMethod)) {
375
					if (isParameterSubsignature(inheritedMethod, otherInheritedMethod)) {
376
						matchingInherited[++index] = otherInheritedMethod;
376
						matchingInherited[++index] = otherInheritedMethod;
377
						inherited[j] = null; // do not want to find it again
377
						inherited[j] = null; // do not want to find it again
378
					}
378
					}
Lines 591-598 Link Here
591
	if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
591
	if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
592
	return inheritedMethod;
592
	return inheritedMethod;
593
}
593
}
594
boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
595
	if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
596
		return false;
597
	if (method == inheritedMethod || method.isStatic() || inheritedMethod.isStatic())
598
		return false;
599
	if (inheritedMethod.isPrivate())
600
		return false;
601
	if (inheritedMethod.isDefault() && method.declaringClass.getPackage() != inheritedMethod.declaringClass.getPackage())
602
		return false;
603
	if (!method.isPublic()) { // inheritedMethod is either public or protected & method is less than public
604
		if (inheritedMethod.isPublic())
605
			return false;
606
		if (inheritedMethod.isProtected() && !method.isProtected())
607
			return false;
608
	}
609
	return true;
610
}
611
// Answer whether the method overrides the inheritedMethod
612
// Check the necessary visibility rules & inheritance from the inheritedMethod's declaringClass
613
// See isMethodSubsignature() for parameter comparisons
594
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
614
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
595
	return areParametersEqual(method, inheritedMethod);
615
	if (!couldMethodOverride(method, inheritedMethod))
616
		return false;
617
618
	inheritedMethod = inheritedMethod.original();
619
	TypeBinding match = method.declaringClass.findSuperTypeOriginatingFrom(inheritedMethod.declaringClass);
620
	if (!(match instanceof ReferenceBinding))
621
		return false; // method's declaringClass does not inherit from inheritedMethod's 
622
623
	return isParameterSubsignature(method, inheritedMethod);
596
}
624
}
597
SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
625
SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
598
	return null; // noop in 1.4
626
	return null; // noop in 1.4
Lines 662-667 Link Here
662
	// skip interface method with the same signature if visible to its declaringClass
690
	// skip interface method with the same signature if visible to its declaringClass
663
	return areParametersEqual(existingMethod, inheritedMethod) && existingMethod.declaringClass.implementsInterface(superType, true);
691
	return areParametersEqual(existingMethod, inheritedMethod) && existingMethod.declaringClass.implementsInterface(superType, true);
664
}
692
}
693
public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
694
	return org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector)
695
		&& isParameterSubsignature(method, inheritedMethod);
696
}
697
boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
698
	return areParametersEqual(method, inheritedMethod);
699
}
665
boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) {
700
boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) {
666
	do {
701
	do {
667
		if (testClass == superclass) return true;
702
		if (testClass == superclass) return true;
(-)codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java (-5 / +5 lines)
Lines 5615-5627 Link Here
5615
				
5615
				
5616
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
5616
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
5617
					if (receiverType == otherReceiverType) {
5617
					if (receiverType == otherReceiverType) {
5618
						if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
5618
						if (lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
5619
							if (!superCall || !otherMethod.declaringClass.isInterface()) {
5619
							if (!superCall || !otherMethod.declaringClass.isInterface()) {
5620
								continue next;
5620
								continue next;
5621
							}
5621
							}
5622
						}
5622
						}
5623
					} else {
5623
					} else {
5624
						if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
5624
						if (lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
5625
							if(receiverType.isAnonymousType()) continue next;
5625
							if(receiverType.isAnonymousType()) continue next;
5626
							
5626
							
5627
							if(!superCall) {
5627
							if(!superCall) {
Lines 5921-5927 Link Here
5921
					if (method == otherMethod) continue next;
5921
					if (method == otherMethod) continue next;
5922
					
5922
					
5923
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
5923
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
5924
						if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
5924
						if (lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
5925
							continue next;
5925
							continue next;
5926
						}
5926
						}
5927
					}
5927
					}
Lines 6216-6222 Link Here
6216
					continue next;
6216
					continue next;
6217
				
6217
				
6218
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6218
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6219
					if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
6219
					if (lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6220
						continue next;
6220
						continue next;
6221
					}
6221
					}
6222
				}
6222
				}
Lines 6541-6547 Link Here
6541
					continue next;
6541
					continue next;
6542
6542
6543
				if (CharOperation.equals(method.selector, otherMethod.selector, true)
6543
				if (CharOperation.equals(method.selector, otherMethod.selector, true)
6544
						&& lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
6544
						&& lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6545
					continue next;
6545
					continue next;
6546
				}
6546
				}
6547
			}
6547
			}
(-)src/org/eclipse/jdt/core/tests/dom/CompatibilityRulesTests.java (+270 lines)
Lines 784-787 Link Here
784
		assertTrue("Y#foo() should not override X#foo()", !bindings[0].overrides(bindings[1]));
784
		assertTrue("Y#foo() should not override X#foo()", !bindings[0].overrides(bindings[1]));
785
	}
785
	}
786
	
786
	
787
	/*
788
	 * Ensures that a method with different paramter types is not a subsignature of its super method.
789
	 * (regression test for bug 111093 More problems with IMethodBinding#isSubsignature(..))
790
	 */
791
	public void test035() throws JavaModelException {
792
		IMethodBinding[] bindings = createMethodBindings(
793
			new String[] {
794
				"/P/p1/A.java",
795
				"package p1;\n" +
796
				"public class A<T> {\n" + 
797
				"  public void o1_xoo2(A<?> s) {\n" + 
798
				"  }\n" + 
799
				"}\n" +
800
				"class B<S> extends A<S> {\n" + 
801
				"  @Override\n" + 
802
				"  public void o1_xoo2(A<Object> s) {\n" + 
803
				"  }\n" + 
804
				"}",
805
			},
806
			new String[] {
807
				"Lp1/A;.o1_xoo2(Lp1/A<*>;)V",
808
				"Lp1/A~B;.o1_xoo2(Lp1/A<Ljava/lang/Object;>;)V"
809
			});	
810
		assertFalse("B#o1_xoo2() should not be a subsignature of A#o1_xoo2()", bindings[1].isSubsignature(bindings[0]));
811
	}
812
	
813
	/*
814
	 * Ensures that a method with different paramter types is not a subsignature of its super method.
815
	 * (regression test for bug 111093 More problems with IMethodBinding#isSubsignature(..))
816
	 */
817
	public void test036() throws JavaModelException {
818
		IMethodBinding[] bindings = createMethodBindings(
819
			new String[] {
820
				"/P/p1/A.java",
821
				"package p1;\n" +
822
				"public class A<T> {\n" + 
823
				"  public void o1_xoo3(A<? extends T> s) {\n" + 
824
				"  }\n" + 
825
				"}\n" +
826
				"class B<S> extends A<S> {\n" + 
827
				"  @Override\n" + 
828
				"  public void o1_xoo3(A<? super S> s) {\n" + 
829
				"  }\n" + 
830
				"}",
831
			},
832
			new String[] {
833
				"Lp1/A;.o1_xoo3(Lp1/A<+TT;>;)V",
834
				"Lp1/A~B;.o1_xoo3(Lp1/A<-TS;>;)V"
835
			});	
836
		assertFalse("B#o1_xoo3() should not be a subsignature of A#o1_xoo3()", bindings[1].isSubsignature(bindings[0]));
837
	}
838
	
839
	/*
840
	 * Ensures that a method with different paramter types is not a subsignature of its super method.
841
	 * (regression test for bug 111093 More problems with IMethodBinding#isSubsignature(..))
842
	 */
843
	public void test037() throws JavaModelException {
844
		IMethodBinding[] bindings = createMethodBindings(
845
			new String[] {
846
				"/P/p1/A.java",
847
				"package p1;\n" +
848
				"public class A<S, T> {\n" + 
849
				"  public void o2_xoo1(List<? extends T> t) {\n" + 
850
				"  }\n" + 
851
				"}\n" +
852
				"class B<V, W> extends A<W, V> {\n" + 
853
				"  @Override\n" + 
854
				"  public void o2_xoo1(List<? extends W> t) {\n" + 
855
				"  }\n" + 
856
				"}\n" +
857
				"class List<T> {\n" +
858
				"}",
859
			},
860
			new String[] {
861
				"Lp1/A;.o2_xoo1(Lp1/List<+TT;>;)V",
862
				"Lp1/A~B;.o2_xoo1(Lp1/List<+TW;>;)V"
863
			});	
864
		assertFalse("B#o1_xoo1() should not be a subsignature of A#o1_xoo1()", bindings[1].isSubsignature(bindings[0]));
865
	}
866
	
867
	/*
868
	 * Ensures that a method with different paramter types is not a subsignature of its super method.
869
	 * (regression test for bug 111093 More problems with IMethodBinding#isSubsignature(..))
870
	 */
871
	public void test038() throws JavaModelException {
872
		IMethodBinding[] bindings = createMethodBindings(
873
			new String[] {
874
				"/P/p1/A.java",
875
				"package p1;\n" +
876
				"public class A {\n" + 
877
				"  public void o3_xoo1(List t) {\n" + 
878
				"  }\n" + 
879
				"}\n" +
880
				"class B extends A {\n" + 
881
				"  @Override\n" + 
882
				"  public void o3_xoo1(List<Object> t) {\n" + 
883
				"  }\n" + 
884
				"}\n" + 
885
				"class List<T> {\n" +
886
				"}",
887
			},
888
			new String[] {
889
				"Lp1/A;.o3_xoo1(Lp1/List;)V",
890
				"Lp1/A~B;.o3_xoo1(Lp1/List<Ljava/lang/Object;>;)V"
891
			});	
892
		assertFalse("B#o3_xoo1() should not be a subsignature of A#o3_xoo1()", bindings[1].isSubsignature(bindings[0]));
893
	}
894
	
895
	/*
896
	 * Ensures that a method with different paramter types is not a subsignature of its super method.
897
	 * (regression test for bug 111093 More problems with IMethodBinding#isSubsignature(..))
898
	 */
899
	public void test039() throws JavaModelException {
900
		IMethodBinding[] bindings = createMethodBindings(
901
			new String[] {
902
				"/P/p1/A.java",
903
				"package p1;\n" +
904
				"public class A<T> {\n" + 
905
				"  public void o4_xoo1(T t) {\n" + 
906
				"  }\n" + 
907
				"}\n" +
908
				"class B extends A<List<String>> {\n" + 
909
				"  @Override\n" + 
910
				"  public void o4_xoo1(List<?> t) {\n" + 
911
				"  }\n" + 
912
				"}\n" + 
913
				"class List<T> {\n" +
914
				"}",
915
			},
916
			new String[] {
917
				"Lp1/A;.o4_xoo1(TT;)V",
918
				"Lp1/A~B;.o4_xoo1(Lp1/List<*>;)V"
919
			});	
920
		assertFalse("B#o4_xoo1() should not be a subsignature of A#o4_xoo1()", bindings[1].isSubsignature(bindings[0]));
921
	}
922
	
923
	/*
924
	 * Ensures that a method with different paramter types is not a subsignature of its super method.
925
	 * (regression test for bug 111093 More problems with IMethodBinding#isSubsignature(..))
926
	 */
927
	public void test040() throws JavaModelException {
928
		IMethodBinding[] bindings = createMethodBindings(
929
			new String[] {
930
				"/P/p1/A.java",
931
				"package p1;\n" +
932
				"public class A<S> {\n" + 
933
				"  public <X, Y> void tp1_xoo3(X x, Y y) {\n" + 
934
				"  }\n" + 
935
				"}\n" +
936
				"class B extends A<String> {\n" + 
937
				"  @Override\n" + 
938
				"  public <W, V> void tp1_xoo3(V x, W y) {\n" + 
939
				"  }\n" + 
940
				"}",
941
			},
942
			new String[] {
943
				"Lp1/A;.tp1_xoo3<X:Ljava/lang/Object;Y:Ljava/lang/Object;>(TX;TY;)V",
944
				"Lp1/A~B;.tp1_xoo3<W:Ljava/lang/Object;V:Ljava/lang/Object;>(TV;TW;)V"
945
			});	
946
		assertFalse("B#tp1_xoo3() should not be a subsignature of A#tp1_xoo3()", bindings[1].isSubsignature(bindings[0]));
947
	}
948
	
949
	/*
950
	 * Ensures that a method with different paramter types is not a subsignature of its super method.
951
	 * (regression test for bug 111093 More problems with IMethodBinding#isSubsignature(..))
952
	 */
953
	public void test041() throws JavaModelException {
954
		IMethodBinding[] bindings = createMethodBindings(
955
			new String[] {
956
				"/P/p1/A.java",
957
				"package p1;\n" +
958
				"public class A<S> {\n" + 
959
				"  public <X, Y> void tp1_foo2(S s, X x, Y y) {\n" + 
960
				"  }\n" + 
961
				"}\n" +
962
				"class B extends A<String> {\n" + 
963
				"  @Override\n" + 
964
				"  public void tp1_foo2(String s, Object x, Object y) {\n" + 
965
				"  }\n" + 
966
				"}",
967
			},
968
			new String[] {
969
				"Lp1/A;.tp1_foo2<X:Ljava/lang/Object;Y:Ljava/lang/Object;>(TS;TX;TY;)V",
970
				"Lp1/A~B;.tp1_foo2(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V"
971
			});	
972
		assertTrue("B#tp1_foo2() should be a subsignature of A#tp1_foo2()", bindings[1].isSubsignature(bindings[0]));
973
	}
974
	
975
	/*
976
	 * Ensures that a method with different paramter types is not a subsignature of its super method.
977
	 * (regression test for bug 111093 More problems with IMethodBinding#isSubsignature(..))
978
	 */
979
	public void test042() throws JavaModelException {
980
		IMethodBinding[] bindings = createMethodBindings(
981
			new String[] {
982
				"/P/p1/A.java",
983
				"package p1;\n" +
984
				"public abstract class A<T> {\n" + 
985
				"  void g2 (T t) {\n" + 
986
				"  }\n" + 
987
				"}\n" + 
988
				"class B extends A<List<Number>> {\n" + 
989
				"  void g2 (List<Number> t) {\n" + 
990
				"  }\n" + 
991
				"}\n" + 
992
				"class List<T> {\n" + 
993
				"}\n" +
994
				"class Number {\n" +
995
				"}",
996
			},
997
			new String[] {
998
				"Lp1/A~B;.g2(Lp1/List<Lp1/Number;>;)V"
999
			});	
1000
		ITypeBinding superType = bindings[0].getDeclaringClass().getSuperclass(); // parameterized type
1001
		IMethodBinding ag2 = superType.getDeclaredMethods()[1];
1002
		assertTrue("B#g2() should be a subsignature of A#g2()", bindings[0].isSubsignature(ag2));
1003
	}
1004
	
1005
	/*
1006
	 * Ensures that a method with same signature in a different hierarchy doesn't overide another one
1007
	 */
1008
	public void test043() throws JavaModelException {
1009
		IMethodBinding[] bindings = createMethodBindings(
1010
			new String[] {
1011
				"/P/p1/X.java",
1012
				"package p1;\n" +
1013
				"public class X {\n" +
1014
				"  void foo() {\n" +
1015
				"  }\n" +
1016
				"}",
1017
				"/P/p1/Y.java",
1018
				"package p1;\n" +
1019
				"public class Y {\n" +
1020
				"  void foo() {\n" +
1021
				"  }\n" +
1022
				"}",
1023
			},
1024
			new String[] {
1025
				"Lp1/X;.foo()V",
1026
				"Lp1/Y;.foo()V"
1027
			});	
1028
		assertFalse("Y#foo() should not override X#foo()", bindings[1].overrides(bindings[0]));
1029
	}
1030
	
1031
	/*
1032
	 * Ensures that a method is a subsignature of the same method in a different hierarchy 
1033
	 */
1034
	public void test044() throws JavaModelException {
1035
		IMethodBinding[] bindings = createMethodBindings(
1036
			new String[] {
1037
				"/P/p1/X.java",
1038
				"package p1;\n" +
1039
				"public class X {\n" +
1040
				"  void foo() {\n" +
1041
				"  }\n" +
1042
				"}",
1043
				"/P/p1/Y.java",
1044
				"package p1;\n" +
1045
				"public class Y {\n" +
1046
				"  void foo() {\n" +
1047
				"  }\n" +
1048
				"}",
1049
			},
1050
			new String[] {
1051
				"Lp1/X;.foo()V",
1052
				"Lp1/Y;.foo()V"
1053
			});	
1054
		assertTrue("Y#foo() should be a subsignature of X#foo()", bindings[1].isSubsignature(bindings[0]));
1055
	}
1056
	
787
}
1057
}

Return to bug 111093