Update jdt.core from origin BETA_JAVA8 with
a3a00115caa9dfd2b9b6d5b9fcf61ba0f8479cd9 upto
4026eca435898014ba04ac7657504a426815df33 (end of BETA_JAVA8_LUNA)
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index b26c7b1..391a84e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -2864,4 +2864,40 @@
"----------\n",
null, true, customOptions);
}
+public void testBug430296() {
+ runNegativeTest(
+ new String[] {
+ "AnnotationCollector.java",
+ "import java.lang.annotation.*;\n" +
+ "import java.util.*;\n" +
+ "import java.util.function.*;\n" +
+ "import java.util.stream.*;\n" +
+ "\n" +
+ "public abstract class AnnotationCollector {\n" +
+ " \n" +
+ " Map<String, Person> test2(Stream<Person> persons) {\n" +
+ " return persons.collect(Collectors.toMap((Person p) -> p.getLastName(),\n" +
+ " Function::identity,\n" +
+ " (p1, p2) -> p1));\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "class Person {\n" +
+ " String getLastName() { return \"\"; }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in AnnotationCollector.java (at line 9)\n" +
+ " return persons.collect(Collectors.toMap((Person p) -> p.getLastName(),\n" +
+ " Function::identity,\n" +
+ " (p1, p2) -> p1));\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from Map<String,Object> to Map<String,Person>\n" +
+ "----------\n" +
+ "2. ERROR in AnnotationCollector.java (at line 10)\n" +
+ " Function::identity,\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "The type Function does not define identity(Person) that is applicable here\n" +
+ "----------\n");
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR335ClassFileTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR335ClassFileTest.java
index c25c341..2702e2e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR335ClassFileTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR335ClassFileTest.java
@@ -2754,7 +2754,7 @@
" Method[] methods = X.class.getDeclaredMethods();\n" +
" for (Method method : methods) {\n" +
" if (method.getName().contains(\"lambda\")) {\n" +
- " Parameter[] parameters = methods[2].getParameters();\n" +
+ " Parameter[] parameters = method.getParameters();\n" +
" System.out.println(Arrays.asList(parameters));\n" +
" }\n" +
" }\n" +
@@ -2801,18 +2801,247 @@
String expectedOutput =
" // Method descriptor #28 (I)V\n" +
" // Stack: 0, Locals: 1\n" +
- " private static synthetic void lambda$0(int arg0);\n" +
+ " private static synthetic void lambda$0(int <anonymous>);\n" +
" 0 return\n" +
" Line numbers:\n" +
" [pc: 0, line: 7]\n" +
" Local variable table:\n" +
" [pc: 0, pc: 1] local: i index: 0 type: int\n" +
" Method Parameters:\n" +
- " synthetic arg0\n" +
+ " synthetic <anonymous>\n" +
"\n";
verifyClassFile(expectedOutput, "X.class", ClassFileBytesDisassembler.SYSTEM);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430035, [1.8][compiler][codegen] Bridge methods are not generated for lambdas/method references
+public void test430035() throws IOException, ClassFormatException {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I<T> {\n" +
+ " void foo(String t, T u);\n" +
+ "}\n" +
+ "interface J<T> {\n" +
+ " void foo(T t, String u);\n" +
+ "}\n" +
+ "interface K extends I<String>, J<String> {\n" +
+ " void foo(String t, String u);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String... x) {\n" +
+ " K k = (s, u) -> System.out.println(\"m(\"+ s + u + ')');\n" +
+ " k.foo(\"direct\", \" call\");\n" +
+ " J<String> j = k;\n" +
+ " j.foo(\"bridge\", \" method(j)\");\n" +
+ " I<String> i = k;\n" +
+ " i.foo(\"bridge\", \" method(i)\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "m(direct call)\n" +
+ "m(bridge method(j))\n" +
+ "m(bridge method(i))");
+
+ String expectedOutput =
+ "// Compiled from X.java (version 1.8 : 52.0, super bit)\n" +
+ "public class X {\n" +
+ " Constant pool:\n" +
+ " constant #1 class: #2 X\n" +
+ " constant #2 utf8: \"X\"\n" +
+ " constant #3 class: #4 java/lang/Object\n" +
+ " constant #4 utf8: \"java/lang/Object\"\n" +
+ " constant #5 utf8: \"<init>\"\n" +
+ " constant #6 utf8: \"()V\"\n" +
+ " constant #7 utf8: \"Code\"\n" +
+ " constant #8 method_ref: #3.#9 java/lang/Object.<init> ()V\n" +
+ " constant #9 name_and_type: #5.#6 <init> ()V\n" +
+ " constant #10 utf8: \"LineNumberTable\"\n" +
+ " constant #11 utf8: \"LocalVariableTable\"\n" +
+ " constant #12 utf8: \"this\"\n" +
+ " constant #13 utf8: \"LX;\"\n" +
+ " constant #14 utf8: \"main\"\n" +
+ " constant #15 utf8: \"([Ljava/lang/String;)V\"\n" +
+ " constant #16 name_and_type: #17.#18 foo ()LK;\n" +
+ " constant #17 utf8: \"foo\"\n" +
+ " constant #18 utf8: \"()LK;\"\n" +
+ " constant #19 invoke dynamic: #0 #16 foo ()LK;\n" +
+ " constant #20 string: #21 \"direct\"\n" +
+ " constant #21 utf8: \"direct\"\n" +
+ " constant #22 string: #23 \" call\"\n" +
+ " constant #23 utf8: \" call\"\n" +
+ " constant #24 interface_method_ref: #25.#27 K.foo (Ljava/lang/String;Ljava/lang/String;)V\n" +
+ " constant #25 class: #26 K\n" +
+ " constant #26 utf8: \"K\"\n" +
+ " constant #27 name_and_type: #17.#28 foo (Ljava/lang/String;Ljava/lang/String;)V\n" +
+ " constant #28 utf8: \"(Ljava/lang/String;Ljava/lang/String;)V\"\n" +
+ " constant #29 string: #30 \"bridge\"\n" +
+ " constant #30 utf8: \"bridge\"\n" +
+ " constant #31 string: #32 \" method(j)\"\n" +
+ " constant #32 utf8: \" method(j)\"\n" +
+ " constant #33 interface_method_ref: #34.#36 J.foo (Ljava/lang/Object;Ljava/lang/String;)V\n" +
+ " constant #34 class: #35 J\n" +
+ " constant #35 utf8: \"J\"\n" +
+ " constant #36 name_and_type: #17.#37 foo (Ljava/lang/Object;Ljava/lang/String;)V\n" +
+ " constant #37 utf8: \"(Ljava/lang/Object;Ljava/lang/String;)V\"\n" +
+ " constant #38 string: #39 \" method(i)\"\n" +
+ " constant #39 utf8: \" method(i)\"\n" +
+ " constant #40 interface_method_ref: #41.#43 I.foo (Ljava/lang/String;Ljava/lang/Object;)V\n" +
+ " constant #41 class: #42 I\n" +
+ " constant #42 utf8: \"I\"\n" +
+ " constant #43 name_and_type: #17.#44 foo (Ljava/lang/String;Ljava/lang/Object;)V\n" +
+ " constant #44 utf8: \"(Ljava/lang/String;Ljava/lang/Object;)V\"\n" +
+ " constant #45 utf8: \"x\"\n" +
+ " constant #46 utf8: \"[Ljava/lang/String;\"\n" +
+ " constant #47 utf8: \"k\"\n" +
+ " constant #48 utf8: \"LK;\"\n" +
+ " constant #49 utf8: \"j\"\n" +
+ " constant #50 utf8: \"LJ;\"\n" +
+ " constant #51 utf8: \"i\"\n" +
+ " constant #52 utf8: \"LI;\"\n" +
+ " constant #53 utf8: \"LocalVariableTypeTable\"\n" +
+ " constant #54 utf8: \"LJ<Ljava/lang/String;>;\"\n" +
+ " constant #55 utf8: \"LI<Ljava/lang/String;>;\"\n" +
+ " constant #56 utf8: \"lambda$0\"\n" +
+ " constant #57 field_ref: #58.#60 java/lang/System.out Ljava/io/PrintStream;\n" +
+ " constant #58 class: #59 java/lang/System\n" +
+ " constant #59 utf8: \"java/lang/System\"\n" +
+ " constant #60 name_and_type: #61.#62 out Ljava/io/PrintStream;\n" +
+ " constant #61 utf8: \"out\"\n" +
+ " constant #62 utf8: \"Ljava/io/PrintStream;\"\n" +
+ " constant #63 class: #64 java/lang/StringBuilder\n" +
+ " constant #64 utf8: \"java/lang/StringBuilder\"\n" +
+ " constant #65 string: #66 \"m(\"\n" +
+ " constant #66 utf8: \"m(\"\n" +
+ " constant #67 method_ref: #63.#68 java/lang/StringBuilder.<init> (Ljava/lang/String;)V\n" +
+ " constant #68 name_and_type: #5.#69 <init> (Ljava/lang/String;)V\n" +
+ " constant #69 utf8: \"(Ljava/lang/String;)V\"\n" +
+ " constant #70 method_ref: #63.#71 java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;\n" +
+ " constant #71 name_and_type: #72.#73 append (Ljava/lang/String;)Ljava/lang/StringBuilder;\n" +
+ " constant #72 utf8: \"append\"\n" +
+ " constant #73 utf8: \"(Ljava/lang/String;)Ljava/lang/StringBuilder;\"\n" +
+ " constant #74 method_ref: #63.#75 java/lang/StringBuilder.append (C)Ljava/lang/StringBuilder;\n" +
+ " constant #75 name_and_type: #72.#76 append (C)Ljava/lang/StringBuilder;\n" +
+ " constant #76 utf8: \"(C)Ljava/lang/StringBuilder;\"\n" +
+ " constant #77 method_ref: #63.#78 java/lang/StringBuilder.toString ()Ljava/lang/String;\n" +
+ " constant #78 name_and_type: #79.#80 toString ()Ljava/lang/String;\n" +
+ " constant #79 utf8: \"toString\"\n" +
+ " constant #80 utf8: \"()Ljava/lang/String;\"\n" +
+ " constant #81 method_ref: #82.#84 java/io/PrintStream.println (Ljava/lang/String;)V\n" +
+ " constant #82 class: #83 java/io/PrintStream\n" +
+ " constant #83 utf8: \"java/io/PrintStream\"\n" +
+ " constant #84 name_and_type: #85.#69 println (Ljava/lang/String;)V\n" +
+ " constant #85 utf8: \"println\"\n" +
+ " constant #86 utf8: \"s\"\n" +
+ " constant #87 utf8: \"Ljava/lang/String;\"\n" +
+ " constant #88 utf8: \"u\"\n" +
+ " constant #89 utf8: \"SourceFile\"\n" +
+ " constant #90 utf8: \"X.java\"\n" +
+ " constant #91 utf8: \"BootstrapMethods\"\n" +
+ " constant #92 method_ref: #93.#95 java/lang/invoke/LambdaMetafactory.altMetafactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n" +
+ " constant #93 class: #94 java/lang/invoke/LambdaMetafactory\n" +
+ " constant #94 utf8: \"java/lang/invoke/LambdaMetafactory\"\n" +
+ " constant #95 name_and_type: #96.#97 altMetafactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n" +
+ " constant #96 utf8: \"altMetafactory\"\n" +
+ " constant #97 utf8: \"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\"\n" +
+ " constant #98 method handle: invokestatic (6) #92 \n" +
+ " constant #99 method type: #28 (Ljava/lang/String;Ljava/lang/String;)V\n" +
+ " constant #100 method_ref: #1.#101 X.lambda$0 (Ljava/lang/String;Ljava/lang/String;)V\n" +
+ " constant #101 name_and_type: #56.#28 lambda$0 (Ljava/lang/String;Ljava/lang/String;)V\n" +
+ " constant #102 method handle: invokestatic (6) #100 \n" +
+ " constant #103 method type: #28 (Ljava/lang/String;Ljava/lang/String;)V\n" +
+ " constant #104 integer: 4\n" + // flag bridge
+ " constant #105 integer: 2\n" + // two bridges
+ " constant #106 method type: #44 (Ljava/lang/String;Ljava/lang/Object;)V\n" + // first bridge
+ " constant #107 method type: #37 (Ljava/lang/Object;Ljava/lang/String;)V\n" + // next bridge.
+ " constant #108 utf8: \"InnerClasses\"\n" +
+ " constant #109 class: #110 java/lang/invoke/MethodHandles$Lookup\n" +
+ " constant #110 utf8: \"java/lang/invoke/MethodHandles$Lookup\"\n" +
+ " constant #111 class: #112 java/lang/invoke/MethodHandles\n" +
+ " constant #112 utf8: \"java/lang/invoke/MethodHandles\"\n" +
+ " constant #113 utf8: \"Lookup\"\n" +
+ " \n" +
+ " // Method descriptor #6 ()V\n" +
+ " // Stack: 1, Locals: 1\n" +
+ " public X();\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 invokespecial java.lang.Object() [8]\n" +
+ " 4 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 10]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 5] local: this index: 0 type: X\n" +
+ " \n" +
+ " // Method descriptor #15 ([Ljava/lang/String;)V\n" +
+ " // Stack: 3, Locals: 4\n" +
+ " public static void main(java.lang.String... x);\n" +
+ " 0 invokedynamic 0 foo() : K [19]\n" +
+ " 5 astore_1 [k]\n" +
+ " 6 aload_1 [k]\n" +
+ " 7 ldc <String \"direct\"> [20]\n" +
+ " 9 ldc <String \" call\"> [22]\n" +
+ " 11 invokeinterface K.foo(java.lang.String, java.lang.String) : void [24] [nargs: 3]\n" +
+ " 16 aload_1 [k]\n" +
+ " 17 astore_2 [j]\n" +
+ " 18 aload_2 [j]\n" +
+ " 19 ldc <String \"bridge\"> [29]\n" +
+ " 21 ldc <String \" method(j)\"> [31]\n" +
+ " 23 invokeinterface J.foo(java.lang.Object, java.lang.String) : void [33] [nargs: 3]\n" +
+ " 28 aload_1 [k]\n" +
+ " 29 astore_3 [i]\n" +
+ " 30 aload_3 [i]\n" +
+ " 31 ldc <String \"bridge\"> [29]\n" +
+ " 33 ldc <String \" method(i)\"> [38]\n" +
+ " 35 invokeinterface I.foo(java.lang.String, java.lang.Object) : void [40] [nargs: 3]\n" +
+ " 40 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 12]\n" +
+ " [pc: 6, line: 13]\n" +
+ " [pc: 16, line: 14]\n" +
+ " [pc: 18, line: 15]\n" +
+ " [pc: 28, line: 16]\n" +
+ " [pc: 30, line: 17]\n" +
+ " [pc: 40, line: 18]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 41] local: x index: 0 type: java.lang.String[]\n" +
+ " [pc: 6, pc: 41] local: k index: 1 type: K\n" +
+ " [pc: 18, pc: 41] local: j index: 2 type: J\n" +
+ " [pc: 30, pc: 41] local: i index: 3 type: I\n" +
+ " Local variable type table:\n" +
+ " [pc: 18, pc: 41] local: j index: 2 type: J<java.lang.String>\n" +
+ " [pc: 30, pc: 41] local: i index: 3 type: I<java.lang.String>\n" +
+ " \n" +
+ " // Method descriptor #28 (Ljava/lang/String;Ljava/lang/String;)V\n" +
+ " // Stack: 4, Locals: 2\n" +
+ " private static synthetic void lambda$0(java.lang.String s, java.lang.String u);\n" +
+ " 0 getstatic java.lang.System.out : java.io.PrintStream [57]\n" +
+ " 3 new java.lang.StringBuilder [63]\n" +
+ " 6 dup\n" +
+ " 7 ldc <String \"m(\"> [65]\n" +
+ " 9 invokespecial java.lang.StringBuilder(java.lang.String) [67]\n" +
+ " 12 aload_0 [s]\n" +
+ " 13 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [70]\n" +
+ " 16 aload_1 [u]\n" +
+ " 17 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [70]\n" +
+ " 20 bipush 41\n" +
+ " 22 invokevirtual java.lang.StringBuilder.append(char) : java.lang.StringBuilder [74]\n" +
+ " 25 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [77]\n" +
+ " 28 invokevirtual java.io.PrintStream.println(java.lang.String) : void [81]\n" +
+ " 31 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 12]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 32] local: s index: 0 type: java.lang.String\n" +
+ " [pc: 0, pc: 32] local: u index: 1 type: java.lang.String\n" +
+ "\n" +
+ " Inner classes:\n" +
+ " [inner class info: #109 java/lang/invoke/MethodHandles$Lookup, outer class info: #111 java/lang/invoke/MethodHandles\n" +
+ " inner name: #113 Lookup, accessflags: 25 public static final]\n" +
+ "Bootstrap methods:\n" +
+ " 0 : # 98 arguments: {#99,#102,#103,#104,#105,#106,#107}\n" +
+ "}";
+
+ verifyClassFile(expectedOutput, "X.class", ClassFileBytesDisassembler.SYSTEM);
+}
public static Class testClass() {
return JSR335ClassFileTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index 8f02b3b..d830d9e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -3729,7 +3729,7 @@
" Method[] methods = X.class.getDeclaredMethods();\n" +
" for (Method method : methods) {\n" +
" if (method.getName().contains(\"lambda\")) {\n" +
- " Parameter[] parameters = methods[2].getParameters();\n" +
+ " Parameter[] parameters = method.getParameters();\n" +
" System.out.println(Arrays.asList(parameters));\n" +
" }\n" +
" }\n" +
@@ -3807,6 +3807,296 @@
},
"OK");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430035, [1.8][compiler][codegen] Bridge methods are not generated for lambdas/method references
+public void test430035() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.Consumer;\n" +
+ "public class X {\n" +
+ " interface StringConsumer extends Consumer<String> {\n" +
+ " void accept(String t);\n" +
+ " }\n" +
+ " public static void main(String... x) {\n" +
+ " StringConsumer c = s->System.out.println(\"m(\"+s+')');\n" +
+ " c.accept(\"direct call\");\n" +
+ " Consumer<String> c4b=c;\n" +
+ " c4b.accept(\"bridge method\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "m(direct call)\n" +
+ "m(bridge method)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430035, [1.8][compiler][codegen] Bridge methods are not generated for lambdas/method references
+public void test430035a() { // test reference expressions requiring bridges.
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.function.Consumer;\n" +
+ "public class X {\n" +
+ " interface StringConsumer extends Consumer<String> {\n" +
+ " void accept(String t);\n" +
+ " }\n" +
+ " static void m(String s) { System.out.println(\"m(\"+s+\")\"); } \n" +
+ " public static void main(String... x) {\n" +
+ " StringConsumer c = X::m;\n" +
+ " c.accept(\"direct call\");\n" +
+ " Consumer<String> c4b=c;\n" +
+ " c4b.accept(\"bridge method\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "m(direct call)\n" +
+ "m(bridge method)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430035, [1.8][compiler][codegen] Bridge methods are not generated for lambdas/method references
+public void test430035b() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I<T> {\n" +
+ " void foo(T t);\n" +
+ "}\n" +
+ "interface J<T> {\n" +
+ " void foo(T t);\n" +
+ "}\n" +
+ "interface K extends I<String>, J<String> {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String... x) {\n" +
+ " K k = s -> System.out.println(\"m(\"+s+')');\n" +
+ " k.foo(\"direct call\");\n" +
+ " J<String> j = k;\n" +
+ " j.foo(\"bridge method\");\n" +
+ " I<String> i = k;\n" +
+ " i.foo(\"bridge method\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "m(direct call)\n" +
+ "m(bridge method)\n" +
+ "m(bridge method)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430035, [1.8][compiler][codegen] Bridge methods are not generated for lambdas/method references
+public void test430035c() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I<T> {\n" +
+ " void foo(String t, T u);\n" +
+ "}\n" +
+ "interface J<T> {\n" +
+ " void foo(T t, String u);\n" +
+ "}\n" +
+ "interface K extends I<String>, J<String> {\n" +
+ " void foo(String t, String u);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String... x) {\n" +
+ " K k = (s, u) -> System.out.println(\"m(\"+ s + u + ')');\n" +
+ " k.foo(\"direct\", \" call\");\n" +
+ " J<String> j = k;\n" +
+ " j.foo(\"bridge\", \" method(j)\");\n" +
+ " I<String> i = k;\n" +
+ " i.foo(\"bridge\", \" method(i)\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "m(direct call)\n" +
+ "m(bridge method(j))\n" +
+ "m(bridge method(i))");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430035, [1.8][compiler][codegen] Bridge methods are not generated for lambdas/method references
+public void test430035d() { // 8b131 complains of ambiguity.
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I<T> {\n" +
+ " void foo(String t, T u);\n" +
+ "}\n" +
+ "interface J<T> {\n" +
+ " void foo(T t, String u);\n" +
+ "}\n" +
+ "interface K extends I<String>, J<String> {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String... x) {\n" +
+ " K k = (s, u) -> System.out.println(\"m(\"+ s + u + ')');\n" +
+ " k.foo(\"direct\", \" call\");\n" +
+ " J<String> j = k;\n" +
+ " j.foo(\"bridge\", \" method(j)\");\n" +
+ " I<String> i = k;\n" +
+ " i.foo(\"bridge\", \" method(i)\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "m(direct call)\n" +
+ "m(bridge method(j))\n" +
+ "m(bridge method(i))");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430035, [1.8][compiler][codegen] Bridge methods are not generated for lambdas/method references
+public void test430035e() { // 8b131 complains of ambiguity in call.
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I<T> {\n" +
+ " Object foo(String t, T u);\n" +
+ "}\n" +
+ "interface J<T> {\n" +
+ " String foo(T t, String u);\n" +
+ "}\n" +
+ "interface K extends I<String>, J<String> {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String... x) {\n" +
+ " K k = (s, u) -> s + u;\n" +
+ " System.out.println(k.foo(\"direct\", \" call\"));\n" +
+ " J<String> j = k;\n" +
+ " System.out.println(j.foo(\"bridge\", \" method(j)\"));\n" +
+ " I<String> i = k;\n" +
+ " System.out.println(i.foo(\"bridge\", \" method(i)\"));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "direct call\n" +
+ "bridge method(j)\n" +
+ "bridge method(i)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430035, [1.8][compiler][codegen] Bridge methods are not generated for lambdas/method references
+public void test430035f() { // ensure co-variant return emits a bridge request.
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I<T> {\n" +
+ " Object foo(String t, String u);\n" +
+ "}\n" +
+ "interface J<T> {\n" +
+ " String foo(String t, String u);\n" +
+ "}\n" +
+ "interface K extends I<String>, J<String> {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String... x) {\n" +
+ " K k = (s, u) -> s + u;\n" +
+ " System.out.println(k.foo(\"direct\", \" call\"));\n" +
+ " J<String> j = k;\n" +
+ " System.out.println(j.foo(\"bridge\", \" method(j)\"));\n" +
+ " I<String> i = k;\n" +
+ " System.out.println(i.foo(\"bridge\", \" method(i)\"));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "direct call\n" +
+ "bridge method(j)\n" +
+ "bridge method(i)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430241, [1.8][compiler] Raw return type results in incorrect covariant return bridge request to LambdaMetaFactory
+public void test430241() { // ensure raw return type variant does not emit a bridge request.
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface K extends I, J {\n" +
+ "}\n" +
+ "interface I {\n" +
+ " Comparable<Integer> foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " Comparable foo();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " K k = () -> null;\n" +
+ " System.out.println(k.foo());\n" +
+ " }\n" +
+ "}\n"
+ },
+ "null");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430310, [1.8][compiler] Functional interface incorrectly rejected as not being.
+public void test430310() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface Func1<T1, R> {\n" +
+ " R apply(T1 v1);\n" +
+ " void other();\n" +
+ "}\n" +
+ "@FunctionalInterface // spurious error: F1<T, R> is not a functional interface\n" +
+ "public interface X<T1, R> extends Func1<T1, R> {\n" +
+ " default void other() {}\n" +
+ " public static void main(String [] args) {\n" +
+ " System.out.println(\"OK\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "OK");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430310, [1.8][compiler] Functional interface incorrectly rejected as not being.
+public void test430310a() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "@FunctionalInterface\n" +
+ "public interface X<T1, T2, R> {\n" +
+ " R apply(T1 v1, T2 v2);\n" +
+ " default void other() {}\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"OK\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "OK");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430310, [1.8][compiler] Functional interface incorrectly rejected as not being.
+public void test430310b() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I1 {\n" +
+ " int foo(String s);\n" +
+ "}\n" +
+ "@FunctionalInterface\n" +
+ "interface A1 extends I1 {\n" +
+ " @Override\n" +
+ " default int foo(String s) {\n" +
+ " return -1;\n" +
+ " }\n" +
+ " int foo(java.io.Serializable s);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"OK\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "OK");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430310, [1.8][compiler] Functional interface incorrectly rejected as not being.
+public void test430310c() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I2 {\n" +
+ " int foo(String s);\n" +
+ "}\n" +
+ "@FunctionalInterface\n" +
+ "interface A2 extends I2 {\n" +
+ " @Override\n" +
+ " default int foo(String s) {\n" +
+ " return -1;\n" +
+ " }\n" +
+ " int bar(java.io.Serializable s);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"OK\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "OK");
+}
+
public static Class testClass() {
return LambdaExpressionsTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
index 9ca1bdb..5455324 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
@@ -1695,7 +1695,7 @@
"5. ERROR in X.java (at line 11)\n" +
" D d = (p) -> { return null;};\n" +
" ^^^^^^\n" +
- "Illegal lambda expression: Method foo of type A is generic \n" +
+ "Illegal lambda expression: Method foo of type B is generic \n" +
"----------\n" +
"6. ERROR in X.java (at line 12)\n" +
" E e = (p) -> { return null;};\n" +
@@ -8959,6 +8959,30 @@
"Unhandled exception type Exception\n" +
"----------\n");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430310, [1.8][compiler] Functional interface incorrectly rejected as not being.
+public void test430310() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface Func1<T1, R> {\n" +
+ " R apply(T1 v1);\n" +
+ " void other();\n" +
+ "}\n" +
+ "@FunctionalInterface // spurious error: F1<T, R> is not a functional interface\n" +
+ "interface F1<T1, R> extends Func1<T1, R> {\n" +
+ " default void other() {}\n" +
+ "}\n" +
+ "@FunctionalInterface\n" +
+ "interface F2<T1, R> extends Func1<T1, R> {\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 10)\n" +
+ " interface F2<T1, R> extends Func1<T1, R> {\n" +
+ " ^^\n" +
+ "Invalid \'@FunctionalInterface\' annotation; F2<T1,R> is not a functional interface\n" +
+ "----------\n");
+}
public static Class testClass() {
return NegativeLambdaExpressionsTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index fd91032..25d0c2f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Stephan Herrmann - initial API and implementation
+ * IBM Corporation
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -4342,4 +4343,36 @@
"Null type mismatch (type annotations): required \'List<@NonNull Person>\' but this expression has type \'ArrayList<@Nullable Person>\', corresponding supertype is \'List<@Nullable Person>\'\n" +
"----------\n");
}
+public void testBug430219() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "@NonNullByDefault\n" +
+ "public class X {\n" +
+ " void foo(int @NonNull [] x) {}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " void foo(int @NonNull [] x) {}\n" +
+ " ^^^^^^^\n" +
+ "NonNull cannot be resolved to a type\n" +
+ "----------\n");
+}
+public void testBug430219a() {
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE) @interface Marker{}\n" +
+ "@NonNullByDefault\n" +
+ "public class X {\n" +
+ " void foo(int @Marker[] x) {}\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java
index 46764a6..03dad65 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java
@@ -14,7 +14,6 @@
import java.util.HashMap;
import junit.framework.Test;
-import junit.framework.TestSuite;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IClassFile;
@@ -41,22 +40,7 @@
this.endChar = "";
}
public static Test suite() {
- if (TESTS_PREFIX != null || TESTS_NAMES != null || TESTS_NUMBERS!=null || TESTS_RANGE !=null) {
- return buildModelTestSuite(JavaElement8Tests.class);
- }
- TestSuite suite = new Suite(JavaElement8Tests.class.getName());
- suite.addTest(new JavaElement8Tests("testBug428178"));
- suite.addTest(new JavaElement8Tests("testBug428178a"));
- suite.addTest(new JavaElement8Tests("testBug429641"));
- suite.addTest(new JavaElement8Tests("testBug429641a"));
- suite.addTest(new JavaElement8Tests("test429948"));
- suite.addTest(new JavaElement8Tests("test429948a"));
- suite.addTest(new JavaElement8Tests("test429966"));
- suite.addTest(new JavaElement8Tests("testBug429910"));
- suite.addTest(new JavaElement8Tests("test430026"));
- suite.addTest(new JavaElement8Tests("test430026a"));
- suite.addTest(new JavaElement8Tests("test430033"));
- return suite;
+ return buildModelTestSuite(JavaElement8Tests.class);
}
public void testBug428178() throws Exception {
try {
@@ -325,6 +309,38 @@
deleteProject("Bug429910");
}
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=429910 [1.8][model] Superinterfaces of lambda element's IType are missing type arguments
+ public void testBug429910a() throws Exception {
+ try {
+ IJavaProject project = createJavaProject("Bug429910", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8");
+ project.open(null);
+ String fileContent = "package p;\n" +
+ "public interface MyFunction<T, R> {\n" +
+ " R apply(T t);\n" +
+ " default <V> MyFunction<V, R> compose(MyFunction<? super V, ? extends T> before) {\n" +
+ " return (V v) -> apply(before.apply(v));" +
+ " }" +
+ "}";
+ createFolder("/Bug429910/src/p");
+ createFile( "/Bug429910/src/p/MyFunction.java", fileContent);
+ ICompilationUnit unit = getCompilationUnit("/Bug429910/src/p/MyFunction.java");
+ int start = fileContent.indexOf("v))");
+ IJavaElement[] elements = unit.codeSelect(start, 1);
+ assertEquals("Incorrect no of elements", 1, elements.length);
+ assertEquals("Incorrect element type", IJavaElement.LOCAL_VARIABLE, elements[0].getElementType());
+ IMethod method = (IMethod) elements[0].getParent();
+ assertTrue("Should be a lambda method",method.isLambdaMethod());
+ assertEquals("Incorrect lambda method signature", "(TV;)TR;", method.getSignature());
+ IJavaElement parent = method.getParent();
+ assertTrue("Should be a lambda expression", (parent instanceof LambdaExpression));
+ LambdaExpression lambda = (LambdaExpression) parent;
+ String sigs = lambda.getSuperInterfaceTypeSignatures()[0];
+ assertEquals("Incorrect super interface signature", "Lp.MyFunction<TV;TR;>;", sigs);
+ }
+ finally {
+ deleteProject("Bug429910");
+ }
+ }
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430026, [1.8] Lambda parameter has wrong parent if it declares its type
public void test430026() throws CoreException {
String projectName = "Bug429966";
@@ -414,4 +430,99 @@
}
}
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=430141, [1.8][hierarchy] Incorrect hierarchy with lambda elements missing
+ public void test430141() throws Exception {
+ try {
+ IJavaProject project = createJavaProject("Bug430141", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8");
+ project.open(null);
+ String fileContent =
+ "interface I {\n" +
+ " void doit();\n" +
+ "}\n" +
+ "interface J extends I {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " J j = () -> { System.out.println(\"Lambda\"); };\n" +
+ " j.doit();\n" +
+ " }\n" +
+ "}\n";
+ createFile( "/Bug430141/src/X.java", fileContent);
+ IType type = getCompilationUnit("/Bug430141/src/X.java").getType("I");
+ ITypeHierarchy h = type.newTypeHierarchy(null);
+ assertHierarchyEquals(
+ "Focus: I [in X.java [in <default> [in src [in Bug430141]]]]\n" +
+ "Super types:\n" +
+ "Sub types:\n" +
+ " J [in X.java [in <default> [in src [in Bug430141]]]]\n" +
+ " Lambda(J) [in main(String[]) [in X [in X.java [in <default> [in src [in Bug430141]]]]]]\n",
+ h);
+ }
+ finally {
+ deleteProject("Bug430141");
+ }
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=430141, [1.8][hierarchy] Incorrect hierarchy with lambda elements missing
+ public void test430141a() throws Exception {
+ try {
+ IJavaProject project = createJavaProject("Bug430141", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8");
+ project.open(null);
+ String fileContent =
+ "interface I {\n" +
+ " void doit();\n" +
+ "}\n" +
+ "interface J extends I {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " J j = () -> { System.out.println(\"Lambda\"); };\n" +
+ " j.doit();\n" +
+ " }\n" +
+ "}\n";
+ createFile( "/Bug430141/src/X.java", fileContent);
+ IType type = getCompilationUnit("/Bug430141/src/X.java").getType("J");
+ ITypeHierarchy h = type.newTypeHierarchy(null);
+ assertHierarchyEquals(
+ "Focus: J [in X.java [in <default> [in src [in Bug430141]]]]\n" +
+ "Super types:\n" +
+ " I [in X.java [in <default> [in src [in Bug430141]]]]\n" +
+ "Sub types:\n" +
+ " Lambda(J) [in main(String[]) [in X [in X.java [in <default> [in src [in Bug430141]]]]]]\n",
+ h);
+ }
+ finally {
+ deleteProject("Bug430141");
+ }
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=430136
+ public void test430136() throws CoreException {
+ String projectName = "([Bug430136])";
+ try {
+ IJavaProject project = createJavaProject(projectName, new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8");
+ project.open(null);
+ String fileContent =
+ "interface MyFunction<T, R> {\n" +
+ " R apply(T t);\n" +
+ " default <V> MyFunction<V, R> compose(MyFunction<? super V, ? extends T> before) {\n" +
+ " return v -> apply(before.apply(v));\n" +
+ " }\n" +
+ "}\n";
+ String fileName = "/" + projectName + "/src/X.java";
+ createFile(fileName, fileContent);
+
+ ICompilationUnit unit = getCompilationUnit(fileName);
+ int start = fileContent.indexOf("v");
+ IJavaElement[] elements = unit.codeSelect(start, 1);
+ assertEquals("Incorrect java element", IJavaElement.LOCAL_VARIABLE, elements[0].getElementType());
+ IType lambda = (IType) elements[0].getParent().getParent();
+ String mem = lambda.getHandleIdentifier();
+ String expected = "=\\(\\[Bug430136\\])/src<{X.java[MyFunction~compose~QMyFunction\\<-QV;+QT;>;=)Lambda\\(MyFunction)=\"LMyFunction\\<TV;TR;>;!148!174!151=&apply!1=\"TV;=\"v=\"TR;=\"LX\\~MyFunction\\<LX\\~MyFunction;:1TV;LX\\~MyFunction;:TR;>;.apply\\(TV;)TR;@v!148!148!148!148!Ljava\\/lang\\/Object;!0!true=)";
+ assertEquals("Incorrect memento", expected, mem);
+ IJavaElement result = JavaCore.create(expected);
+ assertEquals("Incorrect element created", lambda, result);
+ }
+ finally {
+ deleteProject(projectName);
+ }
+ }
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs8Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs8Tests.java
index d39c8c6..8e7f126 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs8Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs8Tests.java
@@ -36,6 +36,7 @@
import org.eclipse.jdt.core.search.TypeReferenceMatch;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.search.matching.AndPattern;
/**
* Non-regression tests for bugs fixed in Java Search engine.
@@ -155,6 +156,10 @@
suite.addTest(new JavaSearchBugs8Tests("test429738a"));
suite.addTest(new JavaSearchBugs8Tests("testBug429836"));
suite.addTest(new JavaSearchBugs8Tests("test429934"));
+ suite.addTest(new JavaSearchBugs8Tests("test430159a"));
+ suite.addTest(new JavaSearchBugs8Tests("test430159b"));
+ suite.addTest(new JavaSearchBugs8Tests("test430159c"));
+ suite.addTest(new JavaSearchBugs8Tests("test430159d"));
return suite;
}
class TestCollector extends JavaSearchResultCollector {
@@ -3612,6 +3617,159 @@
"src/b400905/X.java void b400905.X.main(String[]) [Function] EXACT_MATCH\n" +
"src/b400905/X.java void b400905.X.main(String[]) [Function] EXACT_MATCH");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430159, [1.8][search] Lambda Expression not found when searching using OrPattern or AndPattern
+public void test430159a() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b429498/X.java",
+ "interface I {\n" +
+ " public void doit(int xyz);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " I i = (int xyz) -> {};\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "doit";
+ int start = str.indexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ SearchPattern leftPattern = SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, ERASURE_RULE);
+
+ selection = "xyz";
+ start = str.lastIndexOf(selection);
+ length = selection.length();
+
+ elements = this.workingCopies[0].codeSelect(start, length);
+ SearchPattern rightPattern = SearchPattern.createPattern(elements[0].getParent(), ALL_OCCURRENCES, ERASURE_RULE); // mimic https://bugs.eclipse.org/bugs/show_bug.cgi?id=429498#c6
+
+ SearchPattern pattern = SearchPattern.createOrPattern(leftPattern, rightPattern);
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/b429498/X.java void b429498.I.doit(int) [doit] EXACT_MATCH\n" +
+ "src/b429498/X.java void b429498.X.i:Lambda(I).doit(int) [(int xyz) ->] EXACT_MATCH"
+ );
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430159, [1.8][search] Lambda Expression not found when searching using OrPattern or AndPattern
+public void test430159b() throws CoreException { // this test basically checks that and pattern locator does not a lambda from being found.
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b429498/X.java",
+ "interface I {\n" +
+ " public void doit();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " I i = () -> {};\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "doit";
+ int start = str.indexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ SearchPattern leftPattern = SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, ERASURE_RULE);
+
+ selection = "->";
+ start = str.indexOf(selection);
+ length = selection.length();
+
+ elements = this.workingCopies[0].codeSelect(start, length);
+ SearchPattern rightPattern = SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, ERASURE_RULE);
+
+ SearchPattern pattern = new AndPattern(leftPattern, rightPattern);
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/b429498/X.java void b429498.I.doit() [doit] EXACT_MATCH\n" +
+ "src/b429498/X.java void b429498.X.i:Lambda(I).doit() [() ->] EXACT_MATCH"
+ );
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430159, [1.8][search] Lambda Expression not found when searching using OrPattern or AndPattern
+public void test430159c() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b429498/X.java",
+ "interface I {\n" +
+ " public void doit();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo() {}\n" +
+ " static void foo(int i) {}\n" +
+ " I i = X :: foo;\n" +
+ "}\n"
+ );
+ String str = this.workingCopies[0].getSource();
+ String selection = "foo";
+ int start = str.indexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ SearchPattern leftPattern = SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, ERASURE_RULE);
+
+ selection = "::";
+ start = str.indexOf(selection);
+ length = selection.length();
+
+ elements = this.workingCopies[0].codeSelect(start, length);
+ SearchPattern rightPattern = SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, ERASURE_RULE);
+
+ SearchPattern pattern = SearchPattern.createOrPattern(leftPattern, rightPattern);
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/b429498/X.java void b429498.I.doit() [doit] EXACT_MATCH\n" +
+ "src/b429498/X.java b429498.X.i [X :: foo] EXACT_MATCH\n" +
+ "src/b429498/X.java void b429498.X.foo() [foo] EXACT_MATCH"
+ );
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430159, [1.8][search] Lambda Expression not found when searching using OrPattern or AndPattern
+public void test430159d() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b429498/X.java",
+ "interface I {\n" +
+ " public void doit();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " static void foo() {}\n" +
+ " static void foo(int i) {}\n" +
+ " I i = X :: foo;\n" +
+ "}\n"
+ );
+ String str = this.workingCopies[0].getSource();
+ String selection = "foo";
+ int start = str.indexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ SearchPattern leftPattern = SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, ERASURE_RULE);
+
+ selection = "::";
+ start = str.indexOf(selection);
+ length = selection.length();
+
+ elements = this.workingCopies[0].codeSelect(start, length);
+ SearchPattern rightPattern = SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, ERASURE_RULE);
+
+ SearchPattern pattern = new AndPattern(leftPattern, rightPattern);
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(""
+ );
+}
// Add new tests in JavaSearchBugs8Tests
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/MementoTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/MementoTests.java
index b688133..250235b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/MementoTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/MementoTests.java
@@ -251,7 +251,7 @@
IType type = getClassFile("/P/lib/p/X.class").getType();
IMethod method = type.getMethod("foo", new String[] {"Ljava.util.Collection<*>;"});
assertMemento(
- "=P/lib<p(X.class[X~foo~Ljava.util.Collection\\<\\*\\>;",
+ "=P/lib<p(X.class[X~foo~Ljava.util.Collection\\<*>;",
method);
}
@@ -382,7 +382,7 @@
importDecl = getCompilationUnit("/P/src/p/X.java").getImport("java.util.*");
assertMemento(
- "=P/src<p{X.java#java.util.\\*",
+ "=P/src<p{X.java#java.util.*",
importDecl);
}
/*
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java
index 916fdaa..51e9012 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java
@@ -17,9 +17,13 @@
import org.eclipse.jdt.core.ICodeAssist;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.internal.core.LambdaExpression;
+import org.eclipse.jdt.internal.core.LambdaMethod;
public class ResolveTests18 extends AbstractJavaModelTests {
ICompilationUnit wc = null;
@@ -2394,4 +2398,178 @@
IMethod lambda = (IMethod) elements[0].getParent();
assertEquals("(Ljava.util.List<TU;>;I)TU;", lambda.getSignature());
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430136
+public void test430136() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/Resolve/src/X.java",
+ "import java.util.List;\n" +
+ "interface Getter<E> {\n" +
+ " E get(List<E> list, int i);\n" +
+ "}\n" +
+ "public class X<U> {\n" +
+ " public void foo(List<U> l) {\n" +
+ " Getter<U> g= (x, i) -> x.get(i);\n" +
+ " Getter<U> g1= (x, i) -> x.get(i);\n" +
+ " } \n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+
+ String selection = "x,";
+ int start = str.indexOf(selection);
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, 1);
+ IMethod lambda = (IMethod) elements[0].getParent();
+ String memento = lambda.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=&",
+ memento);
+ IJavaElement result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", lambda, result);
+ LambdaExpression expression = (LambdaExpression) lambda.getParent();
+ memento = expression.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=)",
+ memento);
+ result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", expression, result);
+
+ start = str.lastIndexOf(selection);
+ elements = this.workingCopies[0].codeSelect(start, 1);
+ lambda = (IMethod) elements[0].getParent();
+ memento = lambda.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!180!197!188=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!181!181!181!181!Ljava\\/util\\/List;!0!true@i!184!184!184!184!I!0!true=&",
+ memento);
+ result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", lambda, result);
+ expression = (LambdaExpression) lambda.getParent();
+ memento = expression.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!180!197!188=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!181!181!181!181!Ljava\\/util\\/List;!0!true@i!184!184!184!184!I!0!true=)",
+ memento);
+ result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", expression, result);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430307, [1.8][model] NPE trying to get children of a LambdaExpression restored from handleIdentifier
+public void test430307() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/Resolve/src/X.java",
+ "import java.util.List;\n" +
+ "interface Getter<E> {\n" +
+ " E get(List<E> list, int i);\n" +
+ "}\n" +
+ "public class X<U> {\n" +
+ " public void foo(List<U> l) {\n" +
+ " Getter<U> g= (x, i) -> x.get(i);\n" +
+ " } \n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+
+ String selection = "x,";
+ int start = str.indexOf(selection);
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, 1);
+ ILocalVariable local = (ILocalVariable) elements[0];
+ String memento = local.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=&@x!145!145!145!145!Ljava.util.List\\<LU;>;!0!true",
+ memento);
+ IJavaElement result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", local, result);
+
+ IJavaElement parentMethod = result.getParent();
+ IJavaElement parentExpr = parentMethod.getParent();
+ IMethod lambda = (IMethod) elements[0].getParent();
+ memento = lambda.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=&",
+ memento);
+ result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", lambda, result);
+ assertEquals("Java elements should be equal", result, parentMethod);
+ LambdaExpression expression = (LambdaExpression) lambda.getParent();
+ memento = expression.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=)",
+ memento);
+ LambdaExpression recreatedType = (LambdaExpression) JavaCore.create(memento);
+ assertEquals("Java elements should be equal", expression, recreatedType);
+ assertEquals("Java elements should be equal", recreatedType, parentExpr);
+ LambdaMethod child = (LambdaMethod) recreatedType.getChildren()[0];
+ assertEquals("Java elements should be equal", lambda, child);
+}
+public void test430307a() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/Resolve/src/X.java",
+ "interface I {\n" +
+ " I doit(I xyz);\n" +
+ "}\n" +
+ "public class X { \n" +
+ " public static void main(String[] args) {\n" +
+ " I i = (pqr) -> {\n" +
+ " return (xyz) -> {\n" +
+ " return (abc) -> abc; \n" +
+ " };\n" +
+ " };\n" +
+ " }\n" +
+ "}\n");
+ String str = this.workingCopies[0].getSource();
+
+ String selection = "abc)";
+ int start = str.indexOf(selection);
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, 3);
+ ILocalVariable local = (ILocalVariable) elements[0];
+ String memento = local.getHandleIdentifier();
+ assertEquals(
+ "Incorrect memento string",
+ "=Resolve/src<{X.java[X~main~\\[QString;=)Lambda\\(I)=\"LI;!103!169!110=&doit!1=\"LI;=\"pqr=\"LI;=\"LX\\~I;.doit\\(LI;)"
+ + "LI;@pqr!104!106!104!106!LI;!0!true=&=)Lambda\\(I)=\"LI;!124!164!131=&doit!1=\"LI;=\"xyz=\"LI;=\"LX\\~I;.doit\\(LI;)"
+ + "LI;@xyz!125!127!125!127!LI;!0!true=&=)Lambda\\(I)=\"LI;!146!157!153=&doit!1=\"LI;=\"abc=\"LI;=\"LX\\~I;.doit\\(LI;)"
+ + "LI;@abc!147!149!147!149!LI;!0!true=&@abc!147!149!147!149!LI;!0!true",
+ memento);
+ IJavaElement result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", local, result);
+
+ IJavaElement parentMethod = result.getParent();
+ IJavaElement parentExpr = parentMethod.getParent();
+ assertEquals("Java elements should be equal", parentMethod, local.getParent());
+ assertEquals("Java elements should be equal", parentExpr, local.getParent().getParent());
+
+ selection = "xyz)";
+ start = str.lastIndexOf(selection);
+ elements = this.workingCopies[0].codeSelect(start, 3);
+ local = (ILocalVariable) elements[0];
+ memento = local.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~main~\\[QString;=)Lambda\\(I)=\"LI;!103!169!110=&doit!1=\"LI;=\"pqr=\"LI;=\"LX\\~I;.doit\\(LI;)"
+ + "LI;@pqr!104!106!104!106!LI;!0!true=&=)Lambda\\(I)=\"LI;!124!164!131=&doit!1=\"LI;=\"xyz=\"LI;=\"LX\\~I;.doit\\(LI;)"
+ + "LI;@xyz!125!127!125!127!LI;!0!true=&@xyz!125!127!125!127!LI;!0!true",
+ memento);
+ result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", local, result);
+
+ parentMethod = result.getParent();
+ parentExpr = parentMethod.getParent();
+ assertEquals("Java elements should be equal", parentMethod, local.getParent());
+ assertEquals("Java elements should be equal", parentExpr, local.getParent().getParent());
+
+ selection = "pqr)";
+ start = str.indexOf(selection);
+ elements = this.workingCopies[0].codeSelect(start, 3);
+ local = (ILocalVariable) elements[0];
+ memento = local.getHandleIdentifier();
+ assertEquals("Incorrect memento string",
+ "=Resolve/src<{X.java[X~main~\\[QString;=)Lambda\\(I)=\"LI;!103!169!110=&doit!1=\"LI;=\"pqr=\"LI;=\"LX\\~I;.doit\\(LI;)"
+ + "LI;@pqr!104!106!104!106!LI;!0!true=&@pqr!104!106!104!106!LI;!0!true",
+ memento);
+ result = JavaCore.create(memento);
+ assertEquals("Java elements should be equal", local, result);
+
+ parentMethod = result.getParent();
+ parentExpr = parentMethod.getParent();
+ assertEquals("Java elements should be equal", parentMethod, local.getParent());
+ assertEquals("Java elements should be equal", parentExpr, local.getParent().getParent());
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index bed5cb0..6ac0c29 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -2987,11 +2987,12 @@
this.contents[localContentsOffset++] = (byte) numberOfBootstraps;
for (int i = 0; i < numberOfBootstraps; i++) {
FunctionalExpression functional = (FunctionalExpression) functionalExpressionList.get(i);
-
+ MethodBinding [] bridges = functional.getRequiredBridges();
TypeBinding[] markerInterfaces = null;
if (functional instanceof LambdaExpression &&
(((markerInterfaces=((LambdaExpression)functional).getMarkerInterfaces()) != null) ||
- ((LambdaExpression)functional).isSerializable)) {
+ ((LambdaExpression)functional).isSerializable) ||
+ bridges != null) {
LambdaExpression lambdaEx = (LambdaExpression)functional;
// may need even more space
@@ -3000,6 +3001,10 @@
// 2 for the marker interface list size then 2 per marker interface index
extraSpace += (2 + 2 * markerInterfaces.length);
}
+ if (bridges != null) {
+ // 2 for bridge count then 2 per bridge method type.
+ extraSpace += (2 + 2 * bridges.length);
+ }
if (extraSpace + localContentsOffset >= this.contents.length) {
resizeContents(extraSpace);
}
@@ -3014,7 +3019,8 @@
// u2 num_bootstrap_arguments
this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) (4+(markerInterfaces==null?0:1+markerInterfaces.length));
+ this.contents[localContentsOffset++] = (byte) (4 + (markerInterfaces==null?0:1+markerInterfaces.length) +
+ (bridges == null ? 0 : 1 + bridges.length));
int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
@@ -3029,7 +3035,6 @@
this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
this.contents[localContentsOffset++] = (byte) methodTypeIndex;
- // Does this block have to deal with FLAG_BRIDGE? When is it needed?
int bitflags = 0;
if (lambdaEx.isSerializable) {
bitflags |= ClassFileConstants.FLAG_SERIALIZABLE;
@@ -3037,6 +3042,9 @@
if (markerInterfaces!=null) {
bitflags |= ClassFileConstants.FLAG_MARKERS;
}
+ if (bridges != null) {
+ bitflags |= ClassFileConstants.FLAG_BRIDGES;
+ }
int indexForBitflags = this.constantPool.literalIndex(bitflags);
this.contents[localContentsOffset++] = (byte)(indexForBitflags>>8);
@@ -3052,6 +3060,17 @@
this.contents[localContentsOffset++] = (byte)(classTypeIndex);
}
}
+ if (bridges != null) {
+ int bridgeCountIndex = this.constantPool.literalIndex(bridges.length);
+ this.contents[localContentsOffset++] = (byte) (bridgeCountIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) (bridgeCountIndex);
+ for (int m = 0, maxm = bridges.length; m < maxm; m++) {
+ char [] bridgeSignature = bridges[m].signature();
+ int bridgeMethodTypeIndex = this.constantPool.literalIndexForMethodType(bridgeSignature);
+ this.contents[localContentsOffset++] = (byte) (bridgeMethodTypeIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) bridgeMethodTypeIndex;
+ }
+ }
} else {
if (indexForMetaFactory == 0) {
indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
index 6d963b1..5adb280 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
@@ -35,8 +35,11 @@
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.IntersectionCastTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
@@ -164,6 +167,7 @@
public TypeBinding resolveType(BlockScope blockScope) {
this.constant = Constant.NotAConstant;
+ this.enclosingScope = blockScope;
MethodBinding sam = this.expectedType == null ? null : this.expectedType.getSingleAbstractMethod(blockScope, argumentsTypeElided());
if (sam == null) {
blockScope.problemReporter().targetTypeIsNotAFunctionalInterface(this);
@@ -278,4 +282,76 @@
public int diagnosticsSourceEnd() {
return this.sourceEnd;
}
-}
+
+ public MethodBinding[] getRequiredBridges() {
+
+ class BridgeCollector {
+
+ MethodBinding [] bridges;
+ MethodBinding method;
+ char [] selector;
+ LookupEnvironment environment;
+ Scope scope;
+
+ BridgeCollector(ReferenceBinding functionalType, MethodBinding method) {
+ this.method = method;
+ this.selector = method.selector;
+ this.environment = FunctionalExpression.this.enclosingScope.environment();
+ this.scope = FunctionalExpression.this.enclosingScope;
+ collectBridges(functionalType.superInterfaces());
+ }
+
+ void collectBridges(ReferenceBinding[] interfaces) {
+ int length = interfaces == null ? 0 : interfaces.length;
+ for (int i = 0; i < length; i++) {
+ ReferenceBinding superInterface = interfaces[i];
+ if (superInterface == null)
+ continue;
+ MethodBinding [] methods = superInterface.getMethods(this.selector);
+ for (int j = 0, count = methods == null ? 0 : methods.length; j < count; j++) {
+ MethodBinding inheritedMethod = methods[j];
+ if (inheritedMethod == null || this.method == inheritedMethod) // descriptor declaring class may not be same functional interface target type.
+ continue;
+ if (inheritedMethod.isStatic() || inheritedMethod.isDefaultMethod() || inheritedMethod.redeclaresPublicObjectMethod(this.scope))
+ continue;
+ inheritedMethod = MethodVerifier.computeSubstituteMethod(inheritedMethod, this.method, this.environment);
+ if (inheritedMethod == null || !MethodVerifier.isSubstituteParameterSubsignature(this.method, inheritedMethod, this.environment) ||
+ !MethodVerifier.areReturnTypesCompatible(this.method, inheritedMethod, this.environment))
+ continue;
+ final MethodBinding originalInherited = inheritedMethod.original();
+ if (!this.method.areParameterErasuresEqual(originalInherited) || TypeBinding.notEquals(this.method.returnType.erasure(), originalInherited.returnType.erasure()))
+ add(originalInherited);
+ }
+ collectBridges(superInterface.superInterfaces());
+ }
+ }
+ void add(MethodBinding inheritedMethod) {
+ if (this.bridges == null) {
+ this.bridges = new MethodBinding[] { inheritedMethod };
+ return;
+ }
+ int length = this.bridges.length;
+ for (int i = 0; i < length; i++) {
+ if (this.bridges[i].areParameterErasuresEqual(inheritedMethod) && TypeBinding.equalsEquals(this.bridges[i].returnType.erasure(), inheritedMethod.returnType.erasure()))
+ return;
+ }
+ System.arraycopy(this.bridges, 0, this.bridges = new MethodBinding[length + 1], 0, length);
+ this.bridges[length] = inheritedMethod;
+ }
+ MethodBinding [] getBridges () {
+ return this.bridges;
+ }
+ }
+
+ ReferenceBinding functionalType;
+ if (this.expectedType instanceof IntersectionCastTypeBinding) {
+ functionalType = (ReferenceBinding) ((IntersectionCastTypeBinding)this.expectedType).getSAMType(this.enclosingScope);
+ } else {
+ functionalType = (ReferenceBinding) this.expectedType;
+ }
+ return new BridgeCollector(functionalType, this.descriptor).getBridges();
+ }
+ boolean requiresBridges() {
+ return getRequiredBridges() != null;
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index 9b3063c..99a55d4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -180,7 +180,9 @@
return (this.binding.isVarargs() ||
(isConstructorReference() && this.receiverType.syntheticOuterLocalVariables() != null && currentScope.methodScope().isStatic) ||
this.expectedType instanceof IntersectionCastTypeBinding || // marker interfaces require alternate meta factory.
- this.expectedType.findSuperTypeOriginatingFrom(currentScope.getJavaIoSerializable()) != null); // serialization support.
+ this.expectedType.findSuperTypeOriginatingFrom(currentScope.getJavaIoSerializable()) != null || // serialization support.
+ this.requiresBridges()); // bridges.
+ // To fix: We should opt for direct code generation wherever possible.
}
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index 7ae36ba..e2cd332 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -452,6 +452,13 @@
public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
if (this.leafComponentType == unresolvedType) { //$IDENTITY-COMPARISON$
this.leafComponentType = env.convertUnresolvedBinaryToRawType(resolvedType);
+ /* Leaf component type is the key in the type system. If it undergoes change, the array has to be rehashed.
+ We achieve by creating a fresh array with the new component type and equating this array's id with that.
+ This means this array can still be found under the old key, but that is harmless (since the component type
+ is always consulted (see TypeSystem.getArrayType())
+ */
+ if (this.leafComponentType != resolvedType) //$IDENTITY-COMPARISON$
+ this.id = env.createArrayType(this.leafComponentType, this.dimensions, this.typeAnnotations).id;
this.tagBits |= this.leafComponentType.tagBits & (TagBits.HasTypeVariable | TagBits.HasDirectWildcard | TagBits.HasMissingType | TagBits.HasCapturedWildcard);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
index 58f9196..0cb4f64 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
@@ -120,13 +120,20 @@
}
public boolean isCompatibleWith(TypeBinding otherType, Scope captureScope) {
- if (this.upperBounds != null) {
- for (int i = 0; i < this.upperBounds.length; i++) {
- if (this.upperBounds[i].isCompatibleWith(otherType, captureScope))
- return true;
+ if (this.inRecursiveFunction)
+ return true;
+ this.inRecursiveFunction = true;
+ try {
+ if (this.upperBounds != null) {
+ for (int i = 0; i < this.upperBounds.length; i++) {
+ if (this.upperBounds[i].isCompatibleWith(otherType, captureScope))
+ return true;
+ }
}
+ return super.isCompatibleWith(otherType, captureScope);
+ } finally {
+ this.inRecursiveFunction = false;
}
- return super.isCompatibleWith(otherType, captureScope);
}
public TypeBinding findSuperTypeOriginatingFrom(TypeBinding otherType) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 6480402..7b51f10 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -1216,6 +1216,10 @@
AnnotationBinding[] filtered = new AnnotationBinding[newbies.length];
int count = 0;
for (int i = 0; i < newbies.length; i++) {
+ if (newbies[i] == null) {
+ filtered[count++] = null;
+ continue;
+ }
long tagBits = 0;
switch (newbies[i].type.id) {
case TypeIds.T_ConfiguredAnnotationNonNull : tagBits = TagBits.AnnotationNonNull; break;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
index 2c98bc7..de1fe90 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -115,7 +115,7 @@
boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) {
return areReturnTypesCompatible(one, two, this.type.scope.environment());
}
-static boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two, LookupEnvironment environment) {
+public static boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two, LookupEnvironment environment) {
//{ObjectTeams: consider enhanced callin signatures:
TypeBinding oneReturnType = MethodModel.getReturnType(one);
TypeBinding twoReturnType = MethodModel.getReturnType(two);
@@ -887,7 +887,7 @@
return computeSubstituteMethod(inheritedMethod, currentMethod, this.environment);
}
-static MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, LookupEnvironment environment) {
+public static MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, LookupEnvironment environment) {
if (inheritedMethod == null) return null;
//{ObjectTeams: use source-level params in case of enhanced callin methods:
/* orig:
@@ -1109,7 +1109,7 @@
return isSubstituteParameterSubsignature(method, substituteMethod, this.environment);
}
-static boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod, LookupEnvironment environment) {
+public static boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod, LookupEnvironment environment) {
//{ObjectTeams: added 3. argument:
if (!areParametersEqual(method, substituteMethod, environment)) {
// SH}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
index abf42c2..69c189d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -2324,48 +2324,29 @@
int contractsCount = 0;
int contractsLength = 0;
- // -- the following are used for early termination.
- MethodBinding aContract = null;
- int contractParameterLength = 0;
- char [] contractSelector = null;
- // ---
-
ReferenceBinding [] superInterfaces = superInterfaces();
for (int i = 0, length = superInterfaces.length; i < length; i++) {
MethodBinding [] superInterfaceContracts = superInterfaces[i].getInterfaceAbstractContracts(scope);
final int superInterfaceContractsLength = superInterfaceContracts == null ? 0 : superInterfaceContracts.length;
-
if (superInterfaceContractsLength == 0) continue;
- if (aContract == null) {
- aContract = superInterfaceContracts[0];
- contractParameterLength = aContract.parameters.length;
- contractSelector = aContract.selector;
- contracts = superInterfaceContracts;
- contractsCount = contractsLength = superInterfaceContractsLength;
- } else {
- if (superInterfaceContracts[0].parameters.length != contractParameterLength || !CharOperation.equals(contractSelector, superInterfaceContracts[0].selector)) {
- throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
- }
- if (contractsLength < contractsCount + superInterfaceContractsLength) {
- System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength = contractsCount + superInterfaceContractsLength], 0, contractsCount);
- }
- System.arraycopy(superInterfaceContracts, 0, contracts, contractsCount, superInterfaceContractsLength);
- contractsCount += superInterfaceContractsLength;
+ if (contractsLength < contractsCount + superInterfaceContractsLength) {
+ System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength = contractsCount + superInterfaceContractsLength], 0, contractsCount);
}
+ System.arraycopy(superInterfaceContracts, 0, contracts, contractsCount, superInterfaceContractsLength);
+ contractsCount += superInterfaceContractsLength;
}
+
for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++) {
final MethodBinding method = methods[i];
- if (method.isStatic() || method.redeclaresPublicObjectMethod(scope)) continue;
+ if (method == null || method.isStatic() || method.redeclaresPublicObjectMethod(scope))
+ continue;
+ if (!method.isValidBinding())
+ throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
if (method.isDefaultMethod()) {
for (int j = 0; j < contractsCount; j++) {
if (contracts[j] == null)
continue;
if (MethodVerifier.doesMethodOverride(method, contracts[j], scope.environment())) {
- if (aContract == contracts[j]) {
- aContract = null;
- contractParameterLength = 0;
- contractSelector = null;
- }
contractsCount--;
// abstract method from super type rendered default by present interface ==> contracts[j] = null;
if (j < contractsCount)
@@ -2374,16 +2355,6 @@
}
continue; // skip default method itself
}
- final boolean validBinding = method.isValidBinding();
- if (aContract == null && validBinding) {
- aContract = method;
- contractParameterLength = aContract.parameters.length;
- contractSelector = aContract.selector;
- } else {
- if (!validBinding || method.parameters.length != contractParameterLength || !CharOperation.equals(contractSelector, method.selector)) {
- throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
- }
- }
if (contractsCount == contractsLength) {
System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength += 16], 0, contractsCount);
}
@@ -2409,15 +2380,33 @@
MethodBinding[] methods = null;
try {
methods = getInterfaceAbstractContracts(scope);
+ if (methods == null || methods.length == 0)
+ return this.singleAbstractMethod[index] = samProblemBinding;
+ int contractParameterLength = 0;
+ char [] contractSelector = null;
+ for (int i = 0, length = methods.length; i < length; i++) {
+ MethodBinding method = methods[i];
+ if (method == null) continue;
+ if (contractSelector == null) {
+ contractSelector = method.selector;
+ contractParameterLength = method.parameters == null ? 0 : method.parameters.length;
+ } else {
+ int methodParameterLength = method.parameters == null ? 0 : method.parameters.length;
+ if (methodParameterLength != contractParameterLength || !CharOperation.equals(method.selector, contractSelector))
+ return this.singleAbstractMethod[index] = samProblemBinding;
+ }
+ }
} catch (InvalidInputException e) {
return this.singleAbstractMethod[index] = samProblemBinding;
}
- if (methods != null && methods.length == 1)
+ if (methods.length == 1)
return this.singleAbstractMethod[index] = methods[0];
final LookupEnvironment environment = scope.environment();
boolean genericMethodSeen = false;
- next:for (int i = 0, length = methods.length; i < length; i++) {
+ int length = methods.length;
+
+ next:for (int i = length - 1; i >= 0; --i) {
MethodBinding method = methods[i], otherMethod = null;
if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
genericMethodSeen = true;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
index 77ea4aa..1f665ec 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
@@ -862,7 +862,7 @@
* Node type constant indicating a node of type
* <code>NameQualifiedType</code>.
* @see NameQualifiedType
- * @since 3.9 BETA_JAV8
+ * @since 3.10
*/
public static final int NAME_QUALIFIED_TYPE = 88;
@@ -870,7 +870,7 @@
* Node type constant indicating a node of type
* <code>CreationReference</code>.
* @see CreationReference
- * @since 3.9 BETA_JAV8
+ * @since 3.10
*/
public static final int CREATION_REFERENCE = 89;
@@ -878,7 +878,7 @@
* Node type constant indicating a node of type
* <code>ExpressionMethodReference</code>.
* @see ExpressionMethodReference
- * @since 3.9 BETA_JAV8
+ * @since 3.10
*/
public static final int EXPRESSION_METHOD_REFERENCE = 90;
@@ -886,7 +886,7 @@
* Node type constant indicating a node of type
* <code>SuperMethhodReference</code>.
* @see SuperMethodReference
- * @since 3.9 BETA_JAV8
+ * @since 3.10
*/
public static final int SUPER_METHOD_REFERENCE = 91;
@@ -894,7 +894,7 @@
* Node type constant indicating a node of type
* <code>TypeMethodReference</code>.
* @see TypeMethodReference
- * @since 3.9 BETA_JAV8
+ * @since 3.10
*/
public static final int TYPE_METHOD_REFERENCE = 92;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
index f013dcc..2f78a96 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
@@ -74,10 +74,26 @@
public static final char JEM_LOCALVARIABLE = '@';
public static final char JEM_TYPE_PARAMETER = ']';
public static final char JEM_ANNOTATION = '}';
- public static final char JEM_LAMBDA_EXPRESSION = '>';
- public static final char JEM_LAMBDA_METHOD = '*';
+ public static final char JEM_LAMBDA_EXPRESSION = ')';
+ public static final char JEM_LAMBDA_METHOD = '&';
public static final char JEM_STRING = '"';
+ /**
+ * Before ')', '&' and '"' became the newest additions as delimiters, the former two
+ * were allowed as part of element attributes and possibly stored. Trying to recreate
+ * elements from such memento would cause undesirable results. Consider the following
+ * valid project name: (abc)
+ * If we were to use ')' alone as the delimiter and decode the above name, the memento
+ * would be wrongly identified to contain a lambda expression.
+ *
+ * In order to differentiate delimiters from characters that are part of element attributes,
+ * the following escape character is being introduced and all the new delimiters must
+ * be escaped with this. So, a lambda expression would be written as: "=)..."
+ *
+ * @see JavaElement#appendEscapedDelimiter(StringBuffer, char)
+ */
+ public static final char JEM_DELIMITER_ESCAPE = JEM_JAVAPROJECT;
+
/**
* This element's parent, or <code>null</code> if this
@@ -138,6 +154,16 @@
return getElementName().equals(other.getElementName()) &&
this.parent.equals(other.parent);
}
+ /**
+ * @see #JEM_DELIMITER_ESCAPE
+ */
+ protected void appendEscapedDelimiter(StringBuffer buffer, char delimiter) {
+ buffer.append(JEM_DELIMITER_ESCAPE);
+ buffer.append(delimiter);
+ }
+ /*
+ * Do not add new delimiters here
+ */
protected void escapeMementoName(StringBuffer buffer, String mementoName) {
for (int i = 0, length = mementoName.length(); i < length; i++) {
char character = mementoName.charAt(i);
@@ -161,9 +187,6 @@
case JEM_LOCALVARIABLE:
case JEM_TYPE_PARAMETER:
case JEM_ANNOTATION:
- case JEM_LAMBDA_EXPRESSION:
- case JEM_LAMBDA_METHOD:
- case JEM_STRING:
buffer.append(JEM_ESCAPE);
}
buffer.append(character);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaExpression.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaExpression.java
index fd15974..9c0772b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaExpression.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaExpression.java
@@ -36,11 +36,11 @@
// Construction from AST node
public LambdaExpression(JavaElement parent, org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression) {
- super(parent, new String("Lambda(") + new String(lambdaExpression.descriptor.declaringClass.sourceName()) + ')'); //$NON-NLS-1$
+ super(parent, new String("Lambda(") + new String(lambdaExpression.resolvedType.sourceName()) + ')'); //$NON-NLS-1$
this.sourceStart = lambdaExpression.sourceStart;
this.sourceEnd = lambdaExpression.sourceEnd;
this.arrowPosition = lambdaExpression.arrowPosition;
- this.interphase = new String(lambdaExpression.descriptor.declaringClass.readableName());
+ this.interphase = new String(CharOperation.replaceOnCopy(lambdaExpression.resolvedType.genericTypeSignature(), '/', '.'));
this.elementInfo = makeTypeElementInfo(this, this.interphase, this.sourceStart, this.sourceEnd, this.arrowPosition);
this.lambdaMethod = LambdaMethod.make(this, lambdaExpression);
this.elementInfo.children = new IJavaElement[] { this.lambdaMethod };
@@ -84,7 +84,7 @@
elementInfo.addCategories(handle, null);
JavaModelManager manager = JavaModelManager.getJavaModelManager();
- char[][] superinterfaces = new char [][] { manager.intern(interphase.toCharArray()) }; // drops marker interfaces - to fix.
+ char[][] superinterfaces = new char [][] { manager.intern(Signature.toString(interphase).toCharArray()) }; // drops marker interfaces - to fix.
elementInfo.setSuperInterfaceNames(superinterfaces);
return elementInfo;
}
@@ -127,15 +127,17 @@
* @see JavaElement#getHandleMemento(StringBuffer)
*/
protected void getHandleMemento(StringBuffer buff) {
- getHandleMemento(buff, true);
+ getHandleMemento(buff, true, true);
+ // lambda method and lambda expression cannot share the same memento - add a trailing discriminator.
+ appendEscapedDelimiter(buff, getHandleMementoDelimiter());
}
- protected void getHandleMemento(StringBuffer buff, boolean memoizeParent) {
- if (memoizeParent)
+ protected void getHandleMemento(StringBuffer buff, boolean serializeParent, boolean serializeChild) {
+ if (serializeParent)
((JavaElement)getParent()).getHandleMemento(buff);
- buff.append(getHandleMementoDelimiter());
+ appendEscapedDelimiter(buff, getHandleMementoDelimiter());
escapeMementoName(buff, this.name);
- buff.append(JEM_STRING);
+ appendEscapedDelimiter(buff, JEM_STRING);
escapeMementoName(buff, this.interphase);
buff.append(JEM_COUNT);
buff.append(this.sourceStart);
@@ -143,6 +145,8 @@
buff.append(this.sourceEnd);
buff.append(JEM_COUNT);
buff.append(this.arrowPosition);
+ if (serializeChild)
+ this.lambdaMethod.getHandleMemento(buff, false);
}
public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
@@ -175,11 +179,17 @@
}
this.lambdaMethod.elementInfo.arguments = parameters;
this.elementInfo.children = new IJavaElement[] { this.lambdaMethod };
- return this.lambdaMethod;
- }
-
- public boolean isReadOnly() {
- return true;
+ if (!memento.hasMoreTokens())
+ return this.lambdaMethod;
+ switch (memento.nextToken().charAt(0)) {
+ case JEM_LAMBDA_METHOD:
+ if (!memento.hasMoreTokens())
+ return this.lambdaMethod;
+ return this.lambdaMethod.getHandleFromMemento(memento, workingCopyOwner);
+ case JEM_LAMBDA_EXPRESSION:
+ default:
+ return this;
+ }
}
public IJavaElement[] getChildren() throws JavaModelException {
@@ -209,8 +219,7 @@
if (primaryParent instanceof JavaElement) {
JavaElement ancestor = (JavaElement) primaryParent;
StringBuffer buffer = new StringBuffer(32);
- getHandleMemento(buffer, false);
- this.lambdaMethod.getHandleMemento(buffer, false);
+ getHandleMemento(buffer, false, true);
String memento = buffer.toString();
return ancestor.getHandleFromMemento(new MementoTokenizer(memento), DefaultWorkingCopyOwner.PRIMARY).getParent();
}
@@ -218,15 +227,6 @@
}
public String[] getSuperInterfaceTypeSignatures() throws JavaModelException {
- SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
- char[][] names = info.getInterfaceNames();
- if (names == null) {
- return CharOperation.NO_STRINGS;
- }
- String[] strings = new String[names.length];
- for (int i= 0; i < names.length; i++) {
- strings[i] = new String(Signature.createTypeSignature(names[i], true));
- }
- return strings;
+ return new String[] { this.interphase };
}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaMethod.java
index 1bc360d..6abf2a2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaMethod.java
@@ -130,24 +130,24 @@
return this.elementInfo;
}
- public void getHandleMemento(StringBuffer buff, boolean memoizeParent) {
- if (memoizeParent)
- ((JavaElement) getParent()).getHandleMemento(buff);
- char delimiter = getHandleMementoDelimiter();
- buff.append(delimiter);
+ public void getHandleMemento(StringBuffer buff, boolean serializeParent) {
+ if (serializeParent) {
+ ((LambdaExpression) getParent()).getHandleMemento(buff, true, false);
+ }
+ appendEscapedDelimiter(buff, getHandleMementoDelimiter());
escapeMementoName(buff, getElementName());
buff.append(JEM_COUNT);
buff.append(this.parameterTypes.length);
for (int i = 0, length = this.parameterTypes.length; i < length; i++) {
- buff.append(JEM_STRING);
- buff.append(this.parameterTypes[i]);
- buff.append(JEM_STRING);
- buff.append(this.parameterNameStrings[i]);
+ appendEscapedDelimiter(buff, JEM_STRING);
+ escapeMementoName(buff, this.parameterTypes[i]);
+ appendEscapedDelimiter(buff, JEM_STRING);
+ escapeMementoName(buff, this.parameterNameStrings[i]);
}
- buff.append(JEM_STRING);
- buff.append(this.returnTypeString);
- buff.append(JEM_STRING);
- buff.append(this.key);
+ appendEscapedDelimiter(buff, JEM_STRING);
+ escapeMementoName(buff, this.returnTypeString);
+ appendEscapedDelimiter(buff, JEM_STRING);
+ escapeMementoName(buff, this.key);
ILocalVariable[] arguments = this.elementInfo.arguments;
for (int i = 0, length = arguments.length; i < length; i++) {
LocalVariable local = (LocalVariable) arguments[i];
@@ -156,6 +156,8 @@
}
public void getHandleMemento(StringBuffer buff) {
getHandleMemento(buff, true);
+ // lambda method and lambda expression cannot share the same memento - add a trailing discriminator.
+ appendEscapedDelimiter(buff, getHandleMementoDelimiter());
}
protected char getHandleMementoDelimiter() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java
index b64e142..38e4c04 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java
@@ -188,9 +188,9 @@
if (!memento.hasMoreTokens() || memento.nextToken() != MementoTokenizer.COUNT)
return this;
int arrowPosition = Integer.parseInt(memento.nextToken());
- if (!memento.hasMoreTokens() || (token = memento.nextToken()) != MementoTokenizer.LAMBDA_METHOD)
- return this;
LambdaExpression expression = new LambdaExpression(this, name, interphase, sourceStart, sourceEnd, arrowPosition);
+ if (!memento.hasMoreTokens() || (token = memento.nextToken()) != MementoTokenizer.LAMBDA_METHOD)
+ return expression;
return expression.getHandleFromMemento(token, memento, workingCopyOwner);
case JEM_TYPE:
String typeName;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java
index 0ce0e71..025f697 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -37,7 +37,7 @@
/**
* The name of the superclass for this type. This name
- * is fully qualified for binary types and is NOT
+ * is fully qualified for binary types and is NOT always
* fully qualified for source types.
*/
protected char[] superclassName;
@@ -60,7 +60,7 @@
/**
* The names of the interfaces this type implements or
* extends. These names are fully qualified in the case
- * of a binary type, and are NOT fully qualified in the
+ * of a binary type, and are NOT always fully qualified in the
* case of a source type
*/
protected char[][] superInterfaceNames;
@@ -328,13 +328,13 @@
this.handle = handle;
}
/**
- * Sets the (unqualified) name of this type's superclass
+ * Sets the (unresolved) name of this type's superclass
*/
protected void setSuperclassName(char[] superclassName) {
this.superclassName = superclassName;
}
/**
- * Sets the (unqualified) names of the interfaces this type implements or extends
+ * Sets the (unresolved) names of the interfaces this type implements or extends
*/
protected void setSuperInterfaceNames(char[][] superInterfaceNames) {
this.superInterfaceNames = superInterfaceNames;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
index f155dd2..21cf02f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
@@ -599,7 +599,7 @@
decodeModifiersForMethodParameters(buffer, accessFlags);
char [] parameterName = methodParametersAttribute.getParameterName(i);
if (parameterName == null)
- parameterName = CharOperation.concat(Messages.disassembler_parametername.toCharArray(), Integer.toString(i).toCharArray());
+ parameterName = Messages.disassembler_anonymousparametername.toCharArray();
buffer.append(parameterName);
}
}
@@ -2447,7 +2447,7 @@
if (i < parameterCount && parametersAttribute.getParameterName(i) != null) {
parameterNames[i] = parametersAttribute.getParameterName(i);
} else {
- parameterNames[i] = CharOperation.concat(Messages.disassembler_parametername.toCharArray(), Integer.toString(i).toCharArray());
+ parameterNames[i] = Messages.disassembler_anonymousparametername.toCharArray();
}
}
} else if (codeAttribute != null) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java
index 3032da3..5ee6449 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java
@@ -59,6 +59,24 @@
case JavaElement.JEM_COUNT:
return COUNT;
case JavaElement.JEM_JAVAPROJECT:
+ // Also covers JavaElement#JEM_DELIMITER_ESCAPE, in which case,
+ // we seek ahead by one char and check if it's an escaped delimiter
+ // and if that's true, we return that as the token.
+ // Else, we decide that JEM_JAVAPROJECT is the current token.
+ if (this.index < this.length) {
+ char nextChar = this.memento[this.index++];
+ switch(nextChar) {
+ case JavaElement.JEM_LAMBDA_EXPRESSION:
+ return LAMBDA_EXPRESSION;
+ case JavaElement.JEM_LAMBDA_METHOD:
+ return LAMBDA_METHOD;
+ case JavaElement.JEM_STRING:
+ return STRING;
+ default:
+ this.index--;
+ break;
+ }
+ }
return JAVAPROJECT;
case JavaElement.JEM_PACKAGEFRAGMENTROOT:
return PACKAGEFRAGMENTROOT;
@@ -84,12 +102,6 @@
return PACKAGEDECLARATION;
case JavaElement.JEM_IMPORTDECLARATION:
return IMPORTDECLARATION;
- case JavaElement.JEM_LAMBDA_EXPRESSION:
- return LAMBDA_EXPRESSION;
- case JavaElement.JEM_LAMBDA_METHOD:
- return LAMBDA_METHOD;
- case JavaElement.JEM_STRING:
- return STRING;
case JavaElement.JEM_LOCALVARIABLE:
return LOCALVARIABLE;
case JavaElement.JEM_TYPE_PARAMETER:
@@ -120,9 +132,6 @@
case JavaElement.JEM_PACKAGEDECLARATION:
case JavaElement.JEM_IMPORTDECLARATION:
case JavaElement.JEM_LOCALVARIABLE:
- case JavaElement.JEM_LAMBDA_EXPRESSION:
- case JavaElement.JEM_LAMBDA_METHOD:
- case JavaElement.JEM_STRING:
case JavaElement.JEM_TYPE_PARAMETER:
case JavaElement.JEM_ANNOTATION:
break loop;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
index ea222bd..4e52a9e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
@@ -244,6 +244,7 @@
public static String disassembler_opentypedeclaration;
public static String disassembler_closetypedeclaration;
public static String disassembler_parametername;
+ public static String disassembler_anonymousparametername;
public static String disassembler_localvariablename;
public static String disassembler_endofmethodheader;
public static String disassembler_begincommentline;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
index d851b42..383ff0f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
@@ -268,6 +268,7 @@
disassembler_opentypedeclaration =\ '{'
disassembler_closetypedeclaration = }
disassembler_parametername = arg
+disassembler_anonymousparametername = <anonymous>
disassembler_localvariablename = local_{0}
disassembler_endofmethodheader = ;
disassembler_begincommentline = //\
diff --git a/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF
index 0e0d716..0b3adbd 100644
--- a/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: Eclipse Compiler for Java(TM)
Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch
-Bundle-Version: 3.9.2.qualifier
+Bundle-Version: 3.10.0.qualifier
Bundle-ClassPath: .
Bundle-Vendor: Eclipse.org
Export-Package: org.eclipse.jdt.core,
diff --git a/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
index fcb26c6..02a9676 100644
--- a/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
@@ -1,6 +1,6 @@
Bundle-ManifestVersion: 2
Bundle-Name: Source of Eclipse Compiler for Java(TM)
Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch.source
-Bundle-Version: 3.9.2.qualifier
+Bundle-Version: 3.10.0.qualifier
Bundle-Vendor: Eclipse.org
-Eclipse-SourceBundle: org.eclipse.jdt.core.compiler.batch;version="3.9.2.${buildQualifier}";roots:="."
+Eclipse-SourceBundle: org.eclipse.jdt.core.compiler.batch;version="3.10.0.${buildQualifier}";roots:="."
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
index cf07e32..58e3f0e 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
@@ -197,15 +197,15 @@
private void reduceParseTree(CompilationUnitDeclaration unit) {
// remove statements from methods that have no functional interface types.
TypeDeclaration[] types = unit.types;
- for (int i = 0, l = types.length; i < l; i++)
+ for (int i = 0, l = types == null ? 0 : types.length; i < l; i++)
purgeMethodStatements(types[i]);
}
private void purgeMethodStatements(TypeDeclaration type) {
AbstractMethodDeclaration[] methods = type.methods;
- for (int j = 0, length = methods.length; j < length; j++) {
+ for (int j = 0, length = methods == null ? 0 : methods.length; j < length; j++) {
AbstractMethodDeclaration method = methods[j];
- if ((method.bits & ASTNode.HasFunctionalInterfaceTypes) == 0) {
+ if (method != null && (method.bits & ASTNode.HasFunctionalInterfaceTypes) == 0) {
method.statements = null;
method.javadoc = null;
}
@@ -225,7 +225,7 @@
if (expression instanceof LambdaExpression) {
LambdaExpression lambdaExpression = (LambdaExpression) expression;
if (lambdaExpression.binding != null && lambdaExpression.binding.isValidBinding()) {
- final char[] superinterface = lambdaExpression.descriptor.declaringClass.sourceName();
+ final char[] superinterface = lambdaExpression.resolvedType.sourceName();
if (DEBUG) {
System.out.println('\t' + new String(superinterface) + '.' +
new String(lambdaExpression.descriptor.selector) + "-> {}"); //$NON-NLS-1$
@@ -254,7 +254,7 @@
MethodBinding binding = referenceExpression.getMethodBinding();
if (binding != null && binding.isValidBinding()) {
if (DEBUG) {
- System.out.println('\t' + new String(referenceExpression.descriptor.declaringClass.sourceName()) + "::" //$NON-NLS-1$
+ System.out.println('\t' + new String(referenceExpression.resolvedType.sourceName()) + "::" //$NON-NLS-1$
+ new String(referenceExpression.descriptor.selector) + " == " + new String(binding.declaringClass.sourceName()) + '.' + //$NON-NLS-1$
new String(binding.selector));
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java
index 9e9b2aa..68cfb5d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -19,12 +19,14 @@
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -108,6 +110,17 @@
}
return level;
}
+public int match(LambdaExpression node, MatchingNodeSet nodeSet) {
+ int level = IMPOSSIBLE_MATCH;
+ for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+ int newLevel = this.patternLocators[i].match(node, nodeSet);
+ if (newLevel > level) {
+ if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+ level = newLevel;
+ }
+ }
+ return level;
+}
public int match(LocalDeclaration node, MatchingNodeSet nodeSet) {
int level = IMPOSSIBLE_MATCH;
for (int i = 0, length = this.patternLocators.length; i < length; i++) {
@@ -163,6 +176,17 @@
}
return level;
}
+public int match(ReferenceExpression node, MatchingNodeSet nodeSet) {
+ int level = IMPOSSIBLE_MATCH;
+ for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+ int newLevel = this.patternLocators[i].match(node, nodeSet);
+ if (newLevel > level) {
+ if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+ level = newLevel;
+ }
+ }
+ return level;
+}
public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
int level = IMPOSSIBLE_MATCH;
for (int i = 0, length = this.patternLocators.length; i < length; i++) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
index 4d43a60..328773c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -23,12 +23,14 @@
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -116,6 +118,17 @@
}
return level;
}
+public int match(LambdaExpression node, MatchingNodeSet nodeSet) {
+ int level = IMPOSSIBLE_MATCH;
+ for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+ int newLevel = this.patternLocators[i].match(node, nodeSet);
+ if (newLevel > level) {
+ if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+ level = newLevel;
+ }
+ }
+ return level;
+}
public int match(LocalDeclaration node, MatchingNodeSet nodeSet) {
int level = IMPOSSIBLE_MATCH;
for (int i = 0, length = this.patternLocators.length; i < length; i++) {
@@ -258,6 +271,17 @@
}
return level;
}
+public int match(ReferenceExpression node, MatchingNodeSet nodeSet) {
+ int level = IMPOSSIBLE_MATCH;
+ for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+ int newLevel = this.patternLocators[i].match(node, nodeSet);
+ if (newLevel > level) {
+ if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+ level = newLevel;
+ }
+ }
+ return level;
+}
public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
int level = IMPOSSIBLE_MATCH;
for (int i = 0, length = this.patternLocators.length; i < length; i++) {