8159027: JShell API: SourceCodeAnalysis.Suggestion has constructor, ...
Reviewed-by: jlahoda
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Jul 05 22:05:29 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon Aug 15 11:39:53 2016 -0700
@@ -923,7 +923,7 @@
for (String alternative : alternatives) {
if (alternative.startsWith(input)) {
- result.add(new Suggestion(alternative, false));
+ result.add(new ArgSuggestion(alternative));
}
}
@@ -951,7 +951,7 @@
List<Suggestion> result = new ArrayList<>();
try (Stream<Path> dir = Files.list(current)) {
dir.filter(f -> accept.test(f) && f.getFileName().toString().startsWith(prefix))
- .map(f -> new Suggestion(f.getFileName() + (Files.isDirectory(f) ? "/" : ""), false))
+ .map(f -> new ArgSuggestion(f.getFileName() + (Files.isDirectory(f) ? "/" : "")))
.forEach(result::add);
} catch (IOException ex) {
//ignore...
@@ -959,7 +959,7 @@
if (path.isEmpty()) {
StreamSupport.stream(FileSystems.getDefault().getRootDirectories().spliterator(), false)
.filter(root -> accept.test(root) && root.toString().startsWith(prefix))
- .map(root -> new Suggestion(root.toString(), false))
+ .map(root -> new ArgSuggestion(root.toString()))
.forEach(result::add);
}
anchor[0] = path.length();
@@ -981,7 +981,7 @@
? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
: Stream.of(String.valueOf(k.id())))
.filter(k -> k.startsWith(prefix))
- .map(k -> new Suggestion(k, false))
+ .map(k -> new ArgSuggestion(k))
.collect(Collectors.toList());
};
}
@@ -1146,7 +1146,7 @@
.filter(cmd -> cmd.kind.shouldSuggestCompletions)
.map(cmd -> cmd.command)
.filter(key -> key.startsWith(prefix))
- .map(key -> new Suggestion(key + " ", false));
+ .map(key -> new ArgSuggestion(key + " "));
anchor[0] = 0;
} else {
String arg = prefix.substring(space + 1);
@@ -2457,6 +2457,42 @@
this.tid = tid;
}
}
+
+ private static class ArgSuggestion implements Suggestion {
+
+ private final String continuation;
+
+ /**
+ * Create a {@code Suggestion} instance.
+ *
+ * @param continuation a candidate continuation of the user's input
+ */
+ public ArgSuggestion(String continuation) {
+ this.continuation = continuation;
+ }
+
+ /**
+ * The candidate continuation of the given user's input.
+ *
+ * @return the continuation string
+ */
+ @Override
+ public String continuation() {
+ return continuation;
+ }
+
+ /**
+ * Indicates whether input continuation matches the target type and is thus
+ * more likely to be the desired continuation. A matching continuation is
+ * preferred.
+ *
+ * @return {@code false}, non-types analysis
+ */
+ @Override
+ public boolean matchesType() {
+ return false;
+ }
+ }
}
abstract class NonInteractiveIOContext extends IOContext {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java Wed Jul 05 22:05:29 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java Mon Aug 15 11:39:53 2016 -0700
@@ -144,30 +144,16 @@
/**
* The result of {@code analyzeCompletion(String input)}.
- * Describes the completeness and position of the first snippet in the given input.
+ * Describes the completeness of the first snippet in the given input.
*/
- public static class CompletionInfo {
-
- private final Completeness completeness;
- private final int unitEndPos;
- private final String source;
- private final String remaining;
-
- CompletionInfo(Completeness completeness, int unitEndPos, String source, String remaining) {
- this.completeness = completeness;
- this.unitEndPos = unitEndPos;
- this.source = source;
- this.remaining = remaining;
- }
+ public interface CompletionInfo {
/**
* The analyzed completeness of the input.
*
* @return an enum describing the completeness of the input string.
*/
- public Completeness completeness() {
- return completeness;
- }
+ Completeness completeness();
/**
* Input remaining after the complete part of the source.
@@ -175,9 +161,7 @@
* @return the portion of the input string that remains after the
* complete Snippet
*/
- public String remaining() {
- return remaining;
- }
+ String remaining();
/**
* Source code for the first Snippet of code input. For example, first
@@ -186,18 +170,7 @@
*
* @return the source of the first encountered Snippet
*/
- public String source() {
- return source;
- }
-
- /**
- * The end of the first Snippet of source.
- *
- * @return the position of the end of the first Snippet in the input.
- */
- public int unitEndPos() {
- return unitEndPos;
- }
+ String source();
}
/**
@@ -272,30 +245,14 @@
/**
* A candidate for continuation of the given user's input.
*/
- public static class Suggestion {
-
- private final String continuation;
- private final boolean matchesType;
-
- /**
- * Create a {@code Suggestion} instance.
- *
- * @param continuation a candidate continuation of the user's input
- * @param matchesType does the candidate match the target type
- */
- public Suggestion(String continuation, boolean matchesType) {
- this.continuation = continuation;
- this.matchesType = matchesType;
- }
+ public interface Suggestion {
/**
* The candidate continuation of the given user's input.
*
* @return the continuation string
*/
- public String continuation() {
- return continuation;
- }
+ String continuation();
/**
* Indicates whether input continuation matches the target type and is thus
@@ -305,9 +262,7 @@
* @return {@code true} if this suggested continuation matches the
* target type; otherwise {@code false}
*/
- public boolean matchesType() {
- return matchesType;
- }
+ boolean matchesType();
}
/**
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Jul 05 22:05:29 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Mon Aug 15 11:39:53 2016 -0700
@@ -171,13 +171,13 @@
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');
+ return new CompletionInfoImpl(DEFINITELY_INCOMPLETE, null, srcInput + '\n');
}
String cleared = mcm.cleared();
String trimmedInput = Util.trimEnd(cleared);
if (trimmedInput.isEmpty()) {
// Just comment or empty
- return new CompletionInfo(Completeness.EMPTY, srcInput.length(), srcInput, "");
+ return new CompletionInfoImpl(Completeness.EMPTY, srcInput, "");
}
CaInfo info = ca.scan(trimmedInput);
Completeness status = info.status;
@@ -195,12 +195,12 @@
+ mcm.mask().substring(nonCommentNonWhiteLength);
proc.debug(DBG_COMPA, "Complete: %s\n", compileSource);
proc.debug(DBG_COMPA, " nothing remains.\n");
- return new CompletionInfo(status, unitEndPos, compileSource, "");
+ return new CompletionInfoImpl(status, compileSource, "");
} else {
String remain = srcInput.substring(unitEndPos);
proc.debug(DBG_COMPA, "Complete: %s\n", src);
proc.debug(DBG_COMPA, " remaining: %s\n", remain);
- return new CompletionInfo(status, unitEndPos, src, remain);
+ return new CompletionInfoImpl(status, src, remain);
}
case COMPLETE_WITH_SEMI:
// The unit is the whole non-coment/white input plus semicolon
@@ -209,19 +209,19 @@
+ mcm.mask().substring(nonCommentNonWhiteLength);
proc.debug(DBG_COMPA, "Complete with semi: %s\n", compileSource);
proc.debug(DBG_COMPA, " nothing remains.\n");
- return new CompletionInfo(status, unitEndPos, compileSource, "");
+ return new CompletionInfoImpl(status, compileSource, "");
case DEFINITELY_INCOMPLETE:
proc.debug(DBG_COMPA, "Incomplete: %s\n", srcInput);
- return new CompletionInfo(status, unitEndPos, null, srcInput + '\n');
+ return new CompletionInfoImpl(status, null, srcInput + '\n');
case CONSIDERED_INCOMPLETE:
proc.debug(DBG_COMPA, "Considered incomplete: %s\n", srcInput);
- return new CompletionInfo(status, unitEndPos, null, srcInput + '\n');
+ return new CompletionInfoImpl(status, null, srcInput + '\n');
case EMPTY:
proc.debug(DBG_COMPA, "Detected empty: %s\n", srcInput);
- return new CompletionInfo(status, unitEndPos, srcInput, "");
+ return new CompletionInfoImpl(status, srcInput, "");
case UNKNOWN:
proc.debug(DBG_COMPA, "Detected error: %s\n", srcInput);
- return new CompletionInfo(status, unitEndPos, srcInput, "");
+ return new CompletionInfoImpl(status, srcInput, "");
}
throw new InternalError();
}
@@ -665,7 +665,7 @@
if (c.getKind() == ElementKind.CONSTRUCTOR || c.getKind() == ElementKind.METHOD) {
simpleName += paren.apply(hasParams.contains(simpleName));
}
- result.add(new Suggestion(simpleName, smart.test(c)));
+ result.add(new SuggestionImpl(simpleName, smart.test(c)));
}
}
@@ -1700,4 +1700,98 @@
}
}
}
+
+ /**
+ * A candidate for continuation of the given user's input.
+ */
+ private static class SuggestionImpl implements Suggestion {
+
+ private final String continuation;
+ private final boolean matchesType;
+
+ /**
+ * Create a {@code Suggestion} instance.
+ *
+ * @param continuation a candidate continuation of the user's input
+ * @param matchesType does the candidate match the target type
+ */
+ public SuggestionImpl(String continuation, boolean matchesType) {
+ this.continuation = continuation;
+ this.matchesType = matchesType;
+ }
+
+ /**
+ * The candidate continuation of the given user's input.
+ *
+ * @return the continuation string
+ */
+ @Override
+ public String continuation() {
+ return continuation;
+ }
+
+ /**
+ * Indicates whether input continuation matches the target type and is thus
+ * more likely to be the desired continuation. A matching continuation is
+ * preferred.
+ *
+ * @return {@code true} if this suggested continuation matches the
+ * target type; otherwise {@code false}
+ */
+ @Override
+ public boolean matchesType() {
+ return matchesType;
+ }
+ }
+
+ /**
+ * The result of {@code analyzeCompletion(String input)}.
+ * Describes the completeness and position of the first snippet in the given input.
+ */
+ private static class CompletionInfoImpl implements CompletionInfo {
+
+ private final Completeness completeness;
+ private final String source;
+ private final String remaining;
+
+ CompletionInfoImpl(Completeness completeness, String source, String remaining) {
+ this.completeness = completeness;
+ this.source = source;
+ this.remaining = remaining;
+ }
+
+ /**
+ * The analyzed completeness of the input.
+ *
+ * @return an enum describing the completeness of the input string.
+ */
+ @Override
+ public Completeness completeness() {
+ return completeness;
+ }
+
+ /**
+ * Input remaining after the complete part of the source.
+ *
+ * @return the portion of the input string that remains after the
+ * complete Snippet
+ */
+ @Override
+ public String remaining() {
+ return remaining;
+ }
+
+ /**
+ * Source code for the first Snippet of code input. For example, first
+ * statement, or first method declaration. Trailing semicolons will be
+ * added, as needed.
+ *
+ * @return the source of the first encountered Snippet
+ */
+ @Override
+ public String source() {
+ return source;
+ }
+ }
+
}
--- a/langtools/test/jdk/jshell/CompletenessStressTest.java Wed Jul 05 22:05:29 2017 +0200
+++ b/langtools/test/jdk/jshell/CompletenessStressTest.java Mon Aug 15 11:39:53 2016 -0700
@@ -253,10 +253,8 @@
writer.write(String.format("Empty statement: row %d, column %d: -- %s\n",
start, end, unit));
} else {
- String oops = unit.substring(max(0, ci.unitEndPos() - 10), ci.unitEndPos()) + "|||" +
- unit.substring(ci.unitEndPos(), min(unit.length(), ci.unitEndPos() + 10));
writer.write(String.format("Expected %s got %s: '%s' row %d, column %d: -- %s\n",
- expected, ci.completeness(), oops, row, column, unit));
+ expected, ci.completeness(), unit, row, column, unit));
return false;
}
}