8131024: JShell: multi-line comment not detected as incomplete

Reviewed-by: vromero
This commit is contained in:
Robert Field 2016-06-02 12:52:00 -07:00
parent 32e8e4695d
commit 9e48d360f5
4 changed files with 46 additions and 9 deletions

View File

@ -40,35 +40,52 @@ class MaskCommentsAndModifiers {
Stream.of( "public", "protected", "private", "static", "final" )
.collect( Collectors.toSet() );
// Builder to accumulate non-masked characters
private final StringBuilder sbCleared = new StringBuilder();
// Builder to accumulate masked characters
private final StringBuilder sbMask = new StringBuilder();
// The input string
private final String str;
// Entire input string length
private final int length;
// Should leading modifiers be masked away
private final boolean maskModifiers;
// The next character
private int next = 0;
private boolean wasMasked = false;
// We have past any point where a top-level modifier could be
private boolean inside = false;
// Does the string end with an unclosed '/*' style comment?
private boolean openComment = false;
@SuppressWarnings("empty-statement")
public MaskCommentsAndModifiers(String s, boolean maskModifiers) {
MaskCommentsAndModifiers(String s, boolean maskModifiers) {
this.str = s;
this.length = s.length();
this.maskModifiers = maskModifiers;
do { } while (next());
}
public String cleared() {
String cleared() {
return sbCleared.toString();
}
public String mask() {
String mask() {
return sbMask.toString();
}
public boolean wasMasked() {
return wasMasked;
boolean endsWithOpenComment() {
return openComment;
}
/****** private implementation methods ******/
/**
* Read the next character
*/
@ -89,7 +106,6 @@ class MaskCommentsAndModifiers {
}
private void writeMask(int ch) {
wasMasked = true;
write(sbMask, ch);
write(sbCleared, Character.isWhitespace(ch) ? ch : ' ');
}
@ -147,6 +163,7 @@ class MaskCommentsAndModifiers {
int prevc = 0;
while ((c = read()) != '/' || prevc != '*') {
if (c < 0) {
openComment = true;
return false;
}
writeMask(c);

View File

@ -130,6 +130,7 @@ import javax.tools.ToolProvider;
import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
import static java.util.stream.Collectors.joining;
import static jdk.jshell.SourceCodeAnalysis.Completeness.DEFINITELY_INCOMPLETE;
/**
* The concrete implementation of SourceCodeAnalysis.
@ -165,6 +166,10 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
@Override
public CompletionInfo analyzeCompletion(String srcInput) {
MaskCommentsAndModifiers mcm = new MaskCommentsAndModifiers(srcInput, false);
if (mcm.endsWithOpenComment()) {
proc.debug(DBG_COMPA, "Incomplete (open comment): %s\n", srcInput);
return new CompletionInfo(DEFINITELY_INCOMPLETE, srcInput.length(), null, srcInput + '\n');
}
String cleared = mcm.cleared();
String trimmedInput = Util.trimEnd(cleared);
if (trimmedInput.isEmpty()) {

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8149524
* @bug 8149524 8131024
* @summary Test SourceCodeAnalysis
* @build KullaTesting TestingInputStream
* @run testng CompletenessTest
@ -285,6 +285,11 @@ public class CompletenessTest extends KullaTesting {
assertStatus("\"abc\\", UNKNOWN, "\"abc\\");
}
public void testOpenComment() {
assertStatus("int xx; /* hello", DEFINITELY_INCOMPLETE, null);
assertStatus("/** test", DEFINITELY_INCOMPLETE, null);
}
public void testMiscSource() {
assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug
assertStatus("int m() {} dfd", COMPLETE, "int m() {}");

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8153716 8143955 8151754 8150382 8153920 8156910
* @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024
* @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@ -61,6 +61,16 @@ public class ToolSimpleTest extends ReplToolTesting {
);
}
public void testOpenComment() {
test(
(a) -> assertCommand(a, "int z = /* blah", ""),
(a) -> assertCommand(a, "baz */ 5", "z ==> 5"),
(a) -> assertCommand(a, "/** hoge ", ""),
(a) -> assertCommand(a, "baz **/", ""),
(a) -> assertCommand(a, "int v", "v ==> 0")
);
}
public void oneLineOfError() {
test(
(a) -> assertCommand(a, "12+", null),