aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAyushman Jain2012-08-07 01:30:35 (EDT)
committerJayaprakash Arthanareeswaran2012-08-10 03:04:03 (EDT)
commit28a527aa646605138ee088f966d41bc12493ed40 (patch)
tree422eb7bcc638fbc322995ead17d64f693d089bf9
parent9119a1906c2bdf97ef9722a343397a64998ed131 (diff)
downloadeclipse.jdt.core-28a527aa646605138ee088f966d41bc12493ed40.zip
eclipse.jdt.core-28a527aa646605138ee088f966d41bc12493ed40.tar.gz
eclipse.jdt.core-28a527aa646605138ee088f966d41bc12493ed40.tar.bz2
Fixed bug 383780: [compiler] Eclipse 4.2 creates ambiguous varargs
method error in 1.6 compliance mode (does not mimic JDK bug)
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java416
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java36
3 files changed, 450 insertions, 11 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
index 536723b..e2752d0 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * Copyright (c) 2005, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -33,7 +33,7 @@ public class VarargsTest extends AbstractComparableTest {
// Static initializer to specify tests subset using TESTS_* static variables
// All specified tests which does not belong to the class are skipped...
static {
-// TESTS_NAMES = new String[] { "test000" };
+// TESTS_NAMES = new String[] { "test070b" };
// TESTS_NUMBERS = new int[] { 61 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -798,6 +798,55 @@ public class VarargsTest extends AbstractComparableTest {
"----------\n"
);
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383780
+ public void test015_tolerate() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ Map options = getCompilerOptions();
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] s) {\n" +
+ " Y.count(new int[0]);\n" + // for some reason this is not ambiguous
+ " }\n" +
+ "}\n" +
+ "class Y {\n" +
+ " public static void count(int[] array, int ... values) { System.out.print(1); }\n" +
+ " public static void count(int[] array, int[] ... values) { System.out.print(2); }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " Y.count(new int[0]);\n" +
+ " ^^^^^\n" +
+ "The method count(int[], int[]) is ambiguous for the type Y\n" +
+ "----------\n",
+ null, true, options);
+ } else {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] s) {\n" +
+ " Y.count(new int[0]);\n" + // for some reason this is not ambiguous
+ " }\n" +
+ "}\n" +
+ "class Y {\n" +
+ " public static void count(int[] array, int ... values) { System.out.print(1); }\n" +
+ " public static void count(int[] array, int[] ... values) { System.out.print(2); }\n" +
+ "}\n",
+ },
+ "1",
+ null, true, null, options, null);
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+ }
public void test016() { // check behaviour of Scope.mostSpecificMethodBinding()
this.runNegativeTest( // but this call is ambiguous
@@ -1235,7 +1284,7 @@ public class VarargsTest extends AbstractComparableTest {
},
"1");
}
- //https://bugs.eclipse.org/bugs/show_bug.cgi?id=102631
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=102631
public void test033() {
this.runNegativeTest(
new String[] {
@@ -1302,6 +1351,61 @@ public class VarargsTest extends AbstractComparableTest {
"----------\n"
);
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383780
+ public void test033_tolerate() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ Map options = getCompilerOptions();
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void a(boolean b, Object... o) {System.out.print(1);}\n" +
+ " void a(Object... o) {System.out.print(2);}\n" +
+ " public static void main(String[] args) {\n" +
+ " X x = new X();\n" +
+ " x.a(true);\n" +
+ " x.a(true, \"foobar\");\n" +
+ " x.a(\"foo\", \"bar\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " x.a(true);\n" +
+ " ^\n" +
+ "The method a(boolean, Object[]) is ambiguous for the type X\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 7)\n" +
+ " x.a(true, \"foobar\");\n" +
+ " ^\n" +
+ "The method a(boolean, Object[]) is ambiguous for the type X\n" +
+ "----------\n",
+ null, true, options);
+ } else {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void a(boolean b, Object... o) {System.out.print(1);}\n" +
+ " void a(Object... o) {System.out.print(2);}\n" +
+ " public static void main(String[] args) {\n" +
+ " X x = new X();\n" +
+ " x.a(true);\n" +
+ " x.a(true, \"foobar\");\n" +
+ " x.a(\"foo\", \"bar\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "112",
+ null, true, null, options, null);
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+ }
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=106106
public void test034() {
this.runConformTest(
@@ -2818,6 +2922,106 @@ public class VarargsTest extends AbstractComparableTest {
},
"Done");
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383780
+ public void test070_tolerate() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ Map options = getCompilerOptions();
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel < ClassFileConstants.JDK1_7) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void foo(int ...i) {}\n" +
+ " public static void foo(double...d) {}\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(1, 2, 3);\n" +
+ " System.out.println (\"Done\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " foo(1, 2, 3);\n" +
+ " ^^^\n" +
+ "The method foo(int[]) is ambiguous for the type X\n" +
+ "----------\n",
+ null, true, options);
+ } else {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void foo(int ...i) {}\n" +
+ " public static void foo(double...d) {}\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(1, 2, 3);\n" +
+ " System.out.println (\"Done\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "Done",
+ null, true, null, options, null);
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383780
+ public void test070_tolerate2() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ Map options = getCompilerOptions();
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.Arrays;\n" +
+ "public class X {\n" +
+ " public static void test(int... a) {\n" +
+ " System.out.println(Arrays.toString(a));\n}\n" +
+ " public static <T> void test(Object... a) {\n" +
+ " System.out.println(Arrays.toString(a));\n}\n" +
+ " public static void main(String[] args) {\n" +
+ " test(1);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 10)\n" +
+ " test(1);\n" +
+ " ^^^^\n" +
+ "The method test(int[]) is ambiguous for the type X\n" +
+ "----------\n",
+ null, true, options);
+ } else {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.Arrays;\n" +
+ "public class X {\n" +
+ " public static void test(int... a) {\n" +
+ " System.out.println(Arrays.toString(a));\n}\n" +
+ " public static <T> void test(Object... a) {\n" +
+ " System.out.println(Arrays.toString(a));\n}\n" +
+ " public static void main(String[] args) {\n" +
+ " test(1);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "[1]",
+ null, true, null, options, null);
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+
+ }
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038
public void test070a() throws Exception {
if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
@@ -2835,6 +3039,52 @@ public class VarargsTest extends AbstractComparableTest {
},
"Done");
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383780
+ public void test070a_tolerate() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ Map options = getCompilerOptions();
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel < ClassFileConstants.JDK1_7) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static <T> void foo(int ...i) {}\n" +
+ " public static <T> void foo(double...d) {}\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(1, 2, 3);\n" +
+ " System.out.println (\"Done\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " foo(1, 2, 3);\n" +
+ " ^^^\n" +
+ "The method foo(int[]) is ambiguous for the type X\n" +
+ "----------\n",
+ null, true, options);
+ } else {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static <T> void foo(int ...i) {}\n" +
+ " public static <T> void foo(double...d) {}\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(1, 2, 3);\n" +
+ " System.out.println (\"Done\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "Done",
+ null, true, null, options, null);
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+ }
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038
public void test070b() throws Exception {
if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
@@ -2851,6 +3101,41 @@ public class VarargsTest extends AbstractComparableTest {
},
"");
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383780
+ public void test070b_tolerate() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ String[] src = new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void foo(int ...i) {}\n" +
+ " public static void foo(double d1, double...d) {}\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(1, 2, 3); // foo NOT flagged ambiguous\n" +
+ " }\n" +
+ "}\n"
+ };
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
+ this.runConformTest(
+ src,
+ "");
+ } else {
+ this.runNegativeTest(
+ src,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " foo(1, 2, 3); // foo NOT flagged ambiguous\n" +
+ " ^^^\n" +
+ "The method foo(int[]) is ambiguous for the type X\n" +
+ "----------\n");
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+ }
+
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038
public void test070c() { // check behaviour of Scope.mostSpecificMethodBinding()
this.runNegativeTest(
@@ -2935,6 +3220,48 @@ public class VarargsTest extends AbstractComparableTest {
},
"1");
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383780
+ public void test071_tolerate() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ String[] src =
+ new String[] {
+ "X.java",
+ "public class X implements IClass{\n" +
+ " X(IClass c, X t, IType... args) {\n" +
+ " System.out.println (\"1\");\n" +
+ " }\n" +
+ " X(IClass c, IType... args) {\n" +
+ " System.out.println (\"2\");\n" +
+ " }\n" +
+ " public static void main(String args[]) {\n" +
+ " IClass c = null;\n" +
+ " X t = null;\n" +
+ " X t2 = new X(c, t); // incorrectly flagged ambiguous\n" +
+ " }\n" +
+ "}\n" +
+ "interface IType{}\n" +
+ "interface IClass extends IType{}\n"
+ };
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
+ this.runConformTest(
+ src,
+ "1");
+ } else {
+ this.runNegativeTest(
+ src,
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " X t2 = new X(c, t); // incorrectly flagged ambiguous\n" +
+ " ^^^^^^^^^^^\n" +
+ "The constructor X(IClass, X, IType[]) is ambiguous\n" +
+ "----------\n");
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+ }
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=364672
public void test072() {
this.runConformTest(
@@ -3010,4 +3337,87 @@ public class VarargsTest extends AbstractComparableTest {
"The constructor B(A...) of type B is not applicable as the formal varargs element type A is not accessible here\n" +
"----------\n");
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=382469
+ public void testBug382469() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ String[] src =
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " private static void bar(Object... objs) {\n" +
+ " System.out.println (\"1\");\n" +
+ " }\n" +
+ " private static void bar(int intValue, Object... objs) {\n" +
+ " System.out.println (\"2\");\n" +
+ " }\n" +
+ " public static void main(String args[]) {\n" +
+ " bar(5);\n" +
+ " }\n" +
+ "}\n"
+ };
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel < ClassFileConstants.JDK1_7) {
+ this.runConformTest(
+ src,
+ "2");
+ } else {
+ this.runNegativeTest(
+ src,
+ "----------\n" +
+ "1. WARNING in X.java (at line 5)\n" +
+ " private static void bar(int intValue, Object... objs) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "The method bar(int, Object...) from the type X is never used locally\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 9)\n" +
+ " bar(5);\n" +
+ " ^^^\n" +
+ "The method bar(Object[]) is ambiguous for the type X\n" +
+ "----------\n");
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=386361
+ public void testBug386361() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ String[] src =
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void test(int i, Object... objects) {\n" +
+ " System.out.println (\"1\");\n" +
+ " }\n" +
+ " public static void test(Object... objects) {\n" +
+ " System.out.println (\"2\");\n" +
+ " }\n" +
+ " public static void main(String args[]) {\n" +
+ " test(1,\"test\");\n" +
+ " }\n" +
+ "}\n"
+ };
+ try {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
+ if (this.complianceLevel < ClassFileConstants.JDK1_7) {
+ this.runConformTest(
+ src,
+ "1");
+ } else {
+ this.runNegativeTest(
+ src,
+ "----------\n" +
+ "1. ERROR in X.java (at line 9)\n" +
+ " test(1,\"test\");\n" +
+ " ^^^^\n" +
+ "The method test(int, Object[]) is ambiguous for the type X\n" +
+ "----------\n");
+ }
+ } finally {
+ System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "false");
+ }
+ }
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index ce3a678..101b6ab 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -419,6 +419,15 @@ public class CompilerOptions {
public boolean analyseResourceLeaks;
/** Should missing enum cases be reported even if a default case exists in the same switch? */
public boolean reportMissingEnumCaseDespiteDefault;
+
+ /** Should the compiler tolerate illegal ambiguous varargs invocation in compliance < 1.7
+ * to be bug compatible with javac? (bug 383780) */
+ public static boolean tolerateIllegalAmbiguousVarargsInvocation;
+
+ {
+ String tolerateIllegalAmbiguousVarargs = System.getProperty("tolerateIllegalAmbiguousVarargsInvocation"); //$NON-NLS-1$
+ tolerateIllegalAmbiguousVarargsInvocation = tolerateIllegalAmbiguousVarargs != null && tolerateIllegalAmbiguousVarargs.equalsIgnoreCase("true"); //$NON-NLS-1$
+ }
// keep in sync with warningTokenToIrritant and warningTokenFromIrritant
public final static String[] warningTokens = {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 9066874..3ee0355 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -556,9 +556,9 @@ public abstract class Scope {
if (argLength != paramLength)
if (!isVarArgs || argLength < paramLength - 1)
return null; // incompatible
-
+ CompilerOptions compilerOptions = this.compilerOptions();
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=330435, inference should kick in only at source 1.5+
- if (typeVariables != Binding.NO_TYPE_VARIABLES && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { // generic method
+ if (typeVariables != Binding.NO_TYPE_VARIABLES && compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5) { // generic method
TypeBinding[] newArgs = null;
for (int i = 0; i < argLength; i++) {
TypeBinding param = i < paramLength ? parameters[i] : parameters[paramLength - 1];
@@ -575,7 +575,7 @@ public abstract class Scope {
method = ParameterizedGenericMethodBinding.computeCompatibleMethod(method, arguments, this, invocationSite);
if (method == null) return null; // incompatible
if (!method.isValidBinding()) return method; // bound check issue is taking precedence
- } else if (genericTypeArguments != null && compilerOptions().complianceLevel < ClassFileConstants.JDK1_7) {
+ } else if (genericTypeArguments != null && compilerOptions.complianceLevel < ClassFileConstants.JDK1_7) {
if (method instanceof ParameterizedGenericMethodBinding) {
if (!((ParameterizedGenericMethodBinding) method).wasInferred)
// attempt to invoke generic method of raw type with type hints <String>foo()
@@ -586,6 +586,10 @@ public abstract class Scope {
}
int compatibilityLevel;
+ if (tiebreakingVarargsMethods) {
+ if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && compilerOptions.complianceLevel < ClassFileConstants.JDK1_7)
+ tiebreakingVarargsMethods = false;
+ }
if ((compatibilityLevel = parameterCompatibilityLevel(method, arguments, tiebreakingVarargsMethods)) > NOT_COMPATIBLE) {
if (compatibilityLevel == VARARGS_COMPATIBLE) {
TypeBinding varargsElementType = method.parameters[method.parameters.length - 1].leafComponentType();
@@ -3056,8 +3060,13 @@ public abstract class Scope {
if (i == oneParamsLength - 1 && one.isVarargs() && two.isVarargs()) {
TypeBinding oType = ((ArrayBinding) oneParam).elementsType();
TypeBinding eType = ((ArrayBinding) twoParam).elementsType();
- if (oType == eType || oType.isCompatibleWith(eType))
- return true; // special case to choose between 2 varargs methods when the last arg is Object[]
+ if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && this.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7) {
+ if (oneParam == eType || oneParam.isCompatibleWith(eType))
+ return true; // special case to choose between 2 varargs methods when the last arg is Object[]
+ } else {
+ if (oType == eType || oType.isCompatibleWith(eType))
+ return true; // special case to choose between 2 varargs methods when the last arg is Object[]
+ }
}
return false;
}
@@ -3066,6 +3075,12 @@ public abstract class Scope {
}
if (one.isVarargs() && two.isVarargs()) {
+ if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && this.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7 &&
+ oneParamsLength > twoParamsLength) {
+ // special case when autoboxing makes (int, int...) better than (Object...) but not (int...) or (Integer, int...)
+ if (((ArrayBinding) twoParams[twoParamsLength - 1]).elementsType().id != TypeIds.T_JavaLangObject)
+ return false;
+ }
// check that each parameter before the vararg parameters are compatible (no autoboxing allowed here)
for (int i = (oneParamsLength > twoParamsLength ? twoParamsLength : oneParamsLength) - 2; i >= 0; i--)
if (oneParams[i] != twoParams[i] && !oneParams[i].isCompatibleWith(twoParams[i]))
@@ -4050,7 +4065,8 @@ public abstract class Scope {
int paramLength = parameters.length;
int argLength = arguments.length;
- if (compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) {
+ CompilerOptions compilerOptions = compilerOptions();
+ if (compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) {
if (paramLength != argLength)
return NOT_COMPATIBLE;
for (int i = 0; i < argLength; i++) {
@@ -4062,7 +4078,11 @@ public abstract class Scope {
}
return COMPATIBLE;
}
-
+ if (tiebreakingVarargsMethods) {
+ if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && compilerOptions.complianceLevel < ClassFileConstants.JDK1_7) {
+ tiebreakingVarargsMethods = false;
+ }
+ }
int level = COMPATIBLE; // no autoboxing or varargs support needed
int lastIndex = argLength;
LookupEnvironment env = environment();
@@ -4119,7 +4139,7 @@ public abstract class Scope {
// only called if env.options.sourceLevel >= ClassFileConstants.JDK1_5
if (arg.isCompatibleWith(param))
return COMPATIBLE;
- if (tieBreakingVarargsMethods) {
+ if (tieBreakingVarargsMethods && (this.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_7 || !CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation)) {
/* 15.12.2.5 Choosing the Most Specific Method, ... One variable arity member method named m is more specific than
another variable arity member method of the same name if either ... Only subtypes relationship should be used.
Actually this is true even for fixed arity methods, but in practice is not an issue since we run the algorithm