Skip to content

Commit 325eecb

Browse files
committedApr 15, 2021
8255273: jshell crashes with UnsupportedOperationException: Should not get here.
Reviewed-by: vromero
1 parent e43aee5 commit 325eecb

File tree

2 files changed

+74
-41
lines changed

2 files changed

+74
-41
lines changed
 

‎src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java

+64-40
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,49 @@ private boolean complete(CompletionState completionState) {
364364
.distinct()
365365
.count() == 2;
366366
boolean tooManyItems = suggestions.size() > /*in.getAutoprintThreshold()*/AUTOPRINT_THRESHOLD;
367-
CompletionTask ordinaryCompletion =
368-
new OrdinaryCompletionTask(suggestions,
369-
anchor[0],
370-
!command && !doc.isEmpty(),
371-
hasBoth);
367+
CompletionTask ordinaryCompletion;
368+
List<? extends CharSequence> ordinaryCompletionToShow;
369+
370+
if (hasBoth) {
371+
ordinaryCompletionToShow =
372+
suggestions.stream()
373+
.filter(Suggestion::matchesType)
374+
.map(Suggestion::continuation)
375+
.distinct()
376+
.toList();
377+
} else {
378+
ordinaryCompletionToShow =
379+
suggestions.stream()
380+
.map(Suggestion::continuation)
381+
.distinct()
382+
.toList();
383+
}
384+
385+
if (ordinaryCompletionToShow.isEmpty()) {
386+
ordinaryCompletion = new ContinueCompletionTask();
387+
} else {
388+
Optional<String> prefixOpt =
389+
suggestions.stream()
390+
.map(Suggestion::continuation)
391+
.reduce(ConsoleIOContext::commonPrefix);
392+
393+
String prefix =
394+
prefixOpt.orElse("").substring(cursor - anchor[0]);
395+
396+
if (!prefix.isEmpty() && !command) {
397+
//the completion will fill in the prefix, which will invalidate
398+
//the documentation, avoid adding documentation tasks into the
399+
//todo list:
400+
doc = List.of();
401+
}
402+
403+
ordinaryCompletion =
404+
new OrdinaryCompletionTask(ordinaryCompletionToShow,
405+
prefix,
406+
!command && !doc.isEmpty(),
407+
hasBoth);
408+
}
409+
372410
CompletionTask allCompletion = new AllSuggestionsCompletionTask(suggestions, anchor[0]);
373411

374412
todo = new ArrayList<>();
@@ -567,17 +605,17 @@ public Result perform(String text, int cursor) throws IOException {
567605
}
568606

569607
private final class OrdinaryCompletionTask implements CompletionTask {
570-
private final List<Suggestion> suggestions;
571-
private final int anchor;
608+
private final List<? extends CharSequence> toShow;
609+
private final String prefix;
572610
private final boolean cont;
573611
private final boolean showSmart;
574612

575-
public OrdinaryCompletionTask(List<Suggestion> suggestions,
576-
int anchor,
613+
public OrdinaryCompletionTask(List<? extends CharSequence> toShow,
614+
String prefix,
577615
boolean cont,
578616
boolean showSmart) {
579-
this.suggestions = suggestions;
580-
this.anchor = anchor;
617+
this.toShow = toShow;
618+
this.prefix = prefix;
581619
this.cont = cont;
582620
this.showSmart = showSmart;
583621
}
@@ -589,34 +627,7 @@ public String description() {
589627

590628
@Override
591629
public Result perform(String text, int cursor) throws IOException {
592-
List<? extends CharSequence> toShow;
593-
594-
if (showSmart) {
595-
toShow =
596-
suggestions.stream()
597-
.filter(Suggestion::matchesType)
598-
.map(Suggestion::continuation)
599-
.distinct()
600-
.toList();
601-
} else {
602-
toShow =
603-
suggestions.stream()
604-
.map(Suggestion::continuation)
605-
.distinct()
606-
.toList();
607-
}
608-
609-
if (toShow.isEmpty()) {
610-
return Result.CONTINUE;
611-
}
612-
613-
Optional<String> prefix =
614-
suggestions.stream()
615-
.map(Suggestion::continuation)
616-
.reduce(ConsoleIOContext::commonPrefix);
617-
618-
String prefixStr = prefix.orElse("").substring(cursor - anchor);
619-
in.putString(prefixStr);
630+
in.putString(prefix);
620631

621632
boolean showItems = toShow.size() > 1 || showSmart;
622633

@@ -625,7 +636,7 @@ public Result perform(String text, int cursor) throws IOException {
625636
printColumns(toShow);
626637
}
627638

628-
if (!prefixStr.isEmpty())
639+
if (!prefix.isEmpty())
629640
return showItems ? Result.FINISH : Result.SKIP_NOREPAINT;
630641

631642
return cont ? Result.CONTINUE : Result.FINISH;
@@ -798,6 +809,19 @@ public Result perform(String text, int cursor) throws IOException {
798809

799810
}
800811

812+
private static class ContinueCompletionTask implements ConsoleIOContext.CompletionTask {
813+
814+
@Override
815+
public String description() {
816+
throw new UnsupportedOperationException("Should not get here.");
817+
}
818+
819+
@Override
820+
public CompletionTask.Result perform(String text, int cursor) throws IOException {
821+
return CompletionTask.Result.CONTINUE;
822+
}
823+
}
824+
801825
@Override
802826
public boolean terminalEditorRunning() {
803827
Terminal terminal = in.getTerminal();

‎test/langtools/jdk/jshell/ToolTabSnippetTest.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/**
2525
* @test
26-
* @bug 8177076 8185426 8189595 8188072 8221759
26+
* @bug 8177076 8185426 8189595 8188072 8221759 8255273
2727
* @modules
2828
* jdk.compiler/com.sun.tools.javac.api
2929
* jdk.compiler/com.sun.tools.javac.main
@@ -331,4 +331,13 @@ private Path prepareZip() {
331331
//where:
332332
private final Compiler compiler = new Compiler();
333333

334+
public void testDocumentationAfterInsert() throws Exception {
335+
doRunTest((inputSink, out) -> {
336+
inputSink.write("import java.time.*\n");
337+
waitOutput(out, PROMPT);
338+
339+
inputSink.write("new Instant" + TAB);
340+
waitOutput(out, PROMPT + "new InstantiationE");
341+
});
342+
}
334343
}

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Apr 15, 2021

@openjdk-notifier[bot]
Please sign in to comment.