8341631: JShell should auto-import java.io.IO.*
Reviewed-by: asotona, cstein
This commit is contained in:
parent
5b12a87dcb
commit
cf158bc6cd
@ -1001,6 +1001,11 @@ class ConsoleIOContext extends IOContext {
|
||||
return doReadUserLine(prompt, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readUserLine() throws IOException {
|
||||
return readUserLine("");
|
||||
}
|
||||
|
||||
private synchronized String doReadUserLine(String prompt, Character mask) throws IOException {
|
||||
History prevHistory = in.getHistory();
|
||||
boolean prevDisableCr = Display.DISABLE_CR;
|
||||
|
@ -64,6 +64,8 @@ abstract class IOContext implements AutoCloseable {
|
||||
}
|
||||
|
||||
public String readUserLine(String prompt) throws IOException {
|
||||
userOutput().write(prompt);
|
||||
userOutput().flush();
|
||||
throw new UserInterruptException("");
|
||||
}
|
||||
|
||||
@ -76,6 +78,8 @@ abstract class IOContext implements AutoCloseable {
|
||||
}
|
||||
|
||||
public char[] readPassword(String prompt) throws IOException {
|
||||
userOutput().write(prompt);
|
||||
userOutput().flush();
|
||||
throw new UserInterruptException("");
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import java.io.IOError;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
@ -1192,7 +1193,7 @@ public class JShellTool implements MessageHandler {
|
||||
|
||||
//where
|
||||
private void startUpRun(String start) {
|
||||
try (IOContext suin = new ScannerIOContext(new StringReader(start))) {
|
||||
try (IOContext suin = new ScannerIOContext(new StringReader(start), userout)) {
|
||||
while (run(suin)) {
|
||||
if (!live) {
|
||||
resetState();
|
||||
@ -3125,7 +3126,7 @@ public class JShellTool implements MessageHandler {
|
||||
throw new FileNotFoundException(filename);
|
||||
}
|
||||
}
|
||||
try (var scannerIOContext = new ScannerIOContext(scanner)) {
|
||||
try (var scannerIOContext = new ScannerIOContext(scanner, userout)) {
|
||||
run(scannerIOContext);
|
||||
}
|
||||
return true;
|
||||
@ -3288,8 +3289,10 @@ public class JShellTool implements MessageHandler {
|
||||
resetState();
|
||||
}
|
||||
if (history != null) {
|
||||
run(new ReloadIOContext(history.iterable(),
|
||||
echo ? cmdout : null));
|
||||
try (ReloadIOContext ctx = new ReloadIOContext(history.iterable(),
|
||||
echo ? cmdout : null, userout)) {
|
||||
run(ctx);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -4107,6 +4110,8 @@ public class JShellTool implements MessageHandler {
|
||||
public String readLine(String prompt) {
|
||||
try {
|
||||
return input.readUserLine(prompt);
|
||||
} catch (UserInterruptException ex) {
|
||||
return null;
|
||||
} catch (IOException ex) {
|
||||
throw new IOError(ex);
|
||||
}
|
||||
@ -4125,6 +4130,8 @@ public class JShellTool implements MessageHandler {
|
||||
public char[] readPassword(String prompt) {
|
||||
try {
|
||||
return input.readPassword(prompt);
|
||||
} catch (UserInterruptException ex) {
|
||||
return null;
|
||||
} catch (IOException ex) {
|
||||
throw new IOError(ex);
|
||||
}
|
||||
@ -4144,6 +4151,12 @@ public class JShellTool implements MessageHandler {
|
||||
|
||||
abstract class NonInteractiveIOContext extends IOContext {
|
||||
|
||||
private final Writer userOutput;
|
||||
|
||||
public NonInteractiveIOContext(PrintStream userOutput) {
|
||||
this.userOutput = new OutputStreamWriter(userOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean interactiveOutput() {
|
||||
return false;
|
||||
@ -4178,17 +4191,33 @@ abstract class NonInteractiveIOContext extends IOContext {
|
||||
@Override
|
||||
public void replaceLastHistoryEntry(String source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Writer userOutput() {
|
||||
return userOutput;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
userOutput.flush();
|
||||
} catch (IOException _) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ScannerIOContext extends NonInteractiveIOContext {
|
||||
private final Scanner scannerIn;
|
||||
|
||||
ScannerIOContext(Scanner scannerIn) {
|
||||
ScannerIOContext(Scanner scannerIn, PrintStream userOutput) {
|
||||
super(userOutput);
|
||||
this.scannerIn = scannerIn;
|
||||
}
|
||||
|
||||
ScannerIOContext(Reader rdr) throws FileNotFoundException {
|
||||
this(new Scanner(rdr));
|
||||
ScannerIOContext(Reader rdr, PrintStream userOutput) throws FileNotFoundException {
|
||||
this(new Scanner(rdr), userOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -4202,6 +4231,7 @@ class ScannerIOContext extends NonInteractiveIOContext {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
scannerIn.close();
|
||||
}
|
||||
|
||||
@ -4215,7 +4245,8 @@ class ReloadIOContext extends NonInteractiveIOContext {
|
||||
private final Iterator<String> it;
|
||||
private final PrintStream echoStream;
|
||||
|
||||
ReloadIOContext(Iterable<String> history, PrintStream echoStream) {
|
||||
ReloadIOContext(Iterable<String> history, PrintStream echoStream, PrintStream userOutput) {
|
||||
super(userOutput);
|
||||
this.it = history.iterator();
|
||||
this.echoStream = echoStream;
|
||||
}
|
||||
|
@ -117,6 +117,9 @@ public class ConsoleImpl {
|
||||
|
||||
private char[] readChars() throws IOException {
|
||||
int actualLen = readInt();
|
||||
if (actualLen == (-1)) {
|
||||
return null;
|
||||
}
|
||||
char[] result = new char[actualLen];
|
||||
for (int i = 0; i < actualLen; i++) {
|
||||
result[i] = (char) ((remoteOutput.read() << 8) |
|
||||
@ -267,6 +270,9 @@ public class ConsoleImpl {
|
||||
remoteInput.write(Task.READ_LINE.ordinal());
|
||||
sendChars(chars, 0, chars.length);
|
||||
char[] line = readChars();
|
||||
if (line == null) {
|
||||
return null;
|
||||
}
|
||||
return new String(line);
|
||||
});
|
||||
} catch (IOException ex) {
|
||||
@ -417,8 +423,12 @@ public class ConsoleImpl {
|
||||
char[] data = readCharsOrNull(1);
|
||||
if (data != null) {
|
||||
String line = console.readLine(new String(data));
|
||||
if (line == null) {
|
||||
sendInt(sinkOutput, -1);
|
||||
} else {
|
||||
char[] chars = line.toCharArray();
|
||||
sendChars(sinkOutput, chars, 0, chars.length);
|
||||
}
|
||||
bp = 0;
|
||||
}
|
||||
}
|
||||
@ -432,7 +442,11 @@ public class ConsoleImpl {
|
||||
char[] data = readCharsOrNull(1);
|
||||
if (data != null) {
|
||||
char[] chars = console.readPassword(new String(data));
|
||||
if (chars == null) {
|
||||
sendInt(sinkOutput, -1);
|
||||
} else {
|
||||
sendChars(sinkOutput, chars, 0, chars.length);
|
||||
}
|
||||
bp = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
import module java.base;
|
||||
import static java.io.IO.*;
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8331535
|
||||
* @bug 8331535 8341631
|
||||
* @summary Test the JShell tool Console handling
|
||||
* @modules jdk.internal.le/jdk.internal.org.jline.reader
|
||||
* jdk.jshell/jdk.internal.jshell.tool:+open
|
||||
@ -56,6 +56,40 @@ public class ConsoleToolTest extends ReplToolTesting {
|
||||
);
|
||||
}
|
||||
|
||||
@Test //JDK-8341631
|
||||
public void testIO() {
|
||||
test(new String[] {"--enable-preview"},
|
||||
a -> {assertCommandWithOutputAndTerminal(a,
|
||||
"java.io.IO.readln(\"%%s\");\ninput", //newline automatically appended
|
||||
"$1 ==> \"input\"",
|
||||
"""
|
||||
\u0005java.io.IO.readln(\"%%s\");
|
||||
%%sinput
|
||||
""");},
|
||||
a -> {assertCommandWithOutputAndTerminal(a,
|
||||
"java.io.IO.readln();\ninput!", //newline automatically appended
|
||||
"$2 ==> \"input!\"",
|
||||
"""
|
||||
\u0005java.io.IO.readln();
|
||||
input!
|
||||
""");},
|
||||
a -> {assertCommandWithOutputAndTerminal(a,
|
||||
"java.io.IO.println(\"Hello, World!\");",
|
||||
"",
|
||||
"""
|
||||
\u0005java.io.IO.println(\"Hello, World!\");
|
||||
Hello, World!
|
||||
""");},
|
||||
a -> {assertCommandWithOutputAndTerminal(a,
|
||||
"java.io.IO.println();",
|
||||
"",
|
||||
"""
|
||||
\u0005java.io.IO.println();
|
||||
|
||||
""");}
|
||||
);
|
||||
}
|
||||
|
||||
void assertCommandWithOutputAndTerminal(boolean a, String command, String out, String terminalOut) {
|
||||
assertCommand(a, command, out, null, null, null, null, terminalOut);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023 8186708 8179856 8185840 8190383
|
||||
* @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023 8186708 8179856 8185840 8190383 8341631
|
||||
* @summary Testing startExCe-up options.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
@ -366,14 +366,49 @@ public class StartOptionTest {
|
||||
}
|
||||
|
||||
public void testPreviewEnabled() {
|
||||
String fn = writeToFile("System.out.println(\"prefix\");\n" +
|
||||
"System.out.println(MethodHandle.class.getName());\n" +
|
||||
"System.out.println(\"suffix\");\n" +
|
||||
"/exit\n");
|
||||
String fn = writeToFile(
|
||||
"""
|
||||
System.out.println(\"prefix\");
|
||||
System.out.println(MethodHandle.class.getName());
|
||||
System.out.println(\"suffix\");
|
||||
/exit
|
||||
""");
|
||||
startCheckUserOutput(s -> assertEquals(s, "prefix\nsuffix\n"),
|
||||
fn);
|
||||
startCheckUserOutput(s -> assertEquals(s, "prefix\njava.lang.invoke.MethodHandle\nsuffix\n"),
|
||||
"--enable-preview", fn);
|
||||
//JDK-8341631:
|
||||
String fn2 = writeToFile(
|
||||
"""
|
||||
System.out.println(\"prefix\");
|
||||
IO.println(\"test\");
|
||||
System.out.println(\"suffix\");
|
||||
/exit
|
||||
""");
|
||||
startCheckUserOutput(s -> assertEquals(s, "prefix\nsuffix\n"),
|
||||
fn2);
|
||||
startCheckUserOutput(s -> assertEquals(s, "prefix\ntest\nsuffix\n"),
|
||||
"--enable-preview", fn2);
|
||||
}
|
||||
public void testInput() {
|
||||
//readLine(String):
|
||||
String readLinePrompt = writeToFile(
|
||||
"""
|
||||
var v = System.console().readLine("prompt: ");
|
||||
System.out.println(v);
|
||||
/exit
|
||||
""");
|
||||
startCheckUserOutput(s -> assertEquals(s, "prompt: null\n"),
|
||||
readLinePrompt);
|
||||
//readPassword(String):
|
||||
String readPasswordPrompt = writeToFile(
|
||||
"""
|
||||
var v = System.console().readPassword("prompt: ");
|
||||
System.out.println(java.util.Arrays.toString(v));
|
||||
/exit
|
||||
""");
|
||||
startCheckUserOutput(s -> assertEquals(s, "prompt: null\n"),
|
||||
readPasswordPrompt);
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
|
Loading…
Reference in New Issue
Block a user