Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoopur Gupta2014-10-27 23:58:33 +0000
committerMarkus Keller2014-10-27 23:58:33 +0000
commitfd1973006b8d69c372d0b6fa2cbd79fe8d6cc3fe (patch)
treeb8ebc4148ce473b697589621f017a4ec0f5df310
parent2499089503d2b0333b921bf73c11984cf2379b1b (diff)
downloadeclipse.jdt.ui-I20141028-2000.tar.gz
eclipse.jdt.ui-I20141028-2000.tar.xz
eclipse.jdt.ui-I20141028-2000.zip
Bug 428741: [1.8][quick assist] convert method reference expression to lambdaI20141104-0800I20141029-2000I20141029-0800I20141028-2000I20141028-0800I20141027-2000
Bug 439601: [1.8][quick assist] convert lambda expression to method reference
-rw-r--r--org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java1417
-rw-r--r--org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java68
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java2
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties2
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java4
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java465
6 files changed, 1906 insertions, 52 deletions
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java
index d912c7fd28..2f2b715365 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java
@@ -1093,7 +1093,7 @@ public class AssistQuickFixTest18 extends QuickFixTest {
assertNoErrors(context);
List proposals= collectAssists(context, false);
- assertNumberOfProposals(proposals, 5);
+ assertNumberOfProposals(proposals, 6);
assertCorrectLabels(proposals);
buf= new StringBuffer();
@@ -1242,7 +1242,7 @@ public class AssistQuickFixTest18 extends QuickFixTest {
assertNoErrors(context);
List proposals= collectAssists(context, false);
- assertNumberOfProposals(proposals, 3);
+ assertNumberOfProposals(proposals, 4);
assertCorrectLabels(proposals);
buf= new StringBuffer();
@@ -1476,7 +1476,7 @@ public class AssistQuickFixTest18 extends QuickFixTest {
assertNoErrors(context);
List proposals= collectAssists(context, false);
- assertNumberOfProposals(proposals, 2);
+ assertNumberOfProposals(proposals, 3);
assertCorrectLabels(proposals);
buf= new StringBuffer();
@@ -2100,4 +2100,1415 @@ public class AssistQuickFixTest18 extends QuickFixTest {
String expected1= buf.toString();
assertExpectedExistInProposals(proposals, new String[] { expected1 });
}
+
+ public void testConvertMethodReferenceToLambda1() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public class E1 {\n");
+ buf.append(" Baz bm = E1::test;\n");
+ buf.append(" static <X> void test(X x) {}\n");
+ buf.append("}\n");
+ buf.append("interface Foo<T, N extends Number> {\n");
+ buf.append(" void m(N arg2);\n");
+ buf.append(" void m(T arg1);\n");
+ buf.append("}\n");
+ buf.append("interface Baz extends Foo<Integer, Integer> {}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E1.java", buf.toString(), false, null);
+
+ int offset= buf.toString().indexOf("::") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public class E1 {\n");
+ buf.append(" Baz bm = arg2 -> E1.test(arg2);\n");
+ buf.append(" static <X> void test(X x) {}\n");
+ buf.append("}\n");
+ buf.append("interface Foo<T, N extends Number> {\n");
+ buf.append(" void m(N arg2);\n");
+ buf.append(" void m(T arg1);\n");
+ buf.append("}\n");
+ buf.append("interface Baz extends Foo<Integer, Integer> {}\n");
+ String expected1= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+ }
+
+ public void testConvertMethodReferenceToLambda2() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("interface J<R> {\n");
+ buf.append(" <T> R run(T t);\n");
+ buf.append("}\n");
+ buf.append("public class E2 {\n");
+ buf.append(" J<String> j1 = E2::<Object>test; \n");
+ buf.append(" \n");
+ buf.append(" static <T> String test(T t) {\n");
+ buf.append(" return \"\";\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf.toString(), false, null);
+
+ int offset= buf.toString().indexOf("::") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_lambda_expression);
+ }
+
+ public void testConvertMethodReferenceToLambda3() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf1= new StringBuffer();
+ buf1.append("package test1;\n");
+ buf1.append("import java.util.HashSet;\n");
+ buf1.append("import java.util.function.*;\n");
+ buf1.append("class E3<T> {\n");
+ buf1.append(" IntFunction<int[][][]> ma = int[][][]::/*[1]*/new;\n");
+ buf1.append(" Supplier<MyHashSet<Integer>> mb = MyHashSet::/*[2]*/new;\n");
+ buf1.append(" Function<T, MyHashSet<Number>> mc = MyHashSet<Number>::/*[3]*/<T> new;\n");
+ buf1.append(" Function<String, MyHashSet<Integer>> md = MyHashSet::/*[4]*/new;\n");
+ buf1.append("}\n");
+ buf1.append("class MyHashSet<T> extends HashSet<T> {\n");
+ buf1.append(" public MyHashSet() {}\n");
+ buf1.append(" public <A> MyHashSet(A a) {}\n");
+ buf1.append(" public MyHashSet(String i) {}\n");
+ buf1.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E3.java", buf1.toString(), false, null);
+
+ // [1]
+ int offset= buf1.toString().indexOf("::/*[1]*/") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.HashSet;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("class E3<T> {\n");
+ buf.append(" IntFunction<int[][][]> ma = arg0 -> new int[arg0][][];\n");
+ buf.append(" Supplier<MyHashSet<Integer>> mb = MyHashSet::/*[2]*/new;\n");
+ buf.append(" Function<T, MyHashSet<Number>> mc = MyHashSet<Number>::/*[3]*/<T> new;\n");
+ buf.append(" Function<String, MyHashSet<Integer>> md = MyHashSet::/*[4]*/new;\n");
+ buf.append("}\n");
+ buf.append("class MyHashSet<T> extends HashSet<T> {\n");
+ buf.append(" public MyHashSet() {}\n");
+ buf.append(" public <A> MyHashSet(A a) {}\n");
+ buf.append(" public MyHashSet(String i) {}\n");
+ buf.append("}\n");
+ String expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [2]
+ offset= buf1.toString().indexOf("::/*[2]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.HashSet;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("class E3<T> {\n");
+ buf.append(" IntFunction<int[][][]> ma = int[][][]::/*[1]*/new;\n");
+ buf.append(" Supplier<MyHashSet<Integer>> mb = () -> new MyHashSet<>();\n");
+ buf.append(" Function<T, MyHashSet<Number>> mc = MyHashSet<Number>::/*[3]*/<T> new;\n");
+ buf.append(" Function<String, MyHashSet<Integer>> md = MyHashSet::/*[4]*/new;\n");
+ buf.append("}\n");
+ buf.append("class MyHashSet<T> extends HashSet<T> {\n");
+ buf.append(" public MyHashSet() {}\n");
+ buf.append(" public <A> MyHashSet(A a) {}\n");
+ buf.append(" public MyHashSet(String i) {}\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [3]
+ offset= buf1.toString().indexOf("::/*[3]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.HashSet;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("class E3<T> {\n");
+ buf.append(" IntFunction<int[][][]> ma = int[][][]::/*[1]*/new;\n");
+ buf.append(" Supplier<MyHashSet<Integer>> mb = MyHashSet::/*[2]*/new;\n");
+ buf.append(" Function<T, MyHashSet<Number>> mc = arg0 -> new<T> MyHashSet<Number>(arg0);\n");
+ buf.append(" Function<String, MyHashSet<Integer>> md = MyHashSet::/*[4]*/new;\n");
+ buf.append("}\n");
+ buf.append("class MyHashSet<T> extends HashSet<T> {\n");
+ buf.append(" public MyHashSet() {}\n");
+ buf.append(" public <A> MyHashSet(A a) {}\n");
+ buf.append(" public MyHashSet(String i) {}\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [4]
+ offset= buf1.toString().indexOf("::/*[4]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.HashSet;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("class E3<T> {\n");
+ buf.append(" IntFunction<int[][][]> ma = int[][][]::/*[1]*/new;\n");
+ buf.append(" Supplier<MyHashSet<Integer>> mb = MyHashSet::/*[2]*/new;\n");
+ buf.append(" Function<T, MyHashSet<Number>> mc = MyHashSet<Number>::/*[3]*/<T> new;\n");
+ buf.append(" Function<String, MyHashSet<Integer>> md = arg0 -> new MyHashSet<>(arg0);\n");
+ buf.append("}\n");
+ buf.append("class MyHashSet<T> extends HashSet<T> {\n");
+ buf.append(" public MyHashSet() {}\n");
+ buf.append(" public <A> MyHashSet(A a) {}\n");
+ buf.append(" public MyHashSet(String i) {}\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+ }
+
+ public void testConvertMethodReferenceToLambda4() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E4 {\n");
+ buf.append(" Function<String, String> p1 = E4::<Float> staticMethod;\n");
+ buf.append(" static <F> String staticMethod(String s) {\n");
+ buf.append(" return \"s\";\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E4.java", buf.toString(), false, null);
+
+ int offset= buf.toString().indexOf("::") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E4 {\n");
+ buf.append(" Function<String, String> p1 = arg0 -> E4.<Float> staticMethod(arg0);\n");
+ buf.append(" static <F> String staticMethod(String s) {\n");
+ buf.append(" return \"s\";\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+ }
+
+ public void testConvertMethodReferenceToLambda5() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf1= new StringBuffer();
+ buf1.append("package test1;\n");
+ buf1.append("import java.util.function.*;\n");
+ buf1.append("public class E5<T> {\n");
+ buf1.append(" <F> String method1() {\n");
+ buf1.append(" return \"a\";\n");
+ buf1.append(" }\n");
+ buf1.append(" <F> String method1(E5<T> e) {\n");
+ buf1.append(" return \"b\";\n");
+ buf1.append(" }\n");
+ buf1.append("}\n");
+ buf1.append("class Sub extends E5<Integer> {\n");
+ buf1.append(" Supplier<String> s1 = super::/*[1]*/method1;\n");
+ buf1.append(" Supplier<String> s2 = Sub.super::/*[2]*/<Float>method1;\n");
+ buf1.append(" Function<E5<Integer>, String> s3 = super::/*[3]*/<Float>method1;\n");
+ buf1.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E5.java", buf1.toString(), false, null);
+
+ // [1]
+ int offset= buf1.toString().indexOf("::/*[1]*/") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E5<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" <F> String method1(E5<T> e) {\n");
+ buf.append(" return \"b\";\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("class Sub extends E5<Integer> {\n");
+ buf.append(" Supplier<String> s1 = () -> super./*[1]*/method1();\n");
+ buf.append(" Supplier<String> s2 = Sub.super::/*[2]*/<Float>method1;\n");
+ buf.append(" Function<E5<Integer>, String> s3 = super::/*[3]*/<Float>method1;\n");
+ buf.append("}\n");
+ String expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [2]
+ offset= buf1.toString().indexOf("::/*[2]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E5<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" <F> String method1(E5<T> e) {\n");
+ buf.append(" return \"b\";\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("class Sub extends E5<Integer> {\n");
+ buf.append(" Supplier<String> s1 = super::/*[1]*/method1;\n");
+ buf.append(" Supplier<String> s2 = () -> Sub.super.<Float> method1();\n");
+ buf.append(" Function<E5<Integer>, String> s3 = super::/*[3]*/<Float>method1;\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [3]
+ offset= buf1.toString().indexOf("::/*[3]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E5<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" <F> String method1(E5<T> e) {\n");
+ buf.append(" return \"b\";\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("class Sub extends E5<Integer> {\n");
+ buf.append(" Supplier<String> s1 = super::/*[1]*/method1;\n");
+ buf.append(" Supplier<String> s2 = Sub.super::/*[2]*/<Float>method1;\n");
+ buf.append(" Function<E5<Integer>, String> s3 = arg0 -> super.<Float> method1(arg0);\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+ }
+
+ public void testConvertMethodReferenceToLambda6() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf1= new StringBuffer();
+ buf1.append("package test1;\n");
+ buf1.append("import java.util.function.*;\n");
+ buf1.append("public class E6<T> {\n");
+ buf1.append(" <F> String method1() {\n");
+ buf1.append(" return \"a\";\n");
+ buf1.append(" }\n");
+ buf1.append(" <F> String method1(E6<T> e) {\n");
+ buf1.append(" return \"b\";\n");
+ buf1.append(" }\n");
+ buf1.append(" Supplier<String> v1 = new E6<Integer>()::/*[1]*/method1;\n");
+ buf1.append(" Supplier<String> v2 = this::/*[2]*/<Float>method1;\n");
+ buf1.append(" Function<E6<Integer>, String> v3 = new E6<Integer>()::/*[3]*/<Float>method1;\n");
+ buf1.append(" T1[] ts = new T1[5];\n");
+ buf1.append(" BiFunction<Integer, Integer, Integer> m6 = ts[1]::/*[4]*/bar;\n");
+ buf1.append(" int[] is = new int[5];\n");
+ buf1.append(" Supplier<int[]> m10 = is::/*[5]*/clone;\n");
+ buf1.append("}\n");
+ buf1.append("class T1 {\n");
+ buf1.append(" int bar(int i, int j) { return i + j; }\n");
+ buf1.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E6.java", buf1.toString(), false, null);
+
+ // [1]
+ int offset= buf1.toString().indexOf("::/*[1]*/") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E6<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" <F> String method1(E6<T> e) {\n");
+ buf.append(" return \"b\";\n");
+ buf.append(" }\n");
+ buf.append(" Supplier<String> v1 = () -> new E6<Integer>()./*[1]*/method1();\n");
+ buf.append(" Supplier<String> v2 = this::/*[2]*/<Float>method1;\n");
+ buf.append(" Function<E6<Integer>, String> v3 = new E6<Integer>()::/*[3]*/<Float>method1;\n");
+ buf.append(" T1[] ts = new T1[5];\n");
+ buf.append(" BiFunction<Integer, Integer, Integer> m6 = ts[1]::/*[4]*/bar;\n");
+ buf.append(" int[] is = new int[5];\n");
+ buf.append(" Supplier<int[]> m10 = is::/*[5]*/clone;\n");
+ buf.append("}\n");
+ buf.append("class T1 {\n");
+ buf.append(" int bar(int i, int j) { return i + j; }\n");
+ buf.append("}\n");
+ String expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [2]
+ offset= buf1.toString().indexOf("::/*[2]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E6<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" <F> String method1(E6<T> e) {\n");
+ buf.append(" return \"b\";\n");
+ buf.append(" }\n");
+ buf.append(" Supplier<String> v1 = new E6<Integer>()::/*[1]*/method1;\n");
+ buf.append(" Supplier<String> v2 = () -> this.<Float> method1();\n");
+ buf.append(" Function<E6<Integer>, String> v3 = new E6<Integer>()::/*[3]*/<Float>method1;\n");
+ buf.append(" T1[] ts = new T1[5];\n");
+ buf.append(" BiFunction<Integer, Integer, Integer> m6 = ts[1]::/*[4]*/bar;\n");
+ buf.append(" int[] is = new int[5];\n");
+ buf.append(" Supplier<int[]> m10 = is::/*[5]*/clone;\n");
+ buf.append("}\n");
+ buf.append("class T1 {\n");
+ buf.append(" int bar(int i, int j) { return i + j; }\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [3]
+ offset= buf1.toString().indexOf("::/*[3]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E6<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" <F> String method1(E6<T> e) {\n");
+ buf.append(" return \"b\";\n");
+ buf.append(" }\n");
+ buf.append(" Supplier<String> v1 = new E6<Integer>()::/*[1]*/method1;\n");
+ buf.append(" Supplier<String> v2 = this::/*[2]*/<Float>method1;\n");
+ buf.append(" Function<E6<Integer>, String> v3 = arg0 -> new E6<Integer>().<Float> method1(arg0);\n");
+ buf.append(" T1[] ts = new T1[5];\n");
+ buf.append(" BiFunction<Integer, Integer, Integer> m6 = ts[1]::/*[4]*/bar;\n");
+ buf.append(" int[] is = new int[5];\n");
+ buf.append(" Supplier<int[]> m10 = is::/*[5]*/clone;\n");
+ buf.append("}\n");
+ buf.append("class T1 {\n");
+ buf.append(" int bar(int i, int j) { return i + j; }\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [4]
+ offset= buf1.toString().indexOf("::/*[4]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E6<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" <F> String method1(E6<T> e) {\n");
+ buf.append(" return \"b\";\n");
+ buf.append(" }\n");
+ buf.append(" Supplier<String> v1 = new E6<Integer>()::/*[1]*/method1;\n");
+ buf.append(" Supplier<String> v2 = this::/*[2]*/<Float>method1;\n");
+ buf.append(" Function<E6<Integer>, String> v3 = new E6<Integer>()::/*[3]*/<Float>method1;\n");
+ buf.append(" T1[] ts = new T1[5];\n");
+ buf.append(" BiFunction<Integer, Integer, Integer> m6 = (arg0, arg1) -> ts[1]./*[4]*/bar(arg0, arg1);\n");
+ buf.append(" int[] is = new int[5];\n");
+ buf.append(" Supplier<int[]> m10 = is::/*[5]*/clone;\n");
+ buf.append("}\n");
+ buf.append("class T1 {\n");
+ buf.append(" int bar(int i, int j) { return i + j; }\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [5]
+ offset= buf1.toString().indexOf("::/*[5]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E6<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" <F> String method1(E6<T> e) {\n");
+ buf.append(" return \"b\";\n");
+ buf.append(" }\n");
+ buf.append(" Supplier<String> v1 = new E6<Integer>()::/*[1]*/method1;\n");
+ buf.append(" Supplier<String> v2 = this::/*[2]*/<Float>method1;\n");
+ buf.append(" Function<E6<Integer>, String> v3 = new E6<Integer>()::/*[3]*/<Float>method1;\n");
+ buf.append(" T1[] ts = new T1[5];\n");
+ buf.append(" BiFunction<Integer, Integer, Integer> m6 = ts[1]::/*[4]*/bar;\n");
+ buf.append(" int[] is = new int[5];\n");
+ buf.append(" Supplier<int[]> m10 = () -> is./*[5]*/clone();\n");
+ buf.append("}\n");
+ buf.append("class T1 {\n");
+ buf.append(" int bar(int i, int j) { return i + j; }\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+ }
+
+ public void testConvertMethodReferenceToLambda7() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf1= new StringBuffer();
+ buf1.append("package test1;\n");
+ buf1.append("import java.util.function.*;\n");
+ buf1.append("public class E7<T> {\n");
+ buf1.append(" <F> String method1() {\n");
+ buf1.append(" return \"a\";\n");
+ buf1.append(" }\n");
+ buf1.append(" Function<E7<Integer>, String> v1 = E7<Integer>::/*[1]*/<Float> method1;\n");
+ buf1.append(" Function<int[], int[]> v2 = int[]::/*[2]*/clone;\n");
+ buf1.append(" BiFunction<int[], int[], Boolean> v3 = int[]::/*[3]*/equals;\n");
+ buf1.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E7.java", buf1.toString(), false, null);
+
+ // [1]
+ int offset= buf1.toString().indexOf("::/*[1]*/") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E7<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" Function<E7<Integer>, String> v1 = arg0 -> arg0.<Float> method1();\n");
+ buf.append(" Function<int[], int[]> v2 = int[]::/*[2]*/clone;\n");
+ buf.append(" BiFunction<int[], int[], Boolean> v3 = int[]::/*[3]*/equals;\n");
+ buf.append("}\n");
+ String expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [2]
+ offset= buf1.toString().indexOf("::/*[2]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E7<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" Function<E7<Integer>, String> v1 = E7<Integer>::/*[1]*/<Float> method1;\n");
+ buf.append(" Function<int[], int[]> v2 = arg0 -> arg0./*[2]*/clone();\n");
+ buf.append(" BiFunction<int[], int[], Boolean> v3 = int[]::/*[3]*/equals;\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ // [3]
+ offset= buf1.toString().indexOf("::/*[3]*/") + 1;
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("public class E7<T> {\n");
+ buf.append(" <F> String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append(" Function<E7<Integer>, String> v1 = E7<Integer>::/*[1]*/<Float> method1;\n");
+ buf.append(" Function<int[], int[]> v2 = int[]::/*[2]*/clone;\n");
+ buf.append(" BiFunction<int[], int[], Boolean> v3 = (arg0, arg1) -> arg0./*[3]*/equals(arg1);\n");
+ buf.append("}\n");
+ expected= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+ }
+
+ public void testConvertMethodReferenceToLambda8() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.*;\n");
+ buf.append("import java.util.function.Supplier;\n");
+ buf.append("public class E8 {\n");
+ buf.append(" List<String> list = new ArrayList<>();\n");
+ buf.append(" Supplier<Iterator<String>> mr = (list.size() == 5 ? list.subList(0, 3) : list)::iterator;\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E8.java", buf.toString(), false, null);
+
+ int offset= buf.toString().indexOf("::") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.*;\n");
+ buf.append("import java.util.function.Supplier;\n");
+ buf.append("public class E8 {\n");
+ buf.append(" List<String> list = new ArrayList<>();\n");
+ buf.append(" Supplier<Iterator<String>> mr = () -> (list.size() == 5 ? list.subList(0, 3) : list).iterator();\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+ }
+
+ public void testConvertMethodReferenceToLambda9() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public class E9 {\n");
+ buf.append(" private void test(int t) {\n");
+ buf.append(" FI t1= E9::bar;\n");
+ buf.append(" }\n");
+ buf.append(" private static void bar(int x, int y, int z) {}\n");
+ buf.append("}\n");
+ buf.append("interface FI {\n");
+ buf.append(" void foo(int t, int t1, int t2);\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E9.java", buf.toString(), false, null);
+
+ int offset= buf.toString().indexOf("::") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("public class E9 {\n");
+ buf.append(" private void test(int t) {\n");
+ buf.append(" FI t1= (t3, t11, t2) -> E9.bar(t3, t11, t2);\n");
+ buf.append(" }\n");
+ buf.append(" private static void bar(int x, int y, int z) {}\n");
+ buf.append("}\n");
+ buf.append("interface FI {\n");
+ buf.append(" void foo(int t, int t1, int t2);\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+ }
+
+ public void testConvertMethodReferenceToLambda10() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.lang.annotation.*;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("\n");
+ buf.append("@Target(ElementType.TYPE_USE)\n");
+ buf.append("@interface Great {}\n");
+ buf.append("\n");
+ buf.append("public class E10 {\n");
+ buf.append(" LongSupplier foo() {\n");
+ buf.append(" return @Great System::currentTimeMillis;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E10.java", buf.toString(), false, null);
+
+ int offset= buf.toString().indexOf("::") + 1;
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.lang.annotation.*;\n");
+ buf.append("import java.util.function.*;\n");
+ buf.append("\n");
+ buf.append("@Target(ElementType.TYPE_USE)\n");
+ buf.append("@interface Great {}\n");
+ buf.append("\n");
+ buf.append("public class E10 {\n");
+ buf.append(" LongSupplier foo() {\n");
+ buf.append(" return () -> System.currentTimeMillis();\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+ }
+
+ public void testConvertLambdaToMethodReference1() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.BiFunction;\n");
+ buf.append("import java.util.function.Consumer;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("import java.util.function.IntFunction;\n");
+ buf.append("import java.util.function.Supplier;\n");
+ buf.append("public class E1 extends E {\n");
+ buf.append(" Supplier<String> a1= () ->/*[1]*/ {\n");
+ buf.append(" String s = \"\";\n");
+ buf.append(" return s;\n");
+ buf.append(" };\n");
+ buf.append(" Consumer<String> a2= s ->/*[2]*/ {\n");
+ buf.append(" return;\n");
+ buf.append(" };\n");
+ buf.append("\n");
+ buf.append(" Supplier<E1.In> a3= () ->/*[3]*/ (new E1()).new In();\n");
+ buf.append(" Supplier<E1> a4= () ->/*[4]*/ new E1() {\n");
+ buf.append(" void test() {\n");
+ buf.append(" System.out.println(\"hey\");\n");
+ buf.append(" }\n");
+ buf.append(" };\n");
+ buf.append(" Function<String, Integer> a5= s ->/*[5]*/ new Integer(s+1);\n");
+ buf.append("\n");
+ buf.append(" BiFunction<Integer, Integer, int[][][]> a6 = (a, b) ->/*[6]*/ new int[a][b][];\n");
+ buf.append(" IntFunction<Integer[][][]> a61 = value ->/*[61]*/ new Integer[][][] {{{7, 8}}};\n");
+ buf.append(" Function<Integer, int[]> a7 = t ->/*[7]*/ new int[100];\n");
+ buf.append("\n");
+ buf.append(" BiFunction<Character, Integer, String> a8 = (c, i) ->/*[8]*/ super.method1();\n");
+ buf.append(" BiFunction<Character, Integer, String> a9 = (c, i) ->/*[9]*/ method1();\n");
+ buf.append(" \n");
+ buf.append(" class In {}\n");
+ buf.append("}\n");
+ buf.append("class E {\n");
+ buf.append(" String method1() {\n");
+ buf.append(" return \"a\";\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E1.java", buf.toString(), false, null);
+
+ int offset= buf.toString().indexOf("->/*[1]*/");
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[2]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[3]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[4]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 2);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[5]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[6]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[61]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[7]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[8]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf.toString().indexOf("->/*[9]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+ }
+
+ public void testConvertLambdaToMethodReference2() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf1= new StringBuffer();
+ buf1.append("package test1;\n");
+ buf1.append("import java.util.function.Function;\n");
+ buf1.append("public class E2<T> {\n");
+ buf1.append(" public <A> E2(A a) {}\n");
+ buf1.append(" public E2(String s) {}\n");
+ buf1.append(" \n");
+ buf1.append(" Function<T, E2<Integer>> a1 = t ->/*[1]*/ (new<T> E2<Integer>(t));\n");
+ buf1.append(" Function<String, E2<Integer>> a2 = t ->/*[2]*/ new E2<>(t);\n");
+ buf1.append(" \n");
+ buf1.append(" Function<Integer, Float[]> a3 = t ->/*[3]*/ new Float[t];\n");
+ buf1.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E2.java", buf1.toString(), false, null);
+
+ int offset= buf1.toString().indexOf("->/*[1]*/");
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E2<T> {\n");
+ buf.append(" public <A> E2(A a) {}\n");
+ buf.append(" public E2(String s) {}\n");
+ buf.append(" \n");
+ buf.append(" Function<T, E2<Integer>> a1 = E2<Integer>::<T> new;\n");
+ buf.append(" Function<String, E2<Integer>> a2 = t ->/*[2]*/ new E2<>(t);\n");
+ buf.append(" \n");
+ buf.append(" Function<Integer, Float[]> a3 = t ->/*[3]*/ new Float[t];\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("->/*[2]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E2<T> {\n");
+ buf.append(" public <A> E2(A a) {}\n");
+ buf.append(" public E2(String s) {}\n");
+ buf.append(" \n");
+ buf.append(" Function<T, E2<Integer>> a1 = t ->/*[1]*/ (new<T> E2<Integer>(t));\n");
+ buf.append(" Function<String, E2<Integer>> a2 = E2::new;\n");
+ buf.append(" \n");
+ buf.append(" Function<Integer, Float[]> a3 = t ->/*[3]*/ new Float[t];\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("->/*[3]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E2<T> {\n");
+ buf.append(" public <A> E2(A a) {}\n");
+ buf.append(" public E2(String s) {}\n");
+ buf.append(" \n");
+ buf.append(" Function<T, E2<Integer>> a1 = t ->/*[1]*/ (new<T> E2<Integer>(t));\n");
+ buf.append(" Function<String, E2<Integer>> a2 = t ->/*[2]*/ new E2<>(t);\n");
+ buf.append(" \n");
+ buf.append(" Function<Integer, Float[]> a3 = Float[]::new;\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+ }
+
+ public void testConvertLambdaToMethodReference3() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf1= new StringBuffer();
+ buf1.append("package test1;\n");
+ buf1.append("import java.util.function.Function;\n");
+ buf1.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf1.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf1.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf1.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf1.append("\n");
+ buf1.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf1.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf1.append("\n");
+ buf1.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf1.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf1.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf1.append("\n");
+ buf1.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf1.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf1.append("\n");
+ buf1.append(" <V> String method2() { return \"m2\"; }\n");
+ buf1.append("}\n");
+ buf1.append("class SuperE3<S> {\n");
+ buf1.append(" String method1(int i) { return \"m1\"; }\n");
+ buf1.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf1.append("}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E3.java", buf1.toString(), false, null);
+
+ int offset= buf1.toString().indexOf("-> /*[1]*/");
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = super::method1;\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ String expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[2]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = E3.super::method1;\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[3]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = SuperE3::<Float> staticMethod1;\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[4]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = E3::staticMethod1;\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[5]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = E3::staticMethod1;\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[6]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = this::method1;\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[7]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = this::method1;\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[8]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = (new SuperE3<String>())::method1;\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[9]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = E3<Integer>::<Float> method2;\n");
+ buf.append(" Function<E3, String> p2 = t -> /*[10]*/t.method2();\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("-> /*[10]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E3<T> extends SuperE3<Number> {\n");
+ buf.append(" Function<Integer, String> a1 = t -> /*[1]*/super.method1(t);\n");
+ buf.append(" Function<Integer, String> a2 = t -> /*[2]*/E3.super.method1(t);\n");
+ buf.append(" Function<Integer, String> a3 = t -> /*[3]*/super.<Float> staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> s1 = t -> /*[4]*/(new E3()).staticMethod1(t);\n");
+ buf.append(" Function<Integer, String> s2 = t -> /*[5]*/staticMethod1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<Integer, String> b1 = t -> /*[6]*/method1(t);\n");
+ buf.append(" Function<Integer, String> b2 = t -> /*[7]*/this.method1(t);\n");
+ buf.append(" Function<Integer, String> b3 = t -> /*[8]*/(new SuperE3<String>()).method1(t);\n");
+ buf.append("\n");
+ buf.append(" Function<E3<Integer>, String> p1 = t -> /*[9]*/t.<Float> method2();\n");
+ buf.append(" Function<E3, String> p2 = E3::method2;\n");
+ buf.append("\n");
+ buf.append(" <V> String method2() { return \"m2\"; }\n");
+ buf.append("}\n");
+ buf.append("class SuperE3<S> {\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" static <V> String staticMethod1(int i) { return \"s\"; }\n");
+ buf.append("}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+ }
+
+ public void testConvertLambdaToMethodReference4() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ StringBuffer buf1= new StringBuffer();
+ buf1.append("package test1;\n");
+ buf1.append("import java.util.function.BiFunction;\n");
+ buf1.append("import java.util.function.Function;\n");
+ buf1.append("public class E4 {\n");
+ buf1.append(" static String staticMethod1() { return \"s\"; }\n");
+ buf1.append(" Function<E4, String> s1 = t ->/*[1]*/ staticMethod1();\n");
+ buf1.append(" \n");
+ buf1.append(" int myVal= 0;\n");
+ buf1.append(" String method1(int i) { return \"m1\"; }\n");
+ buf1.append(" BiFunction<Float, Integer, String> p1 = (t, u) ->/*[2]*/ method1(u);\n");
+ buf1.append(" BiFunction<SubE4, Integer, String> p2 = (t, u) ->/*[3]*/ method1(u);\n");
+ buf1.append(" \n");
+ buf1.append(" BiFunction<SubE4, Integer, String> p3 = (t, u) ->/*[4]*/ t.method1(u);\n");
+ buf1.append(" BiFunction<E4, Integer, String> p4 = (t, u) ->/*[5]*/ t.method1(u);\n");
+ buf1.append(" \n");
+ buf1.append(" Function<int[], int[]> a1 = t ->/*[6]*/ t.clone();\n");
+ buf1.append("}\n");
+ buf1.append("class SubE4 extends E4 {}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("E4.java", buf1.toString(), false, null);
+
+ int offset= buf1.toString().indexOf("->/*[1]*/");
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf1.toString().indexOf("->/*[2]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf1.toString().indexOf("->/*[3]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 3);
+ assertCorrectLabels(proposals);
+ assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_method_reference);
+
+ offset= buf1.toString().indexOf("->/*[4]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.BiFunction;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E4 {\n");
+ buf.append(" static String staticMethod1() { return \"s\"; }\n");
+ buf.append(" Function<E4, String> s1 = t ->/*[1]*/ staticMethod1();\n");
+ buf.append(" \n");
+ buf.append(" int myVal= 0;\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" BiFunction<Float, Integer, String> p1 = (t, u) ->/*[2]*/ method1(u);\n");
+ buf.append(" BiFunction<SubE4, Integer, String> p2 = (t, u) ->/*[3]*/ method1(u);\n");
+ buf.append(" \n");
+ buf.append(" BiFunction<SubE4, Integer, String> p3 = SubE4::method1;\n");
+ buf.append(" BiFunction<E4, Integer, String> p4 = (t, u) ->/*[5]*/ t.method1(u);\n");
+ buf.append(" \n");
+ buf.append(" Function<int[], int[]> a1 = t ->/*[6]*/ t.clone();\n");
+ buf.append("}\n");
+ buf.append("class SubE4 extends E4 {}\n");
+ String expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("->/*[5]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.BiFunction;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E4 {\n");
+ buf.append(" static String staticMethod1() { return \"s\"; }\n");
+ buf.append(" Function<E4, String> s1 = t ->/*[1]*/ staticMethod1();\n");
+ buf.append(" \n");
+ buf.append(" int myVal= 0;\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" BiFunction<Float, Integer, String> p1 = (t, u) ->/*[2]*/ method1(u);\n");
+ buf.append(" BiFunction<SubE4, Integer, String> p2 = (t, u) ->/*[3]*/ method1(u);\n");
+ buf.append(" \n");
+ buf.append(" BiFunction<SubE4, Integer, String> p3 = (t, u) ->/*[4]*/ t.method1(u);\n");
+ buf.append(" BiFunction<E4, Integer, String> p4 = E4::method1;\n");
+ buf.append(" \n");
+ buf.append(" Function<int[], int[]> a1 = t ->/*[6]*/ t.clone();\n");
+ buf.append("}\n");
+ buf.append("class SubE4 extends E4 {}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+ offset= buf1.toString().indexOf("->/*[6]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+ assertNumberOfProposals(proposals, 4);
+ assertCorrectLabels(proposals);
+ buf= new StringBuffer();
+ buf.append("package test1;\n");
+ buf.append("import java.util.function.BiFunction;\n");
+ buf.append("import java.util.function.Function;\n");
+ buf.append("public class E4 {\n");
+ buf.append(" static String staticMethod1() { return \"s\"; }\n");
+ buf.append(" Function<E4, String> s1 = t ->/*[1]*/ staticMethod1();\n");
+ buf.append(" \n");
+ buf.append(" int myVal= 0;\n");
+ buf.append(" String method1(int i) { return \"m1\"; }\n");
+ buf.append(" BiFunction<Float, Integer, String> p1 = (t, u) ->/*[2]*/ method1(u);\n");
+ buf.append(" BiFunction<SubE4, Integer, String> p2 = (t, u) ->/*[3]*/ method1(u);\n");
+ buf.append(" \n");
+ buf.append(" BiFunction<SubE4, Integer, String> p3 = (t, u) ->/*[4]*/ t.method1(u);\n");
+ buf.append(" BiFunction<E4, Integer, String> p4 = (t, u) ->/*[5]*/ t.method1(u);\n");
+ buf.append(" \n");
+ buf.append(" Function<int[], int[]> a1 = int[]::clone;\n");
+ buf.append("}\n");
+ buf.append("class SubE4 extends E4 {}\n");
+ expected1= buf.toString();
+ assertExpectedExistInProposals(proposals, new String[] { expected1 });
+ }
}
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java
index 3cb6db497a..00d83f2580 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java
@@ -691,32 +691,7 @@ public class ASTNodes {
if (methodBinding != null) {
ITypeBinding invocationTargetType;
- if (parent instanceof MethodInvocation || parent instanceof SuperMethodInvocation) {
- if (invocationQualifier != null) {
- invocationTargetType= invocationQualifier.resolveTypeBinding();
- if (invocationTargetType != null && parent instanceof SuperMethodInvocation) {
- invocationTargetType= invocationTargetType.getSuperclass();
- }
- } else {
- ITypeBinding enclosingType= getEnclosingType(parent);
- if (enclosingType != null && parent instanceof SuperMethodInvocation) {
- enclosingType= enclosingType.getSuperclass();
- }
- if (enclosingType != null) {
- IMethodBinding methodInHierarchy= Bindings.findMethodInHierarchy(enclosingType, methodBinding.getName(), methodBinding.getParameterTypes());
- if (methodInHierarchy != null) {
- invocationTargetType= enclosingType;
- } else {
- invocationTargetType= methodBinding.getDeclaringClass();
- }
- } else {
- // not expected
- invocationTargetType= methodBinding.getDeclaringClass();
- }
- }
- } else {
- invocationTargetType= methodBinding.getDeclaringClass();
- }
+ invocationTargetType= getInvocationType(parent, methodBinding, invocationQualifier);
if (invocationTargetType != null) {
TypeBindingVisitor visitor= new AmbiguousTargetMethodAnalyzer(invocationTargetType, methodBinding, argumentIndex, argumentCount, expressionIsExplicitlyTyped);
return !(visitor.visit(invocationTargetType) && Bindings.visitHierarchy(invocationTargetType, visitor));
@@ -726,6 +701,47 @@ public class ASTNodes {
return true;
}
+ /**
+ * Returns the binding of the type which declares the method being invoked.
+ *
+ * @param invocationNode the method invocation node
+ * @param methodBinding binding of the method being invoked
+ * @param invocationQualifier the qualifier used for method invocation, or <code>null</code> if
+ * none
+ * @return the binding of the type which declares the method being invoked, or <code>null</code>
+ * if the type cannot be resolved
+ */
+ public static ITypeBinding getInvocationType(ASTNode invocationNode, IMethodBinding methodBinding, Expression invocationQualifier) {
+ ITypeBinding invocationType;
+ if (invocationNode instanceof MethodInvocation || invocationNode instanceof SuperMethodInvocation) {
+ if (invocationQualifier != null) {
+ invocationType= invocationQualifier.resolveTypeBinding();
+ if (invocationType != null && invocationNode instanceof SuperMethodInvocation) {
+ invocationType= invocationType.getSuperclass();
+ }
+ } else {
+ ITypeBinding enclosingType= getEnclosingType(invocationNode);
+ if (enclosingType != null && invocationNode instanceof SuperMethodInvocation) {
+ enclosingType= enclosingType.getSuperclass();
+ }
+ if (enclosingType != null) {
+ IMethodBinding methodInHierarchy= Bindings.findMethodInHierarchy(enclosingType, methodBinding.getName(), methodBinding.getParameterTypes());
+ if (methodInHierarchy != null) {
+ invocationType= enclosingType;
+ } else {
+ invocationType= methodBinding.getDeclaringClass();
+ }
+ } else {
+ // not expected
+ invocationType= methodBinding.getDeclaringClass();
+ }
+ }
+ } else {
+ invocationType= methodBinding.getDeclaringClass();
+ }
+ return invocationType;
+ }
+
private static class AmbiguousTargetMethodAnalyzer implements TypeBindingVisitor {
private ITypeBinding fDeclaringType;
private IMethodBinding fOriginalMethod;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
index 1c10ed4d97..d19910ce6c 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
@@ -47,11 +47,13 @@ public final class CorrectionMessages extends NLS {
public static String QuickAssistProcessor_convert_local_to_field_description;
public static String QuickAssistProcessor_convert_to_indexed_for_loop;
public static String QuickAssistProcessor_convert_to_iterator_for_loop;
+ public static String QuickAssistProcessor_convert_to_lambda_expression;
public static String QuickAssistProcessor_generate_enhanced_for_loop;
public static String QuickAssistProcessor_generate_iterator_for_loop;
public static String QuickAssistProcessor_generate_for_loop;
public static String QuickAssistProcessor_generate_index_for_loop;
public static String QuickAssistProcessor_convert_to_message_format;
+ public static String QuickAssistProcessor_convert_to_method_reference;
public static String QuickAssistProcessor_convert_to_multiple_singletype_catch_blocks;
public static String QuickAssistProcessor_convert_to_single_multicatch_block;
public static String QuickAssistProcessor_convert_to_string_buffer_description;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
index 219f42106c..4017bec53a 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
@@ -347,11 +347,13 @@ QuickAssistProcessor_typetoarrayInitializer_description=Add type to initializer
QuickAssistProcessor_convert_local_to_field_description=Convert local variable to field
QuickAssistProcessor_convert_to_indexed_for_loop=Convert to 'for' loop using index
QuickAssistProcessor_convert_to_iterator_for_loop=Convert to 'for' loop using Iterator
+QuickAssistProcessor_convert_to_lambda_expression=Convert to lambda expression
QuickAssistProcessor_generate_enhanced_for_loop=Create enhanced 'for' loop
QuickAssistProcessor_generate_iterator_for_loop=Create 'for' loop using Iterator
QuickAssistProcessor_generate_for_loop=Create 'for' loop
QuickAssistProcessor_generate_index_for_loop=Create 'for' loop using index
QuickAssistProcessor_convert_to_message_format=Use 'MessageFormat' for string concatenation
+QuickAssistProcessor_convert_to_method_reference=Convert to method reference
QuickAssistProcessor_convert_to_multiple_singletype_catch_blocks=Use separate catch blocks
QuickAssistProcessor_convert_to_single_multicatch_block=Combine catch blocks
QuickAssistProcessor_convert_to_string_buffer_description=Use ''{0}'' for string concatenation
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java
index d9f0fca11d..56723e3965 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java
@@ -126,6 +126,8 @@ public interface IProposalRelevance {
public static final int CHANGE_TO_ATTRIBUTE_SIMILAR_NAME= 6;
public static final int CREATE_FIELD= 6;
public static final int CONVERT_TO_LAMBDA_EXPRESSION= 6;
+ public static final int CONVERT_METHOD_REFERENCE_TO_LAMBDA= 6;
+ public static final int CONVERT_TO_METHOD_REFERENCE= 6;
public static final int ADD_ALL_MISSING_TAGS= 5;
public static final int QUALIFY_INNER_TYPE_NAME= 5;
@@ -290,7 +292,7 @@ public interface IProposalRelevance {
public static final int ADD_PARANOIDAL_PARENTHESES= -9;
public static final int ADD_PARENTHESES_FOR_EXPRESSION= -10;
-
+
//Be careful while tweaking these values because WordCorrectionProposal uses -distance (between the words) as relevance.
public static final int DISABLE_SPELL_CHECKING= Integer.MIN_VALUE + 1;
public static final int WORD_IGNORE= Integer.MIN_VALUE + 1;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
index 4c8b230cba..d4d0df9523 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
@@ -42,6 +42,7 @@ import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
@@ -63,10 +64,12 @@ import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConditionalExpression;
+import org.eclipse.jdt.core.dom.CreationReference;
import org.eclipse.jdt.core.dom.Dimension;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.ExpressionMethodReference;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.ForStatement;
@@ -81,6 +84,7 @@ import org.eclipse.jdt.core.dom.LabeledStatement;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.MethodReference;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NameQualifiedType;
@@ -99,6 +103,7 @@ import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.SuperMethodReference;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.SynchronizedStatement;
@@ -106,6 +111,7 @@ import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.core.dom.TryStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.TypeMethodReference;
import org.eclipse.jdt.core.dom.UnionType;
import org.eclipse.jdt.core.dom.VariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
@@ -123,6 +129,7 @@ import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.DimensionRewrite;
+import org.eclipse.jdt.internal.corext.dom.JdtASTMatcher;
import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder;
import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
import org.eclipse.jdt.internal.corext.dom.Selection;
@@ -236,6 +243,8 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
|| getChangeLambdaBodyToBlockProposal(context, coveringNode, null)
|| getChangeLambdaBodyToExpressionProposal(context, coveringNode, null)
|| getAddInferredLambdaParameterTypes(context, coveringNode, null)
+ || getConvertMethodReferenceToLambdaProposal(context, coveringNode, null)
+ || getConvertLambdaToMethodReferenceProposal(context, coveringNode, null)
|| getRemoveBlockProposals(context, coveringNode, null)
|| getMakeVariableDeclarationFinalProposals(context, null)
|| getMissingCaseStatementProposals(context, coveringNode, null)
@@ -285,6 +294,8 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
getChangeLambdaBodyToBlockProposal(context, coveringNode, resultingCollections);
getChangeLambdaBodyToExpressionProposal(context, coveringNode, resultingCollections);
getAddInferredLambdaParameterTypes(context, coveringNode, resultingCollections);
+ getConvertMethodReferenceToLambdaProposal(context, coveringNode, resultingCollections);
+ getConvertLambdaToMethodReferenceProposal(context, coveringNode, resultingCollections);
if (!getConvertForLoopProposal(context, coveringNode, resultingCollections))
getConvertIterableLoopProposal(context, coveringNode, resultingCollections);
getConvertEnhancedForLoopProposal(context, coveringNode, resultingCollections);
@@ -595,6 +606,219 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
return true;
}
+ private static boolean getConvertMethodReferenceToLambdaProposal(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) throws JavaModelException {
+ MethodReference methodReference;
+ if (covering instanceof MethodReference) {
+ methodReference= (MethodReference) covering;
+ } else if (covering.getParent() instanceof MethodReference) {
+ methodReference= (MethodReference) covering.getParent();
+ } else {
+ return false;
+ }
+
+ IMethodBinding referredMethodBinding= methodReference.resolveMethodBinding();
+ if (referredMethodBinding == null && !(methodReference instanceof CreationReference))
+ return false;
+
+ ITypeBinding targetTypeBinding= ASTNodes.getTargetType(methodReference);
+ if (targetTypeBinding == null)
+ return false;
+
+ IMethodBinding functionalMethod= targetTypeBinding.getFunctionalInterfaceMethod();
+ if (functionalMethod.isSynthetic()) {
+ functionalMethod= Bindings.findOverriddenMethodInType(functionalMethod.getDeclaringClass(), functionalMethod);
+ }
+ if (functionalMethod == null)
+ return false;
+ if (functionalMethod.isGenericMethod()) // generic lambda expressions are not allowed
+ return false;
+
+ if (resultingCollections == null)
+ return true;
+
+ AST ast= methodReference.getAST();
+ ASTRewrite rewrite= ASTRewrite.create(ast);
+ ImportRewrite importRewrite= null;
+ LambdaExpression lambda= ast.newLambdaExpression();
+
+ String[] lambdaParamNames= getUniqueParameterNames(methodReference, functionalMethod);
+ List<VariableDeclaration> lambdaParameters= lambda.parameters();
+ for (String paramName : lambdaParamNames) {
+ VariableDeclarationFragment lambdaParameter= ast.newVariableDeclarationFragment();
+ lambdaParameter.setName(ast.newSimpleName(paramName));
+ lambdaParameters.add(lambdaParameter);
+ }
+
+ int noOfLambdaParameters= lambdaParamNames.length;
+ lambda.setParentheses(noOfLambdaParameters != 1);
+
+ if (methodReference instanceof CreationReference) {
+ CreationReference creationRef= (CreationReference) methodReference;
+ Type type= creationRef.getType();
+ if (type instanceof ArrayType) {
+ ArrayCreation arrayCreation= ast.newArrayCreation();
+ lambda.setBody(arrayCreation);
+
+ ArrayType arrayType= (ArrayType) type;
+ Type copiedElementType= (Type) rewrite.createCopyTarget(arrayType.getElementType());
+ arrayCreation.setType(ast.newArrayType(copiedElementType, arrayType.getDimensions()));
+ arrayCreation.dimensions().add(ast.newSimpleName(lambdaParamNames[0]));
+ } else {
+ ClassInstanceCreation cic= ast.newClassInstanceCreation();
+ lambda.setBody(cic);
+
+ ITypeBinding typeBinding= type.resolveBinding();
+ if (!(type instanceof ParameterizedType) && typeBinding != null && typeBinding.getTypeDeclaration().isGenericType()) {
+ cic.setType(ast.newParameterizedType((Type) rewrite.createCopyTarget(type)));
+ } else {
+ cic.setType((Type) rewrite.createCopyTarget(type));
+ }
+ cic.arguments().addAll(getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames));
+ cic.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
+ }
+
+ } else if (Modifier.isStatic(referredMethodBinding.getModifiers()) && !referredMethodBinding.isSynthetic()) { // TODO: Remove #isSynthetic check after bug 440344 is fixed (eg: int[]::clone)
+ MethodInvocation methodInvocation= ast.newMethodInvocation();
+ lambda.setBody(methodInvocation);
+
+ Expression expr= null;
+ if (methodReference instanceof ExpressionMethodReference) {
+ ExpressionMethodReference expressionMethodReference= (ExpressionMethodReference) methodReference;
+ expr= (Expression) rewrite.createCopyTarget(expressionMethodReference.getExpression());
+ } else if (methodReference instanceof TypeMethodReference) {
+ Type type= ((TypeMethodReference) methodReference).getType();
+ ITypeBinding typeBinding= type.resolveBinding();
+ if (typeBinding != null) {
+ importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true);
+ expr= ast.newName(importRewrite.addImport(typeBinding));
+ }
+ }
+ if (expr == null) {
+ return false;
+ }
+ methodInvocation.setExpression(expr);
+ SimpleName name= getMethodInvocationName(methodReference);
+ methodInvocation.setName((SimpleName) rewrite.createCopyTarget(name));
+ methodInvocation.arguments().addAll(getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames));
+ methodInvocation.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
+
+ } else if (methodReference instanceof SuperMethodReference) {
+ SuperMethodInvocation superMethodInvocation= ast.newSuperMethodInvocation();
+ lambda.setBody(superMethodInvocation);
+
+ Name superQualifier= ((SuperMethodReference) methodReference).getQualifier();
+ if (superQualifier != null) {
+ superMethodInvocation.setQualifier((Name) rewrite.createCopyTarget(superQualifier));
+ }
+ SimpleName name= getMethodInvocationName(methodReference);
+ superMethodInvocation.setName((SimpleName) rewrite.createCopyTarget(name));
+ superMethodInvocation.arguments().addAll(getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames));
+ superMethodInvocation.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
+
+ } else {
+ MethodInvocation methodInvocation= ast.newMethodInvocation();
+ lambda.setBody(methodInvocation);
+
+ boolean isTypeReference= isTypeReferenceToInstanceMethod(methodReference);
+ if (isTypeReference) {
+ methodInvocation.setExpression(ast.newSimpleName(lambdaParamNames[0]));
+ } else {
+ Expression expr= ((ExpressionMethodReference) methodReference).getExpression();
+ methodInvocation.setExpression((Expression) rewrite.createCopyTarget(expr));
+ }
+ SimpleName name= getMethodInvocationName(methodReference);
+ methodInvocation.setName((SimpleName) rewrite.createCopyTarget(name));
+ methodInvocation.arguments().addAll(getInvocationArguments(ast, isTypeReference ? 1 : 0, noOfLambdaParameters, lambdaParamNames));
+ methodInvocation.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
+ }
+
+ rewrite.replace(methodReference, lambda, null);
+
+ // add proposal
+ String label= CorrectionMessages.QuickAssistProcessor_convert_to_lambda_expression;
+ Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+ ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.CONVERT_METHOD_REFERENCE_TO_LAMBDA, image);
+ if (importRewrite != null) {
+ proposal.setImportRewrite(importRewrite);
+ }
+ resultingCollections.add(proposal);
+ return true;
+ }
+
+ private static String[] getUniqueParameterNames(MethodReference methodReference, IMethodBinding functionalMethod) throws JavaModelException {
+ String[] parameterNames= ((IMethod) functionalMethod.getJavaElement()).getParameterNames();
+ List<String> oldNames= new ArrayList<String>(Arrays.asList(parameterNames));
+ String[] newNames= new String[oldNames.size()];
+ List<String> excludedNames= new ArrayList<String>(ASTNodes.getVisibleLocalVariablesInScope(methodReference));
+
+ for (int i= 0; i < oldNames.size(); i++) {
+ String paramName= oldNames.get(i);
+ List<String> allNamesToExclude= new ArrayList<String>(excludedNames);
+ allNamesToExclude.addAll(oldNames.subList(0, i));
+ allNamesToExclude.addAll(oldNames.subList(i + 1, oldNames.size()));
+ if (allNamesToExclude.contains(paramName)) {
+ String newParamName= createName(paramName, allNamesToExclude);
+ excludedNames.add(newParamName);
+ newNames[i]= newParamName;
+ } else {
+ newNames[i]= paramName;
+ }
+ }
+ return newNames;
+ }
+
+ private static String createName(String candidate, List<String> excludedNames) {
+ int i= 1;
+ String result= candidate;
+ while (excludedNames.contains(result)) {
+ result= candidate + i++;
+ }
+ return result;
+ }
+
+ private static boolean isTypeReferenceToInstanceMethod(MethodReference methodReference) {
+ if (methodReference instanceof TypeMethodReference)
+ return true;
+ if (methodReference instanceof ExpressionMethodReference) {
+ Expression expression= ((ExpressionMethodReference) methodReference).getExpression();
+ if (expression instanceof Name) {
+ IBinding nameBinding= ((Name) expression).resolveBinding();
+ if (nameBinding != null && nameBinding instanceof ITypeBinding) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static List<SimpleName> getInvocationArguments(AST ast, int begIndex, int noOfLambdaParameters, String[] lambdaParamNames) {
+ List<SimpleName> args= new ArrayList<SimpleName>();
+ for (int i= begIndex; i < noOfLambdaParameters; i++) {
+ args.add(ast.newSimpleName(lambdaParamNames[i]));
+ }
+ return args;
+ }
+
+ private static List<Type> getCopiedTypeArguments(ASTRewrite rewrite, List<Type> typeArguments) {
+ List<Type> copiedTypeArgs= new ArrayList<Type>();
+ for (Type typeArg : typeArguments) {
+ copiedTypeArgs.add((Type) rewrite.createCopyTarget(typeArg));
+ }
+ return copiedTypeArgs;
+ }
+
+ private static SimpleName getMethodInvocationName(MethodReference methodReference) {
+ SimpleName name= null;
+ if (methodReference instanceof ExpressionMethodReference) {
+ name= ((ExpressionMethodReference) methodReference).getName();
+ } else if (methodReference instanceof TypeMethodReference) {
+ name= ((TypeMethodReference) methodReference).getName();
+ } else if (methodReference instanceof SuperMethodReference) {
+ name= ((SuperMethodReference) methodReference).getName();
+ }
+ return name;
+ }
+
private static boolean getChangeLambdaBodyToBlockProposal(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
LambdaExpression lambda;
if (covering instanceof LambdaExpression) {
@@ -653,26 +877,10 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
return false;
Block lambdaBody= (Block) lambda.getBody();
- if (lambdaBody.statements().size() != 1)
- return false;
- Expression exprBody;
- Statement singleStatement= (Statement) lambdaBody.statements().get(0);
- if (singleStatement instanceof ReturnStatement) {
- Expression returnExpr= ((ReturnStatement) singleStatement).getExpression();
- if (returnExpr == null)
- return false;
- exprBody= returnExpr;
- } else if (singleStatement instanceof ExpressionStatement) {
- Expression expression= ((ExpressionStatement) singleStatement).getExpression();
- if (isValidExpressionBody(expression)) {
- exprBody= expression;
- } else {
- return false;
- }
- } else {
+ Expression exprBody= getExpressionFromLambdaBody(lambdaBody);
+ if (exprBody == null)
return false;
- }
if (resultingCollections == null)
return true;
@@ -691,21 +899,234 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
return true;
}
+ private static Expression getExpressionFromLambdaBody(Block lambdaBody) {
+ if (lambdaBody.statements().size() != 1)
+ return null;
+ Statement singleStatement= (Statement) lambdaBody.statements().get(0);
+ if (singleStatement instanceof ReturnStatement) {
+ return ((ReturnStatement) singleStatement).getExpression();
+ } else if (singleStatement instanceof ExpressionStatement) {
+ Expression expression= ((ExpressionStatement) singleStatement).getExpression();
+ if (isValidExpressionBody(expression)) {
+ return expression;
+ }
+ }
+ return null;
+ }
+
private static boolean isValidExpressionBody(Expression expression) {
- boolean isValidExpressionBody= expression instanceof Assignment
+ if (expression instanceof Assignment
|| expression instanceof ClassInstanceCreation
|| expression instanceof MethodInvocation
|| expression instanceof PostfixExpression
- || expression instanceof SuperMethodInvocation;
+ || expression instanceof SuperMethodInvocation) {
+ return true;
+ }
if (expression instanceof PrefixExpression) {
Operator operator= ((PrefixExpression) expression).getOperator();
if (operator == Operator.INCREMENT || operator == Operator.DECREMENT) {
- isValidExpressionBody= true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean getConvertLambdaToMethodReferenceProposal(IInvocationContext context, ASTNode coveringNode, Collection<ICommandAccess> resultingCollections) {
+ LambdaExpression lambda;
+ if (coveringNode instanceof LambdaExpression) {
+ lambda= (LambdaExpression) coveringNode;
+ } else if (coveringNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY) {
+ lambda= (LambdaExpression) coveringNode.getParent();
+ } else {
+ return false;
+ }
+
+ ASTNode lambdaBody= lambda.getBody();
+ Expression exprBody;
+ if (lambdaBody instanceof Block) {
+ exprBody= getExpressionFromLambdaBody((Block) lambdaBody);
+ } else {
+ exprBody= (Expression) lambdaBody;
+ }
+ while (exprBody instanceof ParenthesizedExpression) {
+ exprBody= ((ParenthesizedExpression) exprBody).getExpression();
+ }
+ if (exprBody == null || !isValidReferenceToMethod(exprBody))
+ return false;
+
+ List<Expression> lambdaParameters= new ArrayList<Expression>();
+ for (VariableDeclaration param : (List<VariableDeclaration>) lambda.parameters()) {
+ lambdaParameters.add(param.getName());
+ }
+ if (exprBody instanceof ClassInstanceCreation) {
+ ClassInstanceCreation cic= (ClassInstanceCreation) exprBody;
+ if (cic.getExpression() != null || cic.getAnonymousClassDeclaration() != null)
+ return false;
+ if (!matches(lambdaParameters, cic.arguments()))
+ return false;
+ } else if (exprBody instanceof ArrayCreation) {
+ List<Expression> dimensions= ((ArrayCreation) exprBody).dimensions();
+ if (dimensions.size() != 1)
+ return false;
+ if (!matches(lambdaParameters, dimensions))
+ return false;
+ } else if (exprBody instanceof SuperMethodInvocation) {
+ SuperMethodInvocation superMethodInvocation= (SuperMethodInvocation) exprBody;
+ IMethodBinding methodBinding= superMethodInvocation.resolveMethodBinding();
+ if (methodBinding == null)
+ return false;
+ if (Modifier.isStatic(methodBinding.getModifiers())) {
+ ITypeBinding invocationTypeBinding= ASTNodes.getInvocationType(superMethodInvocation, methodBinding, superMethodInvocation.getQualifier());
+ if (invocationTypeBinding == null)
+ return false;
+ }
+ if (!matches(lambdaParameters, superMethodInvocation.arguments()))
+ return false;
+ } else { // MethodInvocation
+ MethodInvocation methodInvocation= (MethodInvocation) exprBody;
+ IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
+ if (methodBinding == null)
+ return false;
+
+ Expression invocationExpr= methodInvocation.getExpression();
+ if (Modifier.isStatic(methodBinding.getModifiers())) {
+ ITypeBinding invocationTypeBinding= ASTNodes.getInvocationType(methodInvocation, methodBinding, invocationExpr);
+ if (invocationTypeBinding == null)
+ return false;
+ if (!matches(lambdaParameters, methodInvocation.arguments()))
+ return false;
+ } else if ((lambda.parameters().size() - methodInvocation.arguments().size()) == 1) {
+ if (invocationExpr == null)
+ return false;
+ ITypeBinding invocationTypeBinding= invocationExpr.resolveTypeBinding();
+ if (invocationTypeBinding == null)
+ return false;
+ IMethodBinding lambdaMethodBinding= lambda.resolveMethodBinding();
+ if (lambdaMethodBinding == null)
+ return false;
+ ITypeBinding firstParamType= lambdaMethodBinding.getParameterTypes()[0];
+ if (!((Bindings.equals(invocationTypeBinding, firstParamType) || Bindings.isSuperType(invocationTypeBinding, firstParamType))
+ && JdtASTMatcher.doNodesMatch(lambdaParameters.get(0), invocationExpr)
+ && matches(lambdaParameters.subList(1, lambdaParameters.size()), methodInvocation.arguments())))
+ return false;
+ } else if (!matches(lambdaParameters, methodInvocation.arguments())) {
+ return false;
+ }
+ }
+
+ if (resultingCollections == null)
+ return true;
+
+ AST ast= lambda.getAST();
+ ASTRewrite rewrite= ASTRewrite.create(ast);
+ ImportRewrite importRewrite= null;
+ MethodReference replacement;
+
+ if (exprBody instanceof ClassInstanceCreation) {
+ CreationReference creationReference= ast.newCreationReference();
+ replacement= creationReference;
+
+ ClassInstanceCreation cic= (ClassInstanceCreation) exprBody;
+ Type type= cic.getType();
+ if (type.isParameterizedType() && ((ParameterizedType) type).typeArguments().size() == 0) {
+ type= ((ParameterizedType) type).getType();
+ }
+ creationReference.setType((Type) rewrite.createCopyTarget(type));
+ creationReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, cic.typeArguments()));
+ } else if (exprBody instanceof ArrayCreation) {
+ CreationReference creationReference= ast.newCreationReference();
+ replacement= creationReference;
+
+ ArrayType arrayType= ((ArrayCreation) exprBody).getType();
+ Type copiedElementType= (Type) rewrite.createCopyTarget(arrayType.getElementType());
+ creationReference.setType(ast.newArrayType(copiedElementType, arrayType.getDimensions()));
+ } else if (exprBody instanceof SuperMethodInvocation) {
+ SuperMethodInvocation superMethodInvocation= (SuperMethodInvocation) exprBody;
+ IMethodBinding methodBinding= superMethodInvocation.resolveMethodBinding();
+ Name superQualifier= superMethodInvocation.getQualifier();
+
+ if (Modifier.isStatic(methodBinding.getModifiers())) {
+ TypeMethodReference typeMethodReference= ast.newTypeMethodReference();
+ replacement= typeMethodReference;
+
+ typeMethodReference.setName((SimpleName) rewrite.createCopyTarget(superMethodInvocation.getName()));
+ importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true);
+ ITypeBinding invocationTypeBinding= ASTNodes.getInvocationType(superMethodInvocation, methodBinding, superQualifier);
+ typeMethodReference.setType(importRewrite.addImport(invocationTypeBinding.getTypeDeclaration(), ast));
+ typeMethodReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, superMethodInvocation.typeArguments()));
+ } else {
+ SuperMethodReference superMethodReference= ast.newSuperMethodReference();
+ replacement= superMethodReference;
+
+ if (superQualifier != null) {
+ superMethodReference.setQualifier((Name) rewrite.createCopyTarget(superQualifier));
+ }
+ superMethodReference.setName((SimpleName) rewrite.createCopyTarget(superMethodInvocation.getName()));
+ superMethodReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, superMethodInvocation.typeArguments()));
+ }
+ } else { // MethodInvocation
+ MethodInvocation methodInvocation= (MethodInvocation) exprBody;
+ IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
+ Expression invocationQualifier= methodInvocation.getExpression();
+
+ boolean isStaticMethod= Modifier.isStatic(methodBinding.getModifiers());
+ boolean isTypeRefToInstanceMethod= methodInvocation.arguments().size() != lambda.parameters().size();
+
+ if (isStaticMethod || isTypeRefToInstanceMethod) {
+ TypeMethodReference typeMethodReference= ast.newTypeMethodReference();
+ replacement= typeMethodReference;
+
+ typeMethodReference.setName((SimpleName) rewrite.createCopyTarget(methodInvocation.getName()));
+ importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true);
+ ITypeBinding invocationTypeBinding= ASTNodes.getInvocationType(methodInvocation, methodBinding, invocationQualifier);
+ typeMethodReference.setType(importRewrite.addImport(invocationTypeBinding, ast));
+ typeMethodReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodInvocation.typeArguments()));
+
+ } else {
+ ExpressionMethodReference exprMethodReference= ast.newExpressionMethodReference();
+ replacement= exprMethodReference;
+
+ exprMethodReference.setName((SimpleName) rewrite.createCopyTarget(methodInvocation.getName()));
+ if (invocationQualifier != null) {
+ exprMethodReference.setExpression((Expression) rewrite.createCopyTarget(invocationQualifier));
+ } else {
+ exprMethodReference.setExpression(ast.newThisExpression());
+ }
+ exprMethodReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodInvocation.typeArguments()));
}
}
- return isValidExpressionBody;
+
+ rewrite.replace(lambda, replacement, null);
+
+ // add correction proposal
+ String label= CorrectionMessages.QuickAssistProcessor_convert_to_method_reference;
+ Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+ ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.CONVERT_TO_METHOD_REFERENCE, image);
+ if (importRewrite != null) {
+ proposal.setImportRewrite(importRewrite);
+ }
+ resultingCollections.add(proposal);
+ return true;
+ }
+
+ private static boolean isValidReferenceToMethod(Expression expression) {
+ return expression instanceof ClassInstanceCreation
+ || expression instanceof ArrayCreation
+ || expression instanceof SuperMethodInvocation
+ || expression instanceof MethodInvocation;
+ }
+
+ private static boolean matches(List<Expression> expected, List<Expression> toMatch) {
+ if (toMatch.size() != expected.size())
+ return false;
+ for (int i= 0; i < toMatch.size(); i++) {
+ if (!JdtASTMatcher.doNodesMatch(expected.get(i), toMatch.get(i)))
+ return false;
+ }
+ return true;
}
+
public static boolean getAddInferredLambdaParameterTypes(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
LambdaExpression lambda;
if (covering instanceof LambdaExpression) {

Back to the top