8223782: jshell parser should handle Text Blocks
Summary: Completion analysis should detect text blocks properly.
Reviewed-by: jlaskey, rfield
--- a/src/jdk.jshell/share/classes/jdk/jshell/MaskCommentsAndModifiers.java Thu Jun 06 09:30:00 2019 +0200
+++ b/src/jdk.jshell/share/classes/jdk/jshell/MaskCommentsAndModifiers.java Fri Jun 07 10:09:41 2019 +0200
@@ -139,10 +139,36 @@
}
}
+ @SuppressWarnings("fallthrough")
private void next() {
switch (c) {
- case '\'':
case '"': {
+ int pos = next - 1;
+ maskModifiers = false;
+ if (str.startsWith("\"\"\"", next - 1)) {
+ //text block/multi-line string literal:
+ int searchPoint = next + 2;
+ int end;
+ while ((end = str.indexOf("\"\"\"", searchPoint)) != (-1)) {
+ if (str.charAt(end - 1) != '\\')
+ break;
+ searchPoint = end + 1;
+ }
+ if (end == (-1)) {
+ openToken = true;
+ end = str.length();
+ } else {
+ end += 3;
+ }
+ write(c);
+ while (next < end) {
+ write(read());
+ }
+ break;
+ }
+ }
+ //intentional fall-through:
+ case '\'': {
maskModifiers = false;
write(c);
int match = c;
@@ -155,37 +181,6 @@
write(c); // write match // line-end
break;
}
- case '`': { // RawString
- maskModifiers = false;
- int backtickCount = 0;
- do {
- write(c);
- ++backtickCount;
- read();
- } while (c == '`');
- while (true) {
- if (c == '`') {
- int cnt = 0;
- do {
- write(c);
- ++cnt;
- read();
- } while (c == '`');
- if (cnt == backtickCount) {
- unread();
- break;
- }
- } else {
- write(c);
- if (c < 0) {
- openToken = true;
- break;
- }
- read();
- }
- }
- break;
- }
case '/':
read();
switch (c) {
--- a/test/langtools/jdk/jshell/CompletenessTest.java Thu Jun 06 09:30:00 2019 +0200
+++ b/test/langtools/jdk/jshell/CompletenessTest.java Fri Jun 07 10:09:41 2019 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842 8182268
+ * @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842 8182268 8223782
* @summary Test SourceCodeAnalysis
* @build KullaTesting TestingInputStream
* @run testng CompletenessTest
@@ -328,6 +328,18 @@
assertStatus("/** test", DEFINITELY_INCOMPLETE, null);
}
+ public void testTextBlocks() {
+ assertStatus("\"\"\"", DEFINITELY_INCOMPLETE, null);
+ assertStatus("\"\"\"broken", DEFINITELY_INCOMPLETE, null);
+ assertStatus("\"\"\"\ntext", DEFINITELY_INCOMPLETE, null);
+ assertStatus("\"\"\"\ntext\"\"", DEFINITELY_INCOMPLETE, "\"\"\"\ntext\"\"\"");
+ assertStatus("\"\"\"\ntext\"\"\"", COMPLETE, "\"\"\"\ntext\"\"\"");
+ assertStatus("\"\"\"\ntext\\\"\"\"\"", COMPLETE, "\"\"\"\ntext\\\"\"\"\"");
+ assertStatus("\"\"\"\ntext\\\"\"\"", DEFINITELY_INCOMPLETE, null);
+ assertStatus("\"\"\"\ntext\\\"\"\"\\\"\"\"", DEFINITELY_INCOMPLETE, null);
+ assertStatus("\"\"\"\ntext\\\"\"\"\\\"\"\"\"\"\"", COMPLETE, "\"\"\"\ntext\\\"\"\"\\\"\"\"\"\"\"");
+ }
+
public void testMiscSource() {
assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug
assertStatus("int m() {} dfd", COMPLETE, "int m() {}");
--- a/test/langtools/jdk/jshell/CompletionSuggestionTest.java Thu Jun 06 09:30:00 2019 +0200
+++ b/test/langtools/jdk/jshell/CompletionSuggestionTest.java Fri Jun 07 10:09:41 2019 +0200
@@ -107,6 +107,8 @@
assertCompletionIncludesExcludes("new C() {}.|",
new HashSet<>(Arrays.asList("method()", "number")),
new HashSet<>(Arrays.asList("D", "E", "F", "H", "class")));
+ assertCompletion("\"\".leng|", "length()");
+ assertCompletion("\"\"\"\n\"\"\".leng|", "length()");
}
public void testStartOfExpression() {