### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java,v retrieving revision 1.309 diff -u -r1.309 Scope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 24 May 2007 14:29:32 -0000 1.309 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 1 Jun 2007 11:59:01 -0000 @@ -724,7 +724,7 @@ } // no need to check for visibility - interface methods are public if (compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) - return mostSpecificMethodBinding(candidates, candidatesCount, argumentTypes, invocationSite, receiverType); + return mostSpecificMethodBinding(candidates, null, candidatesCount, argumentTypes, invocationSite, receiverType); return mostSpecificInterfaceMethodBinding(candidates, candidatesCount, invocationSite); } @@ -1112,6 +1112,7 @@ // if found several candidates, then eliminate those not matching argument types int foundSize = found.size; MethodBinding[] candidates = null; + boolean[] differingCandidates = null; int candidatesCount = 0; MethodBinding problemMethod = null; boolean searchForDefaultAbstractMethod = isCompliant14 && ! receiverTypeIsInterface && (receiverType.isAbstract() || receiverType.isTypeVariable()); @@ -1129,8 +1130,13 @@ unitScope.recordTypeReferences(compatibleMethod.thrownExceptions); return compatibleMethod; } - if (candidatesCount == 0) + if (candidatesCount == 0) { candidates = new MethodBinding[foundSize]; + differingCandidates = new boolean[foundSize]; + } + if (compatibleMethod != methodBinding) { + differingCandidates[candidatesCount] = true; + } candidates[candidatesCount++] = compatibleMethod; } else if (problemMethod == null) { problemMethod = compatibleMethod; @@ -1205,6 +1211,7 @@ if (visiblesCount != i) { candidates[i] = null; candidates[visiblesCount] = methodBinding; + differingCandidates[visiblesCount] = differingCandidates[i]; } visiblesCount++; } @@ -1243,7 +1250,7 @@ } } - MethodBinding mostSpecificMethod = mostSpecificMethodBinding(candidates, visiblesCount, argumentTypes, invocationSite, receiverType); + MethodBinding mostSpecificMethod = mostSpecificMethodBinding(candidates, differingCandidates, visiblesCount, argumentTypes, invocationSite, receiverType); if (searchForDefaultAbstractMethod) { // search interfaces for a better match if (mostSpecificMethod.isValidBinding()) // see if there is a better match in the interfaces - see AutoBoxingTest 99, LookupTest#81 @@ -1670,7 +1677,7 @@ compatible[0].parameters, ProblemReasons.NotVisible); // all of visible are from the same declaringClass, even before 1.4 we can call this method instead of mostSpecificClassMethodBinding - return mostSpecificMethodBinding(visible, visibleIndex, argumentTypes, invocationSite, receiverType); + return mostSpecificMethodBinding(visible, null, visibleIndex, argumentTypes, invocationSite, receiverType); } catch (AbortCompilation e) { e.updateContext(invocationSite, referenceCompilationUnit().compilationResult); throw e; @@ -1949,7 +1956,7 @@ if (visible != null) { MethodBinding[] temp = new MethodBinding[visible.size]; visible.copyInto(temp); - foundMethod = mostSpecificMethodBinding(temp, temp.length, argumentTypes, invocationSite, null); + foundMethod = mostSpecificMethodBinding(temp, null, temp.length, argumentTypes, invocationSite, null); } } } @@ -2561,7 +2568,7 @@ return null; } - protected boolean isAcceptableMethod(MethodBinding one, MethodBinding two) { + protected boolean isAcceptableMethod(MethodBinding one, MethodBinding two, boolean twoIsRawified) { TypeBinding[] oneParams = one.parameters; TypeBinding[] twoParams = two.parameters; int oneParamsLength = oneParams.length; @@ -2581,7 +2588,7 @@ if (oneParam.isCompatibleWith(twoParam)) { if (oneParam.leafComponentType().isRawType()) { // A#RAW is not more specific than a rawified A - if (oneParam.needsUncheckedConversion(two.original().parameters[i])) + if ((twoIsRawified || ! two.parameters[i].isRawType()) && oneParam.needsUncheckedConversion(two.original().parameters[i])) return false; } } else { @@ -3287,7 +3294,7 @@ } // caveat: this is not a direct implementation of JLS - protected final MethodBinding mostSpecificMethodBinding(MethodBinding[] visible, int visibleSize, TypeBinding[] argumentTypes, InvocationSite invocationSite, ReferenceBinding receiverType) { + protected final MethodBinding mostSpecificMethodBinding(MethodBinding[] visible, boolean differing[], int visibleSize, TypeBinding[] argumentTypes, InvocationSite invocationSite, ReferenceBinding receiverType) { int[] compatibilityLevels = new int[visibleSize]; for (int i = 0; i < visibleSize; i++) compatibilityLevels[i] = parameterCompatibilityLevel(visible[i], argumentTypes); @@ -3330,7 +3337,10 @@ */ if (acceptable == null || !acceptable.isValidBinding()) continue nextVisible; - if (!isAcceptableMethod(tiebreakMethod, acceptable)) + if (!isAcceptableMethod(tiebreakMethod, acceptable, + (differing != null && differing[j]) || + /* not enough to replace the differing mechanism: (acceptable instanceof ParameterizedGenericMethodBinding && ((ParameterizedGenericMethodBinding) acceptable).wasInferred) || */ + acceptable != methodToTest)) continue nextVisible; // pick a concrete method over a bridge method when parameters are equal since the return type of the concrete method is more specific if (current.isBridge() && !next.isBridge()) #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java,v retrieving revision 1.46 diff -u -r1.46 AmbiguousMethodTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java 30 May 2007 14:55:43 -0000 1.46 +++ src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java 1 Jun 2007 11:59:04 -0000 @@ -799,7 +799,7 @@ "135" ); } - public void test014h() { + public void test014h1() { this.runConformTest( new String[] { "X.java", @@ -816,8 +816,6 @@ " > void a3(T x) {}\n" + " void a4(G x) {}\n" + " > void a4(S x) {}\n" + - " void a5(T x) {}\n" + - " void a5(F x) {}\n" + " void b(G x) { System.out.print(true); }\n" + " void b(F x) { System.out.print(false); }\n" + " void b2(G x) { System.out.print(true); }\n" + @@ -860,85 +858,268 @@ }, "truetruetruetruetruetruetruetruetruetruetruetruetruetruetruetrue" ); + } + public void test014h2() { this.runNegativeTest( new String[] { - "Y.java", - "public class Y extends X {\n" + + "X.java", + "public class X {\n" + + " void a(G x) {}\n" + + " void a(F x) {}\n" + + "}\n" + + "class A {}\n" + + "class B extends A {}\n" + + "class C extends B {}\n" + + "class F {} \n" + + "class G extends F {}\n" + + "class H extends G {}" + + "class Y extends X {\n" + " public static void ambiguousCases() {\n" + " H h = null;\n" + " H hraw = null;\n" + " new X().a(h);\n" + " new X().a(hraw);\n" + - " new X().a2(h);\n" + - " new X().a2(hraw);\n" + - " new X().a3(h);\n" + - " new X().a3(hraw);\n" + - " new X().a4(h);\n" + - " new X().a4(hraw);\n" + - " new X().a5(h);\n" + - " new X().a5(hraw);\n" + " }\n" + "}\n" }, "----------\n" + - "1. WARNING in Y.java (at line 4)\n" + + "1. WARNING in X.java (at line 2)\n" + + " void a(G x) {}\n" + + " ^\n" + + "G is a raw type. References to generic type G should be parameterized\n" + + "----------\n" + + "2. WARNING in X.java (at line 13)\n" + " H hraw = null;\n" + " ^\n" + "H is a raw type. References to generic type H should be parameterized\n" + "----------\n" + - "2. ERROR in Y.java (at line 5)\n" + + "3. ERROR in X.java (at line 14)\n" + " new X().a(h);\n" + " ^\n" + "The method a(G) is ambiguous for the type X\n" + "----------\n" + - "3. ERROR in Y.java (at line 6)\n" + + "4. ERROR in X.java (at line 15)\n" + " new X().a(hraw);\n" + " ^\n" + "The method a(G) is ambiguous for the type X\n" + + "----------\n", + null, + false + ); + } + public void test014h3() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void a2(G x) {}\n" + + " void a2(F x) {}\n" + + "}\n" + + "class A {}\n" + + "class B extends A {}\n" + + "class C extends B {}\n" + + "class F {} \n" + + "class G extends F {}\n" + + "class H extends G {}" + + "class Y extends X {\n" + + " public static void ambiguousCases() {\n" + + " H h = null;\n" + + " new X().a2(h);\n" + + " }\n" + + "}\n" + }, "----------\n" + - "4. ERROR in Y.java (at line 7)\n" + + "1. WARNING in X.java (at line 2)\n" + + " void a2(G x) {}\n" + + " ^\n" + + "G is a raw type. References to generic type G should be parameterized\n" + + "----------\n" + + "2. ERROR in X.java (at line 13)\n" + " new X().a2(h);\n" + " ^^\n" + "The method a2(G) is ambiguous for the type X\n" + + "----------\n" + ); + } + public void test014h4() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void a2(G x) {}\n" + + " void a2(F x) {}\n" + + "}\n" + + "class A {}\n" + + "class B extends A {}\n" + + "class C extends B {}\n" + + "class F {} \n" + + "class G extends F {}\n" + + "class H extends G {}" + + "class Y extends X {\n" + + " public static void ambiguousCases() {\n" + + " H hraw = null;\n" + + " new X().a2(hraw);\n" + + " }\n" + + "}\n" + }, "----------\n" + - "5. ERROR in Y.java (at line 8)\n" + + "1. WARNING in X.java (at line 2)\n" + + " void a2(G x) {}\n" + + " ^\n" + + "G is a raw type. References to generic type G should be parameterized\n" + + "----------\n" + + "2. WARNING in X.java (at line 12)\n" + + " H hraw = null;\n" + + " ^\n" + + "H is a raw type. References to generic type H should be parameterized\n" + + "----------\n" + + "3. ERROR in X.java (at line 13)\n" + " new X().a2(hraw);\n" + " ^^\n" + "The method a2(G) is ambiguous for the type X\n" + + "----------\n" + ); + } + public void test014h5() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void a3(G x) {}\n" + + " > void a3(T x) {}\n" + + "}\n" + + "class A {}\n" + + "class B extends A {}\n" + + "class C extends B {}\n" + + "class F {} \n" + + "class G extends F {}\n" + + "class H extends G {}" + + "class Y extends X {\n" + + " public static void ambiguousCases() {\n" + + " H h = null;\n" + + " H hraw = null;\n" + + " new X().a3(h);\n" + + " new X().a3(hraw);\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 2)\n" + + " void a3(G x) {}\n" + + " ^\n" + + "G is a raw type. References to generic type G should be parameterized\n" + "----------\n" + - "6. ERROR in Y.java (at line 9)\n" + + "2. WARNING in X.java (at line 13)\n" + + " H hraw = null;\n" + + " ^\n" + + "H is a raw type. References to generic type H should be parameterized\n" + + "----------\n" + + "3. ERROR in X.java (at line 14)\n" + " new X().a3(h);\n" + " ^^\n" + "The method a3(G) is ambiguous for the type X\n" + "----------\n" + - "7. ERROR in Y.java (at line 10)\n" + + "4. ERROR in X.java (at line 15)\n" + " new X().a3(hraw);\n" + " ^^\n" + "The method a3(G) is ambiguous for the type X\n" + + "----------\n", + null, + false + ); + } + public void test014h6() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void a4(G x) {}\n" + + " > void a4(S x) {}\n" + + "}\n" + + "class A {}\n" + + "class B extends A {}\n" + + "class C extends B {}\n" + + "class F {} \n" + + "class G extends F {}\n" + + "class H extends G {}" + + "class Y extends X {\n" + + " public static void ambiguousCases() {\n" + + " H h = null;\n" + + " H hraw = null;\n" + + " new X().a4(h);\n" + + " new X().a4(hraw);\n" + + " }\n" + + "}\n" + }, "----------\n" + - "8. ERROR in Y.java (at line 11)\n" + + "1. WARNING in X.java (at line 2)\n" + + " void a4(G x) {}\n" + + " ^\n" + + "G is a raw type. References to generic type G should be parameterized\n" + + "----------\n" + + "2. WARNING in X.java (at line 13)\n" + + " H hraw = null;\n" + + " ^\n" + + "H is a raw type. References to generic type H should be parameterized\n" + + "----------\n" + + "3. ERROR in X.java (at line 14)\n" + " new X().a4(h);\n" + " ^^\n" + "The method a4(G) is ambiguous for the type X\n" + "----------\n" + - "9. ERROR in Y.java (at line 12)\n" + + "4. ERROR in X.java (at line 15)\n" + " new X().a4(hraw);\n" + " ^^\n" + "The method a4(G) is ambiguous for the type X\n" + + "----------\n", + null, + false + ); + } + public void test014h7() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void a5(T x) {}\n" + + " void a5(F x) {}\n" + + "}\n" + + "class A {}\n" + + "class B extends A {}\n" + + "class C extends B {}\n" + + "class F {} \n" + + "class G extends F {}\n" + + "class H extends G {}" + + "class Y extends X {\n" + + " public static void ambiguousCases() {\n" + + " H h = null;\n" + + " H hraw = null;\n" + + " new X().a5(h);\n" + + " new X().a5(hraw);\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 2)\n" + + " void a5(T x) {}\n" + + " ^\n" + + "G is a raw type. References to generic type G should be parameterized\n" + + "----------\n" + + "2. WARNING in X.java (at line 13)\n" + + " H hraw = null;\n" + + " ^\n" + + "H is a raw type. References to generic type H should be parameterized\n" + "----------\n" + - "10. ERROR in Y.java (at line 13)\n" + + "3. ERROR in X.java (at line 14)\n" + " new X().a5(h);\n" + " ^^\n" + "The method a5(H) is ambiguous for the type X\n" + "----------\n" + - "11. ERROR in Y.java (at line 14)\n" + + "4. ERROR in X.java (at line 15)\n" + " new X().a5(hraw);\n" + " ^^\n" + "The method a5(H) is ambiguous for the type X\n" + - "----------\n", - null, - false - ); + "----------\n"); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=79798 public void test015() { @@ -2091,7 +2272,7 @@ ); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=189933 -public void _test060() { +public void test060() { this.runConformTest( new String[] { "X.java", @@ -2120,7 +2301,7 @@ } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=189933 // variant -public void _test061() { +public void test061() { this.runNegativeTest( new String[] { "X.java", @@ -2177,4 +2358,60 @@ "----------\n" ); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=189933 +// variant +public void test062() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void bar(K p) {\n" + + " new Y(p);\n" + + " new Y((J) p);\n" + + " }\n" + + "}\n" + + "class Y {\n" + + " Y(I p) {\n" + + " }\n" + + " Y(J p) {\n" + + " }\n" + + "}\n" + + "interface I { \n" + + "}\n" + + "interface J extends I {\n" + + "}\n" + + "interface K extends I, J {\n" + + "}" + }, + "" + ); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=189933 +// variant +public void test063() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void bar(K p) {\n" + + " new Y(p);\n" + + " new Y((J) p);\n" + + " }\n" + + "}\n" + + "class Y {\n" + + " Y(I p) {\n" + + " }\n" + + " Y(J p) {\n" + + " }\n" + + "}\n" + + "interface I { \n" + + "}\n" + + "interface J extends I {\n" + + "}\n" + + "interface K extends I, J {\n" + + "}" + }, + "" + ); +} }