/******************************************************************************* * Copyright (c) 2015, 2016 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 * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for * Bug 446691 - [1.8][null][compiler] NullPointerException in SingleNameReference.analyseCode *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; import junit.framework.Test; @SuppressWarnings({ "rawtypes" }) public class LambdaRegressionTest extends AbstractRegressionTest { static { // TESTS_NAMES = new String[] { "test001"}; // TESTS_NUMBERS = new int[] { 50 }; // TESTS_RANGE = new int[] { 11, -1 }; } public LambdaRegressionTest(String name) { super(name); } public static Test suite() { return buildMinimalComplianceTestSuite(testClass(), F_1_8); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=446317, java.lang.VerifyError: Bad type on operand stack with Lambdas and/or inner classes public void test001() { this.runConformTest( new String[] { "X.java", "import java.util.HashMap;\n" + "import java.util.Map;\n" + "import java.util.function.Function;\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " new X().run();\n" + " }\n" + " public void run() {\n" + " class Inner {\n" + " public Inner() {\n" + " System.out.println(\"miep\");\n" + " }\n" + " }\n" + " Map<String, Inner> map = new HashMap<>();\n" + " Function<String, Inner> function = (name) -> {\n" + " Inner i = map.get(name);\n" + " if (i == null) {\n" + " i = new Inner();\n" + " map.put(name, i);\n" + " }\n" + " return i;\n" + "\n" + " };\n" + " function.apply(\"test\");\n" + " }\n" + "}\n", }, "miep" ); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=446317, java.lang.VerifyError: Bad type on operand stack with Lambdas and/or inner classes public void test002() { this.runNegativeTest( new String[] { "X.java", "import java.util.function.Consumer;\n" + "@SuppressWarnings(\"all\")\n" + "public class X {\n" + " private final String text = \"Bug?\";\n" + " public static void main(String[] args) {\n" + " new X().doIt();\n" + " }\n" + " private void doIt() {\n" + " new Sub();\n" + " }\n" + " private class Super<T> {\n" + " public Super(Consumer<T> consumer) {\n" + " }\n" + " }\n" + " private class Sub extends Super<String> {\n" + " public Sub() {\n" + " super(s -> System.out.println(text));\n" + " // super(s -> System.out.println(\"miep\"));\n" + " }\n" + " }\n" + "}\n", }, "----------\n" + "1. ERROR in X.java (at line 17)\n" + " super(s -> System.out.println(text));\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Cannot refer to \'this\' nor \'super\' while explicitly invoking a constructor\n" + "----------\n" ); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=446317, java.lang.VerifyError: Bad type on operand stack with Lambdas and/or inner classes public void test003() { this.runNegativeTest( new String[] { "X.java", "import java.util.function.Consumer;\n" + "@SuppressWarnings(\"all\")\n" + "public class X {\n" + " private final String text = \"Bug?\";\n" + " public static void main(String[] args) {\n" + " new X().doIt();\n" + " }\n" + " private void doIt() {\n" + " new Sub();\n" + " }\n" + " private class Super<T> {\n" + " public Super(Consumer<T> consumer) {\n" + " }\n" + " }\n" + " private class Sub extends Super<String> {\n" + " public Sub() {\n" + " super(s -> System.out.println(\"miep\"));\n" + " }\n" + " }\n" + "}\n", }, "" ); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=446317, java.lang.VerifyError: Bad type on operand stack with Lambdas and/or inner classes public void test004() { this.runConformTest( new String[] { "Y.java", "import java.util.function.Supplier;\n" + "class E {\n" + " E(Supplier<Object> factory) { }\n" + "}\n" + "public class Y extends E {\n" + " Y() {\n" + " super( () -> {\n" + " class Z extends E {\n" + " Z() {\n" + " super(() -> new Object());\n" + " }\n" + " }\n" + " return null;\n" + " });\n" + " }\n" + " public static void main(String[] args) {\n" + " new Y();\n" + " }\n" + "}" }); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=448724, [1.8] [compiler] Wrong resolution of overloaded method when irrelevant type parameter is present and lambda is used as parameter public void test448724() { this.runConformTest( new String[] { "X.java", "import java.util.concurrent.Callable;\n" + "public class X {\n" + " public void mismatchRunnableCallable() throws Exception {\n" + " //Resolves to case1(Runnable) method invocation; lambda with block\n" + " case1(() -> {\"abc\".length();});\n" + " //Resolves to case1(Callable) method invocation, resulting in type mismatch; block removed - lambda with expression\n" + " case1(() -> \"abc\".length());\n" + " }\n" + " public void noSuchMismatch() throws Exception {\n" + " //no difference to case1 \n" + " case2(() -> {\"abc\".length();});\n" + " //the only difference to case 1 is the missing irrelevant <T> type parameter. Properly resolves to case2(Runnable) here\n" + " case2(() -> \"abc\".length());\n" + " }\n" + " public void case1(final Runnable r) {\n" + " System.out.println(\"case1: Runnable\");\n" + " }\n" + " public <T> void case1(Callable<Boolean> c) {\n" + " System.out.println(\"case1: Callable\");\n" + " }\n" + " public void case2(final Runnable supplier) {\n" + " System.out.println(\"case2: Runnable\");\n" + " }\n" + " public void case2(Callable<Boolean> conditionEvaluator) {\n" + " System.out.println(\"case2: Callable\");\n" + " }\n" + " public static void main(String[] args) throws Exception {\n" + " new X().mismatchRunnableCallable();\n" + " new X().noSuchMismatch();\n" + " }\n" + "}\n" }, "case1: Runnable\n" + "case1: Runnable\n" + "case2: Runnable\n" + "case2: Runnable"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767, [1.8][compiler] Spurious method not applicable error due to interaction between overload resolution and type inference public void test447767() { this.runConformTest( new String[] { "X.java", "interface I<T, U, V> {\n" + " T goo(U u, V v);\n" + "}\n" + "public class X {\n" + " static <T, U, V> T foo(T t, U u, V v) {\n" + " System.out.println(\"Wrong!\");\n" + " return null;\n" + " }\n" + " static <T, U, V> V foo(T t, U u, I<T, U, V> i) {\n" + " System.out.println(\"Right!\");\n" + " return null;\n" + " }\n" + " public static void main(String[] args) {\n" + " String s = goo(foo(\"String\", \"String\", (u, v) -> v));\n" + " }\n" + " static <T> T goo(T t) {\n" + " return t; \n" + " }\n" + "}\n" }, "Right!"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767, [1.8][compiler] Spurious method not applicable error due to interaction between overload resolution and type inference public void test447767a() { this.runNegativeTest( new String[] { "X.java", "interface I<T, U, V> {\n" + " T goo(U u, V v);\n" + "}\n" + "public class X {\n" + " static <T, U, V> T foo(T t, U u, I<T, U, V> i) {\n" + " return null;\n" + " }\n" + " public static void main(String[] args) {\n" + " String s = goo(foo(\"String\", \"String\", (u, v) -> v));\n" + " }\n" + " static <T> T goo(T t) {\n" + " return t; \n" + " }\n" + "}\n" }, "----------\n" + "1. ERROR in X.java (at line 9)\n" + " String s = goo(foo(\"String\", \"String\", (u, v) -> v));\n" + " ^\n" + "Type mismatch: cannot convert from Object to String\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767, [1.8][compiler] Spurious method not applicable error due to interaction between overload resolution and type inference public void test447767b() { this.runConformTest( new String[] { "X.java", "interface I<T, U, V> {\n" + " T goo(U u, V v);\n" + "}\n" + "public class X {\n" + " static String goo(String s, String s2) {\n" + " return null;\n" + " }\n" + " static <T, U, V> V foo(T t, U u, I<T, U, V> i) {\n" + " System.out.println(\"Right!\");\n" + " return null;\n" + " }\n" + " public static void main(String[] args) {\n" + " String s = goo(foo(\"String\", \"String\", X::goo));\n" + " }\n" + " static <T> T goo(T t) {\n" + " return t; \n" + " }\n" + "}\n" }, "Right!"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767, [1.8][compiler] Spurious method not applicable error due to interaction between overload resolution and type inference public void test447767c() { this.runConformTest( new String[] { "X.java", "interface I<T, U, V> {\n" + " T goo(U u, V v);\n" + "}\n" + "public class X {\n" + " static String goo(String s, String s2) {\n" + " return null;\n" + " }\n" + " static <T, U, V> T foo(T t, U u, V v) {\n" + " System.out.println(\"Wrong!\");\n" + " return null;\n" + " }\n" + " static <T, U, V> V foo(T t, U u, I<T, U, V> i) {\n" + " System.out.println(\"Right!\");\n" + " return null;\n" + " }\n" + " public static void main(String[] args) {\n" + " String s = goo(foo(\"String\", \"String\", X::goo));\n" + " }\n" + " static <T> T goo(T t) {\n" + " return t; \n" + " }\n" + "}\n" }, "Right!"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767, [1.8][compiler] Spurious method not applicable error due to interaction between overload resolution and type inference public void test447767d() { this.runConformTest( new String[] { "X.java", "interface I<T, U, V> {\n" + " T goo(U u, V v);\n" + "}\n" + "public class X {\n" + " static String goo(String s, String s2) {\n" + " return null;\n" + " }\n" + " static <T, U, V> T foo(T t, U u, V v) {\n" + " System.out.println(\"Wrong!\");\n" + " return null;\n" + " }\n" + " static <T, U, V> V foo(T t, U u, I<T, U, V> i) {\n" + " System.out.println(\"Right!\");\n" + " return null;\n" + " }\n" + " public static void main(String[] args) {\n" + " String s = goo(foo(\"String\", \"String\", X::goo));\n" + " }\n" + " static <T> T goo(T t) {\n" + " return t; \n" + " }\n" + "}\n" }, "Right!"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=449410, [1.8][compiler] Eclipse java compiler does not detect a bad return type in lambda expression public void test449410() { this.runNegativeTest( new String[] { "X.java", "import java.util.Collections;\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " Collections.emptyMap()\n" + " .entrySet()\n" + " .forEach(entry -> test() ? bad() : returnType());\n" + " }\n" + " private static boolean test() {\n" + " return (System.currentTimeMillis() & 0x1) == 0;\n" + " }\n" + " private static void returnType() {\n" + " }\n" + " private static void bad() {\n" + " }\n" + "}\n" }, "----------\n" + "1. ERROR in X.java (at line 6)\n" + " .forEach(entry -> test() ? bad() : returnType());\n" + " ^^^^^^^\n" + "The method forEach(Consumer<? super Map.Entry<Object,Object>>) in the type Iterable<Map.Entry<Object,Object>> is not applicable for the arguments ((<no type> entry) -> {})\n" + "----------\n" + "2. ERROR in X.java (at line 6)\n" + " .forEach(entry -> test() ? bad() : returnType());\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Invalid expression as statement\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=449824, [1.8] Difference in behaviour with method references and lambdas // Captures present behavior - may not be correct. public void test449824() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " public static void main(String[] args) {\n" + " Concrete<Target> fl = new Concrete<Target>();\n" + " fl.call(each -> each.doSomething()); // fails\n" + " fl.call((Target each) -> each.doSomething()); // fails\n" + " fl.call(Target::doSomething); // succeeds in Eclipse 4.5M3 and 4.4.1\n" + " // but fails in Java 8 1.8.0_11\n" + " }\n" + " public static class Target {\n" + " public void doSomething() {\n" + " }\n" + " }\n" + " public static class Concrete<T> implements Left<T>, Right<T> {\n" + " public void call(RightHand<? super T> p) {\n" + " }\n" + " }\n" + " public interface Left<T> {\n" + " default void call(LeftHand<? super T> p) {\n" + " }\n" + " }\n" + " public interface LeftHand<T> {\n" + " public void left(T t);\n" + " }\n" + " public interface Right<T> {\n" + " public void call(RightHand<? super T> p);\n" + " }\n" + " public interface RightHand<T> {\n" + " public void right(T t);\n" + " }\n" + "}\n" }, "----------\n" + "1. ERROR in X.java (at line 4)\n" + " fl.call(each -> each.doSomething()); // fails\n" + " ^^^^\n" + "The method call(X.RightHand<? super X.Target>) is ambiguous for the type X.Concrete<X.Target>\n" + "----------\n" + "2. ERROR in X.java (at line 6)\n" + " fl.call(Target::doSomething); // succeeds in Eclipse 4.5M3 and 4.4.1\n" + " ^^^^\n" + "The method call(X.RightHand<? super X.Target>) is ambiguous for the type X.Concrete<X.Target>\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=448954, [1.8][compiler] Suspect error: "The method foo(String, String, X::goo) is undefined for the type X" public void test448954() { this.runConformTest( new String[] { "X.java", "interface I<T, U, V> {\n" + " T goo(U u, V v);\n" + "}\n" + "interface J {\n" + " void foo();\n" + "}\n" + "public class X {\n" + " static String goo(String s, String s2) {\n" + " return null;\n" + " }\n" + " static <T, U, V> T foo(T t, U u, J j) {\n" + " System.out.println(\"Wrong!\");\n" + " return null;\n" + " }\n" + " static <T, U, V> V foo(T t, U u, I<T, U, V> i) {\n" + " System.out.println(\"Right!\");\n" + " return null;\n" + " }\n" + " public static void main(String[] args) {\n" + " String s = goo(foo(\"String\", \"String\", X::goo));\n" + " }\n" + " static <T> T goo(T t) {\n" + " return t;\n" + " }\n" + "}\n" }, "Right!"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=450380, [1.8][compiler] NPE in Scope.getExactConstructor(..) for bad constructor reference public void test450380() { this.runNegativeTest( new String[] { "X.java", "import java.util.ArrayList;\n" + "import java.util.function.IntFunction;\n" + "public class X {\n" + " IntFunction<ArrayList<String>> noo() {\n" + " return System::new;\n" + " }\n" + "}\n" }, "----------\n" + "1. ERROR in X.java (at line 5)\n" + " return System::new;\n" + " ^^^^^^^^^^^\n" + "The type System does not define System(int) that is applicable here\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=450604, [1.8] CCE at InferenceContext18.getParameter line 1377 public void test450604() { this.runNegativeTest( new String[] { "X.java", "import java.io.IOException;\n" + "import java.util.List;\n" + "import java.util.function.Function;\n" + "public class X<T, E extends Exception> {\n" + " public static <T> List<T> of(T one) { return null; }\n" + " public @SafeVarargs static <T> List<T> of(T... items) { return null; }\n" + " public static void printDependencyLoops() throws IOException {\n" + " Function<? super String, ? extends List<String>> mapping = X::of;\n" + " }\n" + "}\n" }, ""); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=450604, [1.8] CCE at InferenceContext18.getParameter line 1377 public void test450604a() { this.runConformTest( new String[] { "X.java", "import java.util.List;\n" + "public class X {\n" + " public static <T> List<T> of() { return null; }\n" + " public static @SafeVarargs <T> List<T> of(T... values) { return null; }\n" + " static void walkAll() {\n" + " X.<String> of();\n" + " }\n" + "}\n" }); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=451677, [1.8][compiler] missing type inference public void _test451677() { this.runConformTest( new String[] { "X.java", "import java.util.ArrayList;\n" + "import java.util.function.Function;\n" + "public class X {\n" + " public static void test() {\n" + " operationOnCreated(create(123, size -> new ArrayList<Integer>(size)), l -> l.size()); // works with: (ArrayList<Integer> l) -> l.size()\n" + " }\n" + " public static <R, A> R create(A arg, Function<A, R> factory) {\n" + " return factory.apply(arg);\n" + " }\n" + " public static <R, A> R operationOnCreated(A created, Function<A, R> function) {\n" + " return function.apply(created);\n" + " }\n" + "}\n" }); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=451840 // [1.8] java.lang.BootstrapMethodError when running code with constructor reference public void testBug451840() { runNegativeTest(new String [] { "X.java", "public class X {\n" + " public static void main(String[] args) {\n" + " X test = new X();\n" + " MySupplier<X> s = test::new; // incorrect\n" + " }\n" + " public interface MySupplier<T> {\n" + " T create();\n" + " }\n" + "}"}, "----------\n" + "1. ERROR in X.java (at line 4)\n" + " MySupplier<X> s = test::new; // incorrect\n" + " ^^^^\n" + "test cannot be resolved to a type\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=448556 // [1.8][compiler] Invalid compiler error about effectively final variable outside the context of a lambda. public void testBug4448556() { this.runConformTest(new String [] { "X.java", "import java.io.Serializable;\n" + "import java.util.Arrays;\n" + "import java.util.List;\n" + "public class X {\n" + " private static final List<Integer> INTEGERS = Arrays.asList(1, 2, 3, 4);\n" + " public static void main(String[] args) {\n" + " for (int i = 0; i < INTEGERS.size(); i++) {\n" + " MyPredicate<Integer> predicate = INTEGERS.get(i)::equals;\n" + " }\n" + " } \n" + " public interface MyPredicate<T> extends Serializable {\n" + " boolean accept(T each);\n" + " }\n" + "}" }, ""); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=448556 // [1.8][compiler] Invalid compiler error about effectively final variable outside the context of a lambda. public void testBug4448556a() { this.runConformTest(new String [] { "X.java", "import java.io.Serializable;\n" + "import java.util.Arrays;\n" + "import java.util.List;\n" + "public class X {\n" + " int value = 0; \n" + " private static final List<Integer> INTEGERS = Arrays.asList(1, 2, 3, 4);\n" + " public Integer next() {\n" + " return new Integer(++value);\n" + " }\n" + " public static void main(String[] args) {\n" + " X t = new X();\n" + " MyPredicate<Integer> predicate = t.next()::equals;\n" + " System.out.println(\"Value \" + t.value + \" accept \" + predicate.accept(t.value));\n" + " }\n" + " public interface MyPredicate<T> extends Serializable {\n" + " boolean accept(T each);\n" + " }\n" + "}" }, "Value 1 accept true"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=453687 // [1.8][compiler]Incorrect errors when compiling code with Method References public void testBug453687() { this.runConformTest(new String [] { "X.java", "import static java.util.stream.Collectors.groupingBy;\n" + "import static java.util.stream.Collectors.mapping;\n" + "import static java.util.stream.Collectors.toSet;\n" + "import java.util.Locale;\n" + "import java.util.Map;\n" + "import java.util.Set;\n" + "import java.util.stream.Stream;\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " Map<String, Set<String>> countryLanguagesMap = Stream.of(Locale.getAvailableLocales()).collect(\n" + " groupingBy(Locale::getDisplayCountry, mapping(Locale::getDisplayLanguage, toSet())));\n" + " }\n" + "} " }, ""); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=456481 - [1.8] VerifyError on constructor reference inside lambda public void testBug456481() { this.runConformTest(new String [] { "Test.java", "public class Test {\n" + " interface Constructor {\n" + " MyTest execute();\n" + " }\n" + " interface ArrayConstructor {\n" + " MyTest[] execute(int no);\n" + " }\n" + " interface ParameterizedConstructor {\n" + " MyParameterizedTest<String> execute();\n" + " }\n" + " class MyTest {\n" + " MyTest() { System.out.println(\"Constructor executed\"); }\n" + " }\n" + " class MyParameterizedTest<T> {\n" + " MyParameterizedTest() {\n" + " System.out.println(\"Parameterized Constructor executed\");\n" + " }\n" + " }\n" + " public Constructor getConstructor() {\n" + " return getConstructor(() -> { return MyTest::new; });\n" + " }\n" + " public MyTest[] getArray(int no) {\n" + " return new MyTest[no];\n" + " }\n" + " ArrayConstructor getArrayConstructor() {\n" + " return getArrayConstructor(() -> {return MyTest[]::new;});\n" + " }\n" + " ParameterizedConstructor getParameterizedConstructor() {\n" + " return getParameterizedConstructor(() -> {return MyParameterizedTest<String>::new;});\n" + " }\n" + " ArrayConstructor getArrayConstructor(ArrayWrapper w) {\n" + " return w.unwrap();\n" + " }\n" + " public static void main(String argv[]) {\n" + " Test t = new Test();\n" + " MyTest mytest = t.getConstructor().execute();\n" + " MyTest[] array = t.getArrayConstructor().execute(2);\n" + " MyParameterizedTest<String> pt = t.getParameterizedConstructor().execute();\n" + " }\n" + " ParameterizedConstructor getParameterizedConstructor(PTWrapper ptw) {\n" + " return ptw.unwrap();\n" + " }\n" + " Constructor getConstructor(Wrapper arg) {\n" + " return arg.unwrap();\n" + " }\n" + " interface PTWrapper {\n" + " ParameterizedConstructor unwrap();\n" + " }\n" + " interface ArrayWrapper {\n" + " ArrayConstructor unwrap();\n" + " }\n" + " interface Wrapper {\n" + " Constructor unwrap();\n" + " }\n" + "}" }, "Constructor executed\n" + "Parameterized Constructor executed"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=457007, VerifyError public void testBug457007() { this.runConformTest(new String [] { "Test.java", "public class Test {\n" + " void method() {\n" + " class Bar {}\n" + " java.util.function.Function<String, Bar> f = str -> new Bar();\n" + " }\n" + " public static void main(String[] args) {\n" + " System.out.println(\"done\");\n" + " }\n" + "}" }, "done"); } public void testBug446691_comment5() { runConformTest(new String [] { "Test.java", "import java.util.*;\n" + "\n" + "public class Test {\n" + " protected final Integer myInt;\n" + "\n" + " public Test() {\n" + " myInt = Integer.valueOf(0);\n" + " try {\n" + " Optional.empty().orElseThrow(() -> new IllegalArgumentException(myInt.toString()));\n" + " } catch (IllegalArgumentException e) {\n" + " throw new RuntimeException();\n" + " }\n" + " return;\n" + " }\n" + "}\n" }); } public void testBug446691_comment8() { runConformTest(new String [] { "Boom.java", "public class Boom {\n" + " private final String field;\n" + " public Boom(String arg) {\n" + " this.field = arg;\n" + " try {\n" + " java.util.function.Supplier<String> supplier = () -> field;\n" + " } catch (Exception e) {\n" + " \n" + " }\n" + " }\n" + "}\n" }); } public void testBug446691_comment14() { runNegativeTest(new String [] { "test/Main.java", "package test;\n" + "\n" + "import java.util.logging.Logger;\n" + "\n" + "public class Main {\n" + "\n" + " private static final Logger LOG = Logger.getLogger(\"test\");\n" + " private final static String value;\n" + "\n" + " static {\n" + " try {\n" + " LOG.info(() -> String.format(\"Value is: %s\", value));\n" + " } catch (final Exception ex) {\n" + " throw new ExceptionInInitializerError(ex);\n" + " }\n" + " }\n" + "}" }, "----------\n" + "1. ERROR in test\\Main.java (at line 8)\n" + " private final static String value;\n" + " ^^^^^\n" + "The blank final field value may not have been initialized\n" + "----------\n" + "2. ERROR in test\\Main.java (at line 12)\n" + " LOG.info(() -> String.format(\"Value is: %s\", value));\n" + " ^^^^^\n" + "The blank final field value may not have been initialized\n" + "----------\n"); } // error in lambda even if field is assigned later public void testBug446691_comment14b() { runNegativeTest(new String [] { "test/Main.java", "package test;\n" + "\n" + "import java.util.logging.Logger;\n" + "\n" + "public class Main {\n" + "\n" + " private static final Logger LOG = Logger.getLogger(\"test\");\n" + " private final static String value;\n" + "\n" + " static {\n" + " try {\n" + " LOG.info(() -> String.format(\"Value is: %s\", value));\n" + " } catch (final Exception ex) {\n" + " throw new ExceptionInInitializerError(ex);\n" + " }\n" + " value = \"\";" + " }\n" + "}" }, "----------\n" + "1. ERROR in test\\Main.java (at line 12)\n" + " LOG.info(() -> String.format(\"Value is: %s\", value));\n" + " ^^^^^\n" + "The blank final field value may not have been initialized\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=463526 // Parenthesis are incorrectly allowed in lambda when LambdaBody is an expression statement public void testBug463526() { runNegativeTest(new String [] { "Test.java", "public class Test {\n" + " public static void main(String[] args) {\n" + " Receiver r = new Receiver();\n" + " r.accept((l) -> (doItOnTheClass(new Object())));\n" + " }\n" + " public static void doItOnTheClass(Object o) {\n" + " System.out.println(\"done it\");\n" + " }\n" + " public static class Receiver {\n" + " public void accept(Listener l) {\n" + " l.doIt(new Object());\n" + " }\n" + " }\n" + " public static interface Listener {\n" + " public void doIt(Object o);\n" + " }\n" + "}" }, "----------\n" + "1. ERROR in Test.java (at line 4)\n" + " r.accept((l) -> (doItOnTheClass(new Object())));\n" + " ^^^^^^\n" + "The method accept(Test.Listener) in the type Test.Receiver is not applicable for the arguments ((<no type> l) -> {})\n" + "----------\n" + "2. ERROR in Test.java (at line 4)\n" + " r.accept((l) -> (doItOnTheClass(new Object())));\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Invalid expression as statement\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=463526 // Parenthesis are incorrectly allowed in lambda when LambdaBody is an expression statement public void testBug463526b() { runNegativeTest(new String [] { "Test.java", "import java.util.function.Consumer;\n" + "public class Test {\n" + " public static void main(String[] args) {\n" + " Receiver r = new Receiver();\n" + " r.process((o) -> (new Object()));\n" + " }\n" + " public static class Receiver {\n" + " public void process(Consumer<Object> p) {\n" + " }\n" + " }\n" + "}" }, "----------\n" + "1. ERROR in Test.java (at line 5)\n" + " r.process((o) -> (new Object()));\n" + " ^^^^^^^\n" + "The method process(Consumer<Object>) in the type Test.Receiver is not applicable for the arguments ((<no type> o) -> {})\n" + "----------\n" + "2. ERROR in Test.java (at line 5)\n" + " r.process((o) -> (new Object()));\n" + " ^^^^^^^^^^^^^^\n" + "Void methods cannot return a value\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=463526 // Parenthesis are incorrectly allowed in lambda when LambdaBody is an expression statement public void testBug463526c() { runNegativeTest(new String [] { "Test.java", "import java.util.function.Consumer;\n" + "public class Test {\n" + " public static void main(String[] args) {\n" + " Receiver r = new Receiver();\n" + " r.assign((o) -> (o = new Object()));\n" + " }\n" + " public static class Receiver {\n" + " public void assign(Consumer<Object> a) {\n" + " }\n" + " }\n" + "}" }, "----------\n" + "1. ERROR in Test.java (at line 5)\n" + " r.assign((o) -> (o = new Object()));\n" + " ^^^^^^\n" + "The method assign(Consumer<Object>) in the type Test.Receiver is not applicable for the arguments ((<no type> o) -> {})\n" + "----------\n" + "2. ERROR in Test.java (at line 5)\n" + " r.assign((o) -> (o = new Object()));\n" + " ^^^^^^^^^^^^^^^^^^\n" + "Void methods cannot return a value\n" + "----------\n"); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=464408 public void testBug464408() { runNegativeTest(new String[]{ "test/X.java", "import java.util.ArrayList;\n" + "import java.util.List;\n" + "public class X {\n" + " void x() {\n" + " List<List<String>> list = new ArrayList<>();\n" + " list.stream().toArray(List<String>[]::new);\n" + " }" + "}" }, "----------\n" + "1. ERROR in test\\X.java (at line 6)\n" + " list.stream().toArray(List<String>[]::new);\n" + " ^^^^^^^^^^^^^^^^^^^\n" + "Cannot create a generic array of List<String>\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=465900 // Internal compiler error: java.lang.IllegalArgumentException: info cannot be null at org.eclipse.jdt.internal.compiler.codegen.StackMapFrame.addStackItem(StackMapFrame.java:81) public void testBug465900() { this.runConformTest(new String [] { "X.java", "import java.io.Serializable;\n" + "import java.util.ArrayList;\n" + "import java.util.List;\n" + "import java.util.function.Supplier;\n" + "public class X {\n" + " private static final long serialVersionUID = 1L;\n" + " protected void x() {\n" + " String str = \"groep.koppeling.\" + (\"\".isEmpty() ? \"toevoegen\" : \"bewerken\");\n" + " List<String> bean = new ArrayList<>();\n" + " test(bean.get(0)::isEmpty);\n" + " }\n" + " private void test(SerializableSupplier<Boolean> test) {}\n" + "}\n" + "@FunctionalInterface\n" + "interface SerializableSupplier<T> extends Supplier<T>, Serializable {}\n" }, ""); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=477888 // [1.8][compiler] Compiler silently produces garbage but editor shows no errors public void testBug477888() { runNegativeTest(new String [] { "Test.java", "import java.io.IOException;\n" + "import java.nio.file.Files;\n" + "import java.nio.file.Paths;\n" + "import java.util.function.Consumer;\n" + "public class Test {\n" + " public static void main(String[] args) throws IOException {\n" + " Files.lines(Paths.get(args[0])).filter(x -> {return !x.startsWith(\".\");}).forEach(printMe());\n" + " }\n" + " private static Consumer<String> printMe() {\n" + " return x -> x.isEmpty() ? System.out.println() : System.out.println(getIndex() + \" \" + x); // error must be reported here!\n" + " }\n" + " static int idx;\n" + "\n" + " private static int getIndex() {\n" + " return ++idx;\n" + " }\n" + "}\n" }, "----------\n" + "1. ERROR in Test.java (at line 10)\n" + " return x -> x.isEmpty() ? System.out.println() : System.out.println(getIndex() + \" \" + x); // error must be reported here!\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Invalid expression as statement\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=472648 // [compiler][1.8] Lambda expression referencing method with generic type has incorrect compile errors public void testBug472648() { runNegativeTest(new String [] { "Test.java", "import java.util.ArrayList;\n" + "import java.util.List;\n" + "import java.util.function.Consumer;\n" + "public class Test {\n" + " public static void main(String argv[]) {\n" + " new Test();\n" + " }\n" + " public Test() {\n" + " List<Number> numList = new ArrayList<>();\n" + " numList.add(1);\n" + " numList.add(1.5);\n" + " numList.add(2);\n" + " numList.add(2.5);\n" + " forEachValueOfType(numList, Integer.class, (Integer i) -> (System.out.println(Integer.toString(i))));\n" + " }\n" + " private <T> void forEachValueOfType(List<?> list, Class<T> type, Consumer<T> action) {\n" + " \n" + " for (Object o : list) {\n" + " if (type.isAssignableFrom(o.getClass())) {\n" + " @SuppressWarnings(\"unchecked\")\n" + " T convertedObject = (T) o;\n" + " action.accept(convertedObject);\n" + " }\n" + " }\n" + " }\n" + "}" }, "----------\n" + "1. ERROR in Test.java (at line 14)\n" + " forEachValueOfType(numList, Integer.class, (Integer i) -> (System.out.println(Integer.toString(i))));\n" + " ^^^^^^^^^^^^^^^^^^\n" + "The method forEachValueOfType(List<?>, Class<T>, Consumer<T>) in the type Test is not applicable for the arguments (List<Number>, Class<Integer>, (Integer i) -> {})\n" + "----------\n" + "2. ERROR in Test.java (at line 14)\n" + " forEachValueOfType(numList, Integer.class, (Integer i) -> (System.out.println(Integer.toString(i))));\n" + " ^^^^^^^\n" + "Incompatible type specified for lambda expression's parameter i\n" + "----------\n" + "3. ERROR in Test.java (at line 14)\n" + " forEachValueOfType(numList, Integer.class, (Integer i) -> (System.out.println(Integer.toString(i))));\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Invalid expression as statement\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=473432 // Internal compiler error: java.lang.IllegalArgumentException: info cannot be null at org.eclipse.jdt.internal.compiler.codegen.StackMapFrame.addStackItem(StackMapFrame.java:81) public void testBug473432() { this.runConformTest(new String [] { "Tester.java", "import java.util.function.Function;\n" + "public class Tester {\n" + " private static class ValueWrapper<O> {\n" + " private O val_;\n" + " public ValueWrapper(O val) {\n" + " val_ = val;\n" + " }\n" + " public <R> R mapOrElse(Function<O, R> func, R defaultValue) {\n" + " if(val_ != null) {\n" + " return func.apply(val_);\n" + " }\n" + " return defaultValue;\n" + " }\n" + " }\n" + " private static void handleObject(Object object) {\n" + " System.out.println(\"Handled: \" + object);\n" + " }\n" + " public static void main(String[] args) {\n" + " ValueWrapper<String> wrapper = new ValueWrapper<>(\"value\");\n" + " boolean skipMethod = false;\n" + " // works on both JDT 3.9.2 and 3.11.0\n" + " Boolean result = skipMethod ? true : wrapper.mapOrElse(v -> false, null);\n" + " System.out.println(result);\n" + " wrapper = new ValueWrapper<>(null);\n" + " // works on JDT 3.9.2\n" + " handleObject(skipMethod ?\n" + " true :\n" + " wrapper.mapOrElse(v -> false, null));\n" + " wrapper = new ValueWrapper<>(null);\n" + " // works on neither version\n" + " result = skipMethod ?\n" + " true :\n" + " wrapper.mapOrElse(v -> false, null);\n" + " System.out.println(result);\n" + " }\n" + "}\n" }, "false\n" + "Handled: null\n" + "null"); } public static Class testClass() { return LambdaRegressionTest.class; } }