8306560: Add TOOLING.jsh load file
Reviewed-by: jlahoda
This commit is contained in:
parent
ca54f4e007
commit
547a8b40b3
@ -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\
|
||||
|
@ -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);
|
||||
}
|
@ -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) {
|
||||
|
@ -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()")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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", "")
|
||||
);
|
||||
}
|
||||
|
||||
|
82
test/langtools/jdk/jshell/ToolingTest.java
Normal file
82
test/langtools/jdk/jshell/ToolingTest.java
Normal 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"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user