Update jdt.core to 4.14 M1 (I20191009-1800)
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ParserTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ParserTest.java
index e9c12eb..407758e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ParserTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ParserTest.java
@@ -759,7 +759,7 @@
"1. ERROR in X.java (at line 4)\n" +
" Srtring bar = \"\"\"\n" +
" }\n" +
- " ^^^^^^^^^\n" +
+ " ^^^^\n" +
"Text block is not properly closed with the delimiter\n" +
"----------\n" :
"----------\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 53389d3..582f257 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -106,7 +106,7 @@
public abstract class AbstractRegressionTest extends AbstractCompilerTest implements StopableTestCase {
static final String[] env = System.getenv().entrySet().stream()
- .filter(e -> !"JAVA_TOOL_OPTIONS".equals(e.getKey()))
+ .filter(e -> !"JAVA_TOOL_OPTIONS".equals(e.getKey()) && !"_JAVA_OPTIONS".equals(e.getKey()))
.map(e -> e.getKey() + "=" + e.getValue())
.toArray(String[]::new);
@@ -382,6 +382,12 @@
if ("1.8.0_182".equals(rawVersion)) {
return 2500;
}
+ if ("1.8.0_202".equals(rawVersion)) {
+ return 2600;
+ }
+ if ("1.8.0_212".equals(rawVersion)) {
+ return 2700;
+ }
}
if (version == JavaCore.VERSION_9) {
if ("9".equals(rawVersion)) {
@@ -2440,6 +2446,8 @@
}
private void deleteSourceFiles(File directory) {
try {
+ if (!directory.exists())
+ return;
Files.walk(directory.toPath())
.filter(f -> f.endsWith(SuffixConstants.SUFFIX_STRING_java))
.map(java.nio.file.Path::toFile)
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index 884b680..195dc75 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -10783,17 +10783,17 @@
+ " -proceedOnError -err:+unused -d \"" + OUTPUT_DIR + "\"",
"",
"----------\n" +
- "1. INFO in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" +
+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" +
" @SuppressWarnings(\"unused\")\n" +
" ^^^^^^^^\n" +
- "At least one of the problems in category 'unused' is not analysed due to a compiler option being ignored\n" +
+ "Unnecessary @SuppressWarnings(\"unused\")\n" +
"----------\n" +
"2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 3)\n" +
" private int i;\n" +
" ^\n" +
"The value of the field X.i is not used\n" +
"----------\n" +
- "2 problems (1 error, 0 warnings, 1 info)\n",
+ "2 problems (1 error, 1 warning)\n",
true);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=295551
@@ -10874,17 +10874,17 @@
+ " -proceedOnError -warn:-suppress -err:+suppress,unused -warn:+suppress -d \"" + OUTPUT_DIR + "\"",
"",
"----------\n" +
- "1. INFO in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" +
+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" +
" @SuppressWarnings(\"unused\")\n" +
" ^^^^^^^^\n" +
- "At least one of the problems in category 'unused' is not analysed due to a compiler option being ignored\n" +
+ "Unnecessary @SuppressWarnings(\"unused\")\n" +
"----------\n" +
"2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 3)\n" +
" private int i;\n" +
" ^\n" +
"The value of the field X.i is not used\n" +
"----------\n" +
- "2 problems (1 error, 0 warnings, 1 info)\n",
+ "2 problems (1 error, 1 warning)\n",
true);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=295551
@@ -13257,4 +13257,28 @@
"",
true);
}
+public void testUnusedObjectAllocation() {
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void foo() {\n" +
+ " new X();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "X.java\""
+ + " -err:+unused"
+ + " -d \"" + OUTPUT_DIR + File.separator + "bin/\"",
+ "",
+ "----------\n" +
+ "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 3)\n" +
+ " new X();\n" +
+ " ^^^^^^^\n" +
+ "The allocated object is never used\n" +
+ "----------\n" +
+ "1 problem (1 error)\n",
+ true);
+
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConditionalExpressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConditionalExpressionTest.java
index d63e379..c959426 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConditionalExpressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConditionalExpressionTest.java
@@ -576,20 +576,39 @@
if (this.complianceLevel < ClassFileConstants.JDK1_8)
return;
this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X extends Y {\n" +
- " public X(Z[] n) {\n" +
- " super((n == null) ? null : n.clone());\n" +
- " }\n" +
- "}\n" +
- "class Y {\n" +
- " public Y(Z[] notifications) {\n" +
- " }\n" +
- "}\n" +
- "interface Z {}\n",
- },
- "");
+ new String[] {
+ "X.java",
+ "public class X extends Y {\n" +
+ " public X(Z[] n) {\n" +
+ " super((n == null) ? null : n.clone());\n" +
+ " }\n" +
+ "}\n" +
+ "class Y {\n" +
+ " public Y(Z[] notifications) {\n" +
+ " }\n" +
+ "}\n" +
+ "interface Z {}\n",
+ },
+ "");
+ }
+ public void test437444_2() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_8)
+ return;
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X extends Y {\n" +
+ " public X(int[] n) {\n" +
+ " super((n == null) ? null : n.clone());\n" +
+ " }\n" +
+ "}\n" +
+ "class Y {\n" +
+ " public Y(int[] notifications) {\n" +
+ " }\n" +
+ "}\n" +
+ "interface Z {}\n",
+ },
+ "");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=484425: [bytecode] Bad type on operand stack - compiler omitted instructions for unboxing null Boolean
public void test484425() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
index 693beee..28c2127 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
@@ -367,134 +367,126 @@
ClassFileBytesDisassembler.DETAILED);
String expectedOutput =
- " // Method descriptor #15 ([Ljava/lang/String;)V\n" +
- " // Stack: 3, Locals: 4\n" +
- " public static void main(java.lang.String[] args);\n" +
- " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 3 ldc <String \"1\"> [22]\n" +
- " 5 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 8 aconst_null\n" +
- " 9 goto 13\n" +
- " 12 aconst_null\n" +
- " 13 aconst_null\n" +
- " 14 goto 18\n" +
- " 17 aconst_null\n" +
- " 18 if_acmpne 29\n" +
- " 21 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 24 ldc <String \"2\"> [30]\n" +
- " 26 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 29 new java.lang.StringBuffer [32]\n" +
- " 32 dup\n" +
- " 33 ldc <String \"[\"> [34]\n" +
- " 35 invokespecial java.lang.StringBuffer(java.lang.String) [36]\n" +
- " 38 aconst_null\n" +
- " 39 invokevirtual java.lang.StringBuffer.append(java.lang.Object) : java.lang.StringBuffer [38]\n" +
- " 42 ldc <String \"]\"> [42]\n" +
- " 44 invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [44]\n" +
- " 47 invokevirtual java.lang.StringBuffer.toString() : java.lang.String [47]\n" +
- " 50 ldc <String \"[null]\"> [51]\n" +
- " 52 if_acmpne 59\n" +
- " 55 iconst_1\n" +
- " 56 goto 60\n" +
- " 59 iconst_0\n" +
- " 60 istore_1 [b]\n" +
- " 61 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 64 ldc <String \"3\"> [53]\n" +
- " 66 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 69 aconst_null\n" +
- " 70 astore_2 [s]\n" +
- " 71 aload_2 [s]\n" +
- " 72 ifnonnull 83\n" +
- " 75 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 78 ldc <String \"4\"> [55]\n" +
- " 80 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 83 ldc <String \"aaa\"> [57]\n" +
- " 85 astore_3 [s2]\n" +
- " 86 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 89 ldc <String \"5\"> [59]\n" +
- " 91 invokevirtual java.io.PrintStream.println(java.lang.String) : void [61]\n" +
- " 94 return\n" +
- " Line numbers:\n" +
- " [pc: 0, line: 3]\n" +
- " [pc: 8, line: 4]\n" +
- " [pc: 21, line: 5]\n" +
- " [pc: 29, line: 6]\n" +
- " [pc: 61, line: 7]\n" +
- " [pc: 69, line: 8]\n" +
- " [pc: 71, line: 9]\n" +
- " [pc: 83, line: 10]\n" +
- " [pc: 86, line: 11]\n" +
- " [pc: 94, line: 12]\n" +
- " Local variable table:\n" +
- " [pc: 0, pc: 95] local: args index: 0 type: java.lang.String[]\n" +
- " [pc: 61, pc: 95] local: b index: 1 type: boolean\n" +
- " [pc: 71, pc: 95] local: s index: 2 type: java.lang.String\n" +
- " [pc: 86, pc: 95] local: s2 index: 3 type: java.lang.String\n";
+ " // Method descriptor #15 ([Ljava/lang/String;)V\n" +
+ " // Stack: 3, Locals: 4\n" +
+ " public static void main(java.lang.String[] args);\n" +
+ " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 3 ldc <String \"1\"> [22]\n" +
+ " 5 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 8 aconst_null\n" +
+ " 9 aconst_null\n" +
+ " 10 if_acmpne 21\n" +
+ " 13 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 16 ldc <String \"2\"> [30]\n" +
+ " 18 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 21 new java.lang.StringBuffer [32]\n" +
+ " 24 dup\n" +
+ " 25 ldc <String \"[\"> [34]\n" +
+ " 27 invokespecial java.lang.StringBuffer(java.lang.String) [36]\n" +
+ " 30 aconst_null\n" +
+ " 31 invokevirtual java.lang.StringBuffer.append(java.lang.Object) : java.lang.StringBuffer [38]\n" +
+ " 34 ldc <String \"]\"> [42]\n" +
+ " 36 invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [44]\n" +
+ " 39 invokevirtual java.lang.StringBuffer.toString() : java.lang.String [47]\n" +
+ " 42 ldc <String \"[null]\"> [51]\n" +
+ " 44 if_acmpne 51\n" +
+ " 47 iconst_1\n" +
+ " 48 goto 52\n" +
+ " 51 iconst_0\n" +
+ " 52 istore_1 [b]\n" +
+ " 53 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 56 ldc <String \"3\"> [53]\n" +
+ " 58 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 61 aconst_null\n" +
+ " 62 astore_2 [s]\n" +
+ " 63 aload_2 [s]\n" +
+ " 64 ifnonnull 75\n" +
+ " 67 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 70 ldc <String \"4\"> [55]\n" +
+ " 72 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 75 ldc <String \"aaa\"> [57]\n" +
+ " 77 astore_3 [s2]\n" +
+ " 78 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 81 ldc <String \"5\"> [59]\n" +
+ " 83 invokevirtual java.io.PrintStream.println(java.lang.String) : void [61]\n" +
+ " 86 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 3]\n" +
+ " [pc: 8, line: 4]\n" +
+ " [pc: 13, line: 5]\n" +
+ " [pc: 21, line: 6]\n" +
+ " [pc: 53, line: 7]\n" +
+ " [pc: 61, line: 8]\n" +
+ " [pc: 63, line: 9]\n" +
+ " [pc: 75, line: 10]\n" +
+ " [pc: 78, line: 11]\n" +
+ " [pc: 86, line: 12]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 87] local: args index: 0 type: java.lang.String[]\n" +
+ " [pc: 53, pc: 87] local: b index: 1 type: boolean\n" +
+ " [pc: 63, pc: 87] local: s index: 2 type: java.lang.String\n" +
+ " [pc: 78, pc: 87] local: s2 index: 3 type: java.lang.String\n";
String expectedOutput15 =
- " // Method descriptor #15 ([Ljava/lang/String;)V\n" +
- " // Stack: 3, Locals: 4\n" +
- " public static void main(java.lang.String[] args);\n" +
- " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 3 ldc <String \"1\"> [22]\n" +
- " 5 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 8 aconst_null\n" +
- " 9 goto 13\n" +
- " 12 aconst_null\n" +
- " 13 aconst_null\n" +
- " 14 goto 18\n" +
- " 17 aconst_null\n" +
- " 18 if_acmpne 29\n" +
- " 21 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 24 ldc <String \"2\"> [30]\n" +
- " 26 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 29 new java.lang.StringBuilder [32]\n" +
- " 32 dup\n" +
- " 33 ldc <String \"[\"> [34]\n" +
- " 35 invokespecial java.lang.StringBuilder(java.lang.String) [36]\n" +
- " 38 aconst_null\n" +
- " 39 invokevirtual java.lang.StringBuilder.append(java.lang.Object) : java.lang.StringBuilder [38]\n" +
- " 42 ldc <String \"]\"> [42]\n" +
- " 44 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [44]\n" +
- " 47 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [47]\n" +
- " 50 ldc <String \"[null]\"> [51]\n" +
- " 52 if_acmpne 59\n" +
- " 55 iconst_1\n" +
- " 56 goto 60\n" +
- " 59 iconst_0\n" +
- " 60 istore_1 [b]\n" +
- " 61 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 64 ldc <String \"3\"> [53]\n" +
- " 66 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 69 aconst_null\n" +
- " 70 astore_2 [s]\n" +
- " 71 aload_2 [s]\n" +
- " 72 ifnonnull 83\n" +
- " 75 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 78 ldc <String \"4\"> [55]\n" +
- " 80 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 83 ldc <String \"aaa\"> [57]\n" +
- " 85 astore_3 [s2]\n" +
- " 86 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 89 ldc <String \"5\"> [59]\n" +
- " 91 invokevirtual java.io.PrintStream.println(java.lang.String) : void [61]\n" +
- " 94 return\n" +
- " Line numbers:\n" +
- " [pc: 0, line: 3]\n" +
- " [pc: 8, line: 4]\n" +
- " [pc: 21, line: 5]\n" +
- " [pc: 29, line: 6]\n" +
- " [pc: 61, line: 7]\n" +
- " [pc: 69, line: 8]\n" +
- " [pc: 71, line: 9]\n" +
- " [pc: 83, line: 10]\n" +
- " [pc: 86, line: 11]\n" +
- " [pc: 94, line: 12]\n" +
- " Local variable table:\n" +
- " [pc: 0, pc: 95] local: args index: 0 type: java.lang.String[]\n" +
- " [pc: 61, pc: 95] local: b index: 1 type: boolean\n" +
- " [pc: 71, pc: 95] local: s index: 2 type: java.lang.String\n" +
- " [pc: 86, pc: 95] local: s2 index: 3 type: java.lang.String\n";
+ " // Method descriptor #15 ([Ljava/lang/String;)V\n" +
+ " // Stack: 3, Locals: 4\n" +
+ " public static void main(java.lang.String[] args);\n" +
+ " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 3 ldc <String \"1\"> [22]\n" +
+ " 5 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 8 aconst_null\n" +
+ " 9 aconst_null\n" +
+ " 10 if_acmpne 21\n" +
+ " 13 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 16 ldc <String \"2\"> [30]\n" +
+ " 18 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 21 new java.lang.StringBuilder [32]\n" +
+ " 24 dup\n" +
+ " 25 ldc <String \"[\"> [34]\n" +
+ " 27 invokespecial java.lang.StringBuilder(java.lang.String) [36]\n" +
+ " 30 aconst_null\n" +
+ " 31 invokevirtual java.lang.StringBuilder.append(java.lang.Object) : java.lang.StringBuilder [38]\n" +
+ " 34 ldc <String \"]\"> [42]\n" +
+ " 36 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [44]\n" +
+ " 39 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [47]\n" +
+ " 42 ldc <String \"[null]\"> [51]\n" +
+ " 44 if_acmpne 51\n" +
+ " 47 iconst_1\n" +
+ " 48 goto 52\n" +
+ " 51 iconst_0\n" +
+ " 52 istore_1 [b]\n" +
+ " 53 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 56 ldc <String \"3\"> [53]\n" +
+ " 58 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 61 aconst_null\n" +
+ " 62 astore_2 [s]\n" +
+ " 63 aload_2 [s]\n" +
+ " 64 ifnonnull 75\n" +
+ " 67 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 70 ldc <String \"4\"> [55]\n" +
+ " 72 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 75 ldc <String \"aaa\"> [57]\n" +
+ " 77 astore_3 [s2]\n" +
+ " 78 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 81 ldc <String \"5\"> [59]\n" +
+ " 83 invokevirtual java.io.PrintStream.println(java.lang.String) : void [61]\n" +
+ " 86 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 3]\n" +
+ " [pc: 8, line: 4]\n" +
+ " [pc: 13, line: 5]\n" +
+ " [pc: 21, line: 6]\n" +
+ " [pc: 53, line: 7]\n" +
+ " [pc: 61, line: 8]\n" +
+ " [pc: 63, line: 9]\n" +
+ " [pc: 75, line: 10]\n" +
+ " [pc: 78, line: 11]\n" +
+ " [pc: 86, line: 12]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 87] local: args index: 0 type: java.lang.String[]\n" +
+ " [pc: 53, pc: 87] local: b index: 1 type: boolean\n" +
+ " [pc: 63, pc: 87] local: s index: 2 type: java.lang.String\n" +
+ " [pc: 78, pc: 87] local: s2 index: 3 type: java.lang.String\n";
if (this.complianceLevel >= ClassFileConstants.JDK1_5) {
int index = actualOutput.indexOf(expectedOutput15);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
index 50a2135..fa024bc 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
@@ -18283,7 +18283,7 @@
runner.runNegativeTest();
}
public void testBug542707_1() {
- if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression
+ if (this.complianceLevel < ClassFileConstants.JDK13) return; // switch expression
Runner runner = new Runner();
runner.customOptions = new HashMap<>();
runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
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 17ef64b..c6e8637 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
@@ -17772,7 +17772,7 @@
);
}
public void testBug542707_1() {
- if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression
+ if (this.complianceLevel < ClassFileConstants.JDK13) return; // switch expression
// switch expression has a functional type with interesting type inference and various null issues:
Runner runner = new Runner();
runner.customOptions = getCompilerOptions();
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
index 36470b3..ce9e6cf 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
@@ -851,13 +851,9 @@
" [pc: 5, pc: 24] local: bar index: 2 type: java.lang.String\n" +
" Stack map table: number of frames 2\n" +
" [pc: 19, full, stack: {java.io.PrintStream}, locals: {java.lang.String[], int, java.lang.String}]\n" +
- (this.complianceLevel >= ClassFileConstants.JDK1_8 ? // in 1.8 the ternary is resolved to its target type j.l.Object
- " [pc: 20, full, stack: {java.io.PrintStream, java.lang.Object}, locals: {java.lang.String[], int, java.lang.String}]\n" :
- " [pc: 20, full, stack: {java.io.PrintStream, java.lang.Comparable}, locals: {java.lang.String[], int, java.lang.String}]\n") +
+ " [pc: 20, full, stack: {java.io.PrintStream, java.lang.Comparable}, locals: {java.lang.String[], int, java.lang.String}]\n" +
" \n" +
- (this.complianceLevel >= ClassFileConstants.JDK1_8 ?
- " // Method descriptor #46 (Ljava/lang/Comparable;)V\n" :
- " // Method descriptor #48 (Ljava/lang/Comparable;)V\n") +
+ " // Method descriptor #48 (Ljava/lang/Comparable;)V\n" +
" // Signature: <T::Ljava/lang/Comparable<*>;>(TT;)V\n" +
" // Stack: 2, Locals: 3\n" +
" void foo(java.lang.Comparable foo);\n" +
@@ -884,11 +880,7 @@
" [pc: 2, pc: 18] local: bar index: 2 type: T\n" +
" Stack map table: number of frames 2\n" +
" [pc: 13, full, stack: {java.io.PrintStream}, locals: {X, java.lang.Comparable, java.lang.Comparable}]\n" +
- (this.complianceLevel < ClassFileConstants.JDK1_8 ?
- " [pc: 14, full, stack: {java.io.PrintStream, java.lang.Comparable}, locals: {X, java.lang.Comparable, java.lang.Comparable}]\n"
- : // in 1.8 the ternary is resolved to its target type j.l.Object
- " [pc: 14, full, stack: {java.io.PrintStream, java.lang.Object}, locals: {X, java.lang.Comparable, java.lang.Comparable}]\n"
- );
+ " [pc: 14, full, stack: {java.io.PrintStream, java.lang.Comparable}, locals: {X, java.lang.Comparable, java.lang.Comparable}]\n";
int index = actualOutput.indexOf(expectedOutput);
if (index == -1 || expectedOutput.length() == 0) {
@@ -2536,17 +2528,16 @@
}
public void test032() {
this.runConformTest(
- new String[] {
- "X.java",
- "import java.util.*;\n" +
- "public class X {\n" +
- " public static void main(String[] args) {\n" +
- " int i = args.length;\n" +
- " X[] array = new X[] { i == 0 ? null : null };\n" +
- " System.out.print(\"SUCCESS\" + array.length);\n" +
- " }\n" +
- "}",
- },
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " int i = args.length;\n" +
+ " X[] array = new X[] { i == 0 ? null : null };\n" +
+ " System.out.print(\"SUCCESS\" + array.length);\n" +
+ " }\n" +
+ "}",
+ },
"SUCCESS1");
}
@@ -8731,4 +8722,112 @@
assertEquals("Wrong contents", expectedOutput, actualOutput);
}
}
+
+ public void test551368() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface A {\n" +
+ "}\n" +
+ "class B implements A {\n" +
+ " public C c;\n" +
+ " \n" +
+ " protected B original() {\n" +
+ " return this;\n" +
+ " }\n" +
+ "}\n" +
+ "class C {\n" +
+ " C parent;\n" +
+ " A context;\n" +
+ "}\n" +
+ "class F extends C {\n" +
+ " \n" +
+ "}\n" +
+ "class G extends C {\n" +
+ " \n" +
+ "}\n" +
+ "abstract class D implements A {\n" +
+ " public F c;\n" +
+ "}\n" +
+ "class E implements A {\n" +
+ " public G c;\n" +
+ "}\n" +
+ "public class X {\n" +
+ " boolean foo(A a) {\n" +
+ " if (a instanceof B && a != ((B) a).original())\n" +
+ " return true;\n" +
+ " C aC = a instanceof D ? ((D) a).c :\n" +
+ " a instanceof E ? ((E) a).c : \n" +
+ " a instanceof B ? ((B) a).c :\n" +
+ " null;\n" +
+ " return aC != null ? foo(aC.parent.context) : false;\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS");
+ }
+ public void test551368_2() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ "\n" +
+ " int size;\n" +
+ " char[][][] elements;\n" +
+ "\n" +
+ " public X() {\n" +
+ " this.size = 0;\n" +
+ " this.elements = new char[10][][];\n" +
+ " }\n" +
+ "\n" +
+ " public void insertIntoArray(char[][][] target) {\n" +
+ " }\n" +
+ "\n" +
+ " public void add(char[][] newElement) {\n" +
+ " insertIntoArray(this.size < this.elements.length ? this.elements : new char[this.elements.length * 2][][]);\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS");
+ }
+ public void test551368_3() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class B {\n" +
+ " public boolean bar() {\n" +
+ " return false;\n" +
+ " }\n" +
+ " public void foo() {}\n" +
+ "}\n" +
+ "public class X {\n" +
+ " \n" +
+ " public B foo(boolean test) {\n" +
+ " B b =\n" +
+ " test ?\n" +
+ " new B() {\n" +
+ " @Override\n" +
+ " public boolean bar() {\n" +
+ " return true;\n" +
+ " }\n" +
+ " } :\n" +
+ " new B();\n" +
+ " b.foo();\n" +
+ " return b;\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS");
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java
index 1fef2d0..32efd3c 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java
@@ -631,20 +631,20 @@
String[] testFiles = new String[] {
"X.java",
"public class X {\n" +
- "public static void bar(Day day) {\n" +
- " switch (day) {\n" +
- " case SATURDAY, SUNDAY: \n" +
- " System.out.println(Day.SUNDAY);\n" +
- " break;\n" +
- " case MONDAY : System.out.println(Day.MONDAY);\n" +
- " break;\n" +
- " }\n" +
- " }" +
- " public static void main(String[] args) {\n" +
- " bar(Day.SATURDAY);\n" +
- " }\n" +
- "}\n" +
- "enum Day { SATURDAY, SUNDAY, MONDAY;}",
+ "public static void bar(Day day) {\n" +
+ " switch (day) {\n" +
+ " case SATURDAY, SUNDAY: \n" +
+ " System.out.println(Day.SUNDAY);\n" +
+ " break;\n" +
+ " case MONDAY : System.out.println(Day.MONDAY);\n" +
+ " break;\n" +
+ " }\n" +
+ " }" +
+ " public static void main(String[] args) {\n" +
+ " bar(Day.SATURDAY);\n" +
+ " }\n" +
+ "}\n" +
+ "enum Day { SATURDAY, SUNDAY, MONDAY;}",
};
String expectedProblemLog =
@@ -2921,4 +2921,64 @@
"Duplicate case\n" +
"----------\n");
}
+ public void _testBug544943() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " @SuppressWarnings(\"preview\")\n" +
+ " public static int foo(int i) throws MyException {\n" +
+ " int v = -1;\n" +
+ " try {\n" +
+ " v = switch (i) {\n" +
+ " case 0 -> switch(i) {\n" +
+ " case 0 -> 1;\n" +
+ " default -> throw new MyException();\n" +
+ " };\n" +
+ " default -> 1;\n" +
+ " };\n" +
+ " } finally {\n" +
+ " // do nothing\n" +
+ " }\n" +
+ " return v;\n" +
+ " } \n" +
+ " public static void main(String argv[]) {\n" +
+ " try {\n" +
+ " System.out.println(X.foo(0));\n" +
+ " } catch (MyException e) {\n" +
+ " e.printStackTrace();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n" +
+ "class MyException extends Exception {\n" +
+ " private static final long serialVersionUID = 3461899582505930473L; \n" +
+ "}"
+ },
+ "1");
+ }
+ public void _testBug544943_2() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " @SuppressWarnings({ \"preview\" })\n" +
+ " public static int foo(int i) throws Exception {\n" +
+ " int v = switch (i) {\n" +
+ " case 0 -> switch (i) {\n" +
+ " case 0 -> 0;\n" +
+ " default-> throw new Exception();\n" +
+ " case 3 -> 3;\n" +
+ " case 2 -> throw new Exception();\n" +
+ " };\n" +
+ " default -> 0;\n" +
+ " };\n" +
+ " return v;\n" +
+ " }\n" +
+ " public static void main(String argv[]) throws Exception {\n" +
+ " System.out.println(X.foo(1));\n" +
+ " }\n" +
+ "}"
+ },
+ "0");
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java
index f0dd255..8c98176 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java
@@ -3480,4 +3480,64 @@
"String literal is not properly closed by a double-quote\n" +
"----------\n");
}
+ public void testBug544943() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " @SuppressWarnings(\"preview\")\n" +
+ " public static int foo(int i) throws MyException {\n" +
+ " int v = -1;\n" +
+ " try {\n" +
+ " v = switch (i) {\n" +
+ " case 0 -> switch(i) {\n" +
+ " case 0 -> 1;\n" +
+ " default -> throw new MyException();\n" +
+ " };\n" +
+ " default -> 1;\n" +
+ " };\n" +
+ " } finally {\n" +
+ " // do nothing\n" +
+ " }\n" +
+ " return v;\n" +
+ " } \n" +
+ " public static void main(String argv[]) {\n" +
+ " try {\n" +
+ " System.out.println(X.foo(0));\n" +
+ " } catch (MyException e) {\n" +
+ " e.printStackTrace();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n" +
+ "class MyException extends Exception {\n" +
+ " private static final long serialVersionUID = 3461899582505930473L; \n" +
+ "}"
+ },
+ "1");
+ }
+ public void testBug544943_2() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " @SuppressWarnings({ \"preview\" })\n" +
+ " public static int foo(int i) throws Exception {\n" +
+ " int v = switch (i) {\n" +
+ " case 0 -> switch (i) {\n" +
+ " case 0 -> 0;\n" +
+ " default-> throw new Exception();\n" +
+ " case 3 -> 3;\n" +
+ " case 2 -> throw new Exception();\n" +
+ " };\n" +
+ " default -> 0;\n" +
+ " };\n" +
+ " return v;\n" +
+ " }\n" +
+ " public static void main(String argv[]) throws Exception {\n" +
+ " System.out.println(X.foo(1));\n" +
+ " }\n" +
+ "}"
+ },
+ "0");
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter13Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter13Test.java
index 867723c..21d4e4b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter13Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter13Test.java
@@ -48,7 +48,7 @@
public class ASTConverter13Test extends ConverterTestSetup {
ICompilationUnit workingCopy;
- private static final String jclLib = "CONVERTER_JCL9_LIB";
+ private static final String jclLib = "CONVERTER_JCL13_LIB";
public void setUpSuite() throws Exception {
super.setUpSuite();
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
index 568caf7..995812c 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
@@ -5424,5 +5424,39 @@
assertEquals("val$outerArg",synVars[0].getName());
assertEquals("val$outerLocal",synVars[1].getName());
}
+public void testCaptureBinding18() throws CoreException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/xyz/X.java", true/* resolve */);
+ StringBuilder buf= new StringBuilder();
+ buf.append("package xyz;\n");
+ buf.append("\n");
+ buf.append("import java.util.List;\n");
+ buf.append("\n");
+ buf.append("public class X {\n");
+ buf.append("\n");
+ buf.append(" protected <E extends Comparable<E>> List<E> createEmptySet() {\n");
+ buf.append(" return null;\n");
+ buf.append(" }\n");
+ buf.append("\n");
+ buf.append(" public void emptySet() {\n");
+ buf.append(" s = createEmptySet();\n");
+ buf.append(" }\n");
+ buf.append("\n");
+ buf.append("}");
+ String content= buf.toString();
+ CompilationUnit cu = (CompilationUnit) buildAST(content, this.workingCopy, false /*i.e. ignore errors*/);
+ MethodDeclaration method= ((TypeDeclaration)cu.types().get(0)).getMethods()[1];
+ Assignment assignment= (Assignment) ((ExpressionStatement) method.getBody().statements().get(0)).getExpression();
+ ITypeBinding binding = assignment.getRightHandSide().resolveTypeBinding();
+ assertTrue("main type is parameterized", binding.isParameterizedType());
+ binding = binding.getTypeArguments()[0];
+ assertTrue("treat as wildcard", binding.isWildcardType());
+ assertFalse("don't treat as capture", binding.isCapture());
+ assertTrue("has upper bound", binding.isUpperbound());
+ ITypeBinding[] typeBounds = binding.getTypeBounds();
+ assertEquals("number of bounds", 1, typeBounds.length);
+ ITypeBinding bound = typeBounds[0];
+ assertTrue("bound is parameterized", bound.isParameterizedType());
+ assertEquals("bound's type argument is the original type argument", binding, bound.getTypeArguments()[0]);
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
index b5f9366..8bd1281 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
@@ -184,10 +184,18 @@
if (JavaCore.getClasspathVariable("CONVERTER_JCL12_LIB") == null) {
setupExternalJCL("converterJclMin12");
JavaCore.setClasspathVariables(
- new String[] {"CONVERTER_JCL11_LIB", "CONVERTER_JCL11_SRC", "CONVERTER_JCL11_SRCROOT"},
+ new String[] {"CONVERTER_JCL12_LIB", "CONVERTER_JCL12_SRC", "CONVERTER_JCL12_SRCROOT"},
new IPath[] {getConverterJCLPath("12"), getConverterJCLSourcePath("12"), getConverterJCLRootSourcePath()},
null);
}
+ } else if ("13".equals(compliance)) {
+ if (JavaCore.getClasspathVariable("CONVERTER_JCL13_LIB") == null) {
+ setupExternalJCL("converterJclMin13");
+ JavaCore.setClasspathVariables(
+ new String[] {"CONVERTER_JCL13_LIB", "CONVERTER_JCL13_SRC", "CONVERTER_JCL13_SRCROOT"},
+ new IPath[] {getConverterJCLPath("13"), getConverterJCLSourcePath("13"), getConverterJCLRootSourcePath()},
+ null);
+ }
} else if (JavaCore.getClasspathVariable("CONVERTER_JCL_LIB") == null) {
setupExternalJCL("converterJclMin");
JavaCore.setClasspathVariables(
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
index 305d9b3..96e0469 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -13022,4 +13022,18 @@
" }\n" +
"}");
}
+/**
+ * https://bugs.eclipse.org/551189 - Consistent ArrayIndexOutOfBounds when saving an incorrect Java file when code clean-up is enabled
+ */
+public void testBug551189() {
+ formatSource(
+ "public class AAA {\n" +
+ "\n" +
+ "import java.awt.*;\n" +
+ "\n" +
+ "public class BBB {\n" +
+ " int a;\n" +
+ "\n" +
+ "}}");
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
index 320fe9a..567280f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
@@ -15242,4 +15242,147 @@
this.formatterPrefs.blank_lines_between_statement_groups_in_switch = ~0;
formatSourceInWorkspace("test390720", "in.java", "B_out.java");
}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436a() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_PRESERVE;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "A_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436b() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_BY_ONE;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "B_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436c() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_DEFAULT;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "C_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436d() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_DEFAULT;
+ this.formatterPrefs.continuation_indentation = 3;
+ formatSourceInWorkspace("test549436", "in.java", "D_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436e() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_ON_COLUMN;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "E_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436f() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_BY_ONE;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "F_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436g() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = true;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_DEFAULT;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "G_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436h() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = true;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_DEFAULT;
+ this.formatterPrefs.continuation_indentation = 3;
+ formatSourceInWorkspace("test549436", "in.java", "H_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436i() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = true;
+ this.formatterPrefs.indent_empty_lines = true;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_ON_COLUMN;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "I_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436j() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.MIXED;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_ON_COLUMN;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "J_out.java");
+}
+/**
+ * https://bugs.eclipse.org/549436 - [13] Formatter support for JEP 355 Text Block
+ */
+public void testBug549436k() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_13);
+ setPageWidth80();
+ this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = false;
+ this.formatterPrefs.indent_empty_lines = false;
+ this.formatterPrefs.text_block_indentation = Alignment.M_INDENT_ON_COLUMN;
+ this.formatterPrefs.continuation_indentation = 2;
+ formatSourceInWorkspace("test549436", "in.java", "K_out.java");
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
index cf1f469..eae922b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
@@ -875,7 +875,7 @@
}
assertEquals("Unexpected type hierarchy", expected, actual);
}
- protected void assertMarkers(String message, String expectedMarkers, IJavaProject project) throws CoreException {
+ protected void assertBuildPathMarkers(String message, String expectedMarkers, IJavaProject project) throws CoreException {
waitForAutoBuild();
IMarker[] markers = project.getProject().findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
sortMarkers(markers);
@@ -891,6 +891,11 @@
};
org.eclipse.jdt.internal.core.util.Util.sort(markers, comparer);
}
+ protected void assertProblemMarkers(String message, String expectedMarkers, IProject project) throws CoreException {
+ IMarker[] markers = project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
+ sortMarkers(markers);
+ assertMarkers(message, expectedMarkers, markers);
+ }
protected void assertMarkers(String message, String expectedMarkers, IMarker[] markers) throws CoreException {
StringBuffer buffer = new StringBuffer();
if (markers != null) {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java
index 38ebad0..2cbf889 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java
@@ -830,7 +830,7 @@
ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[0]));
JavaCore.setClasspathContainer(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER"), new IJavaProject[] {p1}, new IClasspathContainer[] {null}, null);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Unbound classpath container: \'org.eclipse.jdt.core.tests.model.TEST_CONTAINER\' in project \'P1\'",
p1);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
index 1ebb8cb..bf51da4 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
@@ -118,21 +118,22 @@
setupExternalJCL("jclMin");
setupExternalJCL("jclMin1.5");
}
-protected void assertCycleMarkers(IJavaProject project, IJavaProject[] p, int[] expectedCycleParticipants) throws CoreException {
+protected void assertCycleMarkers(IJavaProject project, IJavaProject[] p, int[] expectedCycleParticipants, boolean includeAffected) throws CoreException {
waitForAutoBuild();
StringBuffer expected = new StringBuffer("{");
int expectedCount = 0;
StringBuffer computed = new StringBuffer("{");
int computedCount = 0;
+ int mask = includeAffected ? 3 : 1;
for (int j = 0; j < p.length; j++){
- int markerCount = numberOfCycleMarkers(p[j]);
- if (markerCount > 0){
+ int markerFlags = cycleMarkerFlags(p[j]);
+ if ((markerFlags & mask) > 0){
if (computedCount++ > 0) computed.append(", ");
computed.append(p[j].getElementName());
//computed.append(" (" + markerCount + ")");
}
- markerCount = expectedCycleParticipants[j];
- if (markerCount > 0){
+ markerFlags = expectedCycleParticipants[j];
+ if ((markerFlags & mask) > 0){
if (expectedCount++ > 0) expected.append(", ");
expected.append(p[j].getElementName());
//expected.append(" (" + markerCount + ")");
@@ -169,14 +170,20 @@
file.setLastModified(System.currentTimeMillis() + 2000);
return file;
}
-protected int numberOfCycleMarkers(IJavaProject javaProject) throws CoreException {
+/** @return 1: participates in cycle, 2: affected by cycle (depends on) */
+protected int cycleMarkerFlags(IJavaProject javaProject) throws CoreException {
IMarker[] markers = javaProject.getProject().findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
int result = 0;
for (int i = 0, length = markers.length; i < length; i++) {
IMarker marker = markers[i];
String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED);
if (cycleAttr != null && cycleAttr.equals("true")){ //$NON-NLS-1$
- result++;
+ String message = marker.getAttribute(IMarker.MESSAGE, "");
+ boolean isCycleMember = message.indexOf("\n->{") != -1; // cycle with no prefix
+ if (isCycleMember)
+ result |= 1;
+ else
+ result |= 2;
}
}
return result;
@@ -318,7 +325,7 @@
entries[length] = JavaCore.newContainerEntry(containerSuggestion.getPath());
p.setRawClasspath(entries, null);
- assertMarkers("Failed to find marker", "The user library 'SomeUserLibrary' references non existing library \'" + getExternalResourcePath("idontexistthereforeiamnot.jar") + "'", p);
+ assertBuildPathMarkers("Failed to find marker", "The user library 'SomeUserLibrary' references non existing library \'" + getExternalResourcePath("idontexistthereforeiamnot.jar") + "'", p);
} finally {
deleteProject("Project");
}
@@ -454,7 +461,7 @@
IJavaProject p = createJavaProject("P");
createExternalFolder("externalLib");
setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path(getExternalResourcePath("externalLib")), null, null)});
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib");
deleteProject("P");
@@ -468,7 +475,7 @@
try {
createExternalFolder("externalLib");
IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib")}, "");
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib");
deleteProject("P");
@@ -484,7 +491,7 @@
IJavaProject p = createJavaProject("P");
IPath path = new Path(getExternalResourcePath("externalLib"));
setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(path, null, null)});
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "externalLib\'",
p);
@@ -500,7 +507,7 @@
try {
waitForAutoBuild();
IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib")}, "");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "externalLib\'",
p);
@@ -518,7 +525,7 @@
waitForAutoBuild();
createExternalFolder("externalLib");
refresh(p);
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib");
deleteProject("P");
@@ -536,7 +543,7 @@
waitForAutoBuild();
createExternalFolder("externalLib");
refresh(p);
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib");
deleteProject("P");
@@ -573,7 +580,7 @@
getExternalResourcePath("externalLib.abc"),
JavaCore.VERSION_1_4);
setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path(getExternalResourcePath("externalLib.abc")), null, null)});
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib.abc");
deleteProject("P");
@@ -589,7 +596,7 @@
getExternalResourcePath("externalLib.abc"),
JavaCore.VERSION_1_4);
IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, "");
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib.abc");
deleteProject("P");
@@ -606,7 +613,7 @@
waitForAutoBuild();
setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path(getExternalResourcePath("externalLib.abc")), null, null)});
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "externalLib.abc\'",
p);
@@ -623,7 +630,7 @@
waitForAutoBuild();
IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, "");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "externalLib.abc\'",
p);
@@ -644,7 +651,7 @@
getExternalResourcePath("externalLib.abc"),
JavaCore.VERSION_1_4);
refreshExternalArchives(p);
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib.abc");
deleteProject("P");
@@ -664,7 +671,7 @@
getExternalResourcePath("externalLib.abc"),
JavaCore.VERSION_1_4);
refreshExternalArchives(p);
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib.abc");
deleteProject("P");
@@ -684,7 +691,7 @@
"Manifest-Version: 1.0\n"} ,
JavaCore.VERSION_1_4);
setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("/P/internalLib.abc"), null, null)});
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteProject("P");
}
@@ -761,7 +768,7 @@
// now create the actual resource for the root
project.getProject().getFolder("src").create(false, true, null);
- assertMarkers("Unexpected markers", "", project);
+ assertBuildPathMarkers("Unexpected markers", "", project);
} finally {
// cleanup
this.deleteProject("P");
@@ -2572,7 +2579,7 @@
IJavaProject[] projects = { p1, p2, p3 };
int cycleMarkerCount = 0;
for (int i = 0; i < projects.length; i++){
- cycleMarkerCount += numberOfCycleMarkers(projects[i]);
+ cycleMarkerCount += (cycleMarkerFlags(projects[i]) & 1);
}
assertTrue("Should have no cycle markers", cycleMarkerCount == 0);
@@ -2597,7 +2604,7 @@
waitForAutoBuild(); // wait for cycle markers to be created
cycleMarkerCount = 0;
for (int i = 0; i < projects.length; i++){
- cycleMarkerCount += numberOfCycleMarkers(projects[i]);
+ cycleMarkerCount += (cycleMarkerFlags(projects[i]) & 1);
}
assertEquals("Unexpected number of projects involved in a classpath cycle", 3, cycleMarkerCount);
@@ -2658,7 +2665,7 @@
IJavaProject p = createJavaProject("P");
ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P", "../../nonExisting.jar"}));
setClasspath(p, new IClasspathEntry[] {JavaCore.newContainerEntry(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER"))});
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"The container 'Test container' references non existing library \'" + getExternalPath() + "nonExisting.jar\'",
p);
@@ -2777,7 +2784,7 @@
externalJarPath,
JavaCore.VERSION_1_4);
setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("../external.jar"), null, null)});
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -2794,7 +2801,7 @@
try {
IJavaProject p = createJavaProject("P");
setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("../external.jar"), null, null)});
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getWorkspacePath() + "external.jar\'",
p);
@@ -2894,7 +2901,7 @@
JavaCore.setClasspathVariable("TWO_UP", new Path("../.."), null);
IJavaProject p = createJavaProject("P");
setClasspath(p, new IClasspathEntry[] {JavaCore.newVariableEntry(new Path("TWO_UP/nonExisting.jar"), null, null)});
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "nonExisting.jar\'",
p);
@@ -3184,7 +3191,7 @@
getExternalResourcePath("test185733.jar"),
JavaCore.VERSION_1_4);
refreshExternalArchives(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -3208,7 +3215,7 @@
deleteResource(externalJar);
refreshExternalArchives(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'" + externalJar.getPath() + "\'",
p);
@@ -3450,7 +3457,7 @@
},
JavaCore.VERSION_1_4);
createFile("/P/lib2.jar", "");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -3472,7 +3479,7 @@
"Class-Path: lib2.jar\n",
},
JavaCore.VERSION_1_4);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -3522,7 +3529,7 @@
JavaCore.VERSION_1_4);
createExternalFile("lib2.jar", "");
refreshExternalArchives(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -3546,7 +3553,7 @@
"Class-Path: lib2.jar\n",
},
JavaCore.VERSION_1_4);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -3576,7 +3583,7 @@
deleteExternalResource("lib2.jar");
refreshExternalArchives(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -3707,7 +3714,7 @@
JavaCore.VERSION_1_4);
ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P", getExternalResourcePath("lib1.jar")}));
IJavaProject p = createJavaProject("P", new String[0], new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, "");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -3795,7 +3802,7 @@
null/*no classpath*/,
JavaCore.VERSION_1_4);
refreshExternalArchives(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -3818,7 +3825,7 @@
"Manifest-Version: 1.0\n"} ,
JavaCore.VERSION_1_4);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
project);
@@ -3842,7 +3849,7 @@
simulateExitRestart();
refreshExternalArchives(p);
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib.abc");
deleteProject("P");
@@ -3911,7 +3918,7 @@
" <classpathentry kind=\"output\" path=\"bin\"/>\n" +
"</classpath>"
);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"XML format error in \'.classpath\' file of project 'P': Bad format",
project);
@@ -3933,7 +3940,7 @@
" <classpathentry kind=\"output\" path=\"bin\"/>\n" +
"</classpath>"
);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Illegal entry in \'.classpath\' of project 'P' file: Unknown kind: \'src1\'",
javaProject);
@@ -3943,7 +3950,7 @@
IProject project = javaProject.getProject();
project.build(IncrementalProjectBuilder.FULL_BUILD, null);
waitForAutoBuild();
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Illegal entry in \'.classpath\' of project 'P' file: Unknown kind: \'src1\'",
javaProject);
@@ -3962,7 +3969,7 @@
if (Path.fromOSString(externalPath).segmentCount() > 0)
externalPath = externalPath.substring(0, externalPath.length()-1);
IJavaProject proj = createJavaProject("P", new String[] {}, new String[] {externalPath}, "bin");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'" + externalPath + "\'",
proj);
@@ -3977,7 +3984,7 @@
try {
String jarPath = getExternalPath() + "nonExisting.jar";
IJavaProject proj = createJavaProject("P", new String[] {}, new String[] {jarPath}, "bin");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project 'P' is missing required library: \'" + jarPath + "\'",
proj);
@@ -4029,7 +4036,7 @@
public void testInvalidInternalJar1() throws CoreException {
try {
IJavaProject proj = createJavaProject("P", new String[] {}, new String[] {"/P/nonExisting.jar"}, "bin");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project 'P' is missing required library: \'nonExisting.jar\'",
proj);
@@ -4050,7 +4057,7 @@
"Manifest-Version: 1.0\n"} ,
JavaCore.VERSION_1_4);
proj = createJavaProject("P2", new String[] {}, new String[] {"/P1/existing.txt"}, "bin");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
proj);
@@ -4068,7 +4075,7 @@
try {
createJavaProject("P1");
IJavaProject proj = createJavaProject("P2", new String[] {}, new String[] {}, new String[] {"/P1/src1/src2"}, "bin");
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project 'P2' is missing required source folder: \'/P1/src1/src2\'",
proj);
@@ -4095,7 +4102,7 @@
waitForAutoBuild();
project.build(IncrementalProjectBuilder.FULL_BUILD, null);
waitForAutoBuild();
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Unable to read \'.classpath\' file of project 'P'",
javaProject);
@@ -4114,7 +4121,7 @@
JavaCore.newProjectEntry(new Path("/B"))
};
javaProject.setRawClasspath(classpath, null);
- this.assertMarkers(
+ this.assertBuildPathMarkers(
"Unexpected markers",
"Project 'A' is missing required Java project: \'B\'",
javaProject);
@@ -4134,7 +4141,7 @@
new String[] {}, // lib folders
new String[] {"/B"}, // projects
"");
- this.assertMarkers(
+ this.assertBuildPathMarkers(
"Unexpected markers",
"Project 'A' is missing required Java project: \'B\'",
javaProject);
@@ -4155,7 +4162,7 @@
new String[] {"/B"}, // projects
"");
this.createJavaProject("B", new String[] {}, "");
- this.assertMarkers("Unexpected markers", "", javaProject);
+ this.assertBuildPathMarkers("Unexpected markers", "", javaProject);
} finally {
deleteProjects(new String[] {"A", "B"});
}
@@ -4181,18 +4188,20 @@
new String[] {}, // lib folders
new String[] {"/A"}, // projects
"");
- this.assertMarkers(
+ this.assertBuildPathMarkers(
"Unexpected markers for project A",
- "A cycle was detected in the build path of project 'A'. The cycle consists of projects {A, B}",
+ "One or more cycles were detected in the build path of project 'A'. The paths towards the cycle and cycle are:\n" +
+ "->{A, B}",
projectA);
- this.assertMarkers(
+ this.assertBuildPathMarkers(
"Unexpected markers for project B",
- "A cycle was detected in the build path of project 'B'. The cycle consists of projects {A, B}",
+ "One or more cycles were detected in the build path of project 'B'. The paths towards the cycle and cycle are:\n" +
+ "->{A, B}",
projectB);
// delete project B
this.deleteProject("B");
- this.assertMarkers(
+ this.assertBuildPathMarkers(
"Unexpected markers for project A after deleting of project B",
"Project 'A' is missing required Java project: \'B\'",
projectA);
@@ -4205,13 +4214,15 @@
new String[] {}, // lib folders
new String[] {"/A"}, // projects
"");
- this.assertMarkers(
+ this.assertBuildPathMarkers(
"Unexpected markers for project A after adding project B back",
- "A cycle was detected in the build path of project 'A'. The cycle consists of projects {A, B}",
+ "One or more cycles were detected in the build path of project 'A'. The paths towards the cycle and cycle are:\n" +
+ "->{A, B}",
projectA);
- this.assertMarkers(
+ this.assertBuildPathMarkers(
"Unexpected markers for project B after adding project B back",
- "A cycle was detected in the build path of project 'B'. The cycle consists of projects {A, B}",
+ "One or more cycles were detected in the build path of project 'B'. The paths towards the cycle and cycle are:\n" +
+ "->{A, B}",
projectB);
} finally {
@@ -4458,6 +4469,14 @@
{ 1, 1, 1, 1, 1 }, // after setting CP p[4]
};
+ int[][] expectedAffectedProjects = new int[][] {
+ { 0, 0, 0, 0, 0 }, // after setting CP p[0]
+ { 0, 0, 0, 0, 0 }, // after setting CP p[1]
+ { 1, 1, 1, 0, 0 }, // after setting CP p[2]
+ { 1, 1, 1, 0, 0 }, // after setting CP p[3]
+ { 1, 1, 1, 1, 1 }, // after setting CP p[4]
+ };
+
for (int i = 0; i < p.length; i++){
// append project references
@@ -4471,7 +4490,8 @@
p[i].setRawClasspath(newClasspath, null);
// check cycle markers
- assertCycleMarkers(p[i], p, expectedCycleParticipants[i]);
+ assertCycleMarkers(p[i], p, expectedCycleParticipants[i], false);
+ assertCycleMarkers(p[i], p, expectedAffectedProjects[i], true);
}
//this.startDeltas();
@@ -4533,7 +4553,7 @@
JavaCore.setClasspathVariables(var, variableValues[i], null);
// check cycle markers
- assertCycleMarkers(p[i], p, expectedCycleParticipants[i]);
+ assertCycleMarkers(p[i], p, expectedCycleParticipants[i], false);
}
//this.startDeltas();
@@ -4616,7 +4636,7 @@
}
// check cycle markers
- assertCycleMarkers(p[i], p, expectedCycleParticipants[i]);
+ assertCycleMarkers(p[i], p, expectedCycleParticipants[i], false);
}
//this.startDeltas();
@@ -4699,7 +4719,7 @@
}
// check cycle markers
- assertCycleMarkers(p[i], p, expectedCycleParticipants[i]);
+ assertCycleMarkers(p[i], p, expectedCycleParticipants[i], false);
}
//this.startDeltas();
@@ -4748,7 +4768,8 @@
p[i].setRawClasspath(newClasspath, null);
// check cycle markers
- assertCycleMarkers(p[i], p, expectedCycleParticipants[i]);
+ assertCycleMarkers(p[i], p, expectedCycleParticipants[i], false);
+ assertCycleMarkers(p[i], p, expectedCycleParticipants[i], true);
}
//this.startDeltas();
@@ -4784,7 +4805,7 @@
{ 0, 0, 0, 0, 0, 0 }, // after setting CP p[2]
{ 1, 1, 1, 1, 0, 0 }, // after setting CP p[3]
{ 1, 1, 1, 1, 0, 0 }, // after setting CP p[4]
- { 1, 1, 1, 1, 1 , 1}, // after setting CP p[5]
+ { 1, 1, 1, 1, 1 ,1 }, // after setting CP p[5]
};
for (int i = 0; i < p.length; i++){
@@ -4800,8 +4821,17 @@
p[i].setRawClasspath(newClasspath, null);
// check cycle markers
- assertCycleMarkers(p[i], p, expectedCycleParticipants[i]);
+ assertCycleMarkers(p[i], p, expectedCycleParticipants[i], false);
+ assertCycleMarkers(p[i], p, expectedCycleParticipants[i], true);
}
+
+ IMarker[] markers = p[0].getProject().findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+ // additionally see that we actually have 2 cycles for P0!
+ assertMarkers("Markers of P0",
+ "One or more cycles were detected in the build path of project 'P0'. The paths towards the cycle and cycle are:\n" +
+ "->{P0, P2, P3, P1}\n" +
+ "->{P0, P4, P5, P1}",
+ markers);
//this.startDeltas();
} finally {
@@ -4840,7 +4870,7 @@
waitForAutoBuild();
getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE);
createFile("/P1/test.txt", "");
- assertCycleMarkers(p1, new IJavaProject[] {p1, p2}, new int[] {1, 1});
+ assertCycleMarkers(p1, new IJavaProject[] {p1, p2}, new int[] {1, 1}, false);
} finally {
getWorkspace().removeResourceChangeListener(listener);
deleteProjects(new String[] {"P1", "P2"});
@@ -5027,7 +5057,7 @@
" <classpathentry kind=\"output\" path=\"bin\"/>\n" +
"</classpath>"
);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Build path contains duplicate entry: \'src\' for project 'P'",
project);
@@ -5058,7 +5088,7 @@
"</classpath>"
);
waitForAutoBuild();
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
project);
@@ -5134,7 +5164,7 @@
for (int i = 0; i < numberOfParticipants; i++){
// check cycle markers
- assertCycleMarkers(projects[i], projects, allProjectsInCycle);
+ assertCycleMarkers(projects[i], projects, allProjectsInCycle, false);
}
} finally {
@@ -5207,7 +5237,7 @@
for (int i = 0; i < numberOfParticipants; i++){
// check cycle markers
- assertCycleMarkers(projects[i], projects, allProjectsInCycle);
+ assertCycleMarkers(projects[i], projects, allProjectsInCycle, false);
}
} finally {
@@ -5269,7 +5299,7 @@
// refresh
project.refreshLocal(IResource.DEPTH_INFINITE, null);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Cannot nest \'P/src/src2\' inside \'P/src\'. To enable the nesting exclude \'src2/\' from \'P/src\'",
JavaCore.create(project));
@@ -5289,7 +5319,7 @@
JavaCore.newSourceEntry(new Path("/A/src"), new IPath[0], new IPath[0], new Path("/A/bin"), new IClasspathAttribute[] {attribute})
};
javaProject.setRawClasspath(classpath, null);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
javaProject);
@@ -5309,7 +5339,7 @@
JavaCore.newLibraryEntry(new Path("/A/lib"), null, null, null, new IClasspathAttribute[] {attribute}, false)
};
javaProject.setRawClasspath(classpath, null);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
javaProject);
@@ -5329,7 +5359,7 @@
JavaCore.newProjectEntry(new Path("/B"), null/*no access rules*/, false/*don't combine access rule*/, new IClasspathAttribute[] {attribute}, false/*not exported*/)
};
javaProject.setRawClasspath(classpath, null);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
javaProject);
@@ -5390,7 +5420,7 @@
// refresh
project.refreshLocal(IResource.DEPTH_INFINITE,null);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project 'P' is missing required source folder: \'src1\'\n" +
"Project 'P' is missing required source folder: \'src2\'",
@@ -5440,7 +5470,7 @@
IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib")}, "");
waitForAutoBuild();
setClasspath(p, new IClasspathEntry[] {});
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib");
deleteProject("P");
@@ -5455,7 +5485,7 @@
IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib")}, "");
waitForAutoBuild();
setClasspath(p, new IClasspathEntry[] {});
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -5474,7 +5504,7 @@
waitForAutoBuild();
deleteExternalResource("externalLib");
refresh(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "externalLib\'",
p);
@@ -5496,7 +5526,7 @@
waitForAutoBuild();
deleteExternalResource("externalLib");
refresh(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "externalLib\'",
p);
@@ -5517,7 +5547,7 @@
waitForAutoBuild();
setClasspath(p, new IClasspathEntry[] {});
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteExternalResource("externalLib.abc");
deleteProject("P");
@@ -5534,7 +5564,7 @@
waitForAutoBuild();
setClasspath(p, new IClasspathEntry[] {});
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
p);
@@ -5555,7 +5585,7 @@
deleteExternalResource("externalLib.abc");
refreshExternalArchives(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "externalLib.abc\'",
p);
@@ -5578,7 +5608,7 @@
deleteExternalResource("externalLib.abc");
refreshExternalArchives(p);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'"+ getExternalPath() + "externalLib.abc\'",
p);
@@ -5598,7 +5628,7 @@
waitForAutoBuild();
setClasspath(p, new IClasspathEntry[] {});
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
deleteProject("P");
}
@@ -5619,7 +5649,7 @@
deleteFile("/P/internalLib.abc");
waitForAutoBuild();
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'internalLib.abc\'",
p);
@@ -5657,7 +5687,7 @@
// rename .jar
getFile("/P/lib/test1.jar").move(new Path("/P/lib/test2.jar"), false, null);
- assertMarkers("Unexpected markers", "", p);
+ assertBuildPathMarkers("Unexpected markers", "", p);
} finally {
if (listener != null)
getWorkspace().removeResourceChangeListener(listener);
@@ -5892,7 +5922,7 @@
" <classpathentry kind=\"var\" path=\"TEST_LIB\" sourcepath=\"TEST_SRC\"/>\n" +
"</classpath>"
);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Source attachment path \'tmp.zip\' for IClasspathEntry must be absolute",
javaProject);
@@ -6134,7 +6164,7 @@
"/P/.classpath",
buffer.toString()
);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"",
project);
@@ -6176,7 +6206,7 @@
"/P/.classpath",
buffer.toString()
);
- assertMarkers(
+ assertBuildPathMarkers(
"Unexpected markers",
"Project \'P\' is missing required library: \'" + libPath.toOSString() + "'\n" +
"Unbound classpath container: \'org.eclipse.jdt.core.tests.model.TEST_CONTAINER\' in project \'P\'\n" +
@@ -6902,7 +6932,7 @@
IJavaProject p = createJavaProject("P");
createFile("/P/library.jar", "");
setClasspath(p, new IClasspathEntry[] { JavaCore.newLibraryEntry(new Path("/P/library.jar"), null,null)});
- assertMarkers("Expected marker",
+ assertBuildPathMarkers("Expected marker",
"Archive for required library: \'library.jar\' in project \'P\' cannot be read or is not a valid ZIP file", p);
setClasspath(p, new IClasspathEntry[0]);
addLibrary(p, "library.jar", null, new String[0],
@@ -6918,7 +6948,7 @@
assertNotNull(file);
file.touch(null);
waitForAutoBuild();
- assertMarkers("Unexpected marker",
+ assertBuildPathMarkers("Unexpected marker",
"", p);
} finally {
@@ -6965,7 +6995,7 @@
refresh(javaProject);
waitForAutoBuild();
- assertMarkers("Unexpected markers", "", javaProject);
+ assertBuildPathMarkers("Unexpected markers", "", javaProject);
} finally {
deleteProject("ExternalProject");
@@ -7083,7 +7113,7 @@
status);
proj.setRawClasspath(newCP, null);
- assertMarkers("Unexpected markers", "", proj);
+ assertBuildPathMarkers("Unexpected markers", "", proj);
// Test that with the option set to WARNING, status.isOK() returns true
proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.WARNING);
@@ -7094,7 +7124,7 @@
"Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'",
status);
- assertMarkers("Unexpected markers",
+ assertBuildPathMarkers("Unexpected markers",
"Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", proj);
// Test that with the option set to WARNING and the presence of a more severe error scenario, the error status
@@ -7220,12 +7250,12 @@
eclipsePreferences.addPreferenceChangeListener(prefListener);
simulateExitRestart();
waitForAutoBuild();
- assertMarkers("Unexpected markers", "", proj1);
+ assertBuildPathMarkers("Unexpected markers", "", proj1);
map = proj1.getOptions(false);
map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_1);
proj1.setOptions(map);
waitForManualRefresh();
- assertMarkers("Unexpected markers",
+ assertBuildPathMarkers("Unexpected markers",
"Incompatible .class files version in required binaries. Project \'P1\' is targeting a 1.1 runtime, but is compiled against \'P1/abc.jar\' which requires a 1.4 runtime", proj1);
eclipsePreferences.removePreferenceChangeListener(prefListener);
} finally {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
index 92b530f..4a92277 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
@@ -20590,6 +20590,66 @@
requestor.getResults());
}
+/*
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=285379
+ */
+public void test285379a() throws JavaModelException {
+ CompletionTestsRequestor requestor = new CompletionTestsRequestor();
+ ICompilationUnit cu= getCompilationUnit("Completion", "src", "", "Completion285379.java");
+
+ String str = cu.getSource();
+ String completeBehind = "pkgtest285379.X1.";
+ int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+ cu.codeComplete(cursorLocation, requestor);
+
+ // just not hang...
+}
+
+/*
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=285379
+ */
+public void test285379b() throws JavaModelException {
+ CompletionTestsRequestor requestor = new CompletionTestsRequestor();
+ ICompilationUnit cu= getCompilationUnit("Completion", "src", "", "Completion285379.java");
+
+ String str = cu.getSource();
+ String completeBehind = "return ";
+ int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+ cu.codeComplete(cursorLocation, requestor);
+
+ // just not hang...
+}
+
+/*
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=285379
+ */
+public void test285379c() throws JavaModelException {
+ CompletionTestsRequestor requestor = new CompletionTestsRequestor();
+ ICompilationUnit cu= getCompilationUnit("Completion", "src", "", "Completion285379.java");
+
+ String str = cu.getSource();
+ String completeBehind = "equals";
+ int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+ cu.codeComplete(cursorLocation, requestor);
+
+ // just not hang...
+}
+
+/*
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=285379
+ */
+public void test285379d() throws JavaModelException {
+ CompletionTestsRequestor requestor = new CompletionTestsRequestor();
+ ICompilationUnit cu= getCompilationUnit("Completion", "src", "", "Completion285379.java");
+
+ String str = cu.getSource();
+ String completeBehind = "(var";
+ int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+ cu.codeComplete(cursorLocation, requestor);
+
+ // just not hang...
+}
+
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=270436
public void test270436a() throws JavaModelException {
// This test is to ensure that an interface is not offered as a choice when expecting a class.
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java
index 867bf7a..29ce20f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java
@@ -869,7 +869,7 @@
assertTrue("Invalid selection result", (elements[0] instanceof BinaryModule));
IModuleDescription mod = (IModuleDescription) elements[0];
String id = mod.getHandleIdentifier();
- assertTrue("incorrect id", id.matches("=Java9Elements/.*"+Pattern.quote("\\/jmods\\/java.base.jmod=/module=/true<'`java.base")));
+ assertTrue("incorrect id", id.matches("=Java9Elements/.*"+Pattern.quote("\\/jmods\\/java.base.jmod=/module=/true=/<'`java.base")));
IJavaElement element = JavaCore.create(id);
assertEquals("incorrect element type", IJavaElement.JAVA_MODULE, element.getElementType());
assertEquals("incorrect module name", "java.base", element.getElementName());
@@ -1337,6 +1337,7 @@
IPackageFragmentRoot fragmentRoot = project2.getPackageFragmentRoot(project1.getResource());
IModuleDescription mod2 = JavaCore.getAutomaticModuleDescription(fragmentRoot);
assertNotNull("auto module not found via package fragment root", mod2);
+ assertTrue("should be an auto module", mod2.isAutoModule());
assertEquals("names of module descriptions should be equal", mod1.getElementName(), mod2.getElementName());
@@ -1360,8 +1361,35 @@
assertEquals(fragmentRoot, mod2.getParent());
}
finally {
- deleteProject("Java9Elements");
- deleteProject("Java9Elements2");
+ deleteProject("my_mod");
+ deleteProject("your.mod");
+ }
+ }
+ public void testSystemModule() throws Exception {
+ try {
+ IJavaProject project1 = createJava9Project("my_mod");
+ IModuleDescription mod = project1.findModule("java.base", this.wcOwner);
+ assertTrue("should be a system module", mod.isSystemModule());
+ mod = project1.findModule("java.desktop", this.wcOwner);
+ assertTrue("should be a system module", mod.isSystemModule());
+
+ createFile("/my_mod/src/module-info.java",
+ "module my_mod{\n" +
+ "}");
+ mod = project1.getModuleDescription();
+ assertFalse("should not be a system module", mod.isSystemModule());
+
+ addModularLibrary(project1, "mod.two.jar", "mod.two-sources.zip",
+ new String[] {
+ "module-info.java",
+ "module mod.two {}\n"
+ }, JavaCore.VERSION_9);
+
+ mod = project1.findModule("mod.two", this.wcOwner);
+ assertFalse("should not be a system module", mod.isSystemModule());
+
+ } finally {
+ deleteProject("my_mod");
}
}
public void test526761a() throws Exception {
@@ -1604,7 +1632,7 @@
assertTrue("Invalid selection result", (elements[0] instanceof BinaryModule));
IModuleDescription mod = (IModuleDescription) elements[0];
String id = mod.getHandleIdentifier();
- assertEquals("identifier", "=Java9Elements/"+jdkRootPath.toString().replace("/", "\\/")+"\\/jmods\\/java.base.jmod=/module=/true<'`java.base", id);
+ assertEquals("identifier", "=Java9Elements/"+jdkRootPath.toString().replace("/", "\\/")+"\\/jmods\\/java.base.jmod=/module=/true=/<'`java.base", id);
ISourceRange ir =mod.getNameRange();
assertTrue("positive offset", ir.getOffset() > 0);
assertEquals("length", 9, ir.getLength());
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 2133ba2..4be167b 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
@@ -825,7 +825,7 @@
null);
String[] expectedIdentifiers = {
"=Test/src",
- "=Test/lib.jar=/annotationpath=/\\/Test\\/annots"
+ "=Test/lib.jar=/annotationpath=/\\/Test\\/annots=/"
};
IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
boolean archiveSeen = false;
@@ -867,7 +867,7 @@
JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=ALL-UNNAMED")
};
IJavaProject project = createJava9ProjectWithJREAttributes("Test", new String[] {"src"}, annPathAttr);
- String attributesMemento = "=/annotationpath=/annots=/add-exports=/jdk.rmic\\/sun.rmi.rmic\\=ALL-UNNAMED";
+ String attributesMemento = "=/annotationpath=/annots=/=/add-exports=/jdk.rmic\\/sun.rmi.rmic\\=ALL-UNNAMED=/";
// Module java.base:
String expectedIdentifier = "=Test/"+getEscapedJrtJarPath()+"`java.base"+attributesMemento; // for specific PFR (see below)
@@ -903,4 +903,50 @@
deleteProject("Test");
}
}
+public void testEmptyAttribute() throws CoreException, IOException {
+ try {
+ IJavaProject project = createJavaProject("Test", new String[] {"src"}, null, "bin", "1.8", false);
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] {"test/Test.java", "package test; public class Test {}\n" },
+ null, project.getProject().getLocation().toString()+"/lib.jar", null, "1.8", null);
+
+ project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+ IClasspathAttribute[] attributes = {
+ JavaCore.newClasspathAttribute("foo", "")
+ };
+ addLibraryEntry(project, new Path("/Test/lib.jar"), null, null, null, null, attributes, false);
+ String[] expectedIdentifiers = {
+ "=Test/src",
+ "=Test/lib.jar=/foo=/=/"
+ };
+ IPackageFragmentRoot[] roots = project.getAllPackageFragmentRoots();
+ boolean archiveSeen = false;
+ for (int i = 0; i < roots.length; i++) {
+ IPackageFragmentRoot packageRoot = roots[i];
+ String handleIdentifier = packageRoot.getHandleIdentifier();
+ assertEquals("Root mementos", expectedIdentifiers[i], handleIdentifier);
+ IJavaElement element = JavaCore.create(handleIdentifier, null);
+ assertEquals("Root equivalence", packageRoot, element);
+ if (packageRoot.isArchive()) {
+ archiveSeen = true;
+ // PackageFragment
+ IPackageFragment test = packageRoot.getPackageFragment("test");
+ handleIdentifier = test.getHandleIdentifier();
+ String expected = expectedIdentifiers[i]+"<test";
+ assertEquals("PackageFragment mementos", expected, handleIdentifier);
+ element = JavaCore.create(handleIdentifier, null);
+ assertEquals("PackageFragment equivalence", test, element);
+ // ClassFile:
+ IClassFile classFile = test.getClassFile("Test.class");
+ handleIdentifier = classFile.getHandleIdentifier();
+ assertEquals("ClassFile mementos", expected+"(Test.class", handleIdentifier);
+ element = JavaCore.create(handleIdentifier);
+ assertEquals("ClassFile equivalence", classFile, element);
+ }
+ }
+ assertTrue("Should have seen an archive", archiveSeen);
+ } finally {
+ deleteProject("Test");
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
index 940fc16..3ed24c8 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
@@ -123,7 +123,7 @@
}
}
assertNotNull("Java.base module should not null", base);
- assertMarkers("Unexpected markers", "", project);
+ assertProblemMarkers("Unexpected markers", "", project.getProject());
} finally {
deleteProject("Test01");
}
@@ -136,10 +136,12 @@
" exports com.greetings;\n" +
" requires java.base;\n" +
"}");
+ this.createFile("P1/src/com/greetings/Greet.java", "package com.greetings; public class Greet {}\n");
waitForManualRefresh();
this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
- assertMarkers("Unexpected markers", "", this.currentProject);
+ assertProblemMarkers("Unexpected markers", "", this.currentProject.getProject());
} finally {
+ deleteFile("P1/src/com/greetings/Greet.java");
}
}
// Test that types from java.base module are seen by the compiler
@@ -2613,7 +2615,7 @@
}
}
assertNotNull("Java.base module should not null", base);
- assertMarkers("Unexpected markers", "", project);
+ assertProblemMarkers("Unexpected markers", "", project.getProject());
} finally {
deleteProject("Test01");
}
@@ -5288,10 +5290,10 @@
this.problemRequestor);
javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
- assertMarkers("markers in mod.one", "", javaProject);
+ assertProblemMarkers("markers in mod.one", "", javaProject.getProject());
javaProject2.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
- assertMarkers("markers in mod.two", "", javaProject2);
+ assertProblemMarkers("markers in mod.two", "", javaProject2.getProject());
javaProject.getProject().getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null);
assertNoErrors();
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/OptionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/OptionTests.java
index 069c3ec..4bffa2d 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/OptionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/OptionTests.java
@@ -531,7 +531,7 @@
IJavaProject project = createJavaProject("P", new String[0], new String[] {"TEST"}, "");
waitForAutoBuild();
preferences.put(JavaModelManager.CP_VARIABLE_PREFERENCES_PREFIX+"TEST", getExternalJCLPathString());
- assertMarkers("Unexpected markers", "", project);
+ assertBuildPathMarkers("Unexpected markers", "", project);
} finally {
deleteProject("P");
preferences.remove(JavaModelManager.CP_VARIABLE_PREFERENCES_PREFIX+"TEST");
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
index 6cbd027..9753ba5 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
@@ -34,6 +34,7 @@
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.IOrdinaryClassFile;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
@@ -559,4 +560,44 @@
deleteProject(logg);
}
}
+ public void testModuleCaching() throws Exception {
+ if (!isJRE9 || isJRE11) {
+ System.err.println("Test "+getName()+" requires a JRE [9,11)");
+ return;
+ }
+ IJavaProject prj = createJava9Project("caching");
+ try {
+ IFile file = createFile("caching/src/module-info.java",
+ "module caching {\n" +
+ " requires java.xml.bind;\n" +
+ "}\n");
+ createFolder("caching/src/p");
+ createFile("caching/src/p/X.java",
+ "package p;\n" +
+ "@javax.xml.bind.annotation.XmlRootElement\n" +
+ "public class X {}\n");
+ prj.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ IMarker[] markers = prj.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("unexpected markers",
+ "The module java.xml.bind has been deprecated since version 9 and marked for removal", markers);
+
+ IModuleDescription module = prj.getModuleDescription();
+ assertTrue("module exists", module.exists());
+ assertEquals("module name", "caching", module.getElementName());
+
+ // move module-info away ...
+ createFolder("caching/away");
+ file.move(new Path("/caching/away/module-info.java"), false, null);
+ IModuleDescription mod2 = prj.getModuleDescription();
+ assertNull("no longer a module", mod2);
+
+ // ... and observe javax.xml.bind unobservable:
+ prj.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ markers = prj.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("unexpected markers",
+ "javax.xml.bind cannot be resolved to a type", markers);
+ } finally {
+ deleteProject(prj);
+ }
+ }
}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Completion/.classpath b/org.eclipse.jdt.core.tests.model/workspace/Completion/.classpath
index f1fe1cf..af46168 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/Completion/.classpath
+++ b/org.eclipse.jdt.core.tests.model/workspace/Completion/.classpath
@@ -11,6 +11,7 @@
<classpathentry kind="lib" path="constructors.jar" sourcepath="/Completion/constructorssrc.zip"/>
<classpathentry kind="lib" path="generics.jar" sourcepath="/Completion/genericssrc.zip"/>
<classpathentry kind="lib" path="bug185318.jar"/>
+ <classpathentry kind="lib" path="test285379.jar"/>
<classpathentry kind="lib" path="class-folder"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Completion/src/Completion285379.java b/org.eclipse.jdt.core.tests.model/workspace/Completion/src/Completion285379.java
new file mode 100644
index 0000000..53d98a0
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Completion/src/Completion285379.java
@@ -0,0 +1,26 @@
+import pkgtest285379.X1;
+public class Completion285379 extends X1{
+ public interface testI{
+ void fooI();
+ };
+ X1 testVar;
+ Object o;
+ public static testI foo()
+ {
+ X1 a;
+ return
+ }
+ public void foo1()
+ {
+ pkgtest285379.X1.
+ }
+ public boolean foo2(X1 var)
+ {
+ if (var.equals(testVar))
+ return;
+ }
+ void bar(String var) {
+ X1 x;
+ x.equals(var);
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter13/.classpath b/org.eclipse.jdt.core.tests.model/workspace/Converter13/.classpath
index 3522bc0..1117818 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/Converter13/.classpath
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter13/.classpath
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
- <classpathentry kind="var" path="CONVERTER_JCL18_LIB" sourcepath="CONVERTER_JCL18_SRC" rootpath="CONVERTER_JCL_SRCROOT"/>
+ <classpathentry kind="var" path="CONVERTER_JCL13_LIB" sourcepath="CONVERTER_JCL13_SRC" rootpath="CONVERTER_JCL_SRCROOT"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/A_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/A_out.java
new file mode 100644
index 0000000..d9109d5
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/A_out.java
@@ -0,0 +1,86 @@
+public class Example {
+ String s = """
+aaa
+
+bbb
+
+
+ccc
+""";
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
+ 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc""" + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff" + "ggggggggggggggggg"
+ + "hhhhhhhhhhhhhhh" + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/B_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/B_out.java
new file mode 100644
index 0000000..6a5cd62
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/B_out.java
@@ -0,0 +1,87 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
+ 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc""" + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh"
+ + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/C_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/C_out.java
new file mode 100644
index 0000000..220456b
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/C_out.java
@@ -0,0 +1,87 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 0, 1, 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc""" + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh"
+ + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/D_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/D_out.java
new file mode 100644
index 0000000..909d326
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/D_out.java
@@ -0,0 +1,87 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 1, 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc""" + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg"
+ + "hhhhhhhhhhhhhhh" + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/E_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/E_out.java
new file mode 100644
index 0000000..e85dcf7
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/E_out.java
@@ -0,0 +1,88 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc"""
+ + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh"
+ + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/F_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/F_out.java
new file mode 100644
index 0000000..c748510
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/F_out.java
@@ -0,0 +1,87 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
+ 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc""" + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh"
+ + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/G_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/G_out.java
new file mode 100644
index 0000000..9405e25
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/G_out.java
@@ -0,0 +1,87 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 0, 1, 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc""" + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh"
+ + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/H_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/H_out.java
new file mode 100644
index 0000000..1bf3f50
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/H_out.java
@@ -0,0 +1,87 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 1, 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc""" + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg"
+ + "hhhhhhhhhhhhhhh" + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/I_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/I_out.java
new file mode 100644
index 0000000..a46ed3b
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/I_out.java
@@ -0,0 +1,88 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc"""
+ + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh"
+ + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/J_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/J_out.java
new file mode 100644
index 0000000..02e03da
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/J_out.java
@@ -0,0 +1,88 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc"""
+ + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh"
+ + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/K_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/K_out.java
new file mode 100644
index 0000000..2dcea0b
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/K_out.java
@@ -0,0 +1,88 @@
+public class Example {
+ String s = """
+ aaa
+
+ bbb
+
+
+ ccc
+ """;
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """, """
+ 1""", """
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+ """
+ aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+ System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+
+ String bar(boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg
+ ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh"""
+ : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc"""
+ + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff"
+ + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh"
+ + "iiiiiiiiiiiiiiii"
+ + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/in.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/in.java
new file mode 100644
index 0000000..db75fb0
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test549436/in.java
@@ -0,0 +1,79 @@
+public class Example {
+ String s = """
+aaa
+
+bbb
+
+
+ccc
+""";
+
+ String s2 = """
+ aaa
+
+ bbb
+
+
+ ccc""" + Arrays.asList(1, 2 , 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5);
+
+ Object[] s3 = { "aaaa", """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2 , 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+
+ Object[] s4 = { "aaaa", //
+ """
+ bbb
+
+ ccc
+
+
+ ddd
+ """, 1, 2 , 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
+
+ void foo() {
+ Arrays.asList("""
+ """,
+ """
+ 1""","""
+ 2
+ """, //
+ "", """
+
+
+
+ """, /**/
+"""
+aaa
+ """);
+
+ Object o = new Object("""
+ a,b,c,d""".split("""
+ ,""")) {
+ {
+System.out.println("""
+ aaaaaaaaaaaaaaa
+
+ bbbbbbbbbbbbbb""");
+ }
+ String bar (boolean arg) {
+ return (arg ? """
+ aaaa
+ """ : """
+ bbb
+ """) + (arg ? "cccccccccc" + "ddddddddddd" + "eeeeeeeeee"
+ + "fffffffffff" + "ggggggggg" + """
+ hhhhhhhh""" : """
+ aaaaaaaaa""" + """
+ bbbbbbbbb""" + """
+ cccccccccccc""" + """
+ ddddddddddddd
+ """ + "eeeeeeee" + "fffffffffffff" + "ggggggggggggggggg" + "hhhhhhhhhhhhhhh" + "iiiiiiiiiiiiiiii" + "jjjjjjjjjjjjjjjjjjjjjjj");
+ }
+ };
+ }
+}
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs
index 6f7536a..2ec8851 100644
--- a/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs
@@ -1,94 +1,104 @@
-#Fri May 21 10:24:07 EDT 2010
-ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
-ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
-ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
-API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
-CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
-CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
-CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
-CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
-CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
-CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
-CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
-CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
-ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
-ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
-ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
-FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
-FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
-FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
-FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
-FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
-FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
-FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
-ILLEGAL_EXTEND=Warning
-ILLEGAL_IMPLEMENT=Warning
-ILLEGAL_INSTANTIATE=Warning
-ILLEGAL_OVERRIDE=Warning
-ILLEGAL_REFERENCE=Warning
-INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
-INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
-INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
-INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
-INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
-INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-INVALID_JAVADOC_TAG=Warning
-INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning
-LEAK_EXTEND=Warning
-LEAK_FIELD_DECL=Warning
-LEAK_IMPLEMENT=Warning
-LEAK_METHOD_PARAM=Warning
-LEAK_METHOD_RETURN_TYPE=Warning
-METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
-METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
-METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
-METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
-METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
-METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
-METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
-METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
-TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
-TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
-UNUSED_PROBLEM_FILTERS=Warning
-automatically_removed_unused_problem_filters=false
+ANNOTATION_ELEMENT_TYPE_ADDED_FIELD=Ignore
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Ignore
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Ignore
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Ignore
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Ignore
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Ignore
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Ignore
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Ignore
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Ignore
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Ignore
+API_USE_SCAN_FIELD_SEVERITY=Ignore
+API_USE_SCAN_METHOD_SEVERITY=Ignore
+API_USE_SCAN_TYPE_SEVERITY=Ignore
+CLASS_ELEMENT_TYPE_ADDED_FIELD=Ignore
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Ignore
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Ignore
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Ignore
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Ignore
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Ignore
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Ignore
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Ignore
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Ignore
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Ignore
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Ignore
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Ignore
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Ignore
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Ignore
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Ignore
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Ignore
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Ignore
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Ignore
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Ignore
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Ignore
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Ignore
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Ignore
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Ignore
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Ignore
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Ignore
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Ignore
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Ignore
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Ignore
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Ignore
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Ignore
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Ignore
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Ignore
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Ignore
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Ignore
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Ignore
+ILLEGAL_EXTEND=Ignore
+ILLEGAL_IMPLEMENT=Ignore
+ILLEGAL_INSTANTIATE=Ignore
+ILLEGAL_OVERRIDE=Ignore
+ILLEGAL_REFERENCE=Ignore
+INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Ignore
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Ignore
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Ignore
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Ignore
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Ignore
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Ignore
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Ignore
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Ignore
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Ignore
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Ignore
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Ignore
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Ignore
+INVALID_ANNOTATION=Ignore
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Ignore
+LEAK_EXTEND=Ignore
+LEAK_FIELD_DECL=Ignore
+LEAK_IMPLEMENT=Ignore
+LEAK_METHOD_PARAM=Ignore
+LEAK_METHOD_RETURN_TYPE=Ignore
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Ignore
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Ignore
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Ignore
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Ignore
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Ignore
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Ignore
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Ignore
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Ignore
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Ignore
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Ignore
+MISSING_EE_DESCRIPTIONS=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Ignore
+UNUSED_PROBLEM_FILTERS=Ignore
+automatically_removed_unused_problem_filters=Ignore
+changed_execution_env=Ignore
eclipse.preferences.version=1
-incompatible_api_component_version=Error
+incompatible_api_component_version=Ignore
incompatible_api_component_version_include_major_without_breaking_change=Disabled
incompatible_api_component_version_include_minor_without_api_change=Disabled
-invalid_since_tag_version=Error
-malformed_since_tag=Error
-missing_since_tag=Error
+incompatible_api_component_version_report_major_without_breaking_change=Ignore
+incompatible_api_component_version_report_minor_without_api_change=Ignore
+invalid_since_tag_version=Ignore
+malformed_since_tag=Ignore
+missing_since_tag=Ignore
report_api_breakage_when_major_version_incremented=Disabled
-report_resolution_errors_api_component=Warning
+report_resolution_errors_api_component=Ignore
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index 4611c49..6c317c4 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -28,7 +28,7 @@
org.eclipse.jdt.internal.compiler.codegen;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
org.eclipse.jdt.internal.compiler.env;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
org.eclipse.jdt.internal.compiler.flow;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
- org.eclipse.jdt.internal.compiler.impl;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.impl;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core,org.eclipse.jdt.debug",
org.eclipse.jdt.internal.compiler.lookup;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
org.eclipse.jdt.internal.compiler.parser;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
org.eclipse.jdt.internal.compiler.parser.diagnose;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
@@ -37,7 +37,8 @@
x-friends:="org.eclipse.jdt.apt.pluggable.core,
org.eclipse.jdt.compiler.tool,
org.eclipse.pde.api.tools,
- org.eclipse.jdt.apt.core",
+ org.eclipse.jdt.apt.core,
+ org.eclipse.jdt.debug",
org.eclipse.jdt.internal.core;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools,org.eclipse.jdt.launching",
org.eclipse.jdt.internal.core.builder;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
org.eclipse.jdt.internal.core.dom;x-internal:=true,
@@ -57,7 +58,7 @@
org.eclipse.jdt.internal.core.search.indexing;x-internal:=true,
org.eclipse.jdt.internal.core.search.matching;x-internal:=true,
org.eclipse.jdt.internal.core.search.processing;x-internal:=true,
- org.eclipse.jdt.internal.core.util;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
+ org.eclipse.jdt.internal.core.util;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools,org.eclipse.jdt.debug",
org.eclipse.jdt.internal.eval;x-internal:=true,
org.eclipse.jdt.internal.formatter;x-internal:=true,
org.eclipse.jdt.internal.formatter.linewrap;x-internal:=true,
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 9bda4a9..a08a75c 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -4684,14 +4684,18 @@
setSeverity(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, severity, isEnabling);
return;
} else if (token.equals("unused")) { //$NON-NLS-1$
- setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling);
- setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
- setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
- setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling);
- setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
- setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
- setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling);
setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedExceptionParameter, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedObjectAllocation, severity,isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
setSeverity(CompilerOptions.OPTION_ReportUnusedTypeParameter, severity,isEnabling);
return;
} else if (token.equals("unusedParam")) { //$NON-NLS-1$
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 dcc0faf..80c0575 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
@@ -88,22 +88,25 @@
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrame;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.ExceptionMarker;
-import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackDepthMarker;
-import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackMarker;
import org.eclipse.jdt.internal.compiler.codegen.TypeAnnotationCodeStream;
import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
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.ModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
@@ -847,7 +850,8 @@
attributeNumber++; // code attribute
completeCodeAttributeForClinit(
codeAttributeOffset,
- problemLine);
+ problemLine,
+ null);
if (this.contentsOffset + 2 >= this.contents.length) {
resizeContents(2);
}
@@ -1467,7 +1471,9 @@
.scope
.referenceCompilationUnit()
.compilationResult
- .getLineSeparatorPositions());
+ .getLineSeparatorPositions(),
+ ((SourceTypeBinding) methodBinding.declaringClass)
+ .scope);
// update the number of attributes
this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
this.contents[methodAttributeOffset] = (byte) attributeNumber;
@@ -1485,7 +1491,7 @@
*
* @param codeAttributeOffset <CODE>int</CODE>
*/
- public void completeCodeAttribute(int codeAttributeOffset) {
+ public void completeCodeAttribute(int codeAttributeOffset, MethodScope scope) {
// reinitialize the localContents with the byte modified by the code stream
this.contents = this.codeStream.bCodeStream;
int localContentsOffset = this.codeStream.classFileOffset;
@@ -1605,7 +1611,8 @@
code_length,
codeAttributeOffset,
max_locals,
- false);
+ false,
+ scope);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
@@ -1614,7 +1621,8 @@
code_length,
codeAttributeOffset,
max_locals,
- false);
+ false,
+ scope);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
@@ -1693,7 +1701,7 @@
*
* @param codeAttributeOffset <CODE>int</CODE>
*/
- public void completeCodeAttributeForClinit(int codeAttributeOffset) {
+ public void completeCodeAttributeForClinit(int codeAttributeOffset, Scope scope) {
// reinitialize the contents with the byte modified by the code stream
this.contents = this.codeStream.bCodeStream;
int localContentsOffset = this.codeStream.classFileOffset;
@@ -1803,7 +1811,8 @@
code_length,
codeAttributeOffset,
max_locals,
- true);
+ true,
+ scope);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
@@ -1812,7 +1821,8 @@
code_length,
codeAttributeOffset,
max_locals,
- true);
+ true,
+ scope);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
@@ -1846,7 +1856,8 @@
*/
public void completeCodeAttributeForClinit(
int codeAttributeOffset,
- int problemLine) {
+ int problemLine,
+ MethodScope scope) {
// reinitialize the contents with the byte modified by the code stream
this.contents = this.codeStream.bCodeStream;
int localContentsOffset = this.codeStream.classFileOffset;
@@ -1917,7 +1928,8 @@
code_length,
codeAttributeOffset,
max_locals,
- true);
+ true,
+ scope);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
@@ -1926,7 +1938,8 @@
code_length,
codeAttributeOffset,
max_locals,
- true);
+ true,
+ scope);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
@@ -2000,7 +2013,8 @@
code_length,
codeAttributeOffset,
max_locals,
- false);
+ false,
+ null);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
@@ -2009,7 +2023,8 @@
code_length,
codeAttributeOffset,
max_locals,
- false);
+ false,
+ null);
}
// then we do the local variable attribute
@@ -2096,7 +2111,8 @@
code_length,
codeAttributeOffset,
max_locals,
- false);
+ false,
+ null);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
@@ -2105,7 +2121,8 @@
code_length,
codeAttributeOffset,
max_locals,
- false);
+ false,
+ null);
}
// update the number of attributes// ensure first that there is enough space available inside the localContents array
@@ -2139,7 +2156,8 @@
boolean hasExceptionHandlers,
SyntheticMethodBinding binding,
int codeAttributeOffset,
- int[] startLineIndexes) {
+ int[] startLineIndexes,
+ Scope scope) {
// reinitialize the contents with the byte modified by the code stream
this.contents = this.codeStream.bCodeStream;
int localContentsOffset = this.codeStream.classFileOffset;
@@ -2259,7 +2277,7 @@
attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, true);
}
if (addStackMaps) {
- attributesNumber += generateStackMapTableAttribute(binding, code_length, codeAttributeOffset, max_locals, false);
+ attributesNumber += generateStackMapTableAttribute(binding, code_length, codeAttributeOffset, max_locals, false, scope);
}
if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
@@ -2268,7 +2286,8 @@
code_length,
codeAttributeOffset,
max_locals,
- false);
+ false,
+ scope);
}
// update the number of attributes
@@ -2309,7 +2328,8 @@
false,
binding,
codeAttributeOffset,
- startLineIndexes);
+ startLineIndexes,
+ ((SourceTypeBinding) binding.declaringClass).scope);
}
private void completeArgumentAnnotationInfo(Argument[] arguments, List allAnnotationContexts) {
@@ -4733,14 +4753,15 @@
int code_length,
int codeAttributeOffset,
int max_locals,
- boolean isClinit) {
+ boolean isClinit,
+ Scope scope) {
int attributesNumber = 0;
int localContentsOffset = this.contentsOffset;
StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
stackMapFrameCodeStream.removeFramePosition(code_length);
if (stackMapFrameCodeStream.hasFramePositions()) {
Map frames = new HashMap();
- List realFrames = traverse(isClinit ? null : methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
+ List realFrames = traverse(isClinit ? null : methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit, scope);
int numberOfFrames = realFrames.size();
if (numberOfFrames > 1) {
int stackMapTableAttributeOffset = localContentsOffset;
@@ -4815,17 +4836,17 @@
break;
default:
this.contents[localContentsOffset++] = (byte) info.tag;
- switch (info.tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- int offset = info.offset;
- this.contents[localContentsOffset++] = (byte) (offset >> 8);
- this.contents[localContentsOffset++] = (byte) offset;
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
- this.contents[localContentsOffset++] = (byte) indexForType;
- }
+ switch (info.tag) {
+ case VerificationTypeInfo.ITEM_UNINITIALIZED :
+ int offset = info.offset;
+ this.contents[localContentsOffset++] = (byte) (offset >> 8);
+ this.contents[localContentsOffset++] = (byte) offset;
+ break;
+ case VerificationTypeInfo.ITEM_OBJECT :
+ int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
+ this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
+ this.contents[localContentsOffset++] = (byte) indexForType;
+ }
}
numberOfLocalEntries++;
}
@@ -4910,14 +4931,15 @@
int code_length,
int codeAttributeOffset,
int max_locals,
- boolean isClinit) {
+ boolean isClinit,
+ Scope scope) {
int attributesNumber = 0;
int localContentsOffset = this.contentsOffset;
StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
stackMapFrameCodeStream.removeFramePosition(code_length);
if (stackMapFrameCodeStream.hasFramePositions()) {
Map frames = new HashMap();
- List realFrames = traverse(isClinit ? null: methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
+ List realFrames = traverse(isClinit ? null: methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit, scope);
int numberOfFrames = realFrames.size();
if (numberOfFrames > 1) {
int stackMapTableAttributeOffset = localContentsOffset;
@@ -5456,8 +5478,7 @@
// skip type parameters
int paren = CharOperation.lastIndexOf(')', methodSignature);
// there could be thrown exceptions behind, thus scan one type exactly
- return CharOperation.subarray(methodSignature, paren + 1,
- methodSignature.length);
+ return CharOperation.subarray(methodSignature, paren + 1, methodSignature.length);
}
private final int i4At(byte[] reference, int relativeOffset,
@@ -5643,9 +5664,7 @@
localVariableBinding.recordInitializationStartPC(0);
localVariableBinding.recordInitializationEndPC(codeLength);
- frame.putLocal(resolvedPosition, new VerificationTypeInfo(
- TypeIds.T_JavaLangString,
- ConstantPool.JavaLangStringConstantPoolName));
+ frame.putLocal(resolvedPosition, new VerificationTypeInfo(this.referenceBinding.scope.getJavaLangString()));
resolvedPosition++;
localVariableBinding = new LocalVariableBinding(" ordinal".toCharArray(), TypeBinding.INT, 0, false); //$NON-NLS-1$
@@ -5653,8 +5672,7 @@
this.codeStream.record(localVariableBinding);
localVariableBinding.recordInitializationStartPC(0);
localVariableBinding.recordInitializationEndPC(codeLength);
- frame.putLocal(resolvedPosition, new VerificationTypeInfo(
- TypeBinding.INT));
+ frame.putLocal(resolvedPosition, new VerificationTypeInfo(TypeBinding.INT));
resolvedPosition++;
}
@@ -5989,8 +6007,216 @@
});
return result;
}
+
+ private TypeBinding getTypeBinding(char[] typeConstantPoolName, Scope scope, boolean checkcast) {
+ if (typeConstantPoolName.length == 1) {
+ // base type
+ switch(typeConstantPoolName[0]) {
+ case 'Z':
+ return TypeBinding.BOOLEAN;
+ case 'B':
+ return TypeBinding.BYTE;
+ case 'C':
+ return TypeBinding.CHAR;
+ case 'D':
+ return TypeBinding.DOUBLE;
+ case 'F':
+ return TypeBinding.FLOAT;
+ case 'I':
+ return TypeBinding.INT;
+ case 'J':
+ return TypeBinding.LONG;
+ case 'S':
+ return TypeBinding.SHORT;
+ default:
+ return null;
+ }
+ } else if (typeConstantPoolName[0] == '[') {
+ int dimensions = getDimensions(typeConstantPoolName);
+ if (typeConstantPoolName.length - dimensions == 1) {
+ // array of base types
+ TypeBinding baseType = null;
+ switch(typeConstantPoolName[typeConstantPoolName.length - 1]) {
+ case 'Z':
+ baseType = TypeBinding.BOOLEAN;
+ break;
+ case 'B':
+ baseType = TypeBinding.BYTE;
+ break;
+ case 'C':
+ baseType = TypeBinding.CHAR;
+ break;
+ case 'D':
+ baseType = TypeBinding.DOUBLE;
+ break;
+ case 'F':
+ baseType = TypeBinding.FLOAT;
+ break;
+ case 'I':
+ baseType = TypeBinding.INT;
+ break;
+ case 'J':
+ baseType = TypeBinding.LONG;
+ break;
+ case 'S':
+ baseType = TypeBinding.SHORT;
+ break;
+ case 'V':
+ baseType = TypeBinding.VOID;
+ }
+ return scope.createArrayType(baseType, dimensions);
+ } else {
+ // array of object types
+ char[] typeName = CharOperation.subarray(typeConstantPoolName, dimensions + 1, typeConstantPoolName.length - 1);
+ TypeBinding type = (TypeBinding) scope.getTypeOrPackage(CharOperation.splitOn('/', typeName));
+ if (!type.isValidBinding()) {
+ ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
+ if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0) {
+ type = problemReferenceBinding.closestMatch();
+ } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
+ // check local inner types to see if this is a anonymous type
+ Set<TypeBinding> innerTypeBindings = this.innerClassesBindings.keySet();
+ for (TypeBinding binding : innerTypeBindings) {
+ if (CharOperation.equals(binding.constantPoolName(), typeName)) {
+ type = binding;
+ break;
+ }
+ }
+ }
+ }
+ return scope.createArrayType(type, dimensions);
+ }
+ } else {
+ char[] typeName = checkcast ? typeConstantPoolName : CharOperation.subarray(typeConstantPoolName, 1, typeConstantPoolName.length - 1);
+ TypeBinding type = (TypeBinding) scope.getTypeOrPackage(CharOperation.splitOn('/', typeName));
+ if (!type.isValidBinding()) {
+ ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
+ if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0) {
+ type = problemReferenceBinding.closestMatch();
+ } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
+ // check local inner types to see if this is a anonymous type
+ Set<TypeBinding> innerTypeBindings = this.innerClassesBindings.keySet();
+ for (TypeBinding binding : innerTypeBindings) {
+ if (CharOperation.equals(binding.constantPoolName(), typeName)) {
+ type = binding;
+ break;
+ }
+ }
+ }
+ }
+ return type;
+ }
+ }
- public List traverse(MethodBinding methodBinding, int maxLocals, byte[] bytecodes, int codeOffset, int codeLength, Map frames, boolean isClinit) {
+ private TypeBinding getNewTypeBinding(char[] typeConstantPoolName, Scope scope) {
+ char[] typeName = typeConstantPoolName;
+ TypeBinding type = (TypeBinding) scope.getTypeOrPackage(CharOperation.splitOn('/', typeName));
+ if (!type.isValidBinding()) {
+ ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
+ if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0) {
+ type = problemReferenceBinding.closestMatch();
+ } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
+ // check local inner types to see if this is a anonymous type
+ Set<TypeBinding> innerTypeBindings = this.innerClassesBindings.keySet();
+ for (TypeBinding binding : innerTypeBindings) {
+ if (CharOperation.equals(binding.constantPoolName(), typeName)) {
+ type = binding;
+ break;
+ }
+ }
+ }
+ }
+ return type;
+ }
+
+ private TypeBinding getANewArrayTypeBinding(char[] typeConstantPoolName, Scope scope) {
+ if (typeConstantPoolName[0] == '[') {
+ int dimensions = getDimensions(typeConstantPoolName);
+ if (typeConstantPoolName.length - dimensions == 1) {
+ // array of base types
+ TypeBinding baseType = null;
+ switch(typeConstantPoolName[typeConstantPoolName.length - 1]) {
+ case 'Z':
+ baseType = TypeBinding.BOOLEAN;
+ break;
+ case 'B':
+ baseType = TypeBinding.BYTE;
+ break;
+ case 'C':
+ baseType = TypeBinding.CHAR;
+ break;
+ case 'D':
+ baseType = TypeBinding.DOUBLE;
+ break;
+ case 'F':
+ baseType = TypeBinding.FLOAT;
+ break;
+ case 'I':
+ baseType = TypeBinding.INT;
+ break;
+ case 'J':
+ baseType = TypeBinding.LONG;
+ break;
+ case 'S':
+ baseType = TypeBinding.SHORT;
+ break;
+ case 'V':
+ baseType = TypeBinding.VOID;
+ }
+ return scope.createArrayType(baseType, dimensions);
+ } else {
+ // array of object types
+ char[] elementTypeClassName = CharOperation.subarray(typeConstantPoolName, dimensions + 1, typeConstantPoolName.length - 1);
+ TypeBinding type = (TypeBinding) scope.getTypeOrPackage(
+ CharOperation.splitOn('/', elementTypeClassName));
+ if (!type.isValidBinding()) {
+ ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
+ if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0) {
+ type = problemReferenceBinding.closestMatch();
+ } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
+ // check local inner types to see if this is a anonymous type
+ Set<TypeBinding> innerTypeBindings = this.innerClassesBindings.keySet();
+ for (TypeBinding binding : innerTypeBindings) {
+ if (CharOperation.equals(binding.constantPoolName(), elementTypeClassName)) {
+ type = binding;
+ break;
+ }
+ }
+ }
+ }
+ return scope.createArrayType(type, dimensions);
+ }
+ } else {
+ TypeBinding type = (TypeBinding) scope.getTypeOrPackage(
+ CharOperation.splitOn('/', typeConstantPoolName));
+ if (!type.isValidBinding()) {
+ ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
+ if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0) {
+ type = problemReferenceBinding.closestMatch();
+ } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
+ // check local inner types to see if this is a anonymous type
+ Set<TypeBinding> innerTypeBindings = this.innerClassesBindings.keySet();
+ for (TypeBinding binding : innerTypeBindings) {
+ if (CharOperation.equals(binding.constantPoolName(), typeConstantPoolName)) {
+ type = binding;
+ break;
+ }
+ }
+ }
+ }
+ return type;
+ }
+ }
+
+ public List traverse(
+ MethodBinding methodBinding,
+ int maxLocals,
+ byte[] bytecodes,
+ int codeOffset,
+ int codeLength,
+ Map<Integer, StackMapFrame> frames,
+ boolean isClinit,
+ Scope scope) {
Set realJumpTarget = new HashSet();
StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
@@ -6005,26 +6231,6 @@
int framePositionsLength = framePositions.length;
int currentFramePosition = framePositions[0];
- // set initial values for stack depth markers
- int indexInStackDepthMarkers = 0;
- StackDepthMarker[] stackDepthMarkers = stackMapFrameCodeStream.getStackDepthMarkers();
- int stackDepthMarkersLength = stackDepthMarkers == null ? 0 : stackDepthMarkers.length;
- boolean hasStackDepthMarkers = stackDepthMarkersLength != 0;
- StackDepthMarker stackDepthMarker = null;
- if (hasStackDepthMarkers) {
- stackDepthMarker = stackDepthMarkers[0];
- }
-
- // set initial values for stack markers (used only in cldc mode)
- int indexInStackMarkers = 0;
- StackMarker[] stackMarkers = stackMapFrameCodeStream.getStackMarkers();
- int stackMarkersLength = stackMarkers == null ? 0 : stackMarkers.length;
- boolean hasStackMarkers = stackMarkersLength != 0;
- StackMarker stackMarker = null;
- if (hasStackMarkers) {
- stackMarker = stackMarkers[0];
- }
-
// set initial values for exception markers
int indexInExceptionMarkers = 0;
ExceptionMarker[] exceptionMarkers= stackMapFrameCodeStream.getExceptionMarkers();
@@ -6040,7 +6246,7 @@
initializeDefaultLocals(frame, methodBinding, maxLocals, codeLength);
}
frame.pc = -1;
- add(frames, frame.duplicate());
+ add(frames, frame.duplicate(), scope);
addRealJumpTarget(realJumpTarget, -1);
for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
ExceptionLabel exceptionLabel = this.codeStream.exceptionLabels[i];
@@ -6050,43 +6256,9 @@
}
while (true) {
int currentPC = pc - codeOffset;
- if (hasStackMarkers && stackMarker.pc == currentPC) {
- VerificationTypeInfo[] infos = frame.stackItems;
- VerificationTypeInfo[] tempInfos = new VerificationTypeInfo[frame.numberOfStackItems];
- System.arraycopy(infos, 0, tempInfos, 0, frame.numberOfStackItems);
- stackMarker.setInfos(tempInfos);
- } else if (hasStackMarkers && stackMarker.destinationPC == currentPC) {
- VerificationTypeInfo[] infos = stackMarker.infos;
- frame.stackItems = infos;
- frame.numberOfStackItems = infos.length;
- indexInStackMarkers++;
- if (indexInStackMarkers < stackMarkersLength) {
- stackMarker = stackMarkers[indexInStackMarkers];
- } else {
- hasStackMarkers = false;
- }
- }
- if (hasStackDepthMarkers && stackDepthMarker.pc == currentPC) {
- TypeBinding typeBinding = stackDepthMarker.typeBinding;
- if (typeBinding != null) {
- if (stackDepthMarker.delta > 0) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- } else {
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding);
- }
- } else {
- frame.numberOfStackItems--;
- }
- indexInStackDepthMarkers++;
- if (indexInStackDepthMarkers < stackDepthMarkersLength) {
- stackDepthMarker = stackDepthMarkers[indexInStackDepthMarkers];
- } else {
- hasStackDepthMarkers = false;
- }
- }
if (hasExceptionMarkers && exceptionMarker.pc == currentPC) {
frame.numberOfStackItems = 0;
- frame.addStackItem(new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_OBJECT, exceptionMarker.constantPoolName));
+ frame.addStackItem(new VerificationTypeInfo(exceptionMarker.getBinding()));
indexInExceptionMarkers++;
if (indexInExceptionMarkers < exceptionsMarkersLength) {
exceptionMarker = exceptionMarkers[indexInExceptionMarkers];
@@ -6106,12 +6278,13 @@
}
if (currentFramePosition == currentPC) {
// need to build a new frame and create a stack map attribute entry
- StackMapFrame currentFrame = frame.duplicate();
- currentFrame.pc = currentPC;
- // initialize locals
- initializeLocals(isClinit ? true : methodBinding.isStatic(), currentPC, currentFrame);
- // insert a new frame
- add(frames, currentFrame);
+ StackMapFrame currentFrame = frames.get(Integer.valueOf(currentPC));
+ if (currentFrame == null) {
+ currentFrame = createNewFrame(currentPC, frame, isClinit, methodBinding);
+ add(frames, currentFrame, scope);
+ } else {
+ frame = currentFrame.merge(frame.duplicate(), scope).duplicate();
+ }
indexInFramePositions++;
if (indexInFramePositions < framePositionsLength) {
currentFramePosition = framePositions[indexInFramePositions];
@@ -6125,7 +6298,7 @@
pc++;
break;
case Opcodes.OPC_aconst_null:
- frame.addStackItem(TypeBinding.NULL);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.NULL));
pc++;
break;
case Opcodes.OPC_iconst_m1:
@@ -6135,31 +6308,31 @@
case Opcodes.OPC_iconst_3:
case Opcodes.OPC_iconst_4:
case Opcodes.OPC_iconst_5:
- frame.addStackItem(TypeBinding.INT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
pc++;
break;
case Opcodes.OPC_lconst_0:
case Opcodes.OPC_lconst_1:
- frame.addStackItem(TypeBinding.LONG);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
pc++;
break;
case Opcodes.OPC_fconst_0:
case Opcodes.OPC_fconst_1:
case Opcodes.OPC_fconst_2:
- frame.addStackItem(TypeBinding.FLOAT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
pc++;
break;
case Opcodes.OPC_dconst_0:
case Opcodes.OPC_dconst_1:
- frame.addStackItem(TypeBinding.DOUBLE);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
pc++;
break;
case Opcodes.OPC_bipush:
- frame.addStackItem(TypeBinding.BYTE);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.BYTE));
pc += 2;
break;
case Opcodes.OPC_sipush:
- frame.addStackItem(TypeBinding.SHORT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.SHORT));
pc += 3;
break;
case Opcodes.OPC_ldc:
@@ -6167,20 +6340,16 @@
switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
case ClassFileConstants.StringTag:
frame
- .addStackItem(new VerificationTypeInfo(
- TypeIds.T_JavaLangString,
- ConstantPool.JavaLangStringConstantPoolName));
+ .addStackItem(new VerificationTypeInfo(scope.getJavaLangString()));
break;
case ClassFileConstants.IntegerTag:
- frame.addStackItem(TypeBinding.INT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
break;
case ClassFileConstants.FloatTag:
- frame.addStackItem(TypeBinding.FLOAT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
break;
case ClassFileConstants.ClassTag:
- frame.addStackItem(new VerificationTypeInfo(
- TypeIds.T_JavaLangClass,
- ConstantPool.JavaLangClassConstantPoolName));
+ frame.addStackItem(new VerificationTypeInfo(scope.getJavaLangClass()));
}
pc += 2;
break;
@@ -6189,20 +6358,16 @@
switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
case ClassFileConstants.StringTag:
frame
- .addStackItem(new VerificationTypeInfo(
- TypeIds.T_JavaLangString,
- ConstantPool.JavaLangStringConstantPoolName));
+ .addStackItem(new VerificationTypeInfo(scope.getJavaLangString()));
break;
case ClassFileConstants.IntegerTag:
- frame.addStackItem(TypeBinding.INT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
break;
case ClassFileConstants.FloatTag:
- frame.addStackItem(TypeBinding.FLOAT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
break;
case ClassFileConstants.ClassTag:
- frame.addStackItem(new VerificationTypeInfo(
- TypeIds.T_JavaLangClass,
- ConstantPool.JavaLangClassConstantPoolName));
+ frame.addStackItem(new VerificationTypeInfo(scope.getJavaLangClass()));
}
pc += 3;
break;
@@ -6210,28 +6375,28 @@
index = u2At(bytecodes, 1, pc);
switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
case ClassFileConstants.DoubleTag:
- frame.addStackItem(TypeBinding.DOUBLE);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
break;
case ClassFileConstants.LongTag:
- frame.addStackItem(TypeBinding.LONG);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
break;
}
pc += 3;
break;
case Opcodes.OPC_iload:
- frame.addStackItem(TypeBinding.INT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
pc += 2;
break;
case Opcodes.OPC_lload:
- frame.addStackItem(TypeBinding.LONG);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
pc += 2;
break;
case Opcodes.OPC_fload:
- frame.addStackItem(TypeBinding.FLOAT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
pc += 2;
break;
case Opcodes.OPC_dload:
- frame.addStackItem(TypeBinding.DOUBLE);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
pc += 2;
break;
case Opcodes.OPC_aload:
@@ -6244,28 +6409,28 @@
case Opcodes.OPC_iload_1:
case Opcodes.OPC_iload_2:
case Opcodes.OPC_iload_3:
- frame.addStackItem(TypeBinding.INT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
pc++;
break;
case Opcodes.OPC_lload_0:
case Opcodes.OPC_lload_1:
case Opcodes.OPC_lload_2:
case Opcodes.OPC_lload_3:
- frame.addStackItem(TypeBinding.LONG);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
pc++;
break;
case Opcodes.OPC_fload_0:
case Opcodes.OPC_fload_1:
case Opcodes.OPC_fload_2:
case Opcodes.OPC_fload_3:
- frame.addStackItem(TypeBinding.FLOAT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
pc++;
break;
case Opcodes.OPC_dload_0:
case Opcodes.OPC_dload_1:
case Opcodes.OPC_dload_2:
case Opcodes.OPC_dload_3:
- frame.addStackItem(TypeBinding.DOUBLE);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
pc++;
break;
case Opcodes.OPC_aload_0:
@@ -6294,22 +6459,22 @@
break;
case Opcodes.OPC_iaload:
frame.numberOfStackItems -=2;
- frame.addStackItem(TypeBinding.INT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
pc++;
break;
case Opcodes.OPC_laload:
frame.numberOfStackItems -=2;
- frame.addStackItem(TypeBinding.LONG);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
pc++;
break;
case Opcodes.OPC_faload:
frame.numberOfStackItems -=2;
- frame.addStackItem(TypeBinding.FLOAT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
pc++;
break;
case Opcodes.OPC_daload:
frame.numberOfStackItems -=2;
- frame.addStackItem(TypeBinding.DOUBLE);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
pc++;
break;
case Opcodes.OPC_aaload:
@@ -6319,17 +6484,17 @@
break;
case Opcodes.OPC_baload:
frame.numberOfStackItems -=2;
- frame.addStackItem(TypeBinding.BYTE);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.BYTE));
pc++;
break;
case Opcodes.OPC_caload:
frame.numberOfStackItems -=2;
- frame.addStackItem(TypeBinding.CHAR);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.CHAR));
pc++;
break;
case Opcodes.OPC_saload:
frame.numberOfStackItems -=2;
- frame.addStackItem(TypeBinding.SHORT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.SHORT));
pc++;
break;
case Opcodes.OPC_istore:
@@ -6652,7 +6817,7 @@
case Opcodes.OPC_dcmpl:
case Opcodes.OPC_dcmpg:
frame.numberOfStackItems-=2;
- frame.addStackItem(TypeBinding.INT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
pc++;
break;
case Opcodes.OPC_ifeq:
@@ -6662,7 +6827,8 @@
case Opcodes.OPC_ifgt:
case Opcodes.OPC_ifle:
frame.numberOfStackItems--;
- addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
+ int jumpPC = currentPC + i2At(bytecodes, 1, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 3;
break;
case Opcodes.OPC_if_icmpeq:
@@ -6674,21 +6840,25 @@
case Opcodes.OPC_if_acmpeq:
case Opcodes.OPC_if_acmpne:
frame.numberOfStackItems -= 2;
- addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
+ jumpPC = currentPC + i2At(bytecodes, 1, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 3;
break;
case Opcodes.OPC_goto:
- addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
+ jumpPC = currentPC + i2At(bytecodes, 1, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 3;
addRealJumpTarget(realJumpTarget, pc - codeOffset);
break;
case Opcodes.OPC_tableswitch:
+ frame.numberOfStackItems--;
pc++;
while (((pc - codeOffset) & 0x03) != 0) {
pc++;
}
// default offset
- addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
+ jumpPC = currentPC + i4At(bytecodes, 0, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 4; // default
int low = i4At(bytecodes, 0, pc);
pc += 4;
@@ -6697,27 +6867,29 @@
int length = high - low + 1;
for (int i = 0; i < length; i++) {
// pair offset
- addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
+ jumpPC = currentPC + i4At(bytecodes, 0, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 4;
}
- frame.numberOfStackItems--;
break;
case Opcodes.OPC_lookupswitch:
+ frame.numberOfStackItems--;
pc++;
while (((pc - codeOffset) & 0x03) != 0) {
pc++;
}
- addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
+ jumpPC = currentPC + i4At(bytecodes, 0, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 4; // default offset
int npairs = (int) u4At(bytecodes, 0, pc);
pc += 4; // npair value
for (int i = 0; i < npairs; i++) {
pc += 4; // case value
// pair offset
- addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
+ jumpPC = currentPC + i4At(bytecodes, 0, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 4;
}
- frame.numberOfStackItems--;
break;
case Opcodes.OPC_ireturn:
case Opcodes.OPC_lreturn:
@@ -6742,38 +6914,9 @@
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
- if (descriptor.length == 1) {
- // base type
- switch(descriptor[0]) {
- case 'Z':
- frame.addStackItem(TypeBinding.BOOLEAN);
- break;
- case 'B':
- frame.addStackItem(TypeBinding.BYTE);
- break;
- case 'C':
- frame.addStackItem(TypeBinding.CHAR);
- break;
- case 'D':
- frame.addStackItem(TypeBinding.DOUBLE);
- break;
- case 'F':
- frame.addStackItem(TypeBinding.FLOAT);
- break;
- case 'I':
- frame.addStackItem(TypeBinding.INT);
- break;
- case 'J':
- frame.addStackItem(TypeBinding.LONG);
- break;
- case 'S':
- frame.addStackItem(TypeBinding.SHORT);
- break;
- }
- } else if (descriptor[0] == '[') {
- frame.addStackItem(new VerificationTypeInfo(0, descriptor));
- } else {
- frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1)));
+ TypeBinding typeBinding = getTypeBinding(descriptor, scope, false);
+ if (typeBinding != null) {
+ frame.addStackItem(new VerificationTypeInfo(typeBinding));
}
pc += 3;
break;
@@ -6792,38 +6935,9 @@
poolContents, 1,
constantPoolOffsets[utf8index]));
frame.numberOfStackItems--;
- if (descriptor.length == 1) {
- // base type
- switch(descriptor[0]) {
- case 'Z':
- frame.addStackItem(TypeBinding.BOOLEAN);
- break;
- case 'B':
- frame.addStackItem(TypeBinding.BYTE);
- break;
- case 'C':
- frame.addStackItem(TypeBinding.CHAR);
- break;
- case 'D':
- frame.addStackItem(TypeBinding.DOUBLE);
- break;
- case 'F':
- frame.addStackItem(TypeBinding.FLOAT);
- break;
- case 'I':
- frame.addStackItem(TypeBinding.INT);
- break;
- case 'J':
- frame.addStackItem(TypeBinding.LONG);
- break;
- case 'S':
- frame.addStackItem(TypeBinding.SHORT);
- break;
- }
- } else if (descriptor[0] == '[') {
- frame.addStackItem(new VerificationTypeInfo(0, descriptor));
- } else {
- frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1)));
+ typeBinding = getTypeBinding(descriptor, scope, false);
+ if (typeBinding != null) {
+ frame.addStackItem(new VerificationTypeInfo(typeBinding));
}
pc += 3;
break;
@@ -6849,40 +6963,9 @@
constantPoolOffsets[utf8index]));
frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
char[] returnType = getReturnType(descriptor);
- if (returnType.length == 1) {
- // base type
- switch(returnType[0]) {
- case 'Z':
- frame.addStackItem(TypeBinding.BOOLEAN);
- break;
- case 'B':
- frame.addStackItem(TypeBinding.BYTE);
- break;
- case 'C':
- frame.addStackItem(TypeBinding.CHAR);
- break;
- case 'D':
- frame.addStackItem(TypeBinding.DOUBLE);
- break;
- case 'F':
- frame.addStackItem(TypeBinding.FLOAT);
- break;
- case 'I':
- frame.addStackItem(TypeBinding.INT);
- break;
- case 'J':
- frame.addStackItem(TypeBinding.LONG);
- break;
- case 'S':
- frame.addStackItem(TypeBinding.SHORT);
- break;
- }
- } else {
- if (returnType[0] == '[') {
- frame.addStackItem(new VerificationTypeInfo(0, returnType));
- } else {
- frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
- }
+ typeBinding = getTypeBinding(returnType, scope, false);
+ if (typeBinding != null) {
+ frame.addStackItem(new VerificationTypeInfo(typeBinding));
}
pc += 3;
break;
@@ -6898,40 +6981,9 @@
constantPoolOffsets[utf8index]));
frame.numberOfStackItems -= getParametersCount(descriptor);
returnType = getReturnType(descriptor);
- if (returnType.length == 1) {
- // base type
- switch(returnType[0]) {
- case 'Z':
- frame.addStackItem(TypeBinding.BOOLEAN);
- break;
- case 'B':
- frame.addStackItem(TypeBinding.BYTE);
- break;
- case 'C':
- frame.addStackItem(TypeBinding.CHAR);
- break;
- case 'D':
- frame.addStackItem(TypeBinding.DOUBLE);
- break;
- case 'F':
- frame.addStackItem(TypeBinding.FLOAT);
- break;
- case 'I':
- frame.addStackItem(TypeBinding.INT);
- break;
- case 'J':
- frame.addStackItem(TypeBinding.LONG);
- break;
- case 'S':
- frame.addStackItem(TypeBinding.SHORT);
- break;
- }
- } else {
- if (returnType[0] == '[') {
- frame.addStackItem(new VerificationTypeInfo(0, returnType));
- } else {
- frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
- }
+ typeBinding = getTypeBinding(returnType, scope, false);
+ if (typeBinding != null) {
+ frame.addStackItem(new VerificationTypeInfo(typeBinding));
}
pc += 5;
break;
@@ -6958,40 +7010,9 @@
}
frame.numberOfStackItems--;
returnType = getReturnType(descriptor);
- if (returnType.length == 1) {
- // base type
- switch(returnType[0]) {
- case 'Z':
- frame.addStackItem(TypeBinding.BOOLEAN);
- break;
- case 'B':
- frame.addStackItem(TypeBinding.BYTE);
- break;
- case 'C':
- frame.addStackItem(TypeBinding.CHAR);
- break;
- case 'D':
- frame.addStackItem(TypeBinding.DOUBLE);
- break;
- case 'F':
- frame.addStackItem(TypeBinding.FLOAT);
- break;
- case 'I':
- frame.addStackItem(TypeBinding.INT);
- break;
- case 'J':
- frame.addStackItem(TypeBinding.LONG);
- break;
- case 'S':
- frame.addStackItem(TypeBinding.SHORT);
- break;
- }
- } else {
- if (returnType[0] == '[') {
- frame.addStackItem(new VerificationTypeInfo(0, returnType));
- } else {
- frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
- }
+ typeBinding = getTypeBinding(returnType, scope, false);
+ if (typeBinding != null) {
+ frame.addStackItem(new VerificationTypeInfo(typeBinding));
}
pc += 3;
break;
@@ -7013,40 +7034,9 @@
constantPoolOffsets[utf8index]));
frame.numberOfStackItems -= getParametersCount(descriptor);
returnType = getReturnType(descriptor);
- if (returnType.length == 1) {
- // base type
- switch(returnType[0]) {
- case 'Z':
- frame.addStackItem(TypeBinding.BOOLEAN);
- break;
- case 'B':
- frame.addStackItem(TypeBinding.BYTE);
- break;
- case 'C':
- frame.addStackItem(TypeBinding.CHAR);
- break;
- case 'D':
- frame.addStackItem(TypeBinding.DOUBLE);
- break;
- case 'F':
- frame.addStackItem(TypeBinding.FLOAT);
- break;
- case 'I':
- frame.addStackItem(TypeBinding.INT);
- break;
- case 'J':
- frame.addStackItem(TypeBinding.LONG);
- break;
- case 'S':
- frame.addStackItem(TypeBinding.SHORT);
- break;
- }
- } else {
- if (returnType[0] == '[') {
- frame.addStackItem(new VerificationTypeInfo(0, returnType));
- } else {
- frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
- }
+ typeBinding = getTypeBinding(returnType, scope, false);
+ if (typeBinding != null) {
+ frame.addStackItem(new VerificationTypeInfo(typeBinding));
}
pc += 3;
break;
@@ -7071,40 +7061,9 @@
// u1At(bytecodes, 4, pc); // extra args
frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
returnType = getReturnType(descriptor);
- if (returnType.length == 1) {
- // base type
- switch(returnType[0]) {
- case 'Z':
- frame.addStackItem(TypeBinding.BOOLEAN);
- break;
- case 'B':
- frame.addStackItem(TypeBinding.BYTE);
- break;
- case 'C':
- frame.addStackItem(TypeBinding.CHAR);
- break;
- case 'D':
- frame.addStackItem(TypeBinding.DOUBLE);
- break;
- case 'F':
- frame.addStackItem(TypeBinding.FLOAT);
- break;
- case 'I':
- frame.addStackItem(TypeBinding.INT);
- break;
- case 'J':
- frame.addStackItem(TypeBinding.LONG);
- break;
- case 'S':
- frame.addStackItem(TypeBinding.SHORT);
- break;
- }
- } else {
- if (returnType[0] == '[') {
- frame.addStackItem(new VerificationTypeInfo(0, returnType));
- } else {
- frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
- }
+ typeBinding = getTypeBinding(returnType, scope, false);
+ if (typeBinding != null) {
+ frame.addStackItem(new VerificationTypeInfo(typeBinding));
}
pc += 5;
break;
@@ -7116,40 +7075,41 @@
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
- VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_UNINITIALIZED, className);
+ typeBinding = getNewTypeBinding(className, scope);
+ VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(VerificationTypeInfo.ITEM_UNINITIALIZED, typeBinding);
verificationTypeInfo.offset = currentPC;
frame.addStackItem(verificationTypeInfo);
pc += 3;
break;
case Opcodes.OPC_newarray:
- char[] constantPoolName = null;
+ TypeBinding arrayType = null;
switch (u1At(bytecodes, 1, pc)) {
case ClassFileConstants.INT_ARRAY :
- constantPoolName = new char[] { '[', 'I' };
+ arrayType = scope.createArrayType(TypeBinding.INT, 1);
break;
case ClassFileConstants.BYTE_ARRAY :
- constantPoolName = new char[] { '[', 'B' };
+ arrayType = scope.createArrayType(TypeBinding.BYTE, 1);
break;
case ClassFileConstants.BOOLEAN_ARRAY :
- constantPoolName = new char[] { '[', 'Z' };
+ arrayType = scope.createArrayType(TypeBinding.BOOLEAN, 1);
break;
case ClassFileConstants.SHORT_ARRAY :
- constantPoolName = new char[] { '[', 'S' };
+ arrayType = scope.createArrayType(TypeBinding.SHORT, 1);
break;
case ClassFileConstants.CHAR_ARRAY :
- constantPoolName = new char[] { '[', 'C' };
+ arrayType = scope.createArrayType(TypeBinding.CHAR, 1);
break;
case ClassFileConstants.LONG_ARRAY :
- constantPoolName = new char[] { '[', 'J' };
+ arrayType = scope.createArrayType(TypeBinding.LONG, 1);
break;
case ClassFileConstants.FLOAT_ARRAY :
- constantPoolName = new char[] { '[', 'F' };
+ arrayType = scope.createArrayType(TypeBinding.FLOAT, 1);
break;
case ClassFileConstants.DOUBLE_ARRAY :
- constantPoolName = new char[] { '[', 'D' };
+ arrayType = scope.createArrayType(TypeBinding.DOUBLE, 1);
break;
}
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, constantPoolName);
+ frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(arrayType);
pc += 2;
break;
case Opcodes.OPC_anewarray:
@@ -7160,19 +7120,16 @@
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
- int classNameLength = className.length;
- if (className[0] != '[') {
- // this is a type name (class or interface). So we add appropriate '[', 'L' and ';'.
- System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 3]), 2, classNameLength);
- constantPoolName[0] = '[';
- constantPoolName[1] = 'L';
- constantPoolName[classNameLength + 2] = ';';
- } else {
- // if class name is already an array, we just need to add one dimension
- System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 1]), 1, classNameLength);
- constantPoolName[0] = '[';
+ frame.numberOfStackItems--;
+ typeBinding = getANewArrayTypeBinding(className, scope);
+ if (typeBinding != null) {
+ if (typeBinding.isArrayType()) {
+ ArrayBinding arrayBinding = (ArrayBinding) typeBinding;
+ frame.addStackItem(new VerificationTypeInfo(scope.createArrayType(arrayBinding.leafComponentType(), arrayBinding.dimensions + 1)));
+ } else {
+ frame.addStackItem(new VerificationTypeInfo(scope.createArrayType(typeBinding, 1)));
+ }
}
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, constantPoolName);
pc += 3;
break;
case Opcodes.OPC_arraylength:
@@ -7192,7 +7149,10 @@
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, className);
+ typeBinding = getTypeBinding(className, scope, true);
+ if (typeBinding != null) {
+ frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding);
+ }
pc += 3;
break;
case Opcodes.OPC_instanceof:
@@ -7217,10 +7177,10 @@
// need to handle iload, fload, aload, lload, dload, istore, fstore, astore, lstore or dstore
switch(opcode) {
case Opcodes.OPC_iload :
- frame.addStackItem(TypeBinding.INT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
break;
case Opcodes.OPC_fload :
- frame.addStackItem(TypeBinding.FLOAT);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
break;
case Opcodes.OPC_aload :
localsN = frame.locals[index];
@@ -7230,10 +7190,10 @@
frame.addStackItem(localsN);
break;
case Opcodes.OPC_lload :
- frame.addStackItem(TypeBinding.LONG);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
break;
case Opcodes.OPC_dload :
- frame.addStackItem(TypeBinding.DOUBLE);
+ frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
break;
case Opcodes.OPC_istore :
frame.numberOfStackItems--;
@@ -7265,21 +7225,23 @@
constantPoolOffsets[utf8index]));
int dimensions = u1At(bytecodes, 3, pc); // dimensions
frame.numberOfStackItems -= dimensions;
- classNameLength = className.length;
// class name is already the name of the right array type with all dimensions
- constantPoolName = new char[classNameLength];
- System.arraycopy(className, 0, constantPoolName, 0, classNameLength);
- frame.addStackItem(new VerificationTypeInfo(0, constantPoolName));
+ typeBinding = getTypeBinding(className, scope, false);
+ if (typeBinding != null) {
+ frame.addStackItem(new VerificationTypeInfo(typeBinding));
+ }
pc += 4;
break;
case Opcodes.OPC_ifnull:
case Opcodes.OPC_ifnonnull:
frame.numberOfStackItems--;
- addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
+ jumpPC = currentPC + i2At(bytecodes, 1, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 3;
break;
case Opcodes.OPC_goto_w:
- addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 1, pc));
+ jumpPC = currentPC + i4At(bytecodes, 1, pc);
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 5;
addRealJumpTarget(realJumpTarget, pc - codeOffset); // handle infinite loop
break;
@@ -7314,12 +7276,42 @@
return filterFakeFrames(realJumpTarget, frames, codeLength);
}
+ private StackMapFrame createNewFrame(int currentPC, StackMapFrame frame, boolean isClinit, MethodBinding methodBinding) {
+ StackMapFrame newFrame = frame.duplicate();
+ newFrame.pc = currentPC;
+ // initialize locals
+ initializeLocals(isClinit ? true : methodBinding.isStatic(), currentPC, newFrame);
+ return newFrame;
+ }
+
+ private int getDimensions(char[] returnType) {
+ int dimensions = 0;
+ while (returnType[dimensions] == '[') {
+ dimensions++;
+ }
+ return dimensions;
+ }
+
private void addRealJumpTarget(Set realJumpTarget, int pc) {
realJumpTarget.add(Integer.valueOf(pc));
}
- private void add(Map frames, StackMapFrame frame) {
- frames.put(Integer.valueOf(frame.pc), frame);
+
+ private void addRealJumpTarget(Set realJumpTarget, int pc, Map frames, StackMapFrame frame, Scope scope) {
+ realJumpTarget.add(Integer.valueOf(pc));
+ add(frames, frame, scope);
}
+
+ private void add(Map<Integer, StackMapFrame> frames, StackMapFrame frame, Scope scope) {
+ Integer key = Integer.valueOf(frame.pc);
+ StackMapFrame existingFrame = frames.get(key);
+ if(existingFrame == null) {
+ frames.put(key, frame);
+ } else {
+ // we need to merge
+ frames.put(key, existingFrame.merge(frame, scope));
+ }
+ }
+
private final int u1At(byte[] reference, int relativeOffset,
int structOffset) {
return (reference[relativeOffset + structOffset] & 0xFF);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index 6693e6b..6581ff4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -581,7 +581,7 @@
syntheticArgumentBinding.recordInitializationEndPC(classFile.codeStream.position);
// SH}
try {
- classFile.completeCodeAttribute(codeAttributeOffset);
+ classFile.completeCodeAttribute(codeAttributeOffset,this.scope);
} catch(NegativeArraySizeException e) {
throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
index b57896b..ac36c80 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
@@ -99,7 +99,7 @@
// in interface case, no caching occurs, since cannot make a cache field for interface
if (valueRequired) {
- codeStream.generateClassLiteralAccessForType(this.type.resolvedType, this.syntheticField);
+ codeStream.generateClassLiteralAccessForType(currentScope, this.type.resolvedType, this.syntheticField);
codeStream.generateImplicitConversion(this.implicitConversion);
}
codeStream.recordPositionsFrom(pc, this.sourceStart);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
index db6cf9c..377683b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
@@ -212,6 +212,7 @@
if (this.assertionSyntheticFieldBinding != null) {
// generate code related to the activation of assertion for this class
codeStream.generateClassLiteralAccessForType(
+ classScope,
classScope.outerMostClassScope().enclosingSourceType(),
this.classLiteralSyntheticField);
codeStream.invokeJavaLangClassDesiredAssertionStatus();
@@ -385,7 +386,7 @@
}
// Record the end of the clinit: point to the declaration of the class
codeStream.recordPositionsFrom(0, declaringType.sourceStart);
- classFile.completeCodeAttributeForClinit(codeAttributeOffset);
+ classFile.completeCodeAttributeForClinit(codeAttributeOffset, classScope);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index a312f3e..1210f0a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -251,8 +251,12 @@
return;
}
Constant cst = this.condition.optimizedBooleanConstant();
+ if (cst == Constant.NotAConstant) {
+ cst = this.condition.optimizedNullComparisonConstant();
+ }
boolean needTruePart = !(cst != Constant.NotAConstant && cst.booleanValue() == false);
- boolean needFalsePart = !(cst != Constant.NotAConstant && cst.booleanValue() == true);
+ boolean needFalsePart = !(cst != Constant.NotAConstant && cst.booleanValue() == true);
+
endifLabel = new BranchLabel(codeStream);
// Generate code for the condition
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index a9be73b..729123a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -667,7 +667,7 @@
codeStream.exitUserScope(this.scope);
codeStream.recordPositionsFrom(0, this.bodyEnd > 0 ? this.bodyEnd : this.sourceStart);
try {
- classFile.completeCodeAttribute(codeAttributeOffset);
+ classFile.completeCodeAttribute(codeAttributeOffset, this.scope);
} catch(NegativeArraySizeException e) {
throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
index 140108d..d14d153 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -853,6 +853,22 @@
public boolean isCompactableOperation() {
return false;
}
+
+ @Override
+ protected Constant optimizedNullComparisonConstant() {
+ int operator = (this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+ if (operator == OperatorIds.EQUAL_EQUAL) {
+ if (this.left instanceof NullLiteral && this.right instanceof NullLiteral) {
+ return BooleanConstant.fromValue(true);
+ }
+ } else if (operator == OperatorIds.NOT_EQUAL) {
+ if (this.left instanceof NullLiteral && this.right instanceof NullLiteral) {
+ return BooleanConstant.fromValue(false);
+ }
+ }
+ return Constant.NotAConstant;
+ }
+
@Override
public TypeBinding resolveType(BlockScope scope) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 0b35dd2..4216220 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -1512,4 +1512,8 @@
public boolean isPotentiallyCompatibleWith(TypeBinding targetType, Scope scope) {
return isCompatibleWith(targetType, scope); // for all but functional expressions, potential compatibility is the same as compatibility.
}
+
+protected Constant optimizedNullComparisonConstant() {
+ return Constant.NotAConstant;
+}
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index ad3013d..5b07ed6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -1326,7 +1326,7 @@
codeStream.exitUserScope(this.scope);
codeStream.recordPositionsFrom(0, this.sourceEnd); // WAS declarationSourceEnd.
try {
- classFile.completeCodeAttribute(codeAttributeOffset);
+ classFile.completeCodeAttribute(codeAttributeOffset, this.scope);
} catch(NegativeArraySizeException e) {
throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index ebc5320..beb8b61 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -215,7 +215,7 @@
if (needValueStore()) {
alreadyGeneratedExpression = true;
this.expression.generateCode(currentScope, codeStream, needValue()); // no value needed if non-returning subroutine
- generateStoreSaveValueIfNecessary(codeStream);
+ generateStoreSaveValueIfNecessary(currentScope, codeStream);
}
// generation of code responsible for invoking the finally blocks in sequence
@@ -237,7 +237,7 @@
if (this.expression != null && !alreadyGeneratedExpression) {
this.expression.generateCode(currentScope, codeStream, true);
// hook necessary for Code Snippet
- generateStoreSaveValueIfNecessary(codeStream);
+ generateStoreSaveValueIfNecessary(currentScope, codeStream);
}
// output the suitable return bytecode or wrap the value inside a descriptor for doits
generateReturnBytecode(codeStream);
@@ -260,7 +260,7 @@
codeStream.generateReturnBytecode(this.expression);
}
-public void generateStoreSaveValueIfNecessary(CodeStream codeStream){
+public void generateStoreSaveValueIfNecessary(Scope scope, CodeStream codeStream){
if (this.saveValueVariable != null) {
codeStream.store(this.saveValueVariable, false);
// the variable is visible as soon as the local is stored
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 1a26e6b..aa65304 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -1787,7 +1787,7 @@
/**
* Macro for building a class descriptor object
*/
-public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
+public void generateClassLiteralAccessForType(Scope scope, TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
if (accessedType.isBaseType() && accessedType != TypeBinding.NULL) {
getTYPE(accessedType.id);
return;
@@ -1851,7 +1851,7 @@
on the stack, which means that the stack may not be empty at this point in the
above code gen. So we save its state and restart it from 1. */
- pushExceptionOnStack(TypeBinding.NULL);/*represents ClassNotFoundException*/
+ pushExceptionOnStack(scope.getJavaLangClassNotFoundException());
classNotFoundExceptionHandler.place();
// Transform the current exception, and repush and throw a
@@ -2577,7 +2577,7 @@
public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) {
initializeMaxLocals(methodBinding);
final ReferenceBinding declaringClass = methodBinding.declaringClass;
- generateClassLiteralAccessForType(declaringClass, null);
+ generateClassLiteralAccessForType(((SourceTypeBinding) methodBinding.declaringClass).scope, declaringClass, null);
aload_0();
invokeJavaLangEnumvalueOf(declaringClass);
this.checkcast(declaringClass);
@@ -3164,7 +3164,7 @@
anyExceptionHandler.placeEnd();
goto_(endLabel);
// Generate the body of the exception handler
- pushExceptionOnStack(TypeBinding.LONG /*represents NoSuchFieldError*/);
+ pushExceptionOnStack(scope.getJavaLangNoSuchFieldError());
anyExceptionHandler.place();
pop(); // we don't use it so we can pop it
endLabel.place();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java
index a646ac8..c2ef996 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java
@@ -14,8 +14,10 @@
package org.eclipse.jdt.internal.compiler.codegen;
import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
public class StackMapFrame {
@@ -37,127 +39,156 @@
private int numberOfDifferentLocals = -1;
public int tagBits;
-public StackMapFrame(int initialLocalSize) {
- this.locals = new VerificationTypeInfo[initialLocalSize];
- this.numberOfLocals = -1;
- this.numberOfDifferentLocals = -1;
-}
-public int getFrameType(StackMapFrame prevFrame) {
- final int offsetDelta = getOffsetDelta(prevFrame);
- switch(this.numberOfStackItems) {
- case 0 :
- switch(numberOfDifferentLocals(prevFrame)) {
- case 0 :
- return offsetDelta <= 63 ? SAME_FRAME : SAME_FRAME_EXTENDED;
- case 1 :
- case 2 :
- case 3 :
- return APPEND_FRAME;
- case -1 :
- case -2 :
- case -3 :
- return CHOP_FRAME;
- }
- break;
- case 1 :
- switch(numberOfDifferentLocals(prevFrame)) {
- case 0 :
- return offsetDelta <= 63 ? SAME_LOCALS_1_STACK_ITEMS : SAME_LOCALS_1_STACK_ITEMS_EXTENDED;
- }
+ public StackMapFrame(int initialLocalSize) {
+ this.locals = new VerificationTypeInfo[initialLocalSize];
+ this.numberOfLocals = -1;
+ this.numberOfDifferentLocals = -1;
}
- return FULL_FRAME;
-}
-public void addLocal(int resolvedPosition, VerificationTypeInfo info) {
- if (this.locals == null) {
- this.locals = new VerificationTypeInfo[resolvedPosition + 1];
- this.locals[resolvedPosition] = info;
- } else {
- final int length = this.locals.length;
- if (resolvedPosition >= length) {
- System.arraycopy(this.locals, 0, this.locals = new VerificationTypeInfo[resolvedPosition + 1], 0, length);
- }
- this.locals[resolvedPosition] = info;
- }
-}
-public void addStackItem(VerificationTypeInfo info) {
- if (info == null) {
- throw new IllegalArgumentException("info cannot be null"); //$NON-NLS-1$
- }
- if (this.stackItems == null) {
- this.stackItems = new VerificationTypeInfo[1];
- this.stackItems[0] = info;
- this.numberOfStackItems = 1;
- } else {
- final int length = this.stackItems.length;
- if (this.numberOfStackItems == length) {
- System.arraycopy(this.stackItems, 0, this.stackItems = new VerificationTypeInfo[length + 1], 0, length);
- }
- this.stackItems[this.numberOfStackItems++] = info;
- }
-}
-public void addStackItem(TypeBinding binding) {
- if (this.stackItems == null) {
- this.stackItems = new VerificationTypeInfo[1];
- this.stackItems[0] = new VerificationTypeInfo(binding);
- this.numberOfStackItems = 1;
- } else {
- final int length = this.stackItems.length;
- if (this.numberOfStackItems == length) {
- System.arraycopy(this.stackItems, 0, this.stackItems = new VerificationTypeInfo[length + 1], 0, length);
- }
- this.stackItems[this.numberOfStackItems++] = new VerificationTypeInfo(binding);
- }
-}
-public StackMapFrame duplicate() {
- int length = this.locals.length;
- StackMapFrame result = new StackMapFrame(length);
- result.numberOfLocals = -1;
- result.numberOfDifferentLocals = -1;
- result.pc = this.pc;
- result.numberOfStackItems = this.numberOfStackItems;
- if (length != 0) {
- result.locals = new VerificationTypeInfo[length];
- for (int i = 0; i < length; i++) {
- final VerificationTypeInfo verificationTypeInfo = this.locals[i];
- if (verificationTypeInfo != null) {
- result.locals[i] = verificationTypeInfo.duplicate();
+ public int getFrameType(StackMapFrame prevFrame) {
+ final int offsetDelta = getOffsetDelta(prevFrame);
+ switch (this.numberOfStackItems) {
+ case 0:
+ switch (numberOfDifferentLocals(prevFrame)) {
+ case 0:
+ return offsetDelta <= 63 ? SAME_FRAME : SAME_FRAME_EXTENDED;
+ case 1:
+ case 2:
+ case 3:
+ return APPEND_FRAME;
+ case -1:
+ case -2:
+ case -3:
+ return CHOP_FRAME;
+ }
+ break;
+ case 1:
+ switch (numberOfDifferentLocals(prevFrame)) {
+ case 0:
+ return offsetDelta <= 63 ? SAME_LOCALS_1_STACK_ITEMS : SAME_LOCALS_1_STACK_ITEMS_EXTENDED;
+ }
+ }
+ return FULL_FRAME;
+ }
+
+ public void addLocal(int resolvedPosition, VerificationTypeInfo info) {
+ if (this.locals == null) {
+ this.locals = new VerificationTypeInfo[resolvedPosition + 1];
+ this.locals[resolvedPosition] = info;
+ } else {
+ final int length = this.locals.length;
+ if (resolvedPosition >= length) {
+ System.arraycopy(this.locals, 0, this.locals = new VerificationTypeInfo[resolvedPosition + 1], 0,
+ length);
+ }
+ this.locals[resolvedPosition] = info;
+ }
+ }
+
+ public void addStackItem(VerificationTypeInfo info) {
+ if (info == null) {
+ throw new IllegalArgumentException("info cannot be null"); //$NON-NLS-1$
+ }
+ if (this.stackItems == null) {
+ this.stackItems = new VerificationTypeInfo[1];
+ this.stackItems[0] = info;
+ this.numberOfStackItems = 1;
+ } else {
+ final int length = this.stackItems.length;
+ if (this.numberOfStackItems == length) {
+ System.arraycopy(this.stackItems, 0, this.stackItems = new VerificationTypeInfo[length + 1], 0, length);
+ }
+ this.stackItems[this.numberOfStackItems++] = info;
+ }
+ }
+
+ public StackMapFrame duplicate() {
+ Map<VerificationTypeInfo, VerificationTypeInfo> cache = new HashMap<VerificationTypeInfo, VerificationTypeInfo>();
+ int length = this.locals.length;
+ StackMapFrame result = new StackMapFrame(length);
+ result.numberOfLocals = -1;
+ result.numberOfDifferentLocals = -1;
+ result.pc = this.pc;
+ result.numberOfStackItems = this.numberOfStackItems;
+
+ if (length != 0) {
+ result.locals = new VerificationTypeInfo[length];
+ for (int i = 0; i < length; i++) {
+ final VerificationTypeInfo verificationTypeInfo = this.locals[i];
+ result.locals[i] = getCachedValue(cache, verificationTypeInfo);
}
}
- }
- length = this.numberOfStackItems;
- if (length != 0) {
- result.stackItems = new VerificationTypeInfo[length];
- for (int i = 0; i < length; i++) {
- result.stackItems[i] = this.stackItems[i].duplicate();
+ length = this.numberOfStackItems;
+ if (length != 0) {
+ result.stackItems = new VerificationTypeInfo[length];
+ for (int i = 0; i < length; i++) {
+ final VerificationTypeInfo verificationTypeInfo = this.stackItems[i];
+ result.stackItems[i] = getCachedValue(cache, verificationTypeInfo);
+ }
}
+ return result;
}
- return result;
-}
-public int numberOfDifferentLocals(StackMapFrame prevFrame) {
- if (this.numberOfDifferentLocals != -1) return this.numberOfDifferentLocals;
- if (prevFrame == null) {
- this.numberOfDifferentLocals = 0;
- return 0;
- }
- VerificationTypeInfo[] prevLocals = prevFrame.locals;
- VerificationTypeInfo[] currentLocals = this.locals;
- int prevLocalsLength = prevLocals == null ? 0 : prevLocals.length;
- int currentLocalsLength = currentLocals == null ? 0 : currentLocals.length;
- int prevNumberOfLocals = prevFrame.getNumberOfLocals();
- int currentNumberOfLocals = getNumberOfLocals();
- int result = 0;
- if (prevNumberOfLocals == 0) {
- if (currentNumberOfLocals != 0) {
- // need to check if there is a hole in the locals
- result = currentNumberOfLocals; // append if no hole and currentNumberOfLocals <= 3
+ private VerificationTypeInfo getCachedValue(Map<VerificationTypeInfo, VerificationTypeInfo> cache, VerificationTypeInfo value) {
+ VerificationTypeInfo cachedValue = value;
+ if (value != null) {
+ if (value.tag == VerificationTypeInfo.ITEM_UNINITIALIZED || value.tag == VerificationTypeInfo.ITEM_UNINITIALIZED_THIS) {
+ // we use the cache only for uninitialized info
+ cachedValue = cache.get(value);
+ if (cachedValue == null) {
+ cachedValue = value.duplicate();
+ cache.put(value, cachedValue);
+ }
+ } else {
+ cachedValue = value.duplicate();
+ }
+ }
+ return cachedValue;
+ }
+ public int numberOfDifferentLocals(StackMapFrame prevFrame) {
+ if (this.numberOfDifferentLocals != -1)
+ return this.numberOfDifferentLocals;
+ if (prevFrame == null) {
+ this.numberOfDifferentLocals = 0;
+ return 0;
+ }
+ VerificationTypeInfo[] prevLocals = prevFrame.locals;
+ VerificationTypeInfo[] currentLocals = this.locals;
+ int prevLocalsLength = prevLocals == null ? 0 : prevLocals.length;
+ int currentLocalsLength = currentLocals == null ? 0 : currentLocals.length;
+ int prevNumberOfLocals = prevFrame.getNumberOfLocals();
+ int currentNumberOfLocals = getNumberOfLocals();
+
+ int result = 0;
+ if (prevNumberOfLocals == 0) {
+ if (currentNumberOfLocals != 0) {
+ // need to check if there is a hole in the locals
+ result = currentNumberOfLocals; // append if no hole and currentNumberOfLocals <= 3
+ int counter = 0;
+ for (int i = 0; i < currentLocalsLength && counter < currentNumberOfLocals; i++) {
+ if (currentLocals[i] != null) {
+ switch (currentLocals[i].id()) {
+ case TypeIds.T_double:
+ case TypeIds.T_long:
+ i++;
+ }
+ counter++;
+ } else {
+ result = Integer.MAX_VALUE;
+ this.numberOfDifferentLocals = result;
+ return result;
+ }
+ }
+ }
+ } else if (currentNumberOfLocals == 0) {
+ // need to check if there is a hole in the prev locals
int counter = 0;
- for(int i = 0; i < currentLocalsLength && counter < currentNumberOfLocals; i++) {
- if (currentLocals[i] != null) {
- switch(currentLocals[i].id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
+ result = -prevNumberOfLocals; // chop frame if no hole and prevNumberOfLocals <= 3
+ for (int i = 0; i < prevLocalsLength && counter < prevNumberOfLocals; i++) {
+ if (prevLocals[i] != null) {
+ switch (prevLocals[i].id()) {
+ case TypeIds.T_double:
+ case TypeIds.T_long:
i++;
}
counter++;
@@ -167,216 +198,220 @@
return result;
}
}
- }
- } else if (currentNumberOfLocals == 0) {
- // need to check if there is a hole in the prev locals
- int counter = 0;
- result = -prevNumberOfLocals; // chop frame if no hole and prevNumberOfLocals <= 3
- for(int i = 0; i < prevLocalsLength && counter < prevNumberOfLocals; i++) {
- if (prevLocals[i] != null) {
- switch(prevLocals[i].id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
- i++;
- }
- counter++;
- } else {
- result = Integer.MAX_VALUE;
- this.numberOfDifferentLocals = result;
- return result;
- }
- }
- } else {
- // need to see if prevLocals matches with currentLocals
- int indexInPrevLocals = 0;
- int indexInCurrentLocals = 0;
- int currentLocalsCounter = 0;
- int prevLocalsCounter = 0;
- currentLocalsLoop: for (;indexInCurrentLocals < currentLocalsLength && currentLocalsCounter < currentNumberOfLocals; indexInCurrentLocals++) {
- VerificationTypeInfo currentLocal = currentLocals[indexInCurrentLocals];
- if (currentLocal != null) {
- currentLocalsCounter++;
- switch(currentLocal.id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
- indexInCurrentLocals++; // next entry is null
- }
- }
- if (indexInPrevLocals < prevLocalsLength && prevLocalsCounter < prevNumberOfLocals) {
- VerificationTypeInfo prevLocal = prevLocals[indexInPrevLocals];
- if (prevLocal != null) {
- prevLocalsCounter++;
- switch(prevLocal.id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
- indexInPrevLocals++; // next entry is null
+ } else {
+ // need to see if prevLocals matches with currentLocals
+ int indexInPrevLocals = 0;
+ int indexInCurrentLocals = 0;
+ int currentLocalsCounter = 0;
+ int prevLocalsCounter = 0;
+ currentLocalsLoop: for (; indexInCurrentLocals < currentLocalsLength
+ && currentLocalsCounter < currentNumberOfLocals; indexInCurrentLocals++) {
+ VerificationTypeInfo currentLocal = currentLocals[indexInCurrentLocals];
+ if (currentLocal != null) {
+ currentLocalsCounter++;
+ switch (currentLocal.id()) {
+ case TypeIds.T_double:
+ case TypeIds.T_long:
+ indexInCurrentLocals++; // next entry is null
}
}
- // now we need to check if prevLocal matches with currentLocal
- // the index must be the same
- if (equals(prevLocal, currentLocal) && indexInPrevLocals == indexInCurrentLocals) {
- if (result != 0) {
+ if (indexInPrevLocals < prevLocalsLength && prevLocalsCounter < prevNumberOfLocals) {
+ VerificationTypeInfo prevLocal = prevLocals[indexInPrevLocals];
+ if (prevLocal != null) {
+ prevLocalsCounter++;
+ switch (prevLocal.id()) {
+ case TypeIds.T_double:
+ case TypeIds.T_long:
+ indexInPrevLocals++; // next entry is null
+ }
+ }
+ // now we need to check if prevLocal matches with currentLocal
+ // the index must be the same
+ if (equals(prevLocal, currentLocal) && indexInPrevLocals == indexInCurrentLocals) {
+ if (result != 0) {
+ result = Integer.MAX_VALUE;
+ this.numberOfDifferentLocals = result;
+ return result;
+ }
+ } else {
+ // locals at the same location are not equals - this has to be a full frame
result = Integer.MAX_VALUE;
this.numberOfDifferentLocals = result;
return result;
}
+ indexInPrevLocals++;
+ continue currentLocalsLoop;
+ }
+ // process remaining current locals
+ if (currentLocal != null) {
+ result++;
} else {
- // locals at the same location are not equals - this has to be a full frame
result = Integer.MAX_VALUE;
this.numberOfDifferentLocals = result;
return result;
}
- indexInPrevLocals++;
- continue currentLocalsLoop;
+ indexInCurrentLocals++;
+ break currentLocalsLoop;
}
- // process remaining current locals
- if (currentLocal != null) {
- result++;
- } else {
- result = Integer.MAX_VALUE;
- this.numberOfDifferentLocals = result;
- return result;
- }
- indexInCurrentLocals++;
- break currentLocalsLoop;
- }
- if (currentLocalsCounter < currentNumberOfLocals) {
- for(;indexInCurrentLocals < currentLocalsLength && currentLocalsCounter < currentNumberOfLocals; indexInCurrentLocals++) {
- VerificationTypeInfo currentLocal = currentLocals[indexInCurrentLocals];
- if (currentLocal == null) {
- result = Integer.MAX_VALUE;
- this.numberOfDifferentLocals = result;
- return result;
+ if (currentLocalsCounter < currentNumberOfLocals) {
+ for (; indexInCurrentLocals < currentLocalsLength
+ && currentLocalsCounter < currentNumberOfLocals; indexInCurrentLocals++) {
+ VerificationTypeInfo currentLocal = currentLocals[indexInCurrentLocals];
+ if (currentLocal == null) {
+ result = Integer.MAX_VALUE;
+ this.numberOfDifferentLocals = result;
+ return result;
+ }
+ result++;
+ currentLocalsCounter++;
+ switch (currentLocal.id()) {
+ case TypeIds.T_double:
+ case TypeIds.T_long:
+ indexInCurrentLocals++; // next entry is null
+ }
}
- result++;
- currentLocalsCounter++;
- switch(currentLocal.id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
- indexInCurrentLocals++; // next entry is null
- }
- }
- } else if (prevLocalsCounter < prevNumberOfLocals) {
- result = -result;
- // process possible remaining prev locals
- for(; indexInPrevLocals < prevLocalsLength && prevLocalsCounter < prevNumberOfLocals; indexInPrevLocals++) {
- VerificationTypeInfo prevLocal = prevLocals[indexInPrevLocals];
- if (prevLocal == null) {
- result = Integer.MAX_VALUE;
- this.numberOfDifferentLocals = result;
- return result;
- }
- result--;
- prevLocalsCounter++;
- switch(prevLocal.id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
- indexInPrevLocals++; // next entry is null
+ } else if (prevLocalsCounter < prevNumberOfLocals) {
+ result = -result;
+ // process possible remaining prev locals
+ for (; indexInPrevLocals < prevLocalsLength
+ && prevLocalsCounter < prevNumberOfLocals; indexInPrevLocals++) {
+ VerificationTypeInfo prevLocal = prevLocals[indexInPrevLocals];
+ if (prevLocal == null) {
+ result = Integer.MAX_VALUE;
+ this.numberOfDifferentLocals = result;
+ return result;
+ }
+ result--;
+ prevLocalsCounter++;
+ switch (prevLocal.id()) {
+ case TypeIds.T_double:
+ case TypeIds.T_long:
+ indexInPrevLocals++; // next entry is null
+ }
}
}
}
+ this.numberOfDifferentLocals = result;
+ return result;
}
- this.numberOfDifferentLocals = result;
- return result;
-}
-public int getNumberOfLocals() {
- if (this.numberOfLocals != -1) {
- return this.numberOfLocals;
- }
- int result = 0;
- final int length = this.locals == null ? 0 : this.locals.length;
- for(int i = 0; i < length; i++) {
- if (this.locals[i] != null) {
- switch(this.locals[i].id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
- i++;
- }
- result++;
+
+ public int getNumberOfLocals() {
+ if (this.numberOfLocals != -1) {
+ return this.numberOfLocals;
}
- }
- this.numberOfLocals = result;
- return result;
-}
-public int getOffsetDelta(StackMapFrame prevFrame) {
- if (prevFrame == null) return this.pc;
- return prevFrame.pc == -1 ? this.pc : this.pc - prevFrame.pc - 1;
-}
-@Override
-public String toString() {
- StringBuffer buffer = new StringBuffer();
- printFrame(buffer, this);
- return String.valueOf(buffer);
-}
-private void printFrame(StringBuffer buffer, StackMapFrame frame) {
- String pattern = "[pc : {0} locals: {1} stack items: {2}\nlocals: {3}\nstack: {4}\n]"; //$NON-NLS-1$
- int localsLength = frame.locals == null ? 0 : frame.locals.length;
- buffer.append(MessageFormat.format(
- pattern,
- new Object[] {
- Integer.toString(frame.pc),
- Integer.toString(frame.getNumberOfLocals()),
- Integer.toString(frame.numberOfStackItems),
- print(frame.locals, localsLength),
- print(frame.stackItems, frame.numberOfStackItems)
- }
- ));
-}
-private String print(VerificationTypeInfo[] infos, int length) {
- StringBuffer buffer = new StringBuffer();
- buffer.append('[');
- if (infos != null) {
+ int result = 0;
+ final int length = this.locals == null ? 0 : this.locals.length;
for (int i = 0; i < length; i++) {
- if (i != 0) buffer.append(',');
- VerificationTypeInfo verificationTypeInfo = infos[i];
- if (verificationTypeInfo == null) {
- buffer.append("top"); //$NON-NLS-1$
- continue;
+ if (this.locals[i] != null) {
+ switch (this.locals[i].id()) {
+ case TypeIds.T_double:
+ case TypeIds.T_long:
+ i++;
+ }
+ result++;
}
- buffer.append(verificationTypeInfo);
}
+ this.numberOfLocals = result;
+ return result;
}
- buffer.append(']');
- return String.valueOf(buffer);
-}
-public void putLocal(int resolvedPosition, VerificationTypeInfo info) {
- if (this.locals == null) {
- this.locals = new VerificationTypeInfo[resolvedPosition + 1];
- this.locals[resolvedPosition] = info;
- } else {
- final int length = this.locals.length;
- if (resolvedPosition >= length) {
- System.arraycopy(this.locals, 0, this.locals = new VerificationTypeInfo[resolvedPosition + 1], 0, length);
+
+ public int getOffsetDelta(StackMapFrame prevFrame) {
+ if (prevFrame == null)
+ return this.pc;
+ return prevFrame.pc == -1 ? this.pc : this.pc - prevFrame.pc - 1;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ printFrame(buffer, this);
+ return String.valueOf(buffer);
+ }
+
+ private void printFrame(StringBuffer buffer, StackMapFrame frame) {
+ String pattern = "[pc : {0} locals: {1} stack items: {2}\nlocals: {3}\nstack: {4}\n]"; //$NON-NLS-1$
+ int localsLength = frame.locals == null ? 0 : frame.locals.length;
+ buffer.append(MessageFormat.format(pattern,
+ new Object[] { Integer.toString(frame.pc), Integer.toString(frame.getNumberOfLocals()),
+ Integer.toString(frame.numberOfStackItems), print(frame.locals, localsLength),
+ print(frame.stackItems, frame.numberOfStackItems) }));
+ }
+
+ private String print(VerificationTypeInfo[] infos, int length) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('[');
+ if (infos != null) {
+ for (int i = 0; i < length; i++) {
+ if (i != 0)
+ buffer.append(',');
+ VerificationTypeInfo verificationTypeInfo = infos[i];
+ if (verificationTypeInfo == null) {
+ buffer.append("top"); //$NON-NLS-1$
+ continue;
+ }
+ buffer.append(verificationTypeInfo);
+ }
}
- this.locals[resolvedPosition] = info;
+ buffer.append(']');
+ return String.valueOf(buffer);
}
-}
-public void replaceWithElementType() {
- VerificationTypeInfo info = this.stackItems[this.numberOfStackItems - 1];
- VerificationTypeInfo info2 = info.duplicate();
- info2.replaceWithElementType();
- this.stackItems[this.numberOfStackItems - 1] = info2;
-}
-public int getIndexOfDifferentLocals(int differentLocalsCount) {
- for (int i = this.locals.length - 1; i >= 0; i--) {
- VerificationTypeInfo currentLocal = this.locals[i];
- if (currentLocal == null) {
- // check the previous slot
- continue;
+
+ public void putLocal(int resolvedPosition, VerificationTypeInfo info) {
+ if (this.locals == null) {
+ this.locals = new VerificationTypeInfo[resolvedPosition + 1];
+ this.locals[resolvedPosition] = info;
} else {
- differentLocalsCount--;
- }
- if (differentLocalsCount == 0) {
- return i;
+ final int length = this.locals.length;
+ if (resolvedPosition >= length) {
+ System.arraycopy(this.locals, 0, this.locals = new VerificationTypeInfo[resolvedPosition + 1], 0,
+ length);
+ }
+ this.locals[resolvedPosition] = info;
}
}
- return 0;
-}
-private boolean equals(VerificationTypeInfo info, VerificationTypeInfo info2) {
- if (info == null) {
- return info2 == null;
+
+ public void replaceWithElementType() {
+ VerificationTypeInfo info = this.stackItems[this.numberOfStackItems - 1];
+ VerificationTypeInfo info2 = info.duplicate();
+ info2.replaceWithElementType();
+ this.stackItems[this.numberOfStackItems - 1] = info2;
}
- if (info2 == null) return false;
- return info.equals(info2);
-}
+
+ public int getIndexOfDifferentLocals(int differentLocalsCount) {
+ for (int i = this.locals.length - 1; i >= 0; i--) {
+ VerificationTypeInfo currentLocal = this.locals[i];
+ if (currentLocal == null) {
+ // check the previous slot
+ continue;
+ } else {
+ differentLocalsCount--;
+ }
+ if (differentLocalsCount == 0) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+ private boolean equals(VerificationTypeInfo info, VerificationTypeInfo info2) {
+ if (info == null) {
+ return info2 == null;
+ }
+ if (info2 == null)
+ return false;
+ return info.equals(info2);
+ }
+
+ public StackMapFrame merge(StackMapFrame frame, Scope scope) {
+ if (frame.pc == -1) {
+ // branching
+ return this;
+ }
+ if (this.numberOfStackItems == frame.numberOfStackItems) {
+ for (int i = 0, max = this.numberOfStackItems; i < max; i++) {
+ this.stackItems[i] = this.stackItems[i].merge(frame.stackItems[i], scope);
+ }
+ }
+ return this;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
index 8d0fffe..3e44c49 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
@@ -33,16 +33,17 @@
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
-@SuppressWarnings({"rawtypes", "unchecked"})
+@SuppressWarnings({ "rawtypes", "unchecked" })
public class StackMapFrameCodeStream extends CodeStream {
public static class ExceptionMarker implements Comparable {
- public char[] constantPoolName;
+ private TypeBinding binding;
public int pc;
- public ExceptionMarker(int pc, char[] constantPoolName) {
+ public ExceptionMarker(int pc, TypeBinding typeBinding) {
this.pc = pc;
- this.constantPoolName = constantPoolName;
+ this.binding = typeBinding;
}
+
@Override
public int compareTo(Object o) {
if (o instanceof ExceptionMarker) {
@@ -50,93 +51,29 @@
}
return 0;
}
+
@Override
public boolean equals(Object obj) {
if (obj instanceof ExceptionMarker) {
ExceptionMarker marker = (ExceptionMarker) obj;
- return this.pc == marker.pc && CharOperation.equals(this.constantPoolName, marker.constantPoolName);
+ return this.pc == marker.pc && this.binding.equals(marker.binding);
}
return false;
}
+
+ public TypeBinding getBinding() {
+ return this.binding;
+ }
+
@Override
public int hashCode() {
- return this.pc + CharOperation.hashCode(this.constantPoolName);
- }
- @Override
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append('(').append(this.pc).append(',').append(this.constantPoolName).append(')');
- return String.valueOf(buffer);
- }
- }
-
- public static class StackDepthMarker {
- public int pc;
- public int delta;
- public TypeBinding typeBinding;
-
- public StackDepthMarker(int pc, int delta, TypeBinding typeBinding) {
- this.pc = pc;
- this.typeBinding = typeBinding;
- this.delta = delta;
- }
-
- public StackDepthMarker(int pc, int delta) {
- this.pc = pc;
- this.delta = delta;
+ return this.pc + CharOperation.hashCode(this.binding.constantPoolName());
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
- buffer.append('(').append(this.pc).append(',').append(this.delta);
- if (this.typeBinding != null) {
- if (this.typeBinding.isBaseType()) {
- buffer
- .append(',')
- .append(this.typeBinding.qualifiedSourceName());
- } else {
- buffer
- .append(',')
- .append(this.typeBinding.qualifiedPackageName())
- .append('.')
- .append(this.typeBinding.qualifiedSourceName());
- }
- }
- buffer.append(')');
- return String.valueOf(buffer);
- }
- }
-
- public static class StackMarker {
- public int pc;
- public int destinationPC;
- public VerificationTypeInfo[] infos;
-
- public StackMarker(int pc, int destinationPC) {
- this.pc = pc;
- this.destinationPC = destinationPC;
- }
-
- public void setInfos(VerificationTypeInfo[] infos) {
- this.infos = infos;
- }
-
- @Override
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer
- .append("[copy stack items from ") //$NON-NLS-1$
- .append(this.pc)
- .append(" to ") //$NON-NLS-1$
- .append(this.destinationPC);
- if (this.infos!= null) {
- for (int i = 0, max = this.infos.length; i < max; i++) {
- if (i > 0) buffer.append(',');
- buffer.append(this.infos[i]);
- }
- }
- buffer.append(']');
+ buffer.append('(').append(this.pc).append(',').append(this.binding.constantPoolName()).append(')');
return String.valueOf(buffer);
}
}
@@ -152,483 +89,434 @@
public ArrayList stackDepthMarkers;
public ArrayList stackMarkers;
-public StackMapFrameCodeStream(ClassFile givenClassFile) {
- super(givenClassFile);
- this.generateAttributes |= ClassFileConstants.ATTR_STACK_MAP;
-}
-@Override
-public void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
- // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
- for (int i = 0; i < this.visibleLocalsCount; i++) {
- LocalVariableBinding localBinding = this.visibleLocals[i];
- if (localBinding != null) {
- // Check if the local is definitely assigned
- boolean isDefinitelyAssigned = isDefinitelyAssigned(scope, initStateIndex, localBinding);
- if (!isDefinitelyAssigned) {
- continue;
- } else {
- if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
- /* There are two cases:
- * 1) there is no initialization interval opened ==> add an opened interval
- * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
- * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
- * is equals to -1.
- * initializationPCs is a collection of pairs of int:
- * first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
- * is not closed yet.
- */
- localBinding.recordInitializationStartPC(this.position);
- }
- }
- }
- }
-}
-public void addExceptionMarker(int pc, TypeBinding typeBinding) {
- if (this.exceptionMarkers == null) {
- this.exceptionMarkers = new HashSet();
- }
- if (typeBinding == null) {
- this.exceptionMarkers.add(new ExceptionMarker(pc, ConstantPool.JavaLangThrowableConstantPoolName));
- } else {
- switch(typeBinding.id) {
- case TypeIds.T_null :
- this.exceptionMarkers.add(new ExceptionMarker(pc, ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName));
- break;
- case TypeIds.T_long :
- this.exceptionMarkers.add(new ExceptionMarker(pc, ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName));
- break;
- default:
- this.exceptionMarkers.add(new ExceptionMarker(pc, typeBinding.constantPoolName()));
- }
- }
-}
-public void addFramePosition(int pc) {
- Integer newEntry = Integer.valueOf(pc);
- FramePosition value;
- if ((value = (FramePosition) this.framePositions.get(newEntry)) != null) {
- value.counter++;
- } else {
- this.framePositions.put(newEntry, new FramePosition());
- }
-}
-@Override
-public void optimizeBranch(int oldPosition, BranchLabel lbl) {
- super.optimizeBranch(oldPosition, lbl);
- removeFramePosition(oldPosition);
- removeStackMapMarkers(oldPosition);
-}
-public void removeFramePosition(int pc) {
- Integer entry = Integer.valueOf(pc);
- FramePosition value;
- if ((value = (FramePosition) this.framePositions.get(entry)) != null) {
- value.counter--;
- if (value.counter <= 0) {
- this.framePositions.remove(entry);
- }
- }
-}
-public void removeStackMapMarkers(int markerOldPosition) {
- if (this.stackDepthMarkers != null) {
- for (int i = this.stackDepthMarkers.size() - 1; i >= 0; i--) {
- StackDepthMarker marker = (StackDepthMarker) this.stackDepthMarkers.get(i);
- if (marker.pc == markerOldPosition) {
- this.stackDepthMarkers.remove(i);
- break;
- }
- }
- }
-}
-@Override
-public void addVariable(LocalVariableBinding localBinding) {
- if (localBinding.initializationPCs == null) {
- record(localBinding);
- }
- localBinding.recordInitializationStartPC(this.position);
-}
-private void addStackMarker(int pc, int destinationPC) {
- if (this.stackMarkers == null) {
- this.stackMarkers = new ArrayList();
- this.stackMarkers.add(new StackMarker(pc, destinationPC));
- } else {
- int size = this.stackMarkers.size();
- if (size == 0 || ((StackMarker) this.stackMarkers.get(size - 1)).pc != this.position) {
- this.stackMarkers.add(new StackMarker(pc, destinationPC));
- }
- }
-}
-private void addStackDepthMarker(int pc, int delta, TypeBinding typeBinding) {
- if (this.stackDepthMarkers == null) {
- this.stackDepthMarkers = new ArrayList();
- this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding));
- } else {
- int size = this.stackDepthMarkers.size();
- if (size == 0) {
- this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding));
- } else {
- StackDepthMarker stackDepthMarker = (StackDepthMarker) this.stackDepthMarkers.get(size - 1);
- if (stackDepthMarker.pc != this.position) {
- this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding));
- } else {
- // We replace the recorded stack depth marker with a new value that contains the given typeBinding
- // This case can happen when multiple conditional expression are nested see bug 362591
- this.stackDepthMarkers.set(size - 1, new StackDepthMarker(pc, delta, typeBinding));
- }
- }
- }
-}
-@Override
-public void decrStackSize(int offset) {
- super.decrStackSize(offset);
- addStackDepthMarker(this.position, -1, null);
-}
-@Override
-public void recordExpressionType(TypeBinding typeBinding) {
- addStackDepthMarker(this.position, 0, typeBinding);
-}
-@Override
-public void recordExpressionType(TypeBinding typeBinding, int delta, boolean adjustStackDepth) {
- addStackDepthMarker(this.position, delta, typeBinding);
- if (adjustStackDepth) {
- // optimized goto
- // the break label already adjusted the stack depth (-1 or -2 depending on the return type)
- // we need to adjust back to what it was
- switch(typeBinding.id) {
- case TypeIds.T_long :
- case TypeIds.T_double :
- this.stackDepth+=2;
- break;
- case TypeIds.T_void :
- break;
- default :
- this.stackDepth++;
- break;
- }
- }
-}
-/**
- * Macro for building a class descriptor object
- */
-@Override
-public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
- if (accessedType.isBaseType() && accessedType != TypeBinding.NULL) {
- getTYPE(accessedType.id);
- return;
+ public StackMapFrameCodeStream(ClassFile givenClassFile) {
+ super(givenClassFile);
+ this.generateAttributes |= ClassFileConstants.ATTR_STACK_MAP;
}
- if (this.targetLevel >= ClassFileConstants.JDK1_5) {
- // generation using the new ldc_w bytecode
- this.ldc(accessedType);
- } else {
- // use in CLDC mode
- BranchLabel endLabel = new BranchLabel(this);
- if (syntheticFieldBinding != null) { // non interface case
- fieldAccess(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */);
- dup();
- ifnonnull(endLabel);
- pop();
- }
-
- /* Macro for building a class descriptor object... using or not a field cache to store it into...
- this sequence is responsible for building the actual class descriptor.
-
- If the fieldCache is set, then it is supposed to be the body of a synthetic access method
- factoring the actual descriptor creation out of the invocation site (saving space).
- If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
- we have no way to get a hand on the field cache to do better. */
-
-
- // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
-
- ExceptionLabel classNotFoundExceptionHandler = new ExceptionLabel(this, TypeBinding.NULL /*represents ClassNotFoundException*/);
- classNotFoundExceptionHandler.placeStart();
- this.ldc(accessedType == TypeBinding.NULL ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
- invokeClassForName();
-
- /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
- if (accessedType == BaseTypes.NullBinding) {
- this.ldc("java.lang.Object"); //$NON-NLS-1$
- } else if (accessedType.isArrayType()) {
- this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
- } else {
- // we make it an array type (to avoid class initialization)
- this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
- }
- this.invokeClassForName();
- if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
- this.invokeJavaLangClassGetComponentType();
- }
- */
- /* We need to protect the runtime code from binary inconsistencies
- in case the accessedType is missing, the ClassNotFoundException has to be converted
- into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
- classNotFoundExceptionHandler.placeEnd();
-
- if (syntheticFieldBinding != null) { // non interface case
- dup();
- fieldAccess(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */);
- }
- int fromPC = this.position;
- goto_(endLabel);
- int savedStackDepth = this.stackDepth;
- // Generate the body of the exception handler
- /* ClassNotFoundException on stack -- the class literal could be doing more things
- on the stack, which means that the stack may not be empty at this point in the
- above code gen. So we save its state and restart it from 1. */
-
- pushExceptionOnStack(TypeBinding.NULL);/*represents ClassNotFoundException*/
- classNotFoundExceptionHandler.place();
-
- // Transform the current exception, and repush and throw a
- // NoClassDefFoundError(ClassNotFound.getMessage())
-
- newNoClassDefFoundError();
- dup_x1();
- swap();
-
- // Retrieve the message from the old exception
- invokeThrowableGetMessage();
-
- // Send the constructor taking a message string as an argument
- invokeNoClassDefFoundErrorStringConstructor();
- athrow();
- endLabel.place();
- addStackMarker(fromPC, this.position);
- this.stackDepth = savedStackDepth;
- }
-}
-@Override
-public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
- int currentPosition = this.position;
- super.generateOuterAccess(mappingSequence, invocationSite, target, scope);
- if (currentPosition == this.position) {
- // no code has been generate during outer access => no enclosing instance is available
- throw new AbortMethod(scope.referenceCompilationUnit().compilationResult, null);
- }
-}
-public ExceptionMarker[] getExceptionMarkers() {
- Set exceptionMarkerSet = this.exceptionMarkers;
- if (this.exceptionMarkers == null) return null;
- int size = exceptionMarkerSet.size();
- ExceptionMarker[] markers = new ExceptionMarker[size];
- int n = 0;
- for (Iterator iterator = exceptionMarkerSet.iterator(); iterator.hasNext(); ) {
- markers[n++] = (ExceptionMarker) iterator.next();
- }
- Arrays.sort(markers);
-// System.out.print('[');
-// for (int n = 0; n < size; n++) {
-// if (n != 0) System.out.print(',');
-// System.out.print(positions[n]);
-// }
-// System.out.println(']');
- return markers;
-}
-public int[] getFramePositions() {
- Set set = this.framePositions.keySet();
- int size = set.size();
- int[] positions = new int[size];
- int n = 0;
- for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
- positions[n++] = ((Integer) iterator.next()).intValue();
- }
- Arrays.sort(positions);
-// System.out.print('[');
-// for (int n = 0; n < size; n++) {
-// if (n != 0) System.out.print(',');
-// System.out.print(positions[n]);
-// }
-// System.out.println(']');
- return positions;
-}
-public StackDepthMarker[] getStackDepthMarkers() {
- if (this.stackDepthMarkers == null) return null;
- int length = this.stackDepthMarkers.size();
- if (length == 0) return null;
- StackDepthMarker[] result = new StackDepthMarker[length];
- this.stackDepthMarkers.toArray(result);
- return result;
-}
-public StackMarker[] getStackMarkers() {
- if (this.stackMarkers == null) return null;
- int length = this.stackMarkers.size();
- if (length == 0) return null;
- StackMarker[] result = new StackMarker[length];
- this.stackMarkers.toArray(result);
- return result;
-}
-public boolean hasFramePositions() {
- return this.framePositions.size() != 0;
-}
-@Override
-public void init(ClassFile targetClassFile) {
- super.init(targetClassFile);
- this.stateIndexesCounter = 0;
- if (this.framePositions != null) {
- this.framePositions.clear();
- }
- if (this.exceptionMarkers != null) {
- this.exceptionMarkers.clear();
- }
- if (this.stackDepthMarkers != null) {
- this.stackDepthMarkers.clear();
- }
- if (this.stackMarkers != null) {
- this.stackMarkers.clear();
- }
-}
-
-@Override
-public void initializeMaxLocals(MethodBinding methodBinding) {
- super.initializeMaxLocals(methodBinding);
- if (this.framePositions == null) {
- this.framePositions = new HashMap();
- } else {
- this.framePositions.clear();
- }
-}
-public void popStateIndex() {
- this.stateIndexesCounter--;
-}
-public void pushStateIndex(int naturalExitMergeInitStateIndex) {
- if (this.stateIndexes == null) {
- this.stateIndexes = new int[3];
- }
- int length = this.stateIndexes.length;
- if (length == this.stateIndexesCounter) {
- // resize
- System.arraycopy(this.stateIndexes, 0, (this.stateIndexes = new int[length * 2]), 0, length);
- }
- this.stateIndexes[this.stateIndexesCounter++] = naturalExitMergeInitStateIndex;
-}
-@Override
-public void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
- int index = this.visibleLocalsCount;
- loop : for (int i = 0; i < index; i++) {
- LocalVariableBinding localBinding = this.visibleLocals[i];
- if (localBinding != null && localBinding.initializationCount > 0) {
- boolean isDefinitelyAssigned = isDefinitelyAssigned(scope, initStateIndex, localBinding);
- if (!isDefinitelyAssigned) {
- if (this.stateIndexes != null) {
- for (int j = 0, max = this.stateIndexesCounter; j < max; j++) {
- if (isDefinitelyAssigned(scope, this.stateIndexes[j], localBinding)) {
- continue loop;
- }
+ @Override
+ public void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
+ // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
+ for (int i = 0; i < this.visibleLocalsCount; i++) {
+ LocalVariableBinding localBinding = this.visibleLocals[i];
+ if (localBinding != null) {
+ // Check if the local is definitely assigned
+ boolean isDefinitelyAssigned = isDefinitelyAssigned(scope, initStateIndex, localBinding);
+ if (!isDefinitelyAssigned) {
+ continue;
+ } else {
+ if ((localBinding.initializationCount == 0)
+ || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1)
+ + 1] != -1)) {
+ /*
+ * There are two cases: 1) there is no initialization interval opened ==> add an opened interval
+ * 2) there is already some initialization intervals but the last one is closed ==> add an
+ * opened interval An opened interval means that the value at
+ * localBinding.initializationPCs[localBinding.initializationCount - 1][1] is equals to -1.
+ * initializationPCs is a collection of pairs of int: first value is the startPC and second
+ * value is the endPC. -1 one for the last value means that the interval is not closed yet.
+ */
+ localBinding.recordInitializationStartPC(this.position);
}
}
- localBinding.recordInitializationEndPC(this.position);
}
}
}
-}
-@Override
-public void reset(ClassFile givenClassFile) {
- super.reset(givenClassFile);
- this.stateIndexesCounter = 0;
- if (this.framePositions != null) {
- this.framePositions.clear();
+
+ public void addExceptionMarker(int pc, TypeBinding typeBinding) {
+ if (this.exceptionMarkers == null) {
+ this.exceptionMarkers = new HashSet();
+ }
+
+ this.exceptionMarkers.add(new ExceptionMarker(pc, typeBinding));
}
- if (this.exceptionMarkers != null) {
- this.exceptionMarkers.clear();
- }
- if (this.stackDepthMarkers != null) {
- this.stackDepthMarkers.clear();
- }
- if (this.stackMarkers != null) {
- this.stackMarkers.clear();
- }
-}
-@Override
-protected void writePosition(BranchLabel label) {
- super.writePosition(label);
- addFramePosition(label.position);
-}
-@Override
-protected void writePosition(BranchLabel label, int forwardReference) {
- super.writePosition(label, forwardReference);
- addFramePosition(label.position);
-}
-@Override
-protected void writeSignedWord(int pos, int value) {
- super.writeSignedWord(pos, value);
- addFramePosition(this.position);
-}
-@Override
-protected void writeWidePosition(BranchLabel label) {
- super.writeWidePosition(label);
- addFramePosition(label.position);
-}
-@Override
-public void areturn() {
- super.areturn();
- addFramePosition(this.position);
-}
-@Override
-public void ireturn() {
- super.ireturn();
- addFramePosition(this.position);
-}
-@Override
-public void lreturn() {
- super.lreturn();
- addFramePosition(this.position);
-}
-@Override
-public void freturn() {
- super.freturn();
- addFramePosition(this.position);
-}
-@Override
-public void dreturn() {
- super.dreturn();
- addFramePosition(this.position);
-}
-@Override
-public void return_() {
- super.return_();
- addFramePosition(this.position);
-}
-@Override
-public void athrow() {
- super.athrow();
- addFramePosition(this.position);
-}
-@Override
-public void pushOnStack(TypeBinding binding) {
- super.pushOnStack(binding);
- addStackDepthMarker(this.position, 1, binding);
-}
-@Override
-public void pushExceptionOnStack(TypeBinding binding) {
- super.pushExceptionOnStack(binding);
- addExceptionMarker(this.position, binding);
-}
-@Override
-public void goto_(BranchLabel label) {
- super.goto_(label);
- addFramePosition(this.position);
-}
-@Override
-public void goto_w(BranchLabel label) {
- super.goto_w(label);
- addFramePosition(this.position);
-}
-@Override
-public void resetInWideMode() {
- this.resetSecretLocals();
- super.resetInWideMode();
-}
-@Override
-public void resetForCodeGenUnusedLocals() {
- this.resetSecretLocals();
- super.resetForCodeGenUnusedLocals();
-}
-public void resetSecretLocals() {
- for (int i = 0, max = this.locals.length; i < max; i++) {
- LocalVariableBinding localVariableBinding = this.locals[i];
- if (localVariableBinding != null && localVariableBinding.isSecret()) {
- // all other locals are reinitialized inside the computation of their resolved positions
- localVariableBinding.resetInitializations();
+
+ public void addFramePosition(int pc) {
+ Integer newEntry = Integer.valueOf(pc);
+ FramePosition value;
+ if ((value = (FramePosition) this.framePositions.get(newEntry)) != null) {
+ value.counter++;
+ } else {
+ this.framePositions.put(newEntry, new FramePosition());
}
}
-}
+
+ @Override
+ public void optimizeBranch(int oldPosition, BranchLabel lbl) {
+ super.optimizeBranch(oldPosition, lbl);
+ removeFramePosition(oldPosition);
+ }
+
+ public void removeFramePosition(int pc) {
+ Integer entry = Integer.valueOf(pc);
+ FramePosition value;
+ if ((value = (FramePosition) this.framePositions.get(entry)) != null) {
+ value.counter--;
+ if (value.counter <= 0) {
+ this.framePositions.remove(entry);
+ }
+ }
+ }
+
+ @Override
+ public void addVariable(LocalVariableBinding localBinding) {
+ if (localBinding.initializationPCs == null) {
+ record(localBinding);
+ }
+ localBinding.recordInitializationStartPC(this.position);
+ }
+
+ @Override
+ public void recordExpressionType(TypeBinding typeBinding, int delta, boolean adjustStackDepth) {
+ if (adjustStackDepth) {
+ // optimized goto
+ // the break label already adjusted the stack depth (-1 or -2 depending on the return type)
+ // we need to adjust back to what it was
+ switch (typeBinding.id) {
+ case TypeIds.T_long:
+ case TypeIds.T_double:
+ this.stackDepth += 2;
+ break;
+ case TypeIds.T_void:
+ break;
+ default:
+ this.stackDepth++;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Macro for building a class descriptor object
+ */
+ @Override
+ public void generateClassLiteralAccessForType(Scope scope, TypeBinding accessedType,
+ FieldBinding syntheticFieldBinding) {
+ if (accessedType.isBaseType() && accessedType != TypeBinding.NULL) {
+ getTYPE(accessedType.id);
+ return;
+ }
+
+ if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+ // generation using the new ldc_w bytecode
+ this.ldc(accessedType);
+ } else {
+ // use in CLDC mode
+ BranchLabel endLabel = new BranchLabel(this);
+ if (syntheticFieldBinding != null) { // non interface case
+ fieldAccess(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */);
+ dup();
+ ifnonnull(endLabel);
+ pop();
+ }
+
+ /*
+ * Macro for building a class descriptor object... using or not a field cache to store it into... this
+ * sequence is responsible for building the actual class descriptor.
+ *
+ * If the fieldCache is set, then it is supposed to be the body of a synthetic access method factoring the
+ * actual descriptor creation out of the invocation site (saving space). If the fieldCache is nil, then we
+ * are dumping the bytecode on the invocation site, since we have no way to get a hand on the field cache to
+ * do better.
+ */
+
+ // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
+
+ ExceptionLabel classNotFoundExceptionHandler = new ExceptionLabel(this,
+ TypeBinding.NULL /* represents ClassNotFoundException */);
+ classNotFoundExceptionHandler.placeStart();
+ this.ldc(accessedType == TypeBinding.NULL ? "java.lang.Object" //$NON-NLS-1$
+ : String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
+ invokeClassForName();
+
+ /*
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565 if (accessedType == BaseTypes.NullBinding) {
+ * this.ldc("java.lang.Object"); //$NON-NLS-1$ } else if (accessedType.isArrayType()) {
+ * this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.')); } else { // we make it an
+ * array type (to avoid class initialization) this.ldc("[L" +
+ * String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$ }
+ * this.invokeClassForName(); if (!accessedType.isArrayType()) { // extract the component type, which
+ * doesn't initialize the class this.invokeJavaLangClassGetComponentType(); }
+ */
+ /*
+ * We need to protect the runtime code from binary inconsistencies in case the accessedType is missing, the
+ * ClassNotFoundException has to be converted into a NoClassDefError(old ex message), we thus need to build
+ * an exception handler for this one.
+ */
+ classNotFoundExceptionHandler.placeEnd();
+
+ if (syntheticFieldBinding != null) { // non interface case
+ dup();
+ fieldAccess(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */);
+ }
+ goto_(endLabel);
+ int savedStackDepth = this.stackDepth;
+ // Generate the body of the exception handler
+ /*
+ * ClassNotFoundException on stack -- the class literal could be doing more things on the stack, which means
+ * that the stack may not be empty at this point in the above code gen. So we save its state and restart it
+ * from 1.
+ */
+
+ pushExceptionOnStack(scope.getJavaLangClassNotFoundException());
+ classNotFoundExceptionHandler.place();
+
+ // Transform the current exception, and repush and throw a
+ // NoClassDefFoundError(ClassNotFound.getMessage())
+
+ newNoClassDefFoundError();
+ dup_x1();
+ swap();
+
+ // Retrieve the message from the old exception
+ invokeThrowableGetMessage();
+
+ // Send the constructor taking a message string as an argument
+ invokeNoClassDefFoundErrorStringConstructor();
+ athrow();
+ endLabel.place();
+ this.stackDepth = savedStackDepth;
+ }
+ }
+
+ @Override
+ public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
+ int currentPosition = this.position;
+ super.generateOuterAccess(mappingSequence, invocationSite, target, scope);
+ if (currentPosition == this.position) {
+ // no code has been generate during outer access => no enclosing instance is available
+ throw new AbortMethod(scope.referenceCompilationUnit().compilationResult, null);
+ }
+ }
+
+ public ExceptionMarker[] getExceptionMarkers() {
+ Set exceptionMarkerSet = this.exceptionMarkers;
+ if (this.exceptionMarkers == null)
+ return null;
+ int size = exceptionMarkerSet.size();
+ ExceptionMarker[] markers = new ExceptionMarker[size];
+ int n = 0;
+ for (Iterator iterator = exceptionMarkerSet.iterator(); iterator.hasNext();) {
+ markers[n++] = (ExceptionMarker) iterator.next();
+ }
+ Arrays.sort(markers);
+// System.out.print('[');
+// for (int n = 0; n < size; n++) {
+// if (n != 0) System.out.print(',');
+// System.out.print(positions[n]);
+// }
+// System.out.println(']');
+ return markers;
+ }
+
+ public int[] getFramePositions() {
+ Set set = this.framePositions.keySet();
+ int size = set.size();
+ int[] positions = new int[size];
+ int n = 0;
+ for (Iterator iterator = set.iterator(); iterator.hasNext();) {
+ positions[n++] = ((Integer) iterator.next()).intValue();
+ }
+ Arrays.sort(positions);
+// System.out.print('[');
+// for (int n = 0; n < size; n++) {
+// if (n != 0) System.out.print(',');
+// System.out.print(positions[n]);
+// }
+// System.out.println(']');
+ return positions;
+ }
+
+ public boolean hasFramePositions() {
+ return this.framePositions.size() != 0;
+ }
+
+ @Override
+ public void init(ClassFile targetClassFile) {
+ super.init(targetClassFile);
+ this.stateIndexesCounter = 0;
+ if (this.framePositions != null) {
+ this.framePositions.clear();
+ }
+ if (this.exceptionMarkers != null) {
+ this.exceptionMarkers.clear();
+ }
+ if (this.stackDepthMarkers != null) {
+ this.stackDepthMarkers.clear();
+ }
+ if (this.stackMarkers != null) {
+ this.stackMarkers.clear();
+ }
+ }
+
+ @Override
+ public void initializeMaxLocals(MethodBinding methodBinding) {
+ super.initializeMaxLocals(methodBinding);
+ if (this.framePositions == null) {
+ this.framePositions = new HashMap();
+ } else {
+ this.framePositions.clear();
+ }
+ }
+
+ public void popStateIndex() {
+ this.stateIndexesCounter--;
+ }
+
+ public void pushStateIndex(int naturalExitMergeInitStateIndex) {
+ if (this.stateIndexes == null) {
+ this.stateIndexes = new int[3];
+ }
+ int length = this.stateIndexes.length;
+ if (length == this.stateIndexesCounter) {
+ // resize
+ System.arraycopy(this.stateIndexes, 0, (this.stateIndexes = new int[length * 2]), 0, length);
+ }
+ this.stateIndexes[this.stateIndexesCounter++] = naturalExitMergeInitStateIndex;
+ }
+
+ @Override
+ public void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
+ int index = this.visibleLocalsCount;
+ loop: for (int i = 0; i < index; i++) {
+ LocalVariableBinding localBinding = this.visibleLocals[i];
+ if (localBinding != null && localBinding.initializationCount > 0) {
+ boolean isDefinitelyAssigned = isDefinitelyAssigned(scope, initStateIndex, localBinding);
+ if (!isDefinitelyAssigned) {
+ if (this.stateIndexes != null) {
+ for (int j = 0, max = this.stateIndexesCounter; j < max; j++) {
+ if (isDefinitelyAssigned(scope, this.stateIndexes[j], localBinding)) {
+ continue loop;
+ }
+ }
+ }
+ localBinding.recordInitializationEndPC(this.position);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void reset(ClassFile givenClassFile) {
+ super.reset(givenClassFile);
+ this.stateIndexesCounter = 0;
+ if (this.framePositions != null) {
+ this.framePositions.clear();
+ }
+ if (this.exceptionMarkers != null) {
+ this.exceptionMarkers.clear();
+ }
+ if (this.stackDepthMarkers != null) {
+ this.stackDepthMarkers.clear();
+ }
+ if (this.stackMarkers != null) {
+ this.stackMarkers.clear();
+ }
+ }
+
+ @Override
+ protected void writePosition(BranchLabel label) {
+ super.writePosition(label);
+ addFramePosition(label.position);
+ }
+
+ @Override
+ protected void writePosition(BranchLabel label, int forwardReference) {
+ super.writePosition(label, forwardReference);
+ addFramePosition(label.position);
+ }
+
+ @Override
+ protected void writeSignedWord(int pos, int value) {
+ super.writeSignedWord(pos, value);
+ addFramePosition(this.position);
+ }
+
+ @Override
+ protected void writeWidePosition(BranchLabel label) {
+ super.writeWidePosition(label);
+ addFramePosition(label.position);
+ }
+
+ @Override
+ public void areturn() {
+ super.areturn();
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void ireturn() {
+ super.ireturn();
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void lreturn() {
+ super.lreturn();
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void freturn() {
+ super.freturn();
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void dreturn() {
+ super.dreturn();
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void return_() {
+ super.return_();
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void athrow() {
+ super.athrow();
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void pushExceptionOnStack(TypeBinding binding) {
+ super.pushExceptionOnStack(binding);
+ addExceptionMarker(this.position, binding);
+ }
+
+ @Override
+ public void goto_(BranchLabel label) {
+ super.goto_(label);
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void goto_w(BranchLabel label) {
+ super.goto_w(label);
+ addFramePosition(this.position);
+ }
+
+ @Override
+ public void resetInWideMode() {
+ this.resetSecretLocals();
+ super.resetInWideMode();
+ }
+
+ @Override
+ public void resetForCodeGenUnusedLocals() {
+ this.resetSecretLocals();
+ super.resetForCodeGenUnusedLocals();
+ }
+
+ public void resetSecretLocals() {
+ for (int i = 0, max = this.locals.length; i < max; i++) {
+ LocalVariableBinding localVariableBinding = this.locals[i];
+ if (localVariableBinding != null && localVariableBinding.isSecret()) {
+ // all other locals are reinitialized inside the computation of their resolved positions
+ localVariableBinding.resetInitializations();
+ }
+ }
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java
index 38c24a3..d3afd5b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java
@@ -13,234 +13,237 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
public class VerificationTypeInfo {
/**
* The tag value representing top variable info
+ *
* @since 3.2
*/
public static final int ITEM_TOP = 0;
/**
* The tag value representing integer variable info
+ *
* @since 3.2
*/
public static final int ITEM_INTEGER = 1;
/**
* The tag value representing float variable info
+ *
* @since 3.2
*/
public static final int ITEM_FLOAT = 2;
/**
* The tag value representing double variable info
+ *
* @since 3.2
*/
public static final int ITEM_DOUBLE = 3;
/**
* The tag value representing long variable info
+ *
* @since 3.2
*/
public static final int ITEM_LONG = 4;
/**
* The tag value representing null variable info
+ *
* @since 3.2
*/
public static final int ITEM_NULL = 5;
/**
* The tag value representing uninitialized this variable info
+ *
* @since 3.2
*/
public static final int ITEM_UNINITIALIZED_THIS = 6;
/**
* The tag value representing object variable info
+ *
* @since 3.2
*/
public static final int ITEM_OBJECT = 7;
/**
* The tag value representing uninitialized variable info
+ *
* @since 3.2
*/
public static final int ITEM_UNINITIALIZED = 8;
public int tag;
private int id;
- private char[] constantPoolName;
- public int offset;
+ private TypeBinding binding;
+ public int offset; // where the new opcode is used
+ private List<TypeBinding> bindings;
-private VerificationTypeInfo() {
- // for duplication
-}
-public VerificationTypeInfo(int id, char[] constantPoolName) {
- this(id, VerificationTypeInfo.ITEM_OBJECT, constantPoolName);
-}
-public VerificationTypeInfo(int id, int tag, char[] constantPoolName) {
- this.id = id;
- this.tag = tag;
- this.constantPoolName = constantPoolName;
-}
-public VerificationTypeInfo(int tag, TypeBinding binding) {
- this(binding);
- this.tag = tag;
-}
-public VerificationTypeInfo(TypeBinding binding) {
- this.id = binding.id;
- switch(binding.id) {
- case TypeIds.T_boolean :
- case TypeIds.T_byte :
- case TypeIds.T_char :
- case TypeIds.T_int :
- case TypeIds.T_short :
- this.tag = VerificationTypeInfo.ITEM_INTEGER;
- break;
- case TypeIds.T_float :
- this.tag = VerificationTypeInfo.ITEM_FLOAT;
- break;
- case TypeIds.T_long :
- this.tag = VerificationTypeInfo.ITEM_LONG;
- break;
- case TypeIds.T_double :
- this.tag = VerificationTypeInfo.ITEM_DOUBLE;
- break;
- case TypeIds.T_null :
- this.tag = VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- this.tag = VerificationTypeInfo.ITEM_OBJECT;
- this.constantPoolName = binding.constantPoolName();
+ public VerificationTypeInfo(int tag, TypeBinding binding) {
+ this(binding);
+ this.tag = tag;
}
-}
-public void setBinding(TypeBinding binding) {
- this.constantPoolName = binding.constantPoolName();
- final int typeBindingId = binding.id;
- this.id = typeBindingId;
- switch(typeBindingId) {
- case TypeIds.T_boolean :
- case TypeIds.T_byte :
- case TypeIds.T_char :
- case TypeIds.T_int :
- case TypeIds.T_short :
- this.tag = VerificationTypeInfo.ITEM_INTEGER;
- break;
- case TypeIds.T_float :
- this.tag = VerificationTypeInfo.ITEM_FLOAT;
- break;
- case TypeIds.T_long :
- this.tag = VerificationTypeInfo.ITEM_LONG;
- break;
- case TypeIds.T_double :
- this.tag = VerificationTypeInfo.ITEM_DOUBLE;
- break;
- case TypeIds.T_null :
- this.tag = VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- this.tag = VerificationTypeInfo.ITEM_OBJECT;
- }
-}
-public int id() {
- return this.id;
-}
-@Override
-public String toString() {
- StringBuffer buffer = new StringBuffer();
- switch(this.tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED_THIS :
- buffer.append("uninitialized_this(").append(readableName()).append(")"); //$NON-NLS-1$//$NON-NLS-2$
- break;
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- buffer.append("uninitialized(").append(readableName()).append(")"); //$NON-NLS-1$//$NON-NLS-2$
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- buffer.append(readableName());
- break;
- case VerificationTypeInfo.ITEM_DOUBLE :
- buffer.append('D');
- break;
- case VerificationTypeInfo.ITEM_FLOAT :
- buffer.append('F');
- break;
- case VerificationTypeInfo.ITEM_INTEGER :
- buffer.append('I');
- break;
- case VerificationTypeInfo.ITEM_LONG :
- buffer.append('J');
- break;
- case VerificationTypeInfo.ITEM_NULL :
- buffer.append("null"); //$NON-NLS-1$
- break;
- case VerificationTypeInfo.ITEM_TOP :
- buffer.append("top"); //$NON-NLS-1$
- break;
- }
- return String.valueOf(buffer);
-}
-public VerificationTypeInfo duplicate() {
- final VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo();
- verificationTypeInfo.id = this.id;
- verificationTypeInfo.tag = this.tag;
- verificationTypeInfo.constantPoolName = this.constantPoolName;
- verificationTypeInfo.offset = this.offset;
- return verificationTypeInfo;
-}
-@Override
-public boolean equals(Object obj) {
- if (obj instanceof VerificationTypeInfo) {
- VerificationTypeInfo info1 = (VerificationTypeInfo) obj;
- return info1.tag == this.tag && CharOperation.equals(info1.constantPoolName(), constantPoolName());
- }
- return false;
-}
-@Override
-public int hashCode() {
- return this.tag + this.id + this.constantPoolName.length + this.offset;
-}
-public char[] constantPoolName() {
- return this.constantPoolName;
-}
-public char[] readableName() {
- return this.constantPoolName;
-}
-public void replaceWithElementType() {
- if (this.constantPoolName[1] == 'L') {
- this.constantPoolName = CharOperation.subarray(this.constantPoolName, 2, this.constantPoolName.length - 1);
- } else {
- this.constantPoolName = CharOperation.subarray(this.constantPoolName, 1, this.constantPoolName.length);
- if (this.constantPoolName.length == 1) {
- switch(this.constantPoolName[0]) {
- case 'I' :
- this.id = TypeIds.T_int;
- break;
- case 'B' :
- this.id = TypeIds.T_byte;
- break;
- case 'S' :
- this.id = TypeIds.T_short;
- break;
- case 'C' :
- this.id = TypeIds.T_char;
- break;
- case 'J' :
- this.id = TypeIds.T_long;
- break;
- case 'F' :
- this.id = TypeIds.T_float;
- break;
- case 'D' :
- this.id = TypeIds.T_double;
- break;
- case 'Z' :
- this.id = TypeIds.T_boolean;
- break;
- case 'N' :
- this.id = TypeIds.T_null;
- break;
- case 'V' :
- this.id = TypeIds.T_void;
- break;
- }
+
+ public VerificationTypeInfo(TypeBinding binding) {
+ if (binding == null) return;
+ this.id = binding.id;
+ this.binding = binding;
+ switch (binding.id) {
+ case TypeIds.T_boolean:
+ case TypeIds.T_byte:
+ case TypeIds.T_char:
+ case TypeIds.T_int:
+ case TypeIds.T_short:
+ this.tag = VerificationTypeInfo.ITEM_INTEGER;
+ break;
+ case TypeIds.T_float:
+ this.tag = VerificationTypeInfo.ITEM_FLOAT;
+ break;
+ case TypeIds.T_long:
+ this.tag = VerificationTypeInfo.ITEM_LONG;
+ break;
+ case TypeIds.T_double:
+ this.tag = VerificationTypeInfo.ITEM_DOUBLE;
+ break;
+ case TypeIds.T_null:
+ this.tag = VerificationTypeInfo.ITEM_NULL;
+ break;
+ default:
+ this.tag = VerificationTypeInfo.ITEM_OBJECT;
}
}
-}
+
+ public void setBinding(TypeBinding binding) {
+ final int typeBindingId = binding.id;
+ this.id = typeBindingId;
+ switch (typeBindingId) {
+ case TypeIds.T_boolean:
+ case TypeIds.T_byte:
+ case TypeIds.T_char:
+ case TypeIds.T_int:
+ case TypeIds.T_short:
+ this.tag = VerificationTypeInfo.ITEM_INTEGER;
+ break;
+ case TypeIds.T_float:
+ this.tag = VerificationTypeInfo.ITEM_FLOAT;
+ break;
+ case TypeIds.T_long:
+ this.tag = VerificationTypeInfo.ITEM_LONG;
+ break;
+ case TypeIds.T_double:
+ this.tag = VerificationTypeInfo.ITEM_DOUBLE;
+ break;
+ case TypeIds.T_null:
+ this.tag = VerificationTypeInfo.ITEM_NULL;
+ break;
+ default:
+ this.tag = VerificationTypeInfo.ITEM_OBJECT;
+ }
+ }
+
+ public int id() {
+ return this.id;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ switch (this.tag) {
+ case VerificationTypeInfo.ITEM_UNINITIALIZED_THIS:
+ buffer.append("uninitialized_this(").append(readableName()).append(")"); //$NON-NLS-1$//$NON-NLS-2$
+ break;
+ case VerificationTypeInfo.ITEM_UNINITIALIZED:
+ buffer.append("uninitialized(").append(readableName()).append(")"); //$NON-NLS-1$//$NON-NLS-2$
+ break;
+ case VerificationTypeInfo.ITEM_OBJECT:
+ buffer.append(readableName());
+ break;
+ case VerificationTypeInfo.ITEM_DOUBLE:
+ buffer.append('D');
+ break;
+ case VerificationTypeInfo.ITEM_FLOAT:
+ buffer.append('F');
+ break;
+ case VerificationTypeInfo.ITEM_INTEGER:
+ buffer.append('I');
+ break;
+ case VerificationTypeInfo.ITEM_LONG:
+ buffer.append('J');
+ break;
+ case VerificationTypeInfo.ITEM_NULL:
+ buffer.append("null"); //$NON-NLS-1$
+ break;
+ case VerificationTypeInfo.ITEM_TOP:
+ buffer.append("top"); //$NON-NLS-1$
+ break;
+ }
+ return String.valueOf(buffer);
+ }
+
+ public VerificationTypeInfo duplicate() {
+ VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(this.tag, this.binding);
+ verificationTypeInfo.offset = this.offset;
+ return verificationTypeInfo;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof VerificationTypeInfo) {
+ VerificationTypeInfo info1 = (VerificationTypeInfo) obj;
+ return info1.tag == this.tag && CharOperation.equals(info1.constantPoolName(), constantPoolName());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.tag + this.id + this.binding.constantPoolName().length;
+ }
+
+ public char[] constantPoolName() {
+ return this.binding.constantPoolName();
+ }
+
+ public char[] readableName() {
+ return this.constantPoolName();
+ }
+
+ public void replaceWithElementType() {
+ ArrayBinding arrayBinding = (ArrayBinding) this.binding;
+ this.binding = arrayBinding.elementsType();
+ this.id = this.binding.id;
+ }
+
+ public VerificationTypeInfo merge(VerificationTypeInfo verificationTypeInfo, Scope scope) {
+ if (this.binding.isBaseType() && verificationTypeInfo.binding.isBaseType()) {
+ return this;
+ }
+ if (!this.binding.equals(verificationTypeInfo.binding)) {
+ if (this.bindings == null) {
+ this.bindings = new ArrayList<TypeBinding>();
+ this.bindings.add(this.binding);
+ }
+ this.bindings.add(verificationTypeInfo.binding);
+ this.binding = scope.lowerUpperBound(this.bindings.toArray(new TypeBinding[this.bindings.size()]));
+ if (this.binding != null) {
+ this.id = this.binding.id;
+ switch (this.id) {
+ case TypeIds.T_null:
+ this.tag = VerificationTypeInfo.ITEM_NULL;
+ break;
+ default:
+ this.tag = VerificationTypeInfo.ITEM_OBJECT;
+ }
+ } else {
+ this.binding = scope.getJavaLangObject();
+ this.tag = VerificationTypeInfo.ITEM_OBJECT;
+ }
+ }
+ return this;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 7d9fa4f..a9f41fb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -1292,18 +1292,18 @@
return "dep-ann"; //$NON-NLS-1$
case RawTypeReference :
return "rawtypes"; //$NON-NLS-1$
- case UnusedLabel :
- case UnusedTypeArguments :
+ case DeadCode :
case RedundantSuperinterface :
- case UnusedLocalVariable :
- case UnusedArgument :
+ case RedundantSpecificationOfTypeArguments :
+ case UnusedDeclaredThrownException :
case UnusedExceptionParameter :
case UnusedImport :
- case UnusedPrivateMember :
- case UnusedDeclaredThrownException :
- case DeadCode :
+ case UnusedLabel :
+ case UnusedLocalVariable :
case UnusedObjectAllocation :
- case RedundantSpecificationOfTypeArguments :
+ case UnusedArgument : // OPTION_ReportUnusedParameter
+ case UnusedPrivateMember :
+ case UnusedTypeArguments : // OPTION_ReportUnusedTypeArgumentsForMethodInvocation
case UnusedTypeParameter:
return "unused"; //$NON-NLS-1$
case DiscouragedReference :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 1542692..9e2aebf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -2021,6 +2021,10 @@
this.tagBits |= TagBits.AreMethodsComplete;
return this.methods;
}
+@Override
+public void setHierarchyCheckDone() {
+ this.tagBits |= TagBits.BeginHierarchyCheck | TagBits.EndHierarchyCheck;
+}
@Override
public TypeBinding prototype() {
@@ -2545,8 +2549,60 @@
this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits);
if ((this.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0) // avoid the side-effects of hasTypeBit()!
this.typeBits |= applyCloseableClassWhitelists();
+ detectCircularHierarchy();
return this.superclass;
}
+
+private void breakLoop() {
+ ReferenceBinding currentSuper = this.superclass;
+ ReferenceBinding prevSuper = null;
+ while (currentSuper != null) {
+ if ((currentSuper.tagBits & TagBits.EndHierarchyCheck) != 0 && prevSuper instanceof BinaryTypeBinding) {
+ ((BinaryTypeBinding)prevSuper).superclass = this.environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+ break;
+ }
+ currentSuper.tagBits |= TagBits.EndHierarchyCheck;
+ prevSuper = currentSuper;
+ currentSuper = currentSuper.superclass();
+ }
+}
+
+private void detectCircularHierarchy() {
+ ReferenceBinding currentSuper = this.superclass;
+ ReferenceBinding tempSuper = null;
+ int count = 0;
+ int skipCount = 20;
+ while (currentSuper != null) {
+ if (currentSuper.hasHierarchyCheckStarted())
+ break;
+ if (TypeBinding.equalsEquals(currentSuper, this) || TypeBinding.equalsEquals(currentSuper, tempSuper)) {
+ currentSuper.tagBits |= TagBits.HierarchyHasProblems;
+ if (currentSuper.isBinaryBinding())
+ breakLoop();
+
+ return;
+ }
+ if (count == skipCount) {
+ tempSuper = currentSuper; // for finding loops that only start after a linear chain
+ skipCount *= 2;
+ count = 0;
+ }
+ //Ignore if the super is not yet resolved..
+ if (!currentSuper.isHierarchyConnected())
+ return;
+ currentSuper = currentSuper.superclass();
+ count++;
+ }
+ /* No loop detected and completely found that there is no loop
+ * So, set that info for all the classes
+ */
+ tempSuper = this;
+ while (TypeBinding.notEquals(currentSuper, tempSuper)) {
+ tempSuper.setHierarchyCheckDone();
+ tempSuper=tempSuper.superclass();
+ }
+}
+
//{ObjectTeams:
@Override
public ReferenceBinding baseclass () {
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 7c3f8cd..b7c11f4 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
@@ -440,6 +440,15 @@
return methods();
}
+public boolean hasHierarchyCheckStarted() {
+ return (this.tagBits & TagBits.BeginHierarchyCheck) != 0;
+}
+
+public void setHierarchyCheckDone() {
+ return;
+}
+
+
/**
* Answer true if the receiver can be instantiated
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 7dc9404..6a83d2f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -3106,6 +3106,16 @@
unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_CLONEABLE);
return unitScope.environment.getResolvedJavaBaseType(TypeConstants.JAVA_LANG_CLONEABLE, this);
}
+ public final ReferenceBinding getJavaLangClassNotFoundException() {
+ CompilationUnitScope unitScope = compilationUnitScope();
+ unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_CLASSNOTFOUNDEXCEPTION);
+ return unitScope.environment.getResolvedJavaBaseType(TypeConstants.JAVA_LANG_CLASSNOTFOUNDEXCEPTION, this);
+ }
+ public final ReferenceBinding getJavaLangNoSuchFieldError() {
+ CompilationUnitScope unitScope = compilationUnitScope();
+ unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_NOSUCHFIELDERROR);
+ return unitScope.environment.getResolvedJavaBaseType(TypeConstants.JAVA_LANG_NOSUCHFIELDERROR, this);
+ }
public final ReferenceBinding getJavaLangEnum() {
CompilationUnitScope unitScope = compilationUnitScope();
unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_ENUM);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
index 8fd55e7..e096688 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
@@ -144,6 +144,7 @@
char[][] JAVA_LANG_ASSERTIONERROR = {JAVA, LANG, "AssertionError".toCharArray()}; //$NON-NLS-1$
char[][] JAVA_LANG_CLASS = {JAVA, LANG, "Class".toCharArray()}; //$NON-NLS-1$
char[][] JAVA_LANG_CLASSNOTFOUNDEXCEPTION = {JAVA, LANG, "ClassNotFoundException".toCharArray()}; //$NON-NLS-1$
+ char[][] JAVA_LANG_NOSUCHFIELDERROR = {JAVA, LANG, "NoSuchFieldError".toCharArray()}; //$NON-NLS-1$
char[][] JAVA_LANG_CLONEABLE = {JAVA, LANG, "Cloneable".toCharArray()}; //$NON-NLS-1$
char[][] JAVA_LANG_ENUM = {JAVA, LANG, "Enum".toCharArray()}; //$NON-NLS-1$
char[][] JAVA_LANG_EXCEPTION = {JAVA, LANG, "Exception".toCharArray()}; //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index e89f9fb..83f1800 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -2022,14 +2022,14 @@
if (isTextBlock) {
if (lastQuotePos > 0)
this.currentPosition = lastQuotePos;
+ this.currentPosition = (lastQuotePos > 0) ? lastQuotePos : this.startPosition + this.rawStart;
throw new InvalidInputException(UNTERMINATED_TEXT_BLOCK);
} else {
throw new InvalidInputException(UNTERMINATED_STRING);
}
} catch (IndexOutOfBoundsException e) {
if (isTextBlock) {
- if (lastQuotePos > 0)
- this.currentPosition = lastQuotePos;
+ this.currentPosition = (lastQuotePos > 0) ? lastQuotePos : this.startPosition + this.rawStart;
throw new InvalidInputException(UNTERMINATED_TEXT_BLOCK);
} else {
this.currentPosition--;
@@ -2462,32 +2462,61 @@
break NextToken;
}
case '"' :
+ boolean isTextBlock = false;
+ int firstClosingBrace = 0;
try {
try { // consume next character
- this.unicodeAsBackSlash = false;
- if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
- && (this.source[this.currentPosition] == 'u')) {
- getNextUnicodeChar();
- } else {
- if (this.withoutUnicodePtr != 0) {
- unicodeStore();
+ isTextBlock = scanForTextBlockBeginning();
+ if (!isTextBlock) {
+ this.unicodeAsBackSlash = false;
+ if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+ && (this.source[this.currentPosition] == 'u')) {
+ getNextUnicodeChar();
+ } else {
+ if (this.withoutUnicodePtr != 0) {
+ unicodeStore();
+ }
}
}
} catch (InvalidInputException ex) {
// ignore
}
- while (this.currentCharacter != '"') {
- if (this.currentPosition >= this.eofPosition) {
- return;
+
+ Inner: while (this.currentPosition <= this.eofPosition) {
+ if (isTextBlock) {
+ switch (this.currentCharacter) {
+ case '"':
+ // look for text block delimiter
+ if (scanForTextBlockClose()) {
+ this.currentPosition += 2;
+ this.currentCharacter = this.source[this.currentPosition];
+ isTextBlock = false;
+ break Inner;
+ }
+ break;
+ case '}':
+ if (firstClosingBrace == 0)
+ firstClosingBrace = this.currentPosition;
+ break;
+ case '\r' :
+ if (this.source[this.currentPosition] == '\n')
+ this.currentPosition++;
+ //$FALL-THROUGH$
+ case '\n' :
+ pushLineSeparator();
+ //$FALL-THROUGH$
+ default:
+ this.currentCharacter = this.source[this.currentPosition++];
+ continue Inner;
+ }
+ } else if (this.currentCharacter == '"') {
+ break Inner;
}
if (this.currentCharacter == '\r'){
- // For text block, we don't want to overlook \n. Hence, don't advance past \n
- //if (this.source[this.currentPosition] == '\n') this.currentPosition++;
+ if (this.source[this.currentPosition] == '\n') this.currentPosition++;
break NextToken; // the string cannot go further that the line
}
if (this.currentCharacter == '\n'){
- // For text block, we don't want to overlook \n. Hence, go back one char
- this.currentPosition--;
break; // the string cannot go further that the line
}
if (this.currentCharacter == '\\') {
@@ -2525,7 +2554,13 @@
}
}
} catch (IndexOutOfBoundsException e) {
- return;
+ if(isTextBlock) {
+ // Pull it back to the first closing brace after the beginning
+ // of the unclosed text block and let recovery take over.
+ if (firstClosingBrace > 0) {
+ this.currentPosition = firstClosingBrace - 1;
+ }
+ }
}
break NextToken;
case '/' :
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
index 22aee8f..8bf8ff2 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
@@ -479,7 +479,6 @@
/**
* Creates a new Java abstract syntax tree
- * <p>
* Following option keys are significant:
* <ul>
* <li><code>"org.eclipse.jdt.core.compiler.source"</code>
@@ -489,18 +488,17 @@
* <code>"1.3"</code> means the source code is as per JDK 1.3 and api level {@link #JLS3}.</li>
* <li><code>"1.4", "1.5", "1.6", "1.7" "1.8"</code> implies the respective source JDK levels 1.4, 1.5, 1.6, 1.7 and api level {@link #JLS4}.</li>
* <li><code>"1.8"</code> implies the respective source JDK level 1.8 and api level {@link #JLS8}.</li>
- * <li><code>"9", "10", "11" "12"</code> implies the respective JDK levels 9, 10, 11 and 12
- * and api levels {@link #JLS9}, {@link #JLS10}, {@link #JLS11}, and {@link #JLS12}.</li>
- * Additional legal values may be added later.
- * </li>
+ * <li><code>"9", "10", "11", "12" and "13"</code> implies the respective JDK levels 9, 10, 11, 12 and 13
+ * and api levels {@link #JLS9}, {@link #JLS10}, {@link #JLS11}, {@link #JLS12} and {@link #JLS13}.</li>
+ * <li>Additional legal values may be added later.</li>
* </ul>
+ * </li>
* <li><code>"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"</code> -
* indicates whether the preview is enabled or disabled
* legal values are <code>"enabled"</code> and <code>"disabled"</code> implying preview enabled and disabled respectively.
* preview enabling has an effect only with the latest ast level.
+ * </li>
* </ul>
- * <p>
- * </p>
*
* @param options the table of options
* @see JavaCore#getDefaultOptions()
@@ -1014,7 +1012,6 @@
/**
* Creates a new Java abstract syntax tree
- * <p>
* Following option keys are significant:
* <ul>
* <li><code>"org.eclipse.jdt.core.compiler.source"</code>
@@ -1024,18 +1021,16 @@
* <code>"1.3"</code> means the source code is as per JDK 1.3 and api level {@link #JLS3}.</li>
* <li><code>"1.4", "1.5", "1.6", "1.7" "1.8"</code> implies the respective source JDK levels 1.4, 1.5, 1.6, 1.7 and api level {@link #JLS4}.</li>
* <li><code>"1.8"</code> implies the respective source JDK level 1.8 and api level {@link #JLS8}.</li>
- * <li><code>"9", "10", "11" "12"</code> implies the respective JDK levels 9, 10, 11 and 12
- * and api levels {@link #JLS9}, {@link #JLS10}, {@link #JLS11}, and {@link #JLS12}.</li>
- * Additional legal values may be added later.
- * </li>
+ * <li><code>"9", "10", "11", "12" and "13"</code> implies the respective JDK levels 9, 10, 11, 12 and 13
+ * and api levels {@link #JLS9}, {@link #JLS10}, {@link #JLS11}, {@link #JLS12} and {@link #JLS13}.</li>
+ * <li>Additional legal values may be added later.</li>
* </ul>
- * <li><code>"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"</code> -
- * indicates whether the preview is enabled or disabled
- * legal values are <code>"enabled"</code> and <code>"disabled"</code> implying preview enabled and disabled respectively.
- * preview enabling has an effect only with the latest ast level.
- * </ul>
- * <p>
- * </p>
+ * <li><code>"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"</code> -
+ * indicates whether the preview is enabled or disabled
+ * legal values are <code>"enabled"</code> and <code>"disabled"</code> implying preview enabled and disabled respectively.
+ * preview enabling has an effect only with the latest ast level.
+ * </li>
+ * </ul>
*
* @param options the table of options (key type: <code>String</code>;
* value type: <code>String</code>)
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 52ddf5c..f257a1a 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -32,6 +32,7 @@
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
+import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding18;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
@@ -596,7 +597,7 @@
if (length != 0) {
//{ObjectTeams: make synth role ifc transparent by transitively fetching it's super interfaces:
// accumulate into list not array because we may exceed length:
- List/*<ITypeBinding>*/ interfacesList = new ArrayList(length);
+ List<ITypeBinding> interfacesList = new ArrayList<>(length);
/* orig:
ITypeBinding[] newInterfaces = new ITypeBinding[length];
int interfacesCounter = 0;
@@ -631,7 +632,7 @@
// OT: collect into list instead of array:
interfacesList.add(typeBinding);
}
- ITypeBinding[] newInterfaces = (ITypeBinding[]) interfacesList.toArray(new ITypeBinding[interfacesList.size()]);
+ ITypeBinding[] newInterfaces = interfacesList.toArray(new ITypeBinding[interfacesList.size()]);
/* orig:
newInterfaces[interfacesCounter++] = typeBinding;
}
@@ -1210,7 +1211,7 @@
@Override
public boolean isCapture() {
- return this.binding.isCapture();
+ return this.binding.isCapture() && !(this.binding instanceof CaptureBinding18);
}
@Override
@@ -1551,13 +1552,22 @@
return ((WildcardBinding) this.binding).boundKind == Wildcard.EXTENDS;
case Binding.INTERSECTION_TYPE :
return true;
+ case Binding.TYPE_PARAMETER:
+ if (this.binding instanceof CaptureBinding18) {
+ CaptureBinding18 captureBinding18 = (CaptureBinding18) this.binding;
+ org.eclipse.jdt.internal.compiler.lookup.TypeBinding upperBound = captureBinding18.upperBound();
+ if (upperBound != null && upperBound.id != TypeIds.T_JavaLangObject) {
+ return true;
+ }
+ }
+ return false;
}
return false;
}
@Override
public boolean isWildcardType() {
- return this.binding.isWildcard();
+ return this.binding.isWildcard() || this.binding instanceof CaptureBinding18;
}
//{ObjectTeams: additional queries based on this.binding:
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java
index 96052a9..ccd04ea 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java
@@ -62,7 +62,7 @@
codeStream.return_();
}
@Override
-public void generateStoreSaveValueIfNecessary(CodeStream codeStream){
+public void generateStoreSaveValueIfNecessary(Scope scope, CodeStream codeStream){
// push receiver
codeStream.aload_0();
@@ -73,7 +73,7 @@
codeStream.aconst_null();
// void.class
- codeStream.generateClassLiteralAccessForType(TypeBinding.VOID, null);
+ codeStream.generateClassLiteralAccessForType(scope, TypeBinding.VOID, null);
} else {
// swap with expression
int valueTypeID = this.expression.resolvedType.id;
@@ -90,7 +90,7 @@
}
// generate the expression type
- codeStream.generateClassLiteralAccessForType(this.expression.resolvedType, null);
+ codeStream.generateClassLiteralAccessForType(scope, this.expression.resolvedType, null);
}
// generate the invoke virtual to "setResult(Object,Class)"
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
index 1481eac..31f10d7 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -1893,6 +1893,21 @@
/**
* <pre>
+ * FORMATTER / Option to specify how text blocks are indented
+ * - option id: "org.eclipse.jdt.core.formatter.text_block_indentation"
+ * - possible values: { INDENT_PRESERVE, INDENT_BY_ONE, INDENT_DEFAULT, INDENT_ON_COLUMN }
+ * - default: INDENT_DEFAULT
+ * </pre>
+ * @see #INDENT_PRESERVE
+ * @see #INDENT_BY_ONE
+ * @see #INDENT_DEFAULT
+ * @see #INDENT_ON_COLUMN
+ * @since 3.19
+ */
+ public static final String FORMATTER_TEXT_BLOCK_INDENTATION = JavaCore.PLUGIN_ID + ".formatter.text_block_indentation"; //$NON-NLS-1$
+
+ /**
+ * <pre>
* FORMATTER / Option to insert a new line after an annotation
* - option id: "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation"
* - possible values: { INSERT, DO_NOT_INSERT }
@@ -5060,6 +5075,13 @@
* @since 3.0
*/
public static final int INDENT_ON_COLUMN = 1;
+ /**
+ * <pre>
+ * FORMATTER / Indentation is not touched, it's preserved from original source.
+ * </pre>
+ * @since 3.19
+ */
+ public static final int INDENT_PRESERVE = 3;
/**
* <pre>
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
index 3788db3..6a4156c 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -313,7 +313,7 @@
resultBuilder.setAlignChar(DefaultCodeFormatterOptions.SPACE);
for (Token token : this.tokens) {
List<Token> structure = token.getInternalStructure();
- if (structure != null && !structure.isEmpty())
+ if (token.isComment() && structure != null && !structure.isEmpty())
resultBuilder.processComment(token);
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
index 5c86ffd..7dad994 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
@@ -49,6 +49,8 @@
public static final int M_FORCE = 1; // if bit set, then alignment will be non-optional (default is optional)
public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level)
public static final int M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation)
+ public static final int M_INDENT_DEFAULT = 0;
+ public static final int M_INDENT_PRESERVE = 8;
// split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN
@@ -486,6 +488,7 @@
public int page_width;
public int tab_char;
public boolean use_tabs_only_for_leading_indentations;
+ public int text_block_indentation;
public boolean wrap_before_multiplicative_operator;
public boolean wrap_before_additive_operator;
public boolean wrap_before_string_concatenation;
@@ -877,6 +880,26 @@
}
options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, Integer.toString(this.tab_char == SPACE ? this.indentation_size : this.tab_size)); // reverse values swapping performed by IndentationTabPage
options.put(DefaultCodeFormatterConstants.FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS, this.use_tabs_only_for_leading_indentations ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+
+ int textBlockIndentation;
+ switch (this.text_block_indentation) {
+ case Alignment.M_INDENT_PRESERVE:
+ textBlockIndentation = DefaultCodeFormatterConstants.INDENT_PRESERVE;
+ break;
+ case Alignment.M_INDENT_BY_ONE:
+ textBlockIndentation = DefaultCodeFormatterConstants.INDENT_BY_ONE;
+ break;
+ case Alignment.M_INDENT_DEFAULT:
+ textBlockIndentation = DefaultCodeFormatterConstants.INDENT_DEFAULT;
+ break;
+ case Alignment.M_INDENT_ON_COLUMN:
+ textBlockIndentation = DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid text block indentation: " + this.text_block_indentation); //$NON-NLS-1$
+ }
+ options.put(DefaultCodeFormatterConstants.FORMATTER_TEXT_BLOCK_INDENTATION, Integer.toString(textBlockIndentation));
+
options.put(DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_MULTIPLICATIVE_OPERATOR, this.wrap_before_multiplicative_operator ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
options.put(DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_ADDITIVE_OPERATOR, this.wrap_before_additive_operator ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
options.put(DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_STRING_CONCATENATION, this.wrap_before_string_concatenation ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
@@ -2370,6 +2393,19 @@
if (useTabsOnlyForLeadingIndentationsOption != null) {
this.use_tabs_only_for_leading_indentations = DefaultCodeFormatterConstants.TRUE.equals(useTabsOnlyForLeadingIndentationsOption);
}
+ setInt(settings, DefaultCodeFormatterConstants.FORMATTER_TEXT_BLOCK_INDENTATION, v -> {
+ if (DefaultCodeFormatterConstants.INDENT_PRESERVE == v) {
+ this.text_block_indentation = Alignment.M_INDENT_PRESERVE;
+ } else if (DefaultCodeFormatterConstants.INDENT_BY_ONE == v) {
+ this.text_block_indentation = Alignment.M_INDENT_BY_ONE;
+ } else if (DefaultCodeFormatterConstants.INDENT_DEFAULT == v) {
+ this.text_block_indentation = Alignment.M_INDENT_DEFAULT;
+ } else if (DefaultCodeFormatterConstants.INDENT_ON_COLUMN == v) {
+ this.text_block_indentation = Alignment.M_INDENT_ON_COLUMN;
+ } else {
+ throw new IllegalArgumentException("invalid text block setting: " + v); //$NON-NLS-1$
+ }
+ });
final Object pageWidthOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT);
if (pageWidthOption != null) {
try {
@@ -3112,6 +3148,7 @@
this.page_width = 120;
this.tab_char = TAB; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49081
this.use_tabs_only_for_leading_indentations = false;
+ this.text_block_indentation = Alignment.M_INDENT_DEFAULT;
this.wrap_before_multiplicative_operator = true;
this.wrap_before_additive_operator = true;
this.wrap_before_string_concatenation = true;
@@ -3478,6 +3515,7 @@
this.page_width = 120;
this.tab_char = MIXED;
this.use_tabs_only_for_leading_indentations = false;
+ this.text_block_indentation = Alignment.M_INDENT_DEFAULT;
this.wrap_before_multiplicative_operator = true;
this.wrap_before_additive_operator = true;
this.wrap_before_string_concatenation = true;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
index c143a01..18026f7 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
@@ -23,6 +23,7 @@
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLBRACE;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameRBRACE;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameSEMICOLON;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameTextBlock;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamebase;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameelse;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamefinally;
@@ -76,6 +77,7 @@
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchExpression;
import org.eclipse.jdt.core.dom.SwitchStatement;
+import org.eclipse.jdt.core.dom.TextBlock;
import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.core.dom.TryStatement;
import org.eclipse.jdt.core.dom.TypeDeclaration;
@@ -86,6 +88,9 @@
import org.eclipse.jdt.core.dom.YieldStatement;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.core.dom.AbstractMethodMappingDeclaration;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions.Alignment;
+import org.eclipse.jdt.internal.formatter.Token.WrapMode;
+import org.eclipse.jdt.internal.formatter.Token.WrapPolicy;
public class LineBreaksPreparator extends ASTVisitor {
final private TokenManager tm;
@@ -711,6 +716,56 @@
return true;
}
+ @Override
+ public boolean visit(TextBlock node) {
+ int indentOption = this.options.text_block_indentation;
+ if (indentOption == Alignment.M_INDENT_PRESERVE)
+ return true;
+ Token block = this.tm.firstTokenIn(node, TokenNameTextBlock);
+ ArrayList<Token> lines = new ArrayList<>();
+ lines.add(new Token(block.originalStart, block.originalStart + 2, 0)); // first line; """
+ int incidentalWhitespace = Integer.MAX_VALUE;
+ int blankLines = -1; // will go to 0 on line break after first line
+ int i = block.originalStart + 3;
+ while (i <= block.originalEnd) {
+ int lineStart = i;
+ int firstNonBlank = -1;
+ int lastNonBlank = -1;
+ while (i <= block.originalEnd) {
+ char c = this.tm.charAt(i++);
+ if (c == '\r' || c == '\n') {
+ char c2 = this.tm.charAt(i);
+ if ((c2 == '\r' || c2 == '\n') && c2 != c)
+ i++;
+ break;
+ }
+ if (c != ' ' && c != '\t') {
+ if (firstNonBlank == -1)
+ firstNonBlank = i - 1;
+ lastNonBlank = i - 1;
+ }
+ }
+ if (firstNonBlank != -1) {
+ Token line = new Token(lineStart, lastNonBlank, 0);
+ line.putLineBreaksBefore(blankLines + 1);
+ blankLines = 0;
+ lines.add(line);
+ incidentalWhitespace = Math.min(incidentalWhitespace, firstNonBlank - lineStart);
+ } else {
+ blankLines++;
+ }
+ }
+ WrapPolicy wrapPolicy = new WrapPolicy(WrapMode.DISABLED, 0, -1, 0, 0, 1, false, false);
+ for (i = 1; i < lines.size(); i++) {
+ Token t = lines.get(i);
+ Token line = new Token(t, t.originalStart + incidentalWhitespace, t.originalEnd, TokenNameTextBlock);
+ line.setWrapPolicy(wrapPolicy);
+ lines.set(i, line);
+ }
+ block.setInternalStructure(lines);
+ return true;
+ }
+
private void breakLineBefore(ASTNode node) {
this.tm.firstTokenIn(node, -1).breakBefore();
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java
index 9d9763f..9b2671a 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2018 Mateusz Matela and others.
+ * Copyright (c) 2018, 2019 Mateusz Matela and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -59,6 +59,12 @@
}
@Override
+ public boolean preVisit2(ASTNode node) {
+ boolean isMalformed = (node.getFlags() & ASTNode.MALFORMED) != 0;
+ return !isMalformed;
+ }
+
+ @Override
public void endVisit(TypeDeclaration node) {
if (node.getParent().getLength() == 0)
return; // this is a fake block created by parsing in statements mode
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java
index ef25771..b822e77 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java
@@ -18,6 +18,7 @@
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameNotAToken;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameStringLiteral;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameTextBlock;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameWHITESPACE;
import java.util.ArrayList;
@@ -124,7 +125,7 @@
if (token.tokenType == TokenNameCOMMENT_LINE) {
handleSingleLineComment(token, index);
} else if (structure != null && !structure.isEmpty()) {
- handleMultiLineComment(token, index);
+ handleStructuredToken(token, index);
} else {
flushBuffer(token.originalStart);
if (token.isToEscape()) {
@@ -187,14 +188,17 @@
return;
}
+ boolean isTextBlock = token != null && token.tokenType == TokenNameTextBlock;
this.parent.counter = this.counter;
this.parent.bufferLineSeparator(null, false);
- this.parent.bufferIndent(this.parent.tm.get(this.parentTokenIndex), this.parentTokenIndex);
+ if (!(isTextBlock && emptyLine && !this.options.indent_empty_lines))
+ this.parent.bufferIndent(this.parent.tm.get(this.parentTokenIndex), this.parentTokenIndex);
this.counter = this.parent.counter;
+ if (isTextBlock)
+ return;
if (token != null && token.tokenType == TokenNameNotAToken)
return; // this is an unformatted block comment, don't force asterisk
-
if (getNext() == null && !emptyLine)
return; // this is the last token of block comment, asterisk is included
@@ -511,7 +515,7 @@
flushBuffer(lineComment.originalEnd + 1);
}
- private void handleMultiLineComment(Token comment, int index) {
+ private void handleStructuredToken(Token comment, int index) {
flushBuffer(comment.originalStart);
if (this.childBuilder == null) {
this.childBuilder = new TextEditsBuilder(this);
@@ -538,7 +542,7 @@
if (commentToken.tokenType == TokenNameCOMMENT_LINE) {
handleSingleLineComment(commentToken, this.tm.indexOf(commentToken));
} else {
- handleMultiLineComment(commentToken, this.tm.indexOf(commentToken));
+ handleStructuredToken(commentToken, this.tm.indexOf(commentToken));
}
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
index f054629..071f282 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
@@ -13,10 +13,10 @@
*******************************************************************************/
package org.eclipse.jdt.internal.formatter;
-import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK;
-import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_LINE;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameNotAToken;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameStringLiteral;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameTextBlock;
import java.util.ArrayList;
import java.util.HashMap;
@@ -252,9 +252,16 @@
}
if (traversed.getAlign() > 0)
this.counter = traversed.getAlign();
- List<Token> internalStructure = traversed.getInternalStructure();
- if (internalStructure != null && !internalStructure.isEmpty()) {
- assert traversed.tokenType == TokenNameCOMMENT_BLOCK || traversed.tokenType == TokenNameCOMMENT_JAVADOC;
+ if (traversed.tokenType == TokenNameTextBlock) {
+ List<Token> lines = traversed.getInternalStructure();
+ if (lines == null) {
+ this.counter = getLength(traversed, 0);
+ } else {
+ this.counter = traversed.getIndent() + lines.get(1).getIndent();
+ this.counter += getLength(lines.get(lines.size() - 1), this.counter);
+ }
+ } else if (traversed.isComment()) {
+ assert traversed.tokenType != TokenNameCOMMENT_LINE;
this.counter = TokenManager.this.commentWrapper.wrapMultiLineComment(traversed, this.counter, true,
this.isNLSTagInLine);
} else {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
index 4da2d1a..2fb28a1 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2018 Mateusz Matela and others.
+ * Copyright (c) 2014, 2019 Mateusz Matela and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -18,6 +18,7 @@
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_LINE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameTextBlock;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameWHITESPACE;
import java.util.ArrayDeque;
@@ -28,6 +29,7 @@
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions.Alignment;
import org.eclipse.jdt.internal.formatter.Token;
import org.eclipse.jdt.internal.formatter.TokenManager;
import org.eclipse.jdt.internal.formatter.TokenTraverser;
@@ -99,13 +101,14 @@
private class LineAnalyzer extends TokenTraverser {
+ private final TokenManager tm2 = WrapExecutor.this.tm;
private final CommentWrapExecutor commentWrapper;
private int lineIndent;
int firstPotentialWrap;
int activeTopPriorityWrap;
int minStructureDepth;
int extraLines;
- boolean lineExceeded;
+ int lineWidthExtent;
boolean isNextLineWrapped;
final List<Integer> extraLinesPerComment = new ArrayList<Integer>();
final List<Integer> topPriorityGroupStarts = new ArrayList<Integer>();
@@ -120,25 +123,28 @@
* @return index of the last token in line
*/
public int analyzeLine(int startIndex, int indent) {
- Token startToken = WrapExecutor.this.tm.get(startIndex);
+ Token startToken = this.tm2.get(startIndex);
assert startToken.getLineBreaksBefore() > 0;
- this.counter = WrapExecutor.this.tm.toIndent(indent, startToken.isWrappable());
+ this.counter = this.tm2.toIndent(indent, startToken.isWrappable());
this.lineIndent = indent;
this.firstPotentialWrap = -1;
this.activeTopPriorityWrap = -1;
this.minStructureDepth = Integer.MAX_VALUE;
this.extraLines = 0;
+ this.lineWidthExtent = 0;
this.isNextLineWrapped = false;
this.extraLinesPerComment.clear();
this.topPriorityGroupStarts.clear();
this.currentTopPriorityGroupEnd = -1;
this.isNLSTagInLine = false;
- int lastIndex = WrapExecutor.this.tm.traverse(startIndex, this);
+ int lastIndex = this.tm2.traverse(startIndex, this);
return lastIndex + (this.isNextLineWrapped ? 1 : 0);
}
@Override
protected boolean token(Token token, int index) {
+ setIndent(token, this.lineIndent);
+
if (token.hasNLSTag())
this.isNLSTagInLine = true;
@@ -167,19 +173,30 @@
this.counter++;
}
- if (!token.isComment()) {
- this.counter += WrapExecutor.this.tm.getLength(token, this.counter);
+ if (token.tokenType == TokenNameTextBlock) {
+ List<Token> lines = token.getInternalStructure();
+ if (lines == null) {
+ this.counter = this.tm2.getLength(token, 0);
+ } else {
+ this.lineWidthExtent = Math.max(this.lineWidthExtent,
+ this.counter + this.tm2.getLength(lines.get(0), this.counter));
+ this.counter = this.lineIndent + lines.get(1).getIndent();
+ lines.stream().skip(1).forEach(e -> this.lineWidthExtent = Math.max(this.lineWidthExtent,
+ this.counter + this.tm2.getLength(e, this.counter)));
+ this.counter += this.tm2.getLength(lines.get(lines.size() - 1), this.counter);
+ }
+ } else if (!token.isComment()) {
+ this.counter += this.tm2.getLength(token, this.counter);
} else if (token.tokenType != TokenNameCOMMENT_LINE) {
this.counter = this.commentWrapper.wrapMultiLineComment(token, this.counter, true, this.isNLSTagInLine);
this.extraLines += this.commentWrapper.getLinesCount() - 1;
this.extraLinesPerComment.add(this.commentWrapper.getLinesCount() - 1);
}
- this.lineExceeded = this.counter > WrapExecutor.this.options.page_width;
- if (this.lineExceeded && this.firstPotentialWrap >= 0) {
+ this.lineWidthExtent = Math.max(this.lineWidthExtent, this.counter);
+ if (this.lineWidthExtent > WrapExecutor.this.options.page_width && this.firstPotentialWrap >= 0) {
return false;
}
- token.setIndent(this.lineIndent);
if (getNext() != null && getNext().isWrappable() && getLineBreaksAfter() > 0) {
this.isNextLineWrapped = true;
@@ -188,9 +205,8 @@
return false;
}
- boolean isLineEnd = getLineBreaksAfter() > 0 || getNext() == null
- || (getNext().isNextLineOnWrap() && WrapExecutor.this.tm
- .get(WrapExecutor.this.tm.findFirstTokenInLine(index)).isWrappable());
+ boolean isLineEnd = getLineBreaksAfter() > 0 || getNext() == null || (getNext().isNextLineOnWrap()
+ && this.tm2.get(this.tm2.findFirstTokenInLine(index)).isWrappable());
return !isLineEnd;
}
@@ -199,18 +215,14 @@
return false;
for (int i = index - 1; i > wrapPolicy.wrapParentIndex; i--) {
- Token token = WrapExecutor.this.tm.get(i);
+ Token token = this.tm2.get(i);
if (token.isWrappable() && token.getWrapPolicy().wrapParentIndex == wrapPolicy.wrapParentIndex
- && (token.getLineBreaksBefore() > 0 || WrapExecutor.this.tm.get(i - 1).getLineBreaksAfter() > 0)) {
+ && (token.getLineBreaksBefore() > 0 || this.tm2.get(i - 1).getLineBreaksAfter() > 0)) {
return true;
}
}
return false;
}
-
- public int getLastPosition() {
- return this.counter;
- }
}
private class WrapsApplier extends TokenTraverser {
@@ -235,7 +247,7 @@
token.breakBefore();
newLine(token, index);
} else {
- token.setIndent(this.currentIndent);
+ setIndent(token, this.currentIndent);
}
return true;
}
@@ -244,7 +256,7 @@
while (!this.stack.isEmpty() && index > this.stack.peek().getWrapPolicy().groupEndIndex)
this.stack.pop();
if (token.getWrapPolicy() != null) {
- token.setIndent(getWrapIndent(token));
+ setIndent(token, getWrapIndent(token));
handleOnColumnIndent(index, token.getWrapPolicy());
this.stack.push(token);
} else if (this.stack.isEmpty()) {
@@ -253,7 +265,7 @@
}
this.currentIndent = this.stack.isEmpty() ? this.initialIndent : this.stack.peek().getIndent();
- token.setIndent(this.currentIndent);
+ setIndent(token, this.currentIndent);
this.nextWrap = findWrapsCached(index, this.currentIndent).nextWrap;
}
}
@@ -437,8 +449,8 @@
private WrapResult findWraps(int wrapTokenIndex, int indent) {
final int lastIndex = this.lineAnalyzer.analyzeLine(wrapTokenIndex, indent);
final boolean nextLineWrapped = this.lineAnalyzer.isNextLineWrapped;
- final boolean wrapRequired = this.lineAnalyzer.lineExceeded || nextLineWrapped;
- int lineOverflow = Math.max(0, this.lineAnalyzer.getLastPosition() - this.options.page_width);
+ int lineOverflow = Math.max(0, this.lineAnalyzer.lineWidthExtent - this.options.page_width);
+ final boolean wrapRequired = lineOverflow > 0 || nextLineWrapped;
int extraLines = this.lineAnalyzer.extraLines;
final int firstPotentialWrap = this.lineAnalyzer.firstPotentialWrap;
final int activeTopPriorityWrap = this.lineAnalyzer.activeTopPriorityWrap;
@@ -662,4 +674,25 @@
wrapIndent += policy.extraIndent;
return this.tm.toIndent(wrapIndent, true);
}
+
+ void setIndent(Token token, int indent) {
+ token.setIndent(indent);
+
+ List<Token> structure = token.getInternalStructure();
+ if (token.tokenType == TokenNameTextBlock && structure != null) {
+ int lineIndent;
+ int indentOption = this.options.text_block_indentation;
+ if (indentOption == Alignment.M_INDENT_BY_ONE) {
+ lineIndent = 1 * this.options.indentation_size;
+ } else if (indentOption == Alignment.M_INDENT_DEFAULT) {
+ lineIndent = this.options.continuation_indentation * this.options.indentation_size;
+ } else if (indentOption == Alignment.M_INDENT_ON_COLUMN) {
+ lineIndent = this.tm.toIndent(this.tm.getPositionInLine(this.tm.indexOf(token)), true) - indent;
+ } else {
+ assert false;
+ lineIndent = 0;
+ }
+ structure.stream().skip(1).forEach(t -> t.setIndent(lineIndent));
+ }
+ }
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
index 678cc88..6e10134 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
@@ -1416,7 +1416,7 @@
isNLSTagInLine = true;
}
List<Token> structure = token.getInternalStructure();
- if (structure != null && !structure.isEmpty() && !isNLSTagInLine) {
+ if (token.isComment() && structure != null && !structure.isEmpty() && !isNLSTagInLine) {
int startPosition = this.tm.getPositionInLine(i);
if (token.tokenType == TokenNameCOMMENT_LINE) {
commentWrapper.wrapLineComment(token, startPosition);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IModuleDescription.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IModuleDescription.java
index 5455e73..bf5eed5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IModuleDescription.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IModuleDescription.java
@@ -83,4 +83,12 @@
default boolean isAutoModule() {
return false;
}
+
+ /**
+ * @return true if this module is a system module, else false
+ * @since 3.20
+ */
+ default boolean isSystemModule() {
+ return false;
+ }
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/provisional/JavaModelAccess.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/provisional/JavaModelAccess.java
index 73e7644..0bdc298 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/provisional/JavaModelAccess.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/provisional/JavaModelAccess.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017, 2018 GK Software SE, and others.
+ * Copyright (c) 2017, 2019 GK Software SE, and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -71,7 +71,9 @@
* @param module the module being queried about
* @return {@code true} iff the module is defined in the system library (also known as JRE).
* @since 3.18
+ * @deprecated please use {@link IModuleDescription#isSystemModule()}
*/
+ @Deprecated
public static boolean isSystemModule(IModuleDescription module) {
IPackageFragmentRoot pfr = (IPackageFragmentRoot) module.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
return pfr instanceof JrtPackageFragmentRoot;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryModule.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryModule.java
index 2d6bffd..e2bb12e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryModule.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryModule.java
@@ -19,6 +19,7 @@
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
@@ -65,6 +66,11 @@
return true;
}
@Override
+ public boolean isSystemModule() {
+ IPackageFragmentRoot pfr = (IPackageFragmentRoot) getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+ return pfr instanceof JrtPackageFragmentRoot;
+ }
+ @Override
public int getFlags() throws JavaModelException {
if (getModuleInfo().isOpen())
return ClassFileConstants.ACC_OPEN;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index 784cee9..8ae86f7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -1291,6 +1291,13 @@
this.projectCachesToReset.add(project);
break;
+
+ case IJavaElement.COMPILATION_UNIT :
+ if (element.getElementName().equals(new String(TypeConstants.MODULE_INFO_FILE_NAME))) {
+ this.projectCachesToReset.add(element.getJavaProject()); // change unnamed -> named
+ }
+
+ break;
}
}
}
@@ -1387,6 +1394,13 @@
this.projectCachesToReset.add(project);
break;
+
+ case IJavaElement.COMPILATION_UNIT :
+ if (element.getElementName().equals(new String(TypeConstants.MODULE_INFO_FILE_NAME))) {
+ this.projectCachesToReset.add(element.getJavaProject()); // change named -> unnamed
+ }
+
+ break;
}
}
/*
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index 9f1a666..6e692e0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -23,6 +23,7 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -31,6 +32,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.jar.Manifest;
@@ -403,30 +405,35 @@
HashSet traversed = new HashSet();
// compute cycle participants
- ArrayList prereqChain = new ArrayList();
+ List<IPath> prereqChain = new ArrayList<>();
+ Map<IPath,List<CycleInfo>> cyclesPerProject = new HashMap<>();
for (int i = 0; i < length; i++){
if (hasJavaNature(rscProjects[i])) {
JavaProject project = (projects[i] = (JavaProject)JavaCore.create(rscProjects[i]));
if (!traversed.contains(project.getPath())){
prereqChain.clear();
- project.updateCycleParticipants(prereqChain, cycleParticipants, workspaceRoot, traversed, preferredClasspaths);
+ project.updateCycleParticipants(prereqChain, cycleParticipants, cyclesPerProject, workspaceRoot, traversed, preferredClasspaths);
}
}
}
//System.out.println("updateAllCycleMarkers: " + (System.currentTimeMillis() - start) + " ms");
- String cycleString = cycleParticipants.stream()
- .map(path -> workspaceRoot.findMember(path))
- .filter(r -> r != null)
- .map(r -> JavaCore.create((IProject)r))
- .filter(p -> p != null)
- .map(p -> p.getElementName())
- .collect(Collectors.joining(", ")); //$NON-NLS-1$
-
for (int i = 0; i < length; i++){
JavaProject project = projects[i];
if (project != null) {
- if (cycleParticipants.contains(project.getPath())) {
+ List<CycleInfo> cycles = cyclesPerProject.get(project.getPath());
+ if (cycles != null) {
+ StringBuilder cycleString = new StringBuilder();
+ boolean first = true;
+ for (CycleInfo cycleInfo : cycles) {
+ if (!first) cycleString.append('\n');
+ cycleString.append(cycleInfo.pathToCycleAsString());
+ cycleString.append("->{"); //$NON-NLS-1$
+ cycleString.append(cycleInfo.cycleAsString());
+ cycleString.append('}');
+ first = false;
+ }
+
IMarker cycleMarker = project.getCycleMarker();
String circularCPOption = project.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true);
int circularCPSeverity = JavaCore.ERROR.equals(circularCPOption) ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING;
@@ -439,7 +446,7 @@
}
String existingMessage = cycleMarker.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
String newMessage = new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE,
- project, cycleString).getMessage();
+ project, cycleString.toString()).getMessage();
if (!newMessage.equals(existingMessage)) {
cycleMarker.setAttribute(IMarker.MESSAGE, newMessage);
}
@@ -449,7 +456,7 @@
} else {
// create new marker
project.createClasspathProblemMarker(
- new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project, cycleString));
+ new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project, cycleString.toString()));
}
} else {
project.flushClasspathProblemMarkers(true, false, false);
@@ -2045,12 +2052,11 @@
}
continue;
} else if (token == MementoTokenizer.CLASSPATH_ATTRIBUTE) {
- // PFR memento is optionally trailed by all extra classpath attributes ("=/name=/value"):
- String name = memento.nextToken();
- String separator = memento.nextToken();
- assert separator == MementoTokenizer.CLASSPATH_ATTRIBUTE;
- String value = memento.nextToken();
+ // PFR memento is optionally trailed by all extra classpath attributes ("=/name=/value=/"):
+ String name = memento.getStringDelimitedBy(MementoTokenizer.CLASSPATH_ATTRIBUTE);
+ String value = memento.getStringDelimitedBy(MementoTokenizer.CLASSPATH_ATTRIBUTE);
attributes.add(new ClasspathAttribute(name, value));
+ token = null; // consumed
continue;
}
rootPath += token;
@@ -2613,7 +2619,7 @@
LinkedHashSet cycleParticipants = new LinkedHashSet();
HashMap preferredClasspaths = new HashMap(1);
preferredClasspaths.put(this, preferredClasspath);
- updateCycleParticipants(new ArrayList(2), cycleParticipants, ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2), preferredClasspaths);
+ updateCycleParticipants(new ArrayList(2), cycleParticipants, new HashMap<>(), ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2), preferredClasspaths);
return !cycleParticipants.isEmpty();
}
@@ -3684,6 +3690,48 @@
}
}
+ /** internal structure for detected build path cycles. */
+ static class CycleInfo {
+
+ private List<IPath> pathToCycle;
+ public final List<IPath> cycle;
+
+ public CycleInfo(List<IPath> pathToCycle, List<IPath> cycle) {
+ this.pathToCycle = new ArrayList<>(pathToCycle);
+ this.cycle = new ArrayList<>(cycle);
+ }
+
+ public static Optional<CycleInfo> findCycleContaining(Collection<List<CycleInfo>> infos, IPath path) {
+ return infos.stream().flatMap(l -> l.stream()).filter(c -> c.cycle.contains(path)).findAny();
+ }
+
+ public static void add(IPath project, List<IPath> prefix, List<IPath> cycle, Map<IPath, List<CycleInfo>> cyclesPerProject) {
+ List<CycleInfo> list = cyclesPerProject.get(project);
+ if (list == null) {
+ cyclesPerProject.put(project, list = new ArrayList<>());
+ } else {
+ for (CycleInfo cycleInfo: list) {
+ if (cycleInfo.cycle.equals(cycle)) {
+ // same cycle: use the shorter prefix:
+ if (cycleInfo.pathToCycle.size() > prefix.size()) {
+ cycleInfo.pathToCycle.clear();
+ cycleInfo.pathToCycle.addAll(prefix);
+ }
+ return;
+ }
+ }
+ }
+ list.add(new CycleInfo(prefix, cycle));
+ }
+
+ public String pathToCycleAsString() {
+ return this.pathToCycle.stream().map(IPath::lastSegment).collect(Collectors.joining(", ")); //$NON-NLS-1$
+ }
+
+ public String cycleAsString() {
+ return this.cycle.stream().map(IPath::lastSegment).collect(Collectors.joining(", ")); //$NON-NLS-1$
+ }
+ }
/**
* If a cycle is detected, then cycleParticipants contains all the paths of projects involved in this cycle (directly and indirectly),
* no cycle if the set is empty (and started empty)
@@ -3694,8 +3742,9 @@
* @param preferredClasspaths Map
*/
public void updateCycleParticipants(
- ArrayList prereqChain,
+ List<IPath> prereqChain,
LinkedHashSet cycleParticipants,
+ Map<IPath,List<CycleInfo>> cyclesPerProject,
IWorkspaceRoot workspaceRoot,
HashSet traversed,
Map preferredClasspaths){
@@ -3712,19 +3761,60 @@
if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){
IPath prereqProjectPath = entry.getPath();
- int index = cycleParticipants.contains(prereqProjectPath) ? 0 : prereqChain.indexOf(prereqProjectPath);
- if (index >= 0) { // refer to cycle, or in cycle itself
- for (int size = prereqChain.size(); index < size; index++) {
- cycleParticipants.add(prereqChain.get(index));
+ int prereqIndex = prereqChain.indexOf(prereqProjectPath);
+ if (prereqIndex > -1) {
+ // record a new cycle:
+ List<IPath> cycle = prereqChain.subList(prereqIndex, prereqChain.size());
+ // empty-prefix CycleInfo for all members of the cycle:
+ List<IPath> prefix = Collections.emptyList();
+ for (IPath prjInCycle : cycle) {
+ CycleInfo.add(prjInCycle, prefix, cycle, cyclesPerProject);
}
+ // also record with all members of the prereqChain with transitive dependency on the cycle:
+ for (int j = 0; j < prereqIndex; j++) {
+ CycleInfo.add(prereqChain.get(j), prereqChain.subList(j, prereqIndex), cycle, cyclesPerProject);
+ }
+ } else if (cycleParticipants.contains(prereqProjectPath)) {
+ // record existing cycle as dependency of each project in prereqChain:
+ Optional<CycleInfo> cycle = CycleInfo.findCycleContaining(cyclesPerProject.values(), prereqProjectPath);
+ if (cycle.isPresent()) {
+ List<IPath> theCycle = cycle.get().cycle;
+ for (int j = 0; j < prereqChain.size(); j++) {
+ IPath prereq = prereqChain.get(j);
+ List<IPath> prereqSubList = prereqChain.subList(j, prereqChain.size());
+ int joinIndex1 = theCycle.indexOf(prereq);
+ if (joinIndex1 != -1) {
+ // prereqSubList -> prereqProjectPath + theCycle create a new cycle
+ List<IPath> newCycle = new ArrayList<>(prereqSubList);
+ int joinIndex2 = theCycle.indexOf(prereqProjectPath); // always != -1 since that's how we found 'cycle'
+ while (joinIndex2 != joinIndex1) {
+ newCycle.add(theCycle.get(joinIndex2++));
+ if (joinIndex2 == theCycle.size())
+ joinIndex2 = 0; // it's a cycle :)
+ }
+ for (IPath newMember : newCycle) {
+ CycleInfo.add(newMember, Collections.emptyList(), newCycle, cyclesPerProject);
+ }
+ break; // the rest of prereqChain is already included via newCycle
+ } else {
+ CycleInfo.add(prereq, prereqSubList, theCycle, cyclesPerProject);
+ }
+ }
+ }
+ prereqIndex = 0;
} else {
if (!traversed.contains(prereqProjectPath)) {
IResource member = workspaceRoot.findMember(prereqProjectPath);
if (member != null && member.getType() == IResource.PROJECT){
JavaProject javaProject = (JavaProject)JavaCore.create((IProject)member);
- javaProject.updateCycleParticipants(prereqChain, cycleParticipants, workspaceRoot, traversed, preferredClasspaths);
+ javaProject.updateCycleParticipants(prereqChain, cycleParticipants, cyclesPerProject, workspaceRoot, traversed, preferredClasspaths);
}
}
+ continue;
+ }
+ // fall through from both positive branches above
+ for (int index = prereqIndex, size = prereqChain.size(); index < size; index++) {
+ cycleParticipants.add(prereqChain.get(index));
}
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index 1d8f9c8..8a93a53 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -515,6 +515,7 @@
escapeMementoName(buff, attribute.getName());
appendEscapedDelimiter(buff, JavaElement.JEM_PACKAGEFRAGMENTROOT);
escapeMementoName(buff, attribute.getValue());
+ appendEscapedDelimiter(buff, JavaElement.JEM_PACKAGEFRAGMENTROOT);
}
}
} catch (JavaModelException e) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
index f210573..dc6fce9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
@@ -796,7 +796,7 @@
*/
void mustPropagateStructuralChanges() {
LinkedHashSet cycleParticipants = new LinkedHashSet(3);
- this.javaProject.updateCycleParticipants(new ArrayList(), cycleParticipants, this.workspaceRoot, new HashSet(3), null);
+ this.javaProject.updateCycleParticipants(new ArrayList(), cycleParticipants, new HashMap<>(), this.workspaceRoot, new HashSet(3), null);
IPath currentPath = this.javaProject.getPath();
Iterator i= cycleParticipants.iterator();
while (i.hasNext()) {
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 b610afd..1c53ce6 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
@@ -161,4 +161,12 @@
}
}
+ public String getStringDelimitedBy(String delimiter) {
+ String token = nextToken();
+ if (token == delimiter)
+ return ""; //$NON-NLS-1$
+ String separator = nextToken();
+ assert separator == delimiter;
+ return token;
+ }
}
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 ec02740..725a1cc 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
@@ -150,7 +150,7 @@
classpath_cannotUseLibraryAsOutput = Source folder ''{0}'' in project ''{2}'' cannot output to library ''{1}''
classpath_closedProject = Required project ''{0}'' needs to be open
classpath_couldNotWriteClasspathFile = Could not write ''.classpath'' file of project ''{0}'': {1}
-classpath_cycle = A cycle was detected in the build path of project ''{0}''. The cycle consists of projects '{'{1}'}'
+classpath_cycle = One or more cycles were detected in the build path of project ''{0}''. The paths towards the cycle and cycle are:\n{1}
classpath_duplicateEntryPath = Build path contains duplicate entry: ''{0}'' for project ''{1}''
classpath_illegalContainerPath = Illegal classpath container path: ''{0}'' in project ''{1}'', must have at least one segment (containerID+hints)
classpath_illegalEntryInClasspathFile = Illegal entry in ''.classpath'' of project ''{0}'' file: {1}