Update jdt.core from BETA_JAVA8 with
a27c88e6ab2cdd140d2a25deaa52833a8b2cd1b2 upto
4d5ca8a02167bbefc92469b1dbb1f1e04260a45e
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index b7f17d9..71de456 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -18,6 +18,7 @@
* bug 402237 - [1.8][compiler] investigate differences between compilers re MethodVerifyTest
* bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
* Bug 412203 - [compiler] Internal compiler error: java.lang.IllegalArgumentException: info cannot be null
+ * Bug 422051 - [1.8][compiler][tests] cleanup excuses (JavacHasABug) in InterfaceMethodTests
* Jesper S Moller - Contributions for bug 378674 - "The method can be declared as static" is wrong
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -774,15 +775,7 @@
return compiler.compliance != ClassFileConstants.JDK1_5 ||
compiler.minor != 1600 ? null : this;
}
- }: null,
- Javac8AcceptsDefaultMethodInAnnotationType = RUN_JAVAC ?
- new JavacHasABug(
- MismatchType.EclipseErrorsJavacNone,
- ClassFileConstants.JDK1_8, 23 /* TODO: insert minor when fixed */) : null,
- Javac8ProducesIllegalAccessError = RUN_JAVAC ?
- new JavacHasABug(
- MismatchType.StandardOutputMismatch,
- ClassFileConstants.JDK1_8, 23 /* TODO: insert minor when fixed */) : null;
+ }: null;
}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
index c79521e..50fd25b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
@@ -12,6 +12,7 @@
import java.util.Map;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import junit.framework.Test;
@@ -134,48 +135,84 @@
"----------\n");
}
public void test001d() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "import java.util.ArrayList;\n" +
- "public class X<T> {" +
- " public void ab(ArrayList<String> al){\n" +
- " System.out.println(\"SUCCESS\");\n" +
- " }\n" +
- " public static void main(String[] args) {\n" +
- " X<String> x = new X<>();\n" +
- " x.ab(new ArrayList<>());\n" +
- " }\n" +
- "}",
- },
- "----------\n" +
- "1. ERROR in X.java (at line 7)\n" +
- " x.ab(new ArrayList<>());\n" +
- " ^^\n" +
- "The method ab(ArrayList<String>) in the type X<String> is not applicable for the arguments (ArrayList<Object>)\n" +
- "----------\n");
+ if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.ArrayList;\n" +
+ "public class X<T> {" +
+ " public void ab(ArrayList<String> al){\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " X<String> x = new X<>();\n" +
+ " x.ab(new ArrayList<>());\n" +
+ " }\n" +
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " x.ab(new ArrayList<>());\n" +
+ " ^^\n" +
+ "The method ab(ArrayList<String>) in the type X<String> is not applicable for the arguments (ArrayList<Object>)\n" +
+ "----------\n");
+ } else {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.ArrayList;\n" +
+ "public class X<T> {" +
+ " public void ab(ArrayList<String> al){\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " X<String> x = new X<>();\n" +
+ " x.ab(new ArrayList<>());\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS");
+ }
}
public void test001e() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "import java.util.ArrayList;\n" +
- "public class X<T> {" +
- " public void ab(ArrayList<T> al){\n" +
- " System.out.println(\"SUCCESS\");\n" +
- " }\n" +
- " public static void main(String[] args) {\n" +
- " X<String> x = new X<>();\n" +
- " x.ab(new ArrayList<>());\n" +
- " }\n" +
- "}",
- },
- "----------\n" +
- "1. ERROR in X.java (at line 7)\n" +
- " x.ab(new ArrayList<>());\n" +
- " ^^\n" +
- "The method ab(ArrayList<String>) in the type X<String> is not applicable for the arguments (ArrayList<Object>)\n" +
- "----------\n");
+ if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.ArrayList;\n" +
+ "public class X<T> {" +
+ " public void ab(ArrayList<T> al){\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " X<String> x = new X<>();\n" +
+ " x.ab(new ArrayList<>());\n" +
+ " }\n" +
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " x.ab(new ArrayList<>());\n" +
+ " ^^\n" +
+ "The method ab(ArrayList<String>) in the type X<String> is not applicable for the arguments (ArrayList<Object>)\n" +
+ "----------\n");
+ } else {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.ArrayList;\n" +
+ "public class X<T> {" +
+ " public void ab(ArrayList<T> al){\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " X<String> x = new X<>();\n" +
+ " x.ab(new ArrayList<>());\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS");
+ }
}
public void test001f() {
this.runNegativeTest(
@@ -533,45 +570,69 @@
"2");
}
public void test007a() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X<T> {\n" +
- " public X(){\n" +
- " }\n" +
- " public X(T param){\n" +
- " System.out.println(param);\n" +
- " }\n" +
- " public static void testFunction(X<String> param){\n" +
- " System.out.println(\"SUCCESS\");\n" +
- " }\n" +
- " public static void main(String[] args) {\n" +
- " X.testFunction(new X<>());\n" +
- " X.testFunction(new X(\"hello\"));\n" +
- " }\n" +
- "}",
- },
- "----------\n" +
- "1. ERROR in X.java (at line 11)\n" +
- " X.testFunction(new X<>());\n" +
- " ^^^^^^^^^^^^\n" +
- "The method testFunction(X<String>) in the type X is not applicable for the arguments (X<Object>)\n" +
- "----------\n" +
- "2. WARNING in X.java (at line 12)\n" +
- " X.testFunction(new X(\"hello\"));\n" +
- " ^^^^^^^^^^^^^^\n" +
- "Type safety: The constructor X(Object) belongs to the raw type X. References to generic type X<T> should be parameterized\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 12)\n" +
- " X.testFunction(new X(\"hello\"));\n" +
- " ^^^^^^^^^^^^^^\n" +
- "Type safety: The expression of type X needs unchecked conversion to conform to X<String>\n" +
- "----------\n" +
- "4. WARNING in X.java (at line 12)\n" +
- " X.testFunction(new X(\"hello\"));\n" +
- " ^\n" +
- "X is a raw type. References to generic type X<T> should be parameterized\n" +
- "----------\n");
+ if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " public X(){\n" +
+ " }\n" +
+ " public X(T param){\n" +
+ " System.out.println(param);\n" +
+ " }\n" +
+ " public static void testFunction(X<String> param){\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " X.testFunction(new X<>());\n" +
+ " X.testFunction(new X(\"hello\"));\n" +
+ " }\n" +
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " X.testFunction(new X<>());\n" +
+ " ^^^^^^^^^^^^\n" +
+ "The method testFunction(X<String>) in the type X is not applicable for the arguments (X<Object>)\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 12)\n" +
+ " X.testFunction(new X(\"hello\"));\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "Type safety: The constructor X(Object) belongs to the raw type X. References to generic type X<T> should be parameterized\n" +
+ "----------\n" +
+ "3. WARNING in X.java (at line 12)\n" +
+ " X.testFunction(new X(\"hello\"));\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "Type safety: The expression of type X needs unchecked conversion to conform to X<String>\n" +
+ "----------\n" +
+ "4. WARNING in X.java (at line 12)\n" +
+ " X.testFunction(new X(\"hello\"));\n" +
+ " ^\n" +
+ "X is a raw type. References to generic type X<T> should be parameterized\n" +
+ "----------\n");
+ } else {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " public X(){\n" +
+ " }\n" +
+ " public X(T param){\n" +
+ " System.out.println(param);\n" +
+ " }\n" +
+ " public static void testFunction(X<String> param){\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " X.testFunction(new X<>());\n" +
+ " X.testFunction(new X(\"hello\"));\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS\n" +
+ "hello\n" +
+ "SUCCESS");
+ }
}
//shows the difference between using <> and the raw type - different semantics
public void test008() {
@@ -921,23 +982,38 @@
}
//check inference at method argument position.
public void test0021() {
- this.runNegativeTest(
- new String[] {
- "X.java",
- "import java.util.List;\n" +
- "import java.util.ArrayList;\n" +
- "class X<T> {\n" +
- " public X(T t) {}\n" +
- " int f(List<String> p) {return 0;}\n" +
- " int x = f(new ArrayList<>());\n" +
- "}\n",
- },
- "----------\n" +
- "1. ERROR in X.java (at line 6)\n" +
- " int x = f(new ArrayList<>());\n" +
- " ^\n" +
- "The method f(List<String>) in the type X<T> is not applicable for the arguments (ArrayList<Object>)\n" +
- "----------\n");
+ if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.List;\n" +
+ "import java.util.ArrayList;\n" +
+ "class X<T> {\n" +
+ " public X(T t) {}\n" +
+ " int f(List<String> p) {return 0;}\n" +
+ " int x = f(new ArrayList<>());\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " int x = f(new ArrayList<>());\n" +
+ " ^\n" +
+ "The method f(List<String>) in the type X<T> is not applicable for the arguments (ArrayList<Object>)\n" +
+ "----------\n");
+ } else {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.List;\n" +
+ "import java.util.ArrayList;\n" +
+ "class X<T> {\n" +
+ " public X(T t) {}\n" +
+ " int f(List<String> p) {return 0;}\n" +
+ " int x = f(new ArrayList<>());\n" +
+ "}\n",
+ },
+ "");
+ }
}
public void test0022() {
this.runConformTest(
@@ -1033,6 +1109,7 @@
"----------\n");
}
// Test various scenarios.
+// NOTE: THIS TEST MOST LIKELY CAPTURES THE WRONG OUTPUT FOR JAVA 8. AS WE FIX TYPE INFERENCE ISSUES, THIS MAY FAIL.
public void test0026() {
this.runNegativeTest(
new String[] {
@@ -1055,6 +1132,7 @@
" X<?> x6 = new X<>(list);\n" +
"}\n"
},
+ this.complianceLevel < ClassFileConstants.JDK1_8 ?
"----------\n" +
"1. ERROR in X.java (at line 8)\n" +
" X<Number> x = new X<>(1);\n" +
@@ -1075,7 +1153,28 @@
" int i = m(new X<>(\"\"));\n" +
" ^\n" +
"The method m(X<String>) in the type X<T> is not applicable for the arguments (X<Object>)\n" +
- "----------\n");
+ "----------\n" :
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " X<Number> x = new X<>(1);\n" +
+ " ^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from X<Integer> to X<Number>\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 12)\n" +
+ " X<Object> x4 = new X<>(1).idem();\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from X<Integer> to X<Object>\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 13)\n" +
+ " X<Object> x5 = new X<>(1);\n" +
+ " ^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from X<Integer> to X<Object>\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 15)\n" +
+ " int i = m(new X<>(\"\"));\n" +
+ " ^^^^^^^^^^^\n" +
+ "The constructor X<String>(String) is ambiguous\n" +
+ "----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=344655
public void test0027() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
index 89cc6c4..4e21d0e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
@@ -1100,22 +1100,18 @@
// an annotation type cannot have default methods
public void testAnnotation1() {
runNegativeTest(
- false,
new String[] {
"I.java",
"public @interface I {\n" +
" default String id() { return \"1\"; }\n" +
"}\n"
},
- null,
- null,
"----------\n" +
"1. ERROR in I.java (at line 2)\n" +
" default String id() { return \"1\"; }\n" +
" ^^^^^^^\n" +
"Syntax error on token \"default\", @ expected\n" +
- "----------\n",
- JavacTestOptions.JavacHasABug.Javac8AcceptsDefaultMethodInAnnotationType);
+ "----------\n");
}
// basic situation similar to AmbiguousMethodTest.test009()
@@ -1804,8 +1800,7 @@
}
// class implements interface with default method.
- // - synth. access needed for visibility reasons
- // - witness for NoSuchMethodError in synthetic method (SuperMethodAccess)
+ // - witness for NoSuchMethodError in synthetic method (SuperMethodAccess) - turned out to be a JVM bug
public void testSuperAccess01() {
runConformTest(
new String[] {
@@ -1827,11 +1822,9 @@
}
// class implements interface with default method.
- // - synth. access needed for visibility reasons
// - intermediate public interface
public void testSuperAccess02() {
runConformTest(
- false,
new String[] {
"p1/C.java",
"package p1;\n" +
@@ -1850,10 +1843,34 @@
"}\n" +
"public interface J extends I {}\n"
},
- "",
- "default",
- "",
- JavacTestOptions.JavacHasABug.Javac8ProducesIllegalAccessError);
+ "default");
+ }
+
+ // https://bugs.eclipse.org/421796 - Bug 421796 - [1.8][compiler] java.lang.AbstractMethodError executing default method code.
+ public void testSuperAccess03() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " void foo(); \n" +
+ "}\n" +
+ "\n" +
+ "interface J extends I {\n" +
+ " default void foo() {\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "interface K extends J {\n" +
+ "}\n" +
+ "\n" +
+ "public class X implements K {\n" +
+ " public static void main(String argv[]) {\n" +
+ " X test = new X();\n" +
+ " ((J)test).foo();\n" +
+ " test.foo();\n" +
+ " }\n" +
+ "}\n"
+ });
}
// Variant of test MethodVerifyTest.test144() from https://bugs.eclipse.org/bugs/show_bug.cgi?id=194034
@@ -2183,24 +2200,46 @@
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=421543, [1.8][compiler] Compiler fails to recognize default method being turned into abstract by subtytpe
public void testBug421543b() {
- runNegativeTest(
+ runConformTest(
new String[] {
"X.java",
"interface I<T> {\n" +
" void foo(T t);\n" +
"}\n" +
+ "@SuppressWarnings(\"override\")\n" +
"interface J extends I<J> {\n" +
" default void foo(J t) {}\n" +
"}\n" +
"public class X implements J {\n" +
"}\n"
},
- "----------\n" +
- "1. WARNING in X.java (at line 5)\n" +
- " default void foo(J t) {}\n" +
- " ^^^^^^^^\n" +
- "The method foo(J) of type J should be tagged with @Override since it actually overrides a superinterface method\n" +
- "----------\n");
+ "");
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=421797, [1.8][compiler] ClassFormatError with default methods & I.super.foo() syntax
+ public void testBug421797() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " int m(String s, int val);\n" +
+ " public default int foo(String s, int val) {\n" +
+ " System.out.print(s + \" from I.foo:\");\n" +
+ " return val * val; \n" +
+ " }\n" +
+ "}\n" +
+ "interface T extends I {\n" +
+ " public default int m(String s, int value) { \n" +
+ " I i = I.super::foo; \n" +
+ " return i.foo(s, value);\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String argv[]) { \n" +
+ " System.out.println(new T(){}.m(\"Hello\", 1234));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "Hello from I.foo:1522756");
}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
index ca27e03..ac9610f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
@@ -31,7 +31,7 @@
public class NegativeLambdaExpressionsTest extends AbstractRegressionTest {
static {
-// TESTS_NAMES = new String[] { "testSuperReference03"};
+// TESTS_NAMES = new String[] { "test401610i"};
// TESTS_NUMBERS = new int[] { 50 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -5147,6 +5147,12 @@
"----------\n" +
"3. ERROR in X.java (at line 7)\n" +
" new X().foo(()->{});\n" +
+ " ^^^\n" +
+ "The method foo(I<T>) in the type X is not applicable for the arguments (() -> {\n" +
+ "})\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 7)\n" +
+ " new X().foo(()->{});\n" +
" ^^^^^^\n" +
"The target type of this expression is not a well formed parameterized type due to bound(s) mismatch\n" +
"----------\n");
@@ -5612,15 +5618,10 @@
"----------\n" +
"3. ERROR in X.java (at line 9)\n" +
" foo(true ? x-> 1 : x->0);\n" +
- " ^^^\n" +
- "The method foo(I...) in the type X is not applicable for the arguments ((true ? (<no type> x) -> 1 : (<no type> x) -> 0))\n" +
- "----------\n" +
- "4. ERROR in X.java (at line 9)\n" +
- " foo(true ? x-> 1 : x->0);\n" +
" ^\n" +
"Type mismatch: cannot convert from int to String\n" +
"----------\n" +
- "5. ERROR in X.java (at line 9)\n" +
+ "4. ERROR in X.java (at line 9)\n" +
" foo(true ? x-> 1 : x->0);\n" +
" ^\n" +
"Type mismatch: cannot convert from int to String\n" +
@@ -5785,8 +5786,11 @@
"----------\n" +
"1. ERROR in X.java (at line 8)\n" +
" goo((x) -> { if (x) return null; });\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "This method must return a result of type String\n" +
+ " ^^^\n" +
+ "The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {\n" +
+ " if (x)\n" +
+ " return null;\n" +
+ "})\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401939, [1.8][compiler] Incorrect shape analysis leads to method resolution failure .
@@ -5847,12 +5851,17 @@
" }\n" +
" Zork z;\n" +
"}\n", },
- "----------\n" +
- "1. ERROR in X.java (at line 13)\n" +
- " Zork z;\n" +
- " ^^^^\n" +
- "Zork cannot be resolved to a type\n" +
- "----------\n");
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " new X().goo((p1, p2) -> p1 = p1 + p2);\n" +
+ " ^^^\n" +
+ "The method goo(I) is ambiguous for the type X\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 13)\n" +
+ " Zork z;\n" +
+ " ^^^^\n" +
+ "Zork cannot be resolved to a type\n" +
+ "----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=402219, [1.8][compiler] Compile time errors in lambda during hypothetical type check should render candidate method inapplicable.
public void test402219a() {
@@ -5903,12 +5912,17 @@
" }\n" +
" Zork z;\n" +
"}\n", },
- "----------\n" +
- "1. ERROR in X.java (at line 13)\n" +
- " Zork z;\n" +
- " ^^^^\n" +
- "Zork cannot be resolved to a type\n" +
- "----------\n");
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " new X().goo((p1, p2) -> p1 + p2);\n" +
+ " ^^^\n" +
+ "The method goo(I) is ambiguous for the type X\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 13)\n" +
+ " Zork z;\n" +
+ " ^^^^\n" +
+ "Zork cannot be resolved to a type\n" +
+ "----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=402259, [1.8][compiler] NPE during overload resolution when there are syntax errors.
public void test402259() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java
new file mode 100644
index 0000000..7b241f3
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java
@@ -0,0 +1,991 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import junit.framework.Test;
+public class OverloadResolutionTest8 extends AbstractRegressionTest {
+
+static {
+// TESTS_NAMES = new String[] { "test007"};
+// TESTS_NUMBERS = new int[] { 50 };
+// TESTS_RANGE = new int[] { 11, -1 };
+}
+public OverloadResolutionTest8(String name) {
+ super(name);
+}
+public static Test suite() {
+ return buildMinimalComplianceTestSuite(testClass(), F_1_8);
+}
+public static Class testClass() {
+ return OverloadResolutionTest8.class;
+}
+
+public void test001() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " int foo(int [] a);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " int foo(int a);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(foo((a)->a.length));\n" +
+ " }\n" +
+ " static String foo(I i) {\n" +
+ " return(\"foo(I)\");\n" +
+ " }\n" +
+ " static String foo(J j) {\n" +
+ " return(\"foo(J)\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 9)\n" +
+ " System.out.println(foo((a)->a.length));\n" +
+ " ^^^\n" +
+ "The method foo(I) is ambiguous for the type X\n" +
+ "----------\n"
+ );
+}
+public void test002() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " void foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void goo(I i) {\n" +
+ " System.out.println(\"goo(I)\");\n" +
+ " }\n" +
+ " static void goo(J j) {\n" +
+ " System.out.println(\"goo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " final boolean x = true;\n" +
+ " goo(()-> goo((I)null));\n" +
+ " }\n" +
+ " int f() {\n" +
+ " final boolean x = true;\n" +
+ " while (x);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "goo(I)");
+}
+public void test003() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface J {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static final boolean f = true;\n" +
+ " static void goo(J j) {\n" +
+ " System.out.println(\"goo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " final boolean x = true;\n" +
+ " goo(()-> { \n" +
+ " final boolean y = true;\n" +
+ " while (y); \n" +
+ " });\n" +
+ " goo(()-> { \n" +
+ " while (x); \n" +
+ " });\n" +
+ " goo(()-> { \n" +
+ " while (f); \n" +
+ " });\n" +
+ " }\n" +
+ "}\n",
+ },
+ "goo(J)\n" +
+ "goo(J)\n" +
+ "goo(J)");
+}
+public void test004() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface J {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static boolean f = true;\n" +
+ " static void goo(J j) {\n" +
+ " System.out.println(\"goo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " boolean x = true;\n" +
+ " goo(()-> { \n" +
+ " boolean y = true;\n" +
+ " while (y); \n" +
+ " });\n" +
+ " goo(()-> { \n" +
+ " while (x); \n" +
+ " });\n" +
+ " goo(()-> { \n" +
+ " while (f); \n" +
+ " });\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " goo(()-> { \n" +
+ " ^^^\n" +
+ "The method goo(J) in the type X is not applicable for the arguments (() -> {\n" +
+ " boolean y = true;\n" +
+ " while (y) ;\n" +
+ "})\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 15)\n" +
+ " goo(()-> { \n" +
+ " ^^^\n" +
+ "The method goo(J) in the type X is not applicable for the arguments (() -> {\n" +
+ " while (x) ;\n" +
+ "})\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 18)\n" +
+ " goo(()-> { \n" +
+ " ^^^\n" +
+ "The method goo(J) in the type X is not applicable for the arguments (() -> {\n" +
+ " while (f) ;\n" +
+ "})\n" +
+ "----------\n");
+}
+public void test005() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface J {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " final boolean f = true;\n" +
+ " static void goo(J j) {\n" +
+ " System.out.println(\"goo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " final boolean x = true;\n" +
+ " goo(()-> { \n" +
+ " final boolean y = true;\n" +
+ " while (y); \n" +
+ " });\n" +
+ " goo(()-> { \n" +
+ " while (x); \n" +
+ " });\n" +
+ " goo(()-> { \n" +
+ " while (f); \n" +
+ " });\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 19)\n" +
+ " while (f); \n" +
+ " ^\n" +
+ "Cannot make a static reference to the non-static field f\n" +
+ "----------\n");
+}
+public void test006() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static interface StringToInt {\n" +
+ " int stoi(String s);\n" +
+ " }\n" +
+ " public static interface ReduceInt {\n" +
+ " int reduce(int a, int b);\n" +
+ " }\n" +
+ " void foo(StringToInt s) { }\n" +
+ " void bar(ReduceInt r) { }\n" +
+ " void bar() {\n" +
+ " bar((int x, int y) -> x+y); //SingleVariableDeclarations are OK\n" +
+ " foo(s -> s.length());\n" +
+ " foo((s) -> s.length());\n" +
+ " foo((String s) -> s.length()); //SingleVariableDeclaration is OK\n" +
+ " bar((x, y) -> x+y);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "");
+}
+public void test007() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface J {\n" +
+ " void foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void goo(J j) {\n" +
+ " System.out.println(\"goo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " goo(()-> 10); \n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 9)\n" +
+ " goo(()-> 10); \n" +
+ " ^^\n" +
+ "Void methods cannot return a value\n" +
+ "----------\n");
+}
+public void test008() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Object foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " String foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(foo(()->null));\n" +
+ " }\n" +
+ " static String foo(I i) {\n" +
+ " return(\"foo(I)\");\n" +
+ " }\n" +
+ " static String foo(J j) {\n" +
+ " return(\"foo(J)\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(J)");
+}
+public void test009() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Object foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " void foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(foo(()-> {}));\n" +
+ " }\n" +
+ " static String foo(I i) {\n" +
+ " return(\"foo(I)\");\n" +
+ " }\n" +
+ " static String foo(J j) {\n" +
+ " return(\"foo(J)\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(J)");
+}
+public void test010() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Object foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " void foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(foo(()-> foo(()->null)));\n" +
+ " }\n" +
+ " static String foo(I i) {\n" +
+ " return(\"foo(I)\");\n" +
+ " }\n" +
+ " static String foo(J j) {\n" +
+ " return(\"foo(J)\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test011() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " String foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(foo(()-> \"Hello\" ));\n" +
+ " }\n" +
+ " static String foo(I i) {\n" +
+ " return(\"foo(I)\");\n" +
+ " }\n" +
+ " static String foo(J j) {\n" +
+ " return(\"foo(J)\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(J)");
+}
+public void test012() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " String foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(foo(()-> 1234 ));\n" +
+ " }\n" +
+ " static String foo(I i) {\n" +
+ " return(\"foo(I)\");\n" +
+ " }\n" +
+ " static String foo(J j) {\n" +
+ " return(\"foo(J)\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test013() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " Integer foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(foo(()-> 1234 ));\n" +
+ " }\n" +
+ " static String foo(I i) {\n" +
+ " return(\"foo(I)\");\n" +
+ " }\n" +
+ " static String foo(J j) {\n" +
+ " return(\"foo(J)\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test014() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Integer foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " \n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " \n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " foo(()-> new Integer(10));\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test015() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface J {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "interface I {\n" +
+ " Integer foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " \n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " \n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " foo(()-> new Integer(10));\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test016() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface O {\n" +
+ " Object foo();\n" +
+ "}\n" +
+ "interface S {\n" +
+ " String foo();\n" +
+ "}\n" +
+ "interface I {\n" +
+ " O foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " S foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(()-> ()-> \"String\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(J)");
+}
+public void test017() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface J {\n" +
+ " int foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(()-> new Integer(10));\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(J)");
+}
+public void test018() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " X [] foo(int x);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I x) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " I i = X[]::new;\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(X[]::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test019() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " void foo(int x);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I x) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " I i = X[]::new;\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(X[]::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+
+public void test020() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " Y foo();\n" +
+ "}\n" +
+ "class Y {\n" +
+ " Y() {\n" +
+ " }\n" +
+ " \n" +
+ " Y(int x) {\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 20)\n" +
+ " foo(Y::new);\n" +
+ " ^^^\n" +
+ "The method foo(I) is ambiguous for the type X\n" +
+ "----------\n");
+}
+public void test021() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " Y foo();\n" +
+ "}\n" +
+ "class Y {\n" +
+ " private Y() {\n" +
+ " }\n" +
+ " \n" +
+ " Y(int x) {\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test022() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " Y foo();\n" +
+ "}\n" +
+ "class Y {\n" +
+ " Y(float f) {\n" +
+ " System.out.println(\"Y(float)\");\n" +
+ " }\n" +
+ " \n" +
+ " Y(int x) {\n" +
+ " System.out.println(\"Y(int)\");\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " i.foo(10);\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " j.foo();\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "Y(int)");
+}
+public void test023() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " Y foo();\n" +
+ "}\n" +
+ "class Y {\n" +
+ " Y(int ... x) {\n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 18)\n" +
+ " foo(Y::new);\n" +
+ " ^^^\n" +
+ "The method foo(I) is ambiguous for the type X\n" +
+ "----------\n");
+}
+public void test024() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "class Y {\n" +
+ " Y(int x) {\n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 18)\n" +
+ " foo(Y::new);\n" +
+ " ^^^\n" +
+ "The method foo(I) is ambiguous for the type X\n" +
+ "----------\n");
+}
+public void test025() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " X foo(int x);\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ " Y(int x) {\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test026() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " X foo(int x);\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ " <T> Y(int x) {\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 19)\n" +
+ " foo(Y::new);\n" +
+ " ^^^\n" +
+ "The method foo(I) is ambiguous for the type X\n" +
+ "----------\n");
+}
+public void test027() { // javac 8b115 complains of ambiguity here.
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " X foo(int x);\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ " <T> Y(int x) {\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y::<String>new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test028() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y [] foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " X [] foo();\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(Y []::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(I)");
+}
+public void test029() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y [] foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " X [] foo();\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(X []::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 17)\n" +
+ " foo(X []::new);\n" +
+ " ^^^^^^^^^\n" +
+ "Constructed array X[] cannot be assigned to Y[] as required in the interface descriptor \n" +
+ "----------\n");
+}
+public void test030() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Y [] foo(int x);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " X [] foo(int x);\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo(I i) {\n" +
+ " System.out.println(\"foo(I)\");\n" +
+ " }\n" +
+ " static void foo(J j) {\n" +
+ " System.out.println(\"foo(J)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " foo(X []::new);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(J)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401850, [1.8][compiler] Compiler fails to type poly allocation expressions in method invocation contexts
+public void test031() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " void foo(X<String> s) {\n" +
+ " System.out.println(\"foo(X<String>)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " new X<String>().foo(new X<>());\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(X<String>)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401850, [1.8][compiler] Compiler fails to type poly allocation expressions in method invocation contexts
+public void test032() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " void foo(X<String> s, Object o) {\n" +
+ " System.out.println(\"foo(X<String>)\");\n" +
+ " }\n" +
+ " void foo(X xs, String s) {\n" +
+ " System.out.println(\"foo(X<String>)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " new X<String>().foo(new X<>(), \"Hello\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 5)\n" +
+ " void foo(X xs, String s) {\n" +
+ " ^\n" +
+ "X is a raw type. References to generic type X<T> should be parameterized\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 9)\n" +
+ " new X<String>().foo(new X<>(), \"Hello\");\n" +
+ " ^^^\n" +
+ "The method foo(X<String>, Object) is ambiguous for the type X<String>\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401850, [1.8][compiler] Compiler fails to type poly allocation expressions in method invocation contexts
+public void test033() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class Y<T> {}\n" +
+ "public class X<T> extends Y<T> {\n" +
+ " void foo(X<String> s) {\n" +
+ " System.out.println(\"foo(X<String>)\");\n" +
+ " }\n" +
+ " void foo(Y<String> y) {\n" +
+ " System.out.println(\"foo(Y<String>)\");\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " new X<String>().foo(new X<>());\n" +
+ " }\n" +
+ "}\n",
+ },
+ "foo(X<String>)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=422050, [1.8][compiler] Overloaded method call with poly-conditional expression rejected by the compiler
+public void test422050() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I { \n" +
+ " int foo(); \n" +
+ "}\n" +
+ "interface J { \n" +
+ " double foo(); \n" +
+ "}\n" +
+ "public class X {\n" +
+ " static int foo(I i) {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " static int foo(J j) {\n" +
+ " return 1;\n" +
+ " }\n" +
+ " public static void main(String argv[]) {\n" +
+ " System.out.println(foo (() -> true ? 0 : 1));\n" +
+ " }\n" +
+ "}\n",
+ },
+ "0");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=422050, [1.8][compiler] Overloaded method call with poly-conditional expression rejected by the compiler
+public void test422050a() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I { \n" +
+ " Integer foo(); \n" +
+ "}\n" +
+ "interface J { \n" +
+ " void foo(); \n" +
+ "}\n" +
+ "public class X {\n" +
+ " static int foo(I i) {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " static int foo(J j) {\n" +
+ " return 1;\n" +
+ " }\n" +
+ " public static void main(String argv[]) {\n" +
+ " System.out.println(foo (() -> foo((I) null)));\n" +
+ " }\n" +
+ "}\n",
+ },
+ "0");
+}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
index c5c27b4..d1fff24 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
@@ -139,6 +139,7 @@
since_1_8.add(NullTypeAnnotationTest.class);
since_1_8.add(NegativeLambdaExpressionsTest.class);
since_1_8.add(LambdaExpressionsTest.class);
+ since_1_8.add(OverloadResolutionTest8.class);
since_1_8.add(Jsr335ClassFileTest.class);
since_1_8.add(ExpressionContextTests.class);
since_1_8.add(InterfaceMethodsTest.class);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava8Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava8Tests.java
index 17d56dd..b2c008c 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava8Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava8Tests.java
@@ -27,16 +27,23 @@
import org.eclipse.jdt.core.tests.compiler.parser.LambdaExpressionSyntaxTest;
import org.eclipse.jdt.core.tests.compiler.parser.ReferenceExpressionSyntaxTest;
import org.eclipse.jdt.core.tests.compiler.parser.TypeAnnotationSyntaxTest;
+import org.eclipse.jdt.core.tests.compiler.regression.ClassFileReaderTest_1_8;
+import org.eclipse.jdt.core.tests.compiler.regression.Deprecated18Test;
import org.eclipse.jdt.core.tests.compiler.regression.ExpressionContextTests;
import org.eclipse.jdt.core.tests.compiler.regression.CompilerInvocationTests;
import org.eclipse.jdt.core.tests.compiler.regression.FlowAnalysisTest8;
import org.eclipse.jdt.core.tests.compiler.regression.GrammarCoverageTests308;
import org.eclipse.jdt.core.tests.compiler.regression.InterfaceMethodsTest;
+import org.eclipse.jdt.core.tests.compiler.regression.JSR308SpecSnippetTests;
import org.eclipse.jdt.core.tests.compiler.regression.Jsr335ClassFileTest;
import org.eclipse.jdt.core.tests.compiler.regression.LambdaExpressionsTest;
+import org.eclipse.jdt.core.tests.compiler.regression.MethodParametersAttributeTest;
import org.eclipse.jdt.core.tests.compiler.regression.NegativeLambdaExpressionsTest;
import org.eclipse.jdt.core.tests.compiler.regression.NegativeTypeAnnotationTest;
import org.eclipse.jdt.core.tests.compiler.regression.NullTypeAnnotationTest;
+import org.eclipse.jdt.core.tests.compiler.regression.OverloadResolutionTest8;
+import org.eclipse.jdt.core.tests.compiler.regression.RepeatableAnnotationTest;
+import org.eclipse.jdt.core.tests.compiler.regression.TypeAnnotationTest;
import org.eclipse.jdt.core.tests.dom.ASTConverter15JLS8Test;
import org.eclipse.jdt.core.tests.dom.ASTConverter18Test;
import org.eclipse.jdt.core.tests.dom.ASTConverterAST8Test;
@@ -44,6 +51,7 @@
import org.eclipse.jdt.core.tests.dom.ASTConverterTestAST8_2;
import org.eclipse.jdt.core.tests.dom.ConverterTestSetup;
import org.eclipse.jdt.core.tests.dom.TypeAnnotationsConverterTest;
+import org.eclipse.jdt.core.tests.dom.TypeBindingTests308;
import org.eclipse.jdt.core.tests.formatter.FormatterJSR308Tests;
import org.eclipse.jdt.core.tests.formatter.FormatterJSR335Tests;
import org.eclipse.jdt.core.tests.model.JavaSearchBugs8Tests;
@@ -59,6 +67,7 @@
LambdaExpressionSyntaxTest.class,
NegativeLambdaExpressionsTest.class,
LambdaExpressionsTest.class,
+ OverloadResolutionTest8.class,
Jsr335ClassFileTest.class,
NegativeTypeAnnotationTest.class,
TypeAnnotationSyntaxTest.class,
@@ -73,6 +82,12 @@
FormatterJSR335Tests.class,
FormatterJSR308Tests.class,
JavaSearchBugs8Tests.class,
+ TypeAnnotationTest.class,
+ JSR308SpecSnippetTests.class,
+ Deprecated18Test.class,
+ MethodParametersAttributeTest.class,
+ ClassFileReaderTest_1_8.class,
+ RepeatableAnnotationTest.class,
};
}
@@ -85,6 +100,7 @@
ASTConverter15JLS8Test.class,
ASTConverter18Test.class,
ASTRewritingTest.class,
+ TypeBindingTests308.class,
};
}
public static Test suite() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index c0907ae..c48f3c7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -949,10 +949,6 @@
public void tagAsHavingErrors() {
this.ignoreFurtherInvestigation = true;
}
-
- public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
- // Nothing to do for this context;
- }
//{ObjectTeams: and remove it again:
public void resetErrorFlag() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
index 346e26a..0c104c0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -365,34 +365,24 @@
public TypeBinding resolveType(BlockScope scope) {
// Propagate the type checking to the arguments, and check if the constructor is defined.
- this.constant = Constant.NotAConstant;
- if (this.type == null) {
- // initialization of an enum constant
- this.resolvedType = scope.enclosingReceiverType();
- } else {
+ final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
+ final CompilerOptions compilerOptions = scope.compilerOptions();
+ if (this.constant != Constant.NotAConstant) {
+ this.constant = Constant.NotAConstant;
+ if (this.type == null) {
+ // initialization of an enum constant
+ this.resolvedType = scope.enclosingReceiverType();
+ } else {
//{ObjectTeams: support detection of new path.R():
- this.type.bits |= IsAllocationType;
+ this.type.bits |= IsAllocationType;
// SH}
- this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
- checkIllegalNullAnnotation(scope, this.resolvedType);
- checkParameterizedAllocation: {
- if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
- ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
- if (currentType == null) return currentType;
- do {
- // isStatic() is answering true for toplevel types
- if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
- if (currentType.isRawType()) break checkParameterizedAllocation;
- } while ((currentType = currentType.enclosingType())!= null);
- ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
- for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
- if (qRef.typeArguments[i] != null) {
- scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
- break;
- }
- }
+ this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
+ if (isDiamond && this.typeExpected == null && this.expressionContext == INVOCATION_CONTEXT && compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
+ return this.resolvedType = new PolyTypeBinding(this);
}
}
+ } else {
+ this.resolvedType = this.type.resolvedType;
}
// will check for null after args are resolved
@@ -408,11 +398,10 @@
}
// SH}
- final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
// resolve type arguments (for generic constructor call)
if (this.typeArguments != null) {
int length = this.typeArguments.length;
- boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
+ boolean argHasError = compilerOptions.sourceLevel < ClassFileConstants.JDK1_5;
this.genericTypeArguments = new TypeBinding[length];
for (int i = 0; i < length; i++) {
TypeReference typeReference = this.typeArguments[i];
@@ -473,7 +462,7 @@
for (int i = length; --i >= 0;) {
pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
}
- this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this);
+ this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this, false);
if (this.binding != null && !this.binding.isValidBinding()) {
MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
// record the closest match, for clients who may still need hint about possible method match
@@ -563,7 +552,6 @@
if (!isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, null, argumentTypes, scope);
}
- final CompilerOptions compilerOptions = scope.compilerOptions();
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
@@ -776,14 +764,14 @@
this.expressionContext = context;
}
+public boolean isCompatibleWith(TypeBinding left, Scope scope) {
+ return this.type.resolvedType != null && this.type.resolvedType.actualType().isCompatibleWith(left.actualType());
+}
+
public boolean isPolyExpression() {
return (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) &&
this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
}
-
-public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
- return isPolyExpression() ? !t.isBaseType() && s.isBaseType() : super.tIsMoreSpecific(t, s);
-}
/**
* @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#expectedType()
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 5c9539b..cfbb24a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -810,10 +810,6 @@
this.ignoreFurtherInvestigation = true;
}
-public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
- // Nothing to do for this context;
-}
-
//{ObjectTeams: and let us remove it again:
public void resetErrorFlag() {
this.ignoreFurtherInvestigation = false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index 06f318c..53fc31e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -461,7 +461,7 @@
if (this.originalValueIfTrueType.kind() == Binding.POLY_TYPE || this.originalValueIfFalseType.kind() == Binding.POLY_TYPE) {
this.isPolyExpression = true;
- return new PolyTypeBinding(this);
+ return this.resolvedType = new PolyTypeBinding(this);
}
} else {
if (this.originalValueIfTrueType.kind() == Binding.POLY_TYPE)
@@ -649,6 +649,10 @@
this.expressionContext = context;
}
+ public boolean isPertinentToApplicability() {
+ return this.valueIfTrue.isPertinentToApplicability() && this.valueIfFalse.isPertinentToApplicability();
+ }
+
public boolean isPolyExpression() throws UnsupportedOperationException {
if (this.expressionContext != ASSIGNMENT_CONTEXT && this.expressionContext != INVOCATION_CONTEXT)
return false;
@@ -660,10 +664,10 @@
return this.valueIfTrue.isCompatibleWith(left, scope) && this.valueIfFalse.isCompatibleWith(left, scope);
}
- public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+ public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
return isPolyExpression() ?
- this.valueIfTrue.tIsMoreSpecific(t, s) && this.valueIfFalse.tIsMoreSpecific(t, s):
- super.tIsMoreSpecific(t, s);
+ this.valueIfTrue.sIsMoreSpecific(s, t) && this.valueIfFalse.sIsMoreSpecific(s, t):
+ super.sIsMoreSpecific(s, t);
}
public void tagAsEllipsisArgument() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index 0c336b4..2c064a9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -496,7 +496,7 @@
for (int i = length; --i >= 0;) {
pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
}
- this.binding = scope.findMethod(receiverType, TypeConstants.INIT, pseudoArgs, this);
+ this.binding = scope.findMethod(receiverType, TypeConstants.INIT, pseudoArgs, this, false);
if (this.binding != null && !this.binding.isValidBinding()) {
MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
// record the closest match, for clients who may still need hint about possible method match
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 0a79e7f..66e0473 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -1133,6 +1133,10 @@
return this.constant;
}
+public boolean isPertinentToApplicability() {
+ return true;
+}
+
/**
* Returns the type of the expression after required implicit conversions. When expression type gets promoted
* or inserted a generic cast, the converted type will differ from the resolved type (surface side-effects from
@@ -1323,18 +1327,11 @@
throw new UnsupportedOperationException("Unexpected control flow, should not have reached Expression.isCompatibleWith"); //$NON-NLS-1$
}
-public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
TypeBinding expressionType = this.resolvedType;
if (expressionType == null || !expressionType.isValidBinding()) // Shouldn't get here, just to play it safe
return false; // trigger ambiguity.
-
- if (TypeBinding.equalsEquals(t.findSuperTypeOriginatingFrom(s), s))
- return true;
-
- final boolean tIsBaseType = t.isBaseType();
- final boolean sIsBaseType = s.isBaseType();
-
- return expressionType.isBaseType() ? tIsBaseType && !sIsBaseType : !tIsBaseType && sIsBaseType;
+ return s.findSuperTypeOriginatingFrom(t) != null;
}
public void tagAsEllipsisArgument() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
index b2e589d..1a346c2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
@@ -32,7 +32,6 @@
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBindingVisitor;
-import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
public abstract class FunctionalExpression extends Expression {
@@ -42,8 +41,8 @@
protected MethodBinding actualMethodBinding; // void of synthetics.
boolean ignoreFurtherInvestigation;
protected ExpressionContext expressionContext = VANILLA_CONTEXT;
- protected SimpleLookupTable resultExpressions;
- protected boolean hasIgnoredMandatoryErrors = false;
+ static Expression [] NO_EXPRESSIONS = new Expression[0];
+ protected Expression [] resultExpressions = NO_EXPRESSIONS;
protected CompilationResult compilationResult;
protected BlockScope enclosingScope;
protected boolean ellipsisArgument;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index 7379f43..66182df 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -5,6 +5,10 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
* TU Berlin - implementation of @role tag
@@ -459,7 +463,7 @@
if (CharOperation.equals(resolvedType.sourceName(), fieldRef.token)) {
fieldRef.methodBinding = scope.getConstructor(resolvedType, Binding.NO_TYPES, fieldRef);
} else {
- fieldRef.methodBinding = scope.findMethod(resolvedType, fieldRef.token, Binding.NO_TYPES, fieldRef);
+ fieldRef.methodBinding = scope.findMethod(resolvedType, fieldRef.token, Binding.NO_TYPES, fieldRef, false);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index 2a290cb..66339a6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -23,7 +23,6 @@
package org.eclipse.jdt.internal.compiler.ast;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
-import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
@@ -61,10 +60,10 @@
import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
import org.eclipse.jdt.internal.compiler.problem.AbortType;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
-import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
public class LambdaExpression extends FunctionalExpression implements ReferenceContext, ProblemSeverities {
public Argument [] arguments;
+ private TypeBinding [] argumentTypes = Binding.NO_PARAMETERS;
public Statement body;
public boolean hasParentheses;
public MethodScope scope;
@@ -73,7 +72,6 @@
private boolean shapeAnalysisComplete = false;
private boolean returnsValue;
private boolean returnsVoid;
- private boolean throwsException;
private LambdaExpression original = this;
private SyntheticArgumentBinding[] outerLocalVariables = NO_SYNTHETIC_ARGUMENTS;
private int outerLocalVariablesSlotSize = 0;
@@ -145,7 +143,7 @@
this.enclosingScope = blockScope;
if (this.expectedType == null && this.expressionContext == INVOCATION_CONTEXT) {
- return new PolyTypeBinding(this);
+ return this.resolvedType = new PolyTypeBinding(this);
}
MethodScope methodScope = blockScope.methodScope();
@@ -186,6 +184,9 @@
TypeBinding[] newParameters = new TypeBinding[length];
AnnotationBinding [][] parameterAnnotations = null;
+ if (!argumentsTypeElided) {
+ this.argumentTypes = new TypeBinding[length];
+ }
for (int i = 0; i < length; i++) {
Argument argument = this.arguments[i];
if (argument.isVarArgs()) {
@@ -199,7 +200,7 @@
TypeBinding parameterType;
final TypeBinding expectedParameterType = haveDescriptor && i < this.descriptor.parameters.length ? this.descriptor.parameters[i] : null;
- parameterType = argumentsTypeElided ? expectedParameterType : argument.type.resolveType(this.scope, true /* check bounds*/);
+ parameterType = argumentsTypeElided ? expectedParameterType : (this.argumentTypes[i] = argument.type.resolveType(this.scope, true /* check bounds*/));
if (parameterType == null) {
buggyArguments = true;
} else if (parameterType == TypeBinding.VOID) {
@@ -407,6 +408,18 @@
}
}
+ public boolean isPertinentToApplicability() {
+ if (argumentsTypeElided())
+ return false;
+
+ Expression [] returnExpressions = this.resultExpressions;
+ for (int i = 0, length = returnExpressions.length; i < length; i++) {
+ if (!returnExpressions[i].isPertinentToApplicability())
+ return false;
+ }
+ return true;
+ }
+
public StringBuffer printExpression(int tab, StringBuffer output) {
int parenthesesCount = (this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
String suffix = ""; //$NON-NLS-1$
@@ -450,10 +463,6 @@
return this.scope;
}
- protected boolean errorEqualsIncompatibility() {
- return this.original.shapeAnalysisComplete; // so as not to abort shape analysis.
- }
-
public boolean isCompatibleWith(final TypeBinding left, final Scope someScope) {
final MethodBinding sam = left.getSingleAbstractMethod(this.enclosingScope);
@@ -463,107 +472,125 @@
if (sam.parameters.length != this.arguments.length)
return false;
- if (!this.shapeAnalysisComplete && this.body instanceof Expression) {
- Expression expression = (Expression) this.body;
- this.voidCompatible = expression.statementExpression();
- this.valueCompatible = true;
- this.shapeAnalysisComplete = true;
- }
-
- if (this.shapeAnalysisComplete) {
- if (squarePegInRoundHole(sam))
- return false;
- }
-
- IErrorHandlingPolicy oldPolicy = this.enclosingScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
- this.hasIgnoredMandatoryErrors = false;
- try {
- final LambdaExpression copy = copy();
- if (copy == null)
- return false;
- copy.setExpressionContext(this.expressionContext);
- copy.setExpectedType(left);
- if (this.resultExpressions == null)
- this.resultExpressions = new SimpleLookupTable(); // gather result expressions for most specific method analysis.
- this.resultExpressions.put(left, new Expression[0]);
- copy.resolveType(this.enclosingScope);
- if (!this.shapeAnalysisComplete) {
- boolean lambdaIsFubar = this.hasIgnoredMandatoryErrors; // capture now, before doesNotCompleteNormally which runs analyzeCode on lambda body *without* the enclosing context being analyzed
- if (!this.returnsVoid && !this.returnsValue && this.throwsException) { // () -> { throw new Exception(); } is value compatible.
- Block block = (Block) this.body;
- final Statement[] statements = block.statements;
- final int statementsLength = statements == null ? 0 : statements.length;
- Statement ultimateStatement = statementsLength == 0 ? null : statements[statementsLength - 1];
- this.valueCompatible = ultimateStatement instanceof ThrowStatement ? true: copy.doesNotCompleteNormally();
- }
- this.shapeAnalysisComplete = true;
- if (squarePegInRoundHole(sam) || lambdaIsFubar)
+ if (!this.shapeAnalysisComplete) {
+ IErrorHandlingPolicy oldPolicy = this.enclosingScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
+ try {
+ final LambdaExpression copy = copy();
+ if (copy == null)
return false;
+ copy.setExpressionContext(this.expressionContext);
+ copy.setExpectedType(left);
+ copy.resolveType(this.enclosingScope);
+
+ if (!argumentsTypeElided()) {
+ this.argumentTypes = copy.argumentTypes;
+ }
+
+ if (this.body instanceof Block) {
+ if (!this.returnsVoid) {
+ this.valueCompatible = copy.doesNotCompleteNormally();
+ }
+ } else {
+ this.voidCompatible = ((Expression) this.body).statementExpression();
+ }
+
+ } finally {
+ this.shapeAnalysisComplete = true;
+ this.enclosingScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
}
- } catch (IncongruentLambdaException e) {
- return false;
- } finally {
- this.enclosingScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
- this.hasIgnoredMandatoryErrors = false;
}
+
+ if (sam.returnType.id == TypeIds.T_void) {
+ if (!this.voidCompatible)
+ return false;
+ } else {
+ if (!this.valueCompatible)
+ return false;
+ }
+
+ if (!isPertinentToApplicability())
+ return true;
+
+ Expression [] returnExpressions = this.resultExpressions;
+ for (int i = 0, length = returnExpressions.length; i < length; i++) {
+ if (returnExpressions[i] instanceof FunctionalExpression) { // don't want to use the resolvedType - polluted from some other overload resolution candidate
+ if (!returnExpressions[i].isCompatibleWith(sam.returnType, this.enclosingScope))
+ return false;
+ } else {
+ if (this.enclosingScope.parameterCompatibilityLevel(returnExpressions[i].resolvedType, sam.returnType) == Scope.NOT_COMPATIBLE) {
+ if (sam.returnType.id != TypeIds.T_void || this.body instanceof Block)
+ return false;
+ }
+ }
+ }
+
+ TypeBinding [] samPararameterTypes = sam.parameters;
+ for (int i = 0, length = samPararameterTypes.length; i < length; i++) { // lengths known to be equal.
+ if (TypeBinding.notEquals(samPararameterTypes[i], this.argumentTypes[i]))
+ return false;
+ }
+
return true;
}
- public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
- /* 15.12.2.5 t is more specific than s iff ... Some of the checks here are redundant by the very fact of control reaching here,
- but have been left in for completeness/documentation sakes. These should be cheap anyways.
- */
+ public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
- // Both t and s are functional interface types ...
- MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
- if (tSam == null || !tSam.isValidBinding())
+ // 15.12.2.5
+
+ if (TypeBinding.equalsEquals(s, t))
+ return true;
+
+ if (argumentsTypeElided() || t.findSuperTypeOriginatingFrom(s) != null)
return false;
+
+ s = s.capture(this.enclosingScope, this.sourceEnd);
MethodBinding sSam = s.getSingleAbstractMethod(this.enclosingScope);
if (sSam == null || !sSam.isValidBinding())
return false;
-
- // t should neither be a subinterface nor a superinterface of s
- if (t.findSuperTypeOriginatingFrom(s) != null || s.findSuperTypeOriginatingFrom(t) != null)
+ TypeBinding r1 = sSam.returnType;
+ MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
+ if (tSam == null || !tSam.isValidBinding())
return false;
-
- // If the lambda expression's parameters have inferred types, then the descriptor parameter types of t are the same as the descriptor parameter types of s.
- if (argumentsTypeElided()) {
- if (tSam.parameters.length != sSam.parameters.length)
- return false;
- for (int i = 0, length = tSam.parameters.length; i < length; i++) {
- if (TypeBinding.notEquals(tSam.parameters[i], sSam.parameters[i]))
- return false;
- }
- }
+ TypeBinding r2 = tSam.returnType;
- // either the descriptor return type of s is void or ...
- if (sSam.returnType.id == TypeIds.T_void)
+ if (r2.id == TypeIds.T_void)
return true;
- /* ... or for all result expressions in the lambda body (or for the body itself if the body is an expression),
- the descriptor return type of the capture of T is more specific than the descriptor return type of S.
- */
- Expression [] returnExpressions = (Expression[]) this.resultExpressions.get(t); // should be same as for s
- int returnExpressionsLength = returnExpressions == null ? 0 : returnExpressions.length;
- if (returnExpressionsLength == 0)
- return true; // as good as or as bad as false.
+ if (r1.id == TypeIds.T_void)
+ return false;
- t = t.capture(this.enclosingScope, this.sourceEnd);
- tSam = t.getSingleAbstractMethod(this.enclosingScope);
- for (int i = 0; i < returnExpressionsLength; i++) {
- Expression resultExpression = returnExpressions[i];
- if (!resultExpression.tIsMoreSpecific(tSam.returnType, sSam.returnType))
- return false;
- }
- return true;
- }
-
- private boolean squarePegInRoundHole(final MethodBinding sam) {
- if (sam.returnType.id == TypeIds.T_void) {
- if (!this.voidCompatible)
+ // r1 <: r2
+ if (r1.isCompatibleWith(r2))
+ return true;
+
+ Expression [] returnExpressions = this.resultExpressions;
+ int returnExpressionsLength = returnExpressions == null ? 0 : returnExpressions.length;
+
+ int i;
+ // r1 is a primitive type, r2 is a reference type, and each result expression is a standalone expression (15.2) of a primitive type
+ if (r1.isBaseType() && !r2.isBaseType()) {
+ for (i = 0; i < returnExpressionsLength; i++) {
+ if (returnExpressions[i].isPolyExpression() || !returnExpressions[i].resolvedType.isBaseType())
+ break;
+ }
+ if (i == returnExpressionsLength)
return true;
- } else {
- if (!this.valueCompatible)
+ }
+ if (!r1.isBaseType() && r2.isBaseType()) {
+ for (i = 0; i < returnExpressionsLength; i++) {
+ if (returnExpressions[i].resolvedType.isBaseType())
+ break;
+ }
+ if (i == returnExpressionsLength)
+ return true;
+ }
+ if (r1.isFunctionalInterface(this.enclosingScope) && r2.isFunctionalInterface(this.enclosingScope)) {
+ for (i = 0; i < returnExpressionsLength; i++) {
+ Expression resultExpression = returnExpressions[i];
+ if (!resultExpression.sIsMoreSpecific(r1, r2))
+ break;
+ }
+ if (i == returnExpressionsLength)
return true;
}
return false;
@@ -584,15 +611,22 @@
public void returnsExpression(Expression expression, TypeBinding resultType) {
if (this.original == this) // not in overload resolution context.
return;
+ if (this.body instanceof Expression) {
+ this.original.valueCompatible = resultType != null && resultType.id != TypeIds.T_void;
+ this.original.resultExpressions = new Expression[1];
+ this.original.resultExpressions[0] = expression;
+ return; // void compatibility determined via statementExpression()
+ }
if (expression != null) {
this.original.returnsValue = true;
this.original.voidCompatible = false;
this.original.valueCompatible = !this.original.returnsVoid;
if (resultType != null) {
- Expression [] results = (Expression[]) this.original.resultExpressions.get(this.expectedType);
- int resultsLength = results.length;
- System.arraycopy(results, 0, results = new Expression[resultsLength + 1], 0, resultsLength);
- results[resultsLength] = expression;
+ Expression [] returnExpressions = this.original.resultExpressions;
+ int resultsLength = returnExpressions.length;
+ System.arraycopy(returnExpressions, 0, returnExpressions = new Expression[resultsLength + 1], 0, resultsLength);
+ returnExpressions[resultsLength] = expression;
+ this.original.resultExpressions = returnExpressions;
}
} else {
this.original.returnsVoid = true;
@@ -600,12 +634,6 @@
this.original.voidCompatible = !this.original.returnsValue;
}
}
-
- public void throwsException(TypeBinding exceptionType) {
- if (this.expressionContext != INVOCATION_CONTEXT)
- return;
- this.original.throwsException = true;
- }
public CompilationResult compilationResult() {
return this.compilationResult;
@@ -655,21 +683,6 @@
}
}
- public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
- // 15.27.3 requires exception throw related errors to not influence congruence. Other errors should. Also don't abort shape analysis.
- switch (problemId) {
- case IProblem.UnhandledExceptionOnAutoClose:
- case IProblem.UnhandledExceptionInDefaultConstructor:
- case IProblem.UnhandledException:
- return;
- default:
- if (errorEqualsIncompatibility())
- throw new IncongruentLambdaException();
- this.original().hasIgnoredMandatoryErrors = true;
- return;
- }
- }
-
public void generateCode(ClassScope classScope, ClassFile classFile) {
int problemResetPC = 0;
classFile.codeStream.wideMode = false;
@@ -803,7 +816,4 @@
}
return this.actualMethodBinding;
}
-}
-class IncongruentLambdaException extends RuntimeException {
- private static final long serialVersionUID = 4145723509219836114L;
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 5176ad0..d2f4a4a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -863,7 +863,7 @@
this.binding =
this.receiver.isImplicitThis()
? scope.getImplicitMethod(this.selector, pseudoArgs, this)
- : scope.findMethod((ReferenceBinding) this.actualReceiverType, this.selector, pseudoArgs, this);
+ : scope.findMethod((ReferenceBinding) this.actualReceiverType, this.selector, pseudoArgs, this, false);
if (this.binding != null && !this.binding.isValidBinding()) {
MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
// record the closest match, for clients who may still need hint about possible method match
@@ -1319,7 +1319,7 @@
// methods found in a predefined confined type are actually methods of Object
// (except for _OT$getTeam() which is generated for each role):
ReferenceBinding object = scope.getJavaLangObject();
- this.binding = scope.findMethod(object, this.binding.selector, this.binding.parameters, this);
+ this.binding = scope.findMethod(object, this.binding.selector, this.binding.parameters, this, false);
}
// check whether all anchors in the signature are final
@@ -1472,8 +1472,8 @@
return false;
}
-public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
- return isPolyExpression() ? !t.isBaseType() && s.isBaseType() : super.tIsMoreSpecific(t, s);
+public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
+ return isPolyExpression() ? !s.isBaseType() && t.isBaseType() : super.sIsMoreSpecific(s, t);
}
public void setFieldIndex(int depth) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
index 7dbbe88..66ef722 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
@@ -361,6 +361,7 @@
keep = ((ClassScope) scope).superTypeReference;
((ClassScope) scope).superTypeReference = null;
}
+ final boolean isDiamond = (this.bits & ASTNode.IsDiamond) != 0;
int argLength = this.typeArguments.length;
TypeBinding[] argTypes = new TypeBinding[argLength];
boolean argHasError = false;
@@ -397,7 +398,6 @@
return null;
}
- final boolean isDiamond = (this.bits & ASTNode.IsDiamond) != 0;
TypeVariableBinding[] typeVariables = currentOriginal.typeVariables();
if (typeVariables == Binding.NO_TYPE_VARIABLES) { // non generic invoked with arguments
boolean isCompliant15 = scope.compilerOptions().originalSourceLevel >= ClassFileConstants.JDK1_5;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index 2994364..9d3d4ec 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -522,7 +522,7 @@
for (int i = length; --i >= 0;) {
pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
}
- this.binding = scope.findMethod(referenceReceiver, TypeConstants.INIT, pseudoArgs, this);
+ this.binding = scope.findMethod(referenceReceiver, TypeConstants.INIT, pseudoArgs, this, false);
if (this.binding != null && !this.binding.isValidBinding()) {
MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
// record the closest match, for clients who may still need hint about possible method match
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index 7c7bb6f..5a9d040 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -55,7 +55,6 @@
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
-import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
public class ReferenceExpression extends FunctionalExpression implements InvocationSite {
@@ -70,6 +69,7 @@
MethodBinding syntheticAccessor; // synthetic accessor for inner-emulation
private int depth;
+ private MethodBinding exactMethodBinding; // != null ==> exact method reference.
public ReferenceExpression(CompilationResult compilationResult, Expression lhs, TypeReference [] typeArguments, char [] selector, int sourceEnd) {
super(compilationResult);
@@ -85,9 +85,9 @@
SourceTypeBinding sourceType = currentScope.enclosingSourceType();
if (this.receiverType.isArrayType()) {
if (isConstructorReference()) {
- this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayConstructor);
+ this.actualMethodBinding = this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayConstructor);
} else if (CharOperation.equals(this.selector, TypeConstants.CLONE)) {
- this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayClone);
+ this.actualMethodBinding = this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayClone);
}
} else if (this.syntheticAccessor != null) {
if (this.lhs.isSuper() || isMethodReference())
@@ -258,7 +258,10 @@
}
if (this.expectedType == null && this.expressionContext == INVOCATION_CONTEXT) {
- return new PolyTypeBinding(this);
+ if (isConstructorReference()) {
+ this.exactMethodBinding = scope.getExactConstructor(lhsType, this);
+ }
+ return this.resolvedType = new PolyTypeBinding(this);
}
super.resolveType(scope);
@@ -303,11 +306,12 @@
scope.problemReporter().invalidArrayConstructorReference(this, lhsType, descriptorParameters);
return this.resolvedType = null;
}
- if (!lhsType.isCompatibleWith(this.descriptor.returnType)) {
+ if (!lhsType.isCompatibleWith(this.descriptor.returnType) && this.descriptor.returnType.id != TypeIds.T_void) {
scope.problemReporter().constructedArrayIncompatible(this, lhsType, this.descriptor.returnType);
return this.resolvedType = null;
}
- return this.resolvedType; // No binding construction possible right now. Code generator will have to conjure up a rabbit.
+ this.binding = this.exactMethodBinding = scope.getExactConstructor(lhsType, this);
+ return this.resolvedType;
}
this.haveReceiver = true;
@@ -577,7 +581,7 @@
}
public boolean isCompatibleWith(TypeBinding left, Scope scope) {
- // 15.28.1
+ // 15.28.2
final MethodBinding sam = left.getSingleAbstractMethod(this.enclosingScope);
if (sam == null || !sam.isValidBinding())
return false;
@@ -587,58 +591,45 @@
try {
this.binding = null;
resolveType(this.enclosingScope);
- } catch (IncongruentLambdaException e) {
- return false;
} finally {
this.enclosingScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
isCompatible = this.binding != null && this.binding.isValidBinding();
- if (isCompatible) {
- if (this.resultExpressions == null)
- this.resultExpressions = new SimpleLookupTable(); // gather for more specific analysis later.
- this.resultExpressions.put(left, this.binding.returnType);
- }
this.binding = null;
setExpectedType(null);
}
return isCompatible;
}
- public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
- /* 15.12.2.5 t is more specific than s iff ... Some of the checks here are redundant by the very fact of control reaching here,
- but have been left in for completeness/documentation sakes. These should be cheap anyways.
- */
+
+ public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
- // Both t and s are functional interface types ...
- MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
- if (tSam == null || !tSam.isValidBinding())
+ if (TypeBinding.equalsEquals(s, t))
+ return true;
+
+ if (this.exactMethodBinding == null)
return false;
+
+ s = s.capture(this.enclosingScope, this.sourceEnd);
MethodBinding sSam = s.getSingleAbstractMethod(this.enclosingScope);
if (sSam == null || !sSam.isValidBinding())
return false;
+ TypeBinding r1 = sSam.returnType;
- // t should neither be a subinterface nor a superinterface of s
- if (t.findSuperTypeOriginatingFrom(s) != null || s.findSuperTypeOriginatingFrom(t) != null)
+ MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
+ if (tSam == null || !tSam.isValidBinding())
return false;
-
- // The descriptor parameter types of t are the same as the descriptor parameter types of s.
- if (tSam.parameters.length != sSam.parameters.length)
- return false;
- for (int i = 0, length = tSam.parameters.length; i < length; i++) {
- if (TypeBinding.notEquals(tSam.parameters[i], sSam.parameters[i]))
- return false;
- }
+ TypeBinding r2 = tSam.returnType;
- // Either the descriptor return type of s is void or ...
- if (sSam.returnType.id == TypeIds.T_void)
+ if (r2.id == TypeIds.T_void)
return true;
- /* ... or the descriptor return type of the capture of T is more specific than the descriptor return type of S for
- an invocation expression of the same form as the method reference..
- */
- Expression resultExpression = (Expression) this.resultExpressions.get(t); // should be same as for s
+ if (r1.id == TypeIds.T_void)
+ return false;
- t = t.capture(this.enclosingScope, this.sourceEnd);
- tSam = t.getSingleAbstractMethod(this.enclosingScope);
- return resultExpression.tIsMoreSpecific(tSam.returnType, sSam.returnType);
+ // r1 <: r2
+ if (r1.isCompatibleWith(r2))
+ return true;
+
+ return r1.isBaseType() != r2.isBaseType() && r1.isBaseType() == this.exactMethodBinding.returnType.isBaseType();
}
public org.eclipse.jdt.internal.compiler.lookup.MethodBinding getMethodBinding() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index 3e8132d..36788ea 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -317,7 +317,7 @@
return;
}
expressionType = this.expression.resolveType(scope);
- if (lambda != null && !this.implicitReturn)
+ if (lambda != null)
lambda.returnsExpression(this.expression, expressionType);
if (this.implicitReturn && (expressionType == TypeBinding.VOID || this.expression.statementExpression()))
return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
index 307b49f..775dd3e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
@@ -27,7 +27,6 @@
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
@@ -83,11 +82,6 @@
public void resolve(BlockScope scope) {
this.exceptionType = this.exception.resolveType(scope);
- MethodScope methodScope = scope.methodScope();
- LambdaExpression lambda = methodScope.referenceContext instanceof LambdaExpression ? (LambdaExpression) methodScope.referenceContext : null;
- if (lambda != null) {
- lambda.throwsException(this.exceptionType);
- }
if (this.exceptionType != null && this.exceptionType.isValidBinding()) {
//{ObjectTeams: lowering roles of exceptions:
if (this.exceptionType.isRole()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 472bfe8..08e624b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -2081,10 +2081,6 @@
this.ignoreFurtherInvestigation = true;
}
-public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
- // Nothing to do for this context;
-}
-
//{ObjectTeams: untag class and interface part:
public void resetErrorFlag() {
if (isRole() && this.roleModel != null)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index 9393a34..06144ad 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -762,7 +762,7 @@
public int literalIndexForMethodHandle(MethodBinding binding) {
boolean isInterface = binding.declaringClass.isInterface();
int referenceKind =
- isInterface ? binding.isStatic() ? MethodHandleRefKindInvokeStatic : MethodHandleRefKindInvokeInterface
+ isInterface ? binding.isStatic() ? MethodHandleRefKindInvokeStatic : binding.isPrivate() ? MethodHandleRefKindInvokeSpecial : MethodHandleRefKindInvokeInterface
: binding.isConstructor() ? MethodHandleRefKindNewInvokeSpecial
: binding.isStatic() ? MethodHandleRefKindInvokeStatic
: MethodHandleRefKindInvokeVirtual;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
index 34f2e86..b2130e1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
@@ -38,8 +38,6 @@
boolean hasErrors();
void tagAsHavingErrors();
-
- void tagAsHavingIgnoredMandatoryErrors(int problemId);
//{ObjectTeams: some errors will have to be removed
void resetErrorFlag();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index 9785fa9..f4eae16 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -406,7 +406,7 @@
public TypeBinding maybeWrapRoleType(ASTNode typedNode, TypeArgumentUpdater updater) {
if (!this.leafComponentType.isBaseType()) {
TypeBinding updated = this.leafComponentType.maybeWrapRoleType(typedNode, updater);
- if (updated != this.leafComponentType)
+ if (updated != this.leafComponentType) //$IDENTITY-COMPARISON$
return this.environment.createArrayType(updated, this.dimensions);
}
return this;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
index 43df563..0423f35 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
@@ -77,7 +77,7 @@
public static final CallinCalloutBinding[] NO_CALLIN_CALLOUT_BINDINGS = new CallinCalloutBinding[0];
public static final SyntheticArgumentBinding[] NO_SYNTH_ARGUMENTS = new SyntheticArgumentBinding[0];
//Markus Witte}
-
+
public static final FieldBinding[] UNINITIALIZED_FIELDS = new FieldBinding[0];
public static final MethodBinding[] UNINITIALIZED_METHODS = new MethodBinding[0];
public static final ReferenceBinding[] UNINITIALIZED_REFERENCE_TYPES = new ReferenceBinding[0];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index f3ca840..c089af7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -29,6 +29,7 @@
* bug 409473 - [compiler] JDT cannot compile against JRE 1.8
* Bug 420080 - [1.8] Overridden Default method is reported as duplicated
* Bug 418235 - [compiler][null] Unreported nullness error when using generic
+ * Bug 404690 - [1.8][compiler] revisit bridge generation after VM bug is fixed
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -529,7 +530,7 @@
int length = inherited.length;
for (int i = 0; i < length; i++) {
MethodBinding inheritedMethod = inherited[i];
- if (inheritedMethod.isPublic() && !inheritedMethod.declaringClass.isPublic())
+ if (inheritedMethod.isPublic() && (!inheritedMethod.declaringClass.isInterface() && !inheritedMethod.declaringClass.isPublic()))
this.type.addSyntheticBridgeMethod(inheritedMethod.original());
}
}
@@ -623,7 +624,7 @@
if (matchMethod == null && current != null && this.type.isPublic()) { // current == null case handled already.
MethodBinding inheritedMethod = inherited[i];
- if (inheritedMethod.isPublic() && !inheritedMethod.declaringClass.isPublic()) {
+ if (inheritedMethod.isPublic() && (!inheritedMethod.declaringClass.isInterface() && !inheritedMethod.declaringClass.isPublic())) {
this.type.addSyntheticBridgeMethod(inheritedMethod.original());
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index c8cb7f4..cee3903 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -91,9 +91,7 @@
* May return an UnresolvedReferenceBinding.
* @see ParameterizedTypeBinding#genericType()
*/
-//{ObjectTeams: made public (was protected):
public ReferenceBinding actualType() {
-// SH}
return this.type;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
index f48bb45..5b81510 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
@@ -49,6 +49,10 @@
return this.expression.printExpression(0, new StringBuffer()).toString().toCharArray();
}
+ public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
+ return this.expression.sIsMoreSpecific(s, t);
+ }
+
public String toString() {
StringBuffer buffer = new StringBuffer("PolyTypeBinding for: "); //$NON-NLS-1$
return this.expression.printExpression(0, buffer).toString();
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 32dfc41..a051f07 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
@@ -1105,7 +1105,11 @@
return ((CompilationUnitScope) unitScope).environment;
}
- // abstract method lookup lookup (since maybe missing default abstract methods)
+ /* Abstract method lookup (since maybe missing default abstract methods). "Default abstract methods" are methods that used to be emitted into
+ abstract classes for unimplemented interface methods at JDK 1.1 time frame. See SourceTypeBinding.addDefaultAbstractMethods()
+ See also https://bugs.eclipse.org/bugs/show_bug.cgi?id=174588 for details of problem addressed here. Problem was in the method call in the
+ *abstract* class. Unless the interface methods are looked up, we will emit code that results in infinite recursion.
+ */
protected MethodBinding findDefaultAbstractMethod(
ReferenceBinding receiverType,
char[] selector,
@@ -1543,11 +1547,6 @@
}
// Internal use only - use findMethod()
- public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
- return findMethod(receiverType, selector, argumentTypes, invocationSite, false);
- }
-
- // Internal use only - use findMethod()
public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite, boolean inStaticContext) {
//{ObjectTeams: access to private method from "within" (need class part)?
if ( RoleTypeBinding.isRoleWithoutExplicitAnchor(receiverType)
@@ -1875,7 +1874,7 @@
if (methodBinding.canBeSeenBy(receiverType, invocationSite, this))
return methodBinding;
}
- methodBinding = findMethod(object, selector, argumentTypes, invocationSite);
+ methodBinding = findMethod(object, selector, argumentTypes, invocationSite, false);
if (methodBinding == null)
return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
return methodBinding;
@@ -2248,6 +2247,41 @@
}
// SH}
+ // For exact constructor references. 15.28.1
+ public MethodBinding getExactConstructor(TypeBinding receiverType, InvocationSite invocationSite) {
+ if (receiverType == null || !receiverType.canBeInstantiated())
+ return null;
+ if (receiverType.isArrayType()) {
+ if (!receiverType.leafComponentType().isReifiable())
+ return null;
+ return new MethodBinding(ClassFileConstants.AccPublic, TypeConstants.INIT,
+ receiverType,
+ new TypeBinding[] { TypeBinding.INT },
+ Binding.NO_EXCEPTIONS,
+ getJavaLangObject()); // just lie.
+ }
+
+ CompilationUnitScope unitScope = compilationUnitScope();
+ MethodBinding exactConstructor = null;
+ unitScope.recordTypeReference(receiverType);
+ MethodBinding[] methods = receiverType.getMethods(TypeConstants.INIT);
+ for (int i = 0, length = methods.length; i < length; i++) {
+ MethodBinding constructor = methods[i];
+ if (!constructor.canBeSeenBy(invocationSite, this))
+ continue;
+ if (constructor.isVarargs())
+ return null;
+ if (constructor.typeVariables() != Binding.NO_TYPE_VARIABLES && invocationSite.genericTypeArguments() == null)
+ return null;
+ if (exactConstructor == null) {
+ exactConstructor = constructor;
+ } else {
+ return null;
+ }
+ }
+ return exactConstructor;
+ }
+
public MethodBinding getConstructor(ReferenceBinding receiverType, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
CompilationUnitScope unitScope = compilationUnitScope();
LookupEnvironment env = unitScope.environment;
@@ -2457,7 +2491,7 @@
classScope.origImplicitScope = null;
// SH}
if (methodBinding == null)
- methodBinding = classScope.findMethod(receiverType, selector, argumentTypes, invocationSite);
+ methodBinding = classScope.findMethod(receiverType, selector, argumentTypes, invocationSite, false);
if (methodBinding != null) { // skip it if we did not find anything
if (foundMethod == null) {
if (methodBinding.isValidBinding()) {
@@ -2797,7 +2831,7 @@
MethodBinding methodBinding = findExactMethod(currentType, selector, argumentTypes, invocationSite);
if (methodBinding != null) return methodBinding;
- methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite);
+ methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite, false);
//{ObjectTeams: callout to private role method goes through the role class-part:
// (will later be replaced by synthetic accessor)
if ( methodBinding == null
@@ -2806,7 +2840,7 @@
&& currentType.isRole())
{
currentType = currentType.getRealClass();
- methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite);
+ methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite, false);
}
// SH}
if (methodBinding == null)
@@ -4334,6 +4368,43 @@
// caveat: this is not a direct implementation of JLS
protected final MethodBinding mostSpecificMethodBinding(MethodBinding[] visible, int visibleSize, TypeBinding[] argumentTypes, final InvocationSite invocationSite, ReferenceBinding receiverType) {
+ // Apply one level of filtering per poly expression more specific rules.
+ if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
+ MethodBinding[] moreSpecific = new MethodBinding[visibleSize];
+ int count = 0;
+ for (int i = 0, length = argumentTypes.length; i < length; i++) {
+ TypeBinding argumentType = argumentTypes[i];
+ if (argumentType.kind() != Binding.POLY_TYPE)
+ continue;
+ next:
+ for (int j = 0; j < visibleSize; j++) {
+ final TypeBinding[] mbjParameters = visible[j].parameters;
+ final int mbjParametersLength = mbjParameters.length;
+ TypeBinding t = i < mbjParametersLength ? mbjParameters[i] : mbjParameters[mbjParametersLength - 1];
+ boolean tIsMoreSpecific = false;
+ for (int k = 0; k < visibleSize; k++) {
+ if (j == k) continue;
+ final TypeBinding[] mbkParameters = visible[k].parameters;
+ final int mbkParametersLength = mbkParameters.length;
+ TypeBinding s = i < mbkParametersLength ? mbkParameters[i] : mbkParameters[mbkParametersLength - 1];
+ if (TypeBinding.equalsEquals(t, s))
+ continue;
+ if (!argumentType.sIsMoreSpecific(t,s))
+ continue next;
+ tIsMoreSpecific = true;
+ }
+ if (tIsMoreSpecific)
+ moreSpecific[count++] = visible[j];
+ }
+ }
+ if (count != 0) {
+ visible = moreSpecific;
+ visibleSize = count;
+ }
+ }
+
+ // JLS7 implementation
+
int[] compatibilityLevels = new int[visibleSize];
//{ObjectTeams: also record whether translation is required:
boolean[] useTranslation = new boolean[visibleSize];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 5d0ea39..3cde2bc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -1021,6 +1021,7 @@
/*
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658. Generate a bridge method if a public method is inherited
* from a non-public class into a public class (only in 1.6 or greater)
+ * https://bugs.eclipse.org/404690 : this doesn't apply to inherited interface methods (i.e., default methods)
*/
public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge) {
if (!isPrototype()) throw new IllegalStateException();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
index 029d5b6..b94ae5f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
@@ -570,7 +570,10 @@
public void initializeMethodAccessor(MethodBinding accessedMethod, boolean isSuperAccess, ReferenceBinding receiverType) {
this.targetMethod = accessedMethod;
- this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
+ if (isSuperAccess && receiverType.isInterface() && !accessedMethod.isStatic())
+ this.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccSynthetic;
+ else
+ this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
//{ObjectTeams: different visibility for team accessors:
if (receiverType.isTeam())
this.modifiers |= ClassFileConstants.AccPublic;
@@ -593,7 +596,7 @@
System.arraycopy(accessedMethod.parameters, 0, this.parameters, 2, accessedMethod.parameters.length);
} else
// SH}
- if (accessedMethod.isStatic()) {
+ if (accessedMethod.isStatic() || (isSuperAccess && receiverType.isInterface())) {
this.parameters = accessedMethod.parameters;
} else {
this.parameters = new TypeBinding[accessedMethod.parameters.length + 1];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index 3ac2ab4..603744f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -136,7 +136,7 @@
}
}
-protected ReferenceBinding actualType() {
+public ReferenceBinding actualType() {
return null; // overridden in ParameterizedTypeBinding & WildcardBinding
}
@@ -617,7 +617,7 @@
return false;
}
-public boolean isFunctionalInterface() {
+public boolean isFunctionalInterface(Scope scope) {
return false;
}
@@ -1530,4 +1530,12 @@
public boolean hasTypeBit(int bit) {
return false;
}
+
+public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
+ throw new UnsupportedOperationException("abstract virtual method called"); //$NON-NLS-1$
+}
+
+public MethodBinding[] getMethods(char[] selector) {
+ return Binding.NO_METHODS;
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
index a83009f..48db7d5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
@@ -109,7 +109,7 @@
return this.boundKind;
}
- protected ReferenceBinding actualType() {
+ public ReferenceBinding actualType() {
return this.genericType;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
index 7ab9175..3fe6499 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
@@ -147,16 +147,9 @@
CompilationResult unitResult)
{
// SH}
- if (severity == ProblemSeverities.Ignore)
- return;
- boolean mandatory = (severity & (ProblemSeverities.Error | ProblemSeverities.Optional)) == ProblemSeverities.Error;
- if (this.policy.ignoreAllErrors()) {
- // Error is not to be exposed, but clients may need still notification as to whether there are silently-ignored-errors.
- if (mandatory)
- referenceContext.tagAsHavingIgnoredMandatoryErrors(problemId);
- return;
- }
+ if (severity == ProblemSeverities.Ignore || this.policy.ignoreAllErrors())
+ return;
if ((severity & ProblemSeverities.Optional) != 0 && problemId != IProblem.Task && !this.options.ignoreSourceFolderWarningOption) {
//{ObjectTeams: NPE prevention:
@@ -300,6 +293,7 @@
switch (severity & ProblemSeverities.Error) {
case ProblemSeverities.Error :
+ boolean mandatory = ((severity & ProblemSeverities.Optional) == 0);
record(problem, unitResult, referenceContext, mandatory);
if ((severity & ProblemSeverities.Fatal) != 0) {
// don't abort or tag as error if the error is suppressed
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
index 8437289..d2362c5 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
@@ -247,7 +247,7 @@
if (argHasError) {
if(this.actualReceiverType instanceof ReferenceBinding) {
// record any selector match, for clients who may still need hint about possible method match
- this.binding = scope.findMethod((ReferenceBinding)this.actualReceiverType, this.selector, new TypeBinding[]{}, this);
+ this.binding = scope.findMethod((ReferenceBinding)this.actualReceiverType, this.selector, new TypeBinding[]{}, this, false);
}
return null;
}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
index b07ddf3..16a7723 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
@@ -4,6 +4,10 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
@@ -369,8 +373,8 @@
return null;
}
// Internal use only
-public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
- MethodBinding methodBinding = super.findMethod(receiverType, selector, argumentTypes, invocationSite);
+public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite, boolean inStaticContext) {
+ MethodBinding methodBinding = super.findMethod(receiverType, selector, argumentTypes, invocationSite, inStaticContext);
if (methodBinding != null && methodBinding.isValidBinding())
if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotVisible);
@@ -390,7 +394,7 @@
}
// answers closest approximation, may not check argumentTypes or visibility
- methodBinding = findMethod(object, selector, argumentTypes, invocationSite);
+ methodBinding = findMethod(object, selector, argumentTypes, invocationSite, false);
if (methodBinding == null)
return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
if (methodBinding.isValidBinding()) {
@@ -600,7 +604,7 @@
// retrieve an exact visible match (if possible)
MethodBinding methodBinding = findExactMethod(receiverType, selector, argumentTypes, invocationSite);
if (methodBinding == null)
- methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite);
+ methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite, false);
if (methodBinding != null) { // skip it if we did not find anything
if (methodBinding.isValidBinding())
if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))