8306560: Add TOOLING.jsh load file

Reviewed-by: jlahoda
This commit is contained in:
Christian Stein 2023-05-28 08:14:37 +00:00
parent ca54f4e007
commit 547a8b40b3
6 changed files with 167 additions and 14 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -230,7 +230,7 @@ where possible options include:\n\
\ --help-extra, -X Print help on non-standard options and exit\n\
\n\
A file argument may be a file name, or one of the predefined file names: DEFAULT,\n\
PRINTING, or JAVASE.\n\
PRINTING, TOOLING, or JAVASE.\n\
A load-file may also be "-" to indicate standard input, without interactive I/O.\n\
\n\
For more information on the evaluation context options (--class-path,\n\
@ -331,10 +331,10 @@ Open a file and read its contents as snippets and commands.\n\
Download and use the specified URL as the jshell tool input.\n\
\n\
The <file> may be an operating system file name, or one of the predefined\n\
file names: DEFAULT, PRINTING, or JAVASE.\n\
file names: DEFAULT, PRINTING, TOOLING, or JAVASE.\n\
These are respectively: the default import snippets (as used by -default),\n\
definitions of print(), println(), and printf() method snippets, or\n\
imports of all Java SE packages.\n
definitions of print(), println(), and printf() method snippets, definitions\n\
of method snippets running JDK tools, or imports of all Java SE packages.\n
help.vars.summary = list the declared variables and their values
help.vars.args = [<name or id>|-all|-start]
@ -1136,7 +1136,7 @@ Note: if the startup was last set from a file, this is shown with the\n\
'set start' command followed by the contents of the file.\n\
\n\
The <file> may be an operating system file name, or one of the predefined\n\
startup file names: DEFAULT, PRINTING, or JAVASE.\n\
startup file names: DEFAULT, PRINTING, TOOLING, or JAVASE.\n\
These are respectively: the default import snippets (as used by -default),\n\
definitions of print(), println(), and printf() method snippets, or\n\
imports of all Java SE packages.\n\

View File

@ -0,0 +1,49 @@
void jar(String... args) { run("jar", args); }
void javac(String... args) { run("javac", args); }
void javadoc(String... args) { run("javadoc", args); }
void javap(String... args) { run("javap", args); }
void jdeps(String... args) { run("jdeps", args); }
void jlink(String... args) { run("jlink", args); }
void jmod(String... args) { run("jmod", args); }
void jpackage(String... args) { run("jpackage", args); }
void javap(Class<?> type) throws Exception {
try {
var name = type.getCanonicalName();
if (name == null) throw new IllegalArgumentException("Type not supported: " + type);
if (type == Class.forName(name, false, ClassLoader.getSystemClassLoader())) {
run("javap", "-c", "-v", "-s", name);
return;
}
} catch (ClassNotFoundException ignored) {
// fall-through
}
var temp = java.nio.file.Files.createTempFile("TOOLING-", ".class");
try {
var name = type.getName().replace('.', '/') + ".class";
try (var in = type.getClassLoader().getResourceAsStream(name);
var out = java.nio.file.Files.newOutputStream(temp)) {
if (in == null) throw new AssertionError("Resource not found: " + name);
in.transferTo(out);
}
run("javap", "-c", "-v", "-s", temp.toString());
} finally {
java.nio.file.Files.delete(temp);
}
}
void run(String name, String... args) {
var tool = java.util.spi.ToolProvider.findFirst(name);
if (tool.isEmpty()) throw new RuntimeException("No such tool found: " + name);
var code = tool.get().run(System.out, System.err, args);
if (code == 0) return;
System.err.println(name + " returned non-zero exit code: " + code);
}
void tools() {
java.util.ServiceLoader.load(java.util.spi.ToolProvider.class).stream()
.map(java.util.ServiceLoader.Provider::get)
.map(java.util.spi.ToolProvider::name)
.sorted()
.forEach(System.out::println);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -510,6 +510,26 @@ public class ReplToolTesting {
}
}
public void assertCommandUserOutputContains(boolean after, String cmd, String... hasThese) {
assertCommandCheckUserOutput(after, cmd, (s)
-> assertTrue(Arrays.stream(hasThese)
.allMatch(has -> s.contains(has)),
"User output: \'" + s + "' does not contain: "
+ Arrays.stream(hasThese)
.filter(has -> !s.contains(has))
.collect(Collectors.joining(", "))));
}
public void assertCommandCheckUserOutput(boolean after, String cmd, Consumer<String> check) {
if (!after) {
assertCommand(false, cmd, null);
} else {
String got = getUserOutput();
check.accept(got);
assertCommand(true, cmd, null);
}
}
public void assertCommand(boolean after, String cmd, String out, String err,
String userinput, String print, String usererr) {
if (!after) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -71,9 +71,9 @@ public class ToolLocalSimpleTest extends ToolSimpleTest {
@Override
@Test
public void testCompoundStart() {
test(new String[]{"--startup", "DEFAULT", "--startup", "PRINTING"},
test(new String[]{"--startup", "DEFAULT", "--startup", "PRINTING", "--startup", "TOOLING"},
(a) -> assertCommandOutputContains(a, "/list -start",
"System.out.println", "import java.util.concurrent")
"System.out.println", "import java.util.concurrent", "tools()")
);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,7 @@
* 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848
* 8174041 8173916 8174028 8174262 8174797 8177079 8180508 8177466 8172154
* 8192979 8191842 8198573 8198801 8210596 8210959 8215099 8199623 8236715
* 8239536 8247456 8246774 8238173 8292625
* 8239536 8247456 8246774 8238173 8292625 8306560
* @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@ -749,9 +749,11 @@ public class ToolSimpleTest extends ReplToolTesting {
@Test
public void testCompoundStart() {
test(new String[]{"-R", "-Duser.language=en", "-R", "-Duser.country=US",
"--startup", "DEFAULT", "--startup", "PRINTING"},
"--startup", "DEFAULT", "--startup", "PRINTING", "--startup", "TOOLING"},
(a) -> assertCommand(a, "printf(\"%4.2f\", Math.PI)",
"", "", null, "3.14", "")
"", "", null, "3.14", ""),
(a) -> assertCommand(a, "jar(\"--version\")",
"", "", null, "jar " + System.getProperty("java.version") + "\n", "")
);
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8306560
* @summary Tests for snippets and methods defined in TOOLING.jsh
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
* jdk.jshell/jdk.internal.jshell.tool
* @build KullaTesting TestingInputStream
* @run testng ToolingTest
*/
import org.testng.Assert;
import org.testng.annotations.Test;
public class ToolingTest extends ReplToolTesting {
@Test
public void testListToolingSnippets() {
test(
a -> assertCommand(a, "/open TOOLING",
""),
a -> assertCommandOutputContains(a, "/list",
// Tool methods
"void jar(String... args)",
// ...
"void jpackage(String... args)",
// Utility methods
"void javap(Class<?> type) throws Exception",
"void run(String name, String... args)",
"void tools()")
);
}
@Test
public void testDisassembleJavaLangObjectClass() {
test(
a -> assertCommand(a, "/open TOOLING",
""),
a -> assertCommandUserOutputContains(a, "javap(Object.class)",
"Classfile jrt:/java.base/java/lang/Object.class",
"SourceFile: \"Object.java\"")
);
}
@Test
public void testDisassembleNewRecordClass() {
test(
a -> assertCommand(a, "record Point(int x, int y) {}",
"| created record Point"),
a -> assertCommand(a, "/open TOOLING",
""),
a -> assertCommandUserOutputContains(a, "javap(Point.class)",
"Classfile ", // Classfile /.../TOOLING-13366652659767559204.class
"Point extends java.lang.Record", // public final class REPL.$JShell$11$Point extends java.lang.Record
"SourceFile: \"$JShell$" // SourceFile: "$JShell$11.java"
)
);
}
}