8159027: JShell API: SourceCodeAnalysis.Suggestion has constructor, ..
Reviewed-by: jlahoda
This commit is contained in:
parent
1c1ec9a26e
commit
67028ff853
@ -923,7 +923,7 @@ public class JShellTool implements MessageHandler {
|
|||||||
|
|
||||||
for (String alternative : alternatives) {
|
for (String alternative : alternatives) {
|
||||||
if (alternative.startsWith(input)) {
|
if (alternative.startsWith(input)) {
|
||||||
result.add(new Suggestion(alternative, false));
|
result.add(new ArgSuggestion(alternative));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,7 +951,7 @@ public class JShellTool implements MessageHandler {
|
|||||||
List<Suggestion> result = new ArrayList<>();
|
List<Suggestion> result = new ArrayList<>();
|
||||||
try (Stream<Path> dir = Files.list(current)) {
|
try (Stream<Path> dir = Files.list(current)) {
|
||||||
dir.filter(f -> accept.test(f) && f.getFileName().toString().startsWith(prefix))
|
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);
|
.forEach(result::add);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
//ignore...
|
//ignore...
|
||||||
@ -959,7 +959,7 @@ public class JShellTool implements MessageHandler {
|
|||||||
if (path.isEmpty()) {
|
if (path.isEmpty()) {
|
||||||
StreamSupport.stream(FileSystems.getDefault().getRootDirectories().spliterator(), false)
|
StreamSupport.stream(FileSystems.getDefault().getRootDirectories().spliterator(), false)
|
||||||
.filter(root -> accept.test(root) && root.toString().startsWith(prefix))
|
.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);
|
.forEach(result::add);
|
||||||
}
|
}
|
||||||
anchor[0] = path.length();
|
anchor[0] = path.length();
|
||||||
@ -981,7 +981,7 @@ public class JShellTool implements MessageHandler {
|
|||||||
? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
|
? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
|
||||||
: Stream.of(String.valueOf(k.id())))
|
: Stream.of(String.valueOf(k.id())))
|
||||||
.filter(k -> k.startsWith(prefix))
|
.filter(k -> k.startsWith(prefix))
|
||||||
.map(k -> new Suggestion(k, false))
|
.map(k -> new ArgSuggestion(k))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1146,7 +1146,7 @@ public class JShellTool implements MessageHandler {
|
|||||||
.filter(cmd -> cmd.kind.shouldSuggestCompletions)
|
.filter(cmd -> cmd.kind.shouldSuggestCompletions)
|
||||||
.map(cmd -> cmd.command)
|
.map(cmd -> cmd.command)
|
||||||
.filter(key -> key.startsWith(prefix))
|
.filter(key -> key.startsWith(prefix))
|
||||||
.map(key -> new Suggestion(key + " ", false));
|
.map(key -> new ArgSuggestion(key + " "));
|
||||||
anchor[0] = 0;
|
anchor[0] = 0;
|
||||||
} else {
|
} else {
|
||||||
String arg = prefix.substring(space + 1);
|
String arg = prefix.substring(space + 1);
|
||||||
@ -2457,6 +2457,42 @@ public class JShellTool implements MessageHandler {
|
|||||||
this.tid = tid;
|
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 {
|
abstract class NonInteractiveIOContext extends IOContext {
|
||||||
|
@ -144,30 +144,16 @@ public abstract class SourceCodeAnalysis {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The result of {@code analyzeCompletion(String input)}.
|
* 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 {
|
public interface 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The analyzed completeness of the input.
|
* The analyzed completeness of the input.
|
||||||
*
|
*
|
||||||
* @return an enum describing the completeness of the input string.
|
* @return an enum describing the completeness of the input string.
|
||||||
*/
|
*/
|
||||||
public Completeness completeness() {
|
Completeness completeness();
|
||||||
return completeness;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Input remaining after the complete part of the source.
|
* Input remaining after the complete part of the source.
|
||||||
@ -175,9 +161,7 @@ public abstract class SourceCodeAnalysis {
|
|||||||
* @return the portion of the input string that remains after the
|
* @return the portion of the input string that remains after the
|
||||||
* complete Snippet
|
* complete Snippet
|
||||||
*/
|
*/
|
||||||
public String remaining() {
|
String remaining();
|
||||||
return remaining;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source code for the first Snippet of code input. For example, first
|
* Source code for the first Snippet of code input. For example, first
|
||||||
@ -186,18 +170,7 @@ public abstract class SourceCodeAnalysis {
|
|||||||
*
|
*
|
||||||
* @return the source of the first encountered Snippet
|
* @return the source of the first encountered Snippet
|
||||||
*/
|
*/
|
||||||
public String source() {
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -272,30 +245,14 @@ public abstract class SourceCodeAnalysis {
|
|||||||
/**
|
/**
|
||||||
* A candidate for continuation of the given user's input.
|
* A candidate for continuation of the given user's input.
|
||||||
*/
|
*/
|
||||||
public static class Suggestion {
|
public interface 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The candidate continuation of the given user's input.
|
* The candidate continuation of the given user's input.
|
||||||
*
|
*
|
||||||
* @return the continuation string
|
* @return the continuation string
|
||||||
*/
|
*/
|
||||||
public String continuation() {
|
String continuation();
|
||||||
return continuation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether input continuation matches the target type and is thus
|
* Indicates whether input continuation matches the target type and is thus
|
||||||
@ -305,9 +262,7 @@ public abstract class SourceCodeAnalysis {
|
|||||||
* @return {@code true} if this suggested continuation matches the
|
* @return {@code true} if this suggested continuation matches the
|
||||||
* target type; otherwise {@code false}
|
* target type; otherwise {@code false}
|
||||||
*/
|
*/
|
||||||
public boolean matchesType() {
|
boolean matchesType();
|
||||||
return matchesType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,13 +171,13 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
MaskCommentsAndModifiers mcm = new MaskCommentsAndModifiers(srcInput, false);
|
MaskCommentsAndModifiers mcm = new MaskCommentsAndModifiers(srcInput, false);
|
||||||
if (mcm.endsWithOpenComment()) {
|
if (mcm.endsWithOpenComment()) {
|
||||||
proc.debug(DBG_COMPA, "Incomplete (open comment): %s\n", srcInput);
|
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 cleared = mcm.cleared();
|
||||||
String trimmedInput = Util.trimEnd(cleared);
|
String trimmedInput = Util.trimEnd(cleared);
|
||||||
if (trimmedInput.isEmpty()) {
|
if (trimmedInput.isEmpty()) {
|
||||||
// Just comment or empty
|
// Just comment or empty
|
||||||
return new CompletionInfo(Completeness.EMPTY, srcInput.length(), srcInput, "");
|
return new CompletionInfoImpl(Completeness.EMPTY, srcInput, "");
|
||||||
}
|
}
|
||||||
CaInfo info = ca.scan(trimmedInput);
|
CaInfo info = ca.scan(trimmedInput);
|
||||||
Completeness status = info.status;
|
Completeness status = info.status;
|
||||||
@ -195,12 +195,12 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
+ mcm.mask().substring(nonCommentNonWhiteLength);
|
+ mcm.mask().substring(nonCommentNonWhiteLength);
|
||||||
proc.debug(DBG_COMPA, "Complete: %s\n", compileSource);
|
proc.debug(DBG_COMPA, "Complete: %s\n", compileSource);
|
||||||
proc.debug(DBG_COMPA, " nothing remains.\n");
|
proc.debug(DBG_COMPA, " nothing remains.\n");
|
||||||
return new CompletionInfo(status, unitEndPos, compileSource, "");
|
return new CompletionInfoImpl(status, compileSource, "");
|
||||||
} else {
|
} else {
|
||||||
String remain = srcInput.substring(unitEndPos);
|
String remain = srcInput.substring(unitEndPos);
|
||||||
proc.debug(DBG_COMPA, "Complete: %s\n", src);
|
proc.debug(DBG_COMPA, "Complete: %s\n", src);
|
||||||
proc.debug(DBG_COMPA, " remaining: %s\n", remain);
|
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:
|
case COMPLETE_WITH_SEMI:
|
||||||
// The unit is the whole non-coment/white input plus semicolon
|
// The unit is the whole non-coment/white input plus semicolon
|
||||||
@ -209,19 +209,19 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
+ mcm.mask().substring(nonCommentNonWhiteLength);
|
+ mcm.mask().substring(nonCommentNonWhiteLength);
|
||||||
proc.debug(DBG_COMPA, "Complete with semi: %s\n", compileSource);
|
proc.debug(DBG_COMPA, "Complete with semi: %s\n", compileSource);
|
||||||
proc.debug(DBG_COMPA, " nothing remains.\n");
|
proc.debug(DBG_COMPA, " nothing remains.\n");
|
||||||
return new CompletionInfo(status, unitEndPos, compileSource, "");
|
return new CompletionInfoImpl(status, compileSource, "");
|
||||||
case DEFINITELY_INCOMPLETE:
|
case DEFINITELY_INCOMPLETE:
|
||||||
proc.debug(DBG_COMPA, "Incomplete: %s\n", srcInput);
|
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:
|
case CONSIDERED_INCOMPLETE:
|
||||||
proc.debug(DBG_COMPA, "Considered incomplete: %s\n", srcInput);
|
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:
|
case EMPTY:
|
||||||
proc.debug(DBG_COMPA, "Detected empty: %s\n", srcInput);
|
proc.debug(DBG_COMPA, "Detected empty: %s\n", srcInput);
|
||||||
return new CompletionInfo(status, unitEndPos, srcInput, "");
|
return new CompletionInfoImpl(status, srcInput, "");
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
proc.debug(DBG_COMPA, "Detected error: %s\n", srcInput);
|
proc.debug(DBG_COMPA, "Detected error: %s\n", srcInput);
|
||||||
return new CompletionInfo(status, unitEndPos, srcInput, "");
|
return new CompletionInfoImpl(status, srcInput, "");
|
||||||
}
|
}
|
||||||
throw new InternalError();
|
throw new InternalError();
|
||||||
}
|
}
|
||||||
@ -665,7 +665,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
if (c.getKind() == ElementKind.CONSTRUCTOR || c.getKind() == ElementKind.METHOD) {
|
if (c.getKind() == ElementKind.CONSTRUCTOR || c.getKind() == ElementKind.METHOD) {
|
||||||
simpleName += paren.apply(hasParams.contains(simpleName));
|
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 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -253,10 +253,8 @@ public class CompletenessStressTest extends KullaTesting {
|
|||||||
writer.write(String.format("Empty statement: row %d, column %d: -- %s\n",
|
writer.write(String.format("Empty statement: row %d, column %d: -- %s\n",
|
||||||
start, end, unit));
|
start, end, unit));
|
||||||
} else {
|
} 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",
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user