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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java (+39 lines)
Lines 7510-7513 Link Here
7510
		"The method bar(String, String) of type X is not generic; it cannot be parameterized with arguments <String>\n" + 
7510
		"The method bar(String, String) of type X is not generic; it cannot be parameterized with arguments <String>\n" + 
7511
		"----------\n");
7511
		"----------\n");
7512
}
7512
}
7513
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=174445
7514
public void test127() {
7515
	this.runNegativeTest(
7516
		new String[] {
7517
			"X.java",
7518
			"public class X {\n" + 
7519
			"  enum Enum1 {\n" + 
7520
			"    value;\n" + 
7521
			"  }\n" + 
7522
			"  enum Enum2 {\n" + 
7523
			"    value;\n" + 
7524
			"  }\n" + 
7525
			"  static abstract class A<T> {\n" + 
7526
			"    abstract <U extends T> U foo();\n" + 
7527
			"  }\n" + 
7528
			"  static class B extends A<Enum<?>> {\n" + 
7529
			"    @Override\n" + 
7530
			"    Enum<?> foo() {\n" + 
7531
			"      return Enum1.value;\n" + 
7532
			"    }  \n" + 
7533
			"  }\n" + 
7534
			"  public static void main(String[] args) {\n" + 
7535
			"    A<Enum<?>> a = new B();\n" + 
7536
			"    Enum2 value = a.foo();\n" + 
7537
			"  }\n" + 
7538
			"}"
7539
		},
7540
		"----------\n" + 
7541
		"1. WARNING in X.java (at line 13)\n" + 
7542
		"	Enum<?> foo() {\n" + 
7543
		"	^^^^\n" + 
7544
		"Type safety: The return type Enum<?> for foo() from the type X.B needs unchecked conversion to conform to Enum<E> from the type X.A<Enum<?>>\n" + 
7545
		"----------\n" + 
7546
		"2. WARNING in X.java (at line 13)\n" + 
7547
		"	Enum<?> foo() {\n" + 
7548
		"	^^^^\n" + 
7549
		"Type safety: The return type Enum<?> for foo() from the type X.B needs unchecked conversion to conform to U from the type X.A<T>\n" + 
7550
		"----------\n");
7551
}
7513
}
7552
}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java (-15 / +22 lines)
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);
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java (-3 / +3 lines)
Lines 324-330 Link Here
324
			for (int i = 0, length1 = current.length; i < length1; i++) {
324
			for (int i = 0, length1 = current.length; i < length1; i++) {
325
				MethodBinding currentMethod = current[i];
325
				MethodBinding currentMethod = current[i];
326
				for (int j = 0, length2 = inherited.length; j < length2; j++) {
326
				for (int j = 0, length2 = inherited.length; j < length2; j++) {
327
					MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod);
327
					MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod, false);
328
					if (inheritedMethod != null) {
328
					if (inheritedMethod != null) {
329
						if (doesMethodOverride(currentMethod, inheritedMethod)) {
329
						if (doesMethodOverride(currentMethod, inheritedMethod)) {
330
							matchingInherited[++index] = inheritedMethod;
330
							matchingInherited[++index] = inheritedMethod;
Lines 348-354 Link Here
348
				MethodBinding otherInheritedMethod = inherited[j];
348
				MethodBinding otherInheritedMethod = inherited[j];
349
				if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
349
				if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
350
					continue;
350
					continue;
351
				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
351
				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod, false);
352
				if (otherInheritedMethod != null) {
352
				if (otherInheritedMethod != null) {
353
					if (doesMethodOverride(inheritedMethod, otherInheritedMethod)) {
353
					if (doesMethodOverride(inheritedMethod, otherInheritedMethod)) {
354
						matchingInherited[++index] = otherInheritedMethod;
354
						matchingInherited[++index] = otherInheritedMethod;
Lines 564-570 Link Here
564
		}
564
		}
565
	}
565
	}
566
}
566
}
567
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
567
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, boolean eraseIfTypeParametersNbMismatch) {
568
	if (inheritedMethod == null) return null;
568
	if (inheritedMethod == null) return null;
569
	if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
569
	if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
570
	return inheritedMethod;
570
	return inheritedMethod;
(-).settings/org.eclipse.jdt.core.prefs (-1 / +1 lines)
Lines 1-4 Link Here
1
#Thu Mar 15 15:21:08 CET 2007
1
#Fri Mar 16 07:57:10 CET 2007
2
eclipse.preferences.version=1
2
eclipse.preferences.version=1
3
org.eclipse.jdt.core.builder.cleanOutputFolder=clean
3
org.eclipse.jdt.core.builder.cleanOutputFolder=clean
4
org.eclipse.jdt.core.builder.duplicateResourceTask=warning
4
org.eclipse.jdt.core.builder.duplicateResourceTask=warning

Return to bug 174445