8199193: jshell tool: Add support for preview features

Reviewed-by: sundar
This commit is contained in:
Robert Field 2018-04-23 09:01:03 -07:00
parent 70146f48d5
commit ac44a19694
4 changed files with 131 additions and 19 deletions
src/jdk.jshell/share/classes/jdk
internal/jshell/tool
jshell
test/langtools/jdk/jshell

@ -209,6 +209,7 @@ public class JShellTool implements MessageHandler {
static final EditorSetting BUILT_IN_EDITOR = new EditorSetting(null, false);
private boolean debug = false;
private int debugFlags = 0;
public boolean testPrompt = false;
private Startup startup = null;
private boolean isCurrentlyRunningStartup = false;
@ -261,25 +262,28 @@ public class JShellTool implements MessageHandler {
MODULE_PATH("--module-path", true),
ADD_MODULES("--add-modules", false),
ADD_EXPORTS("--add-exports", false),
TO_COMPILER("-C", false, false, true, false),
TO_REMOTE_VM("-R", false, false, false, true),;
ENABLE_PREVIEW("--enable-preview", true),
SOURCE_RELEASE("-source", true, true, true, false, false), // virtual option, generated by --enable-preview
TO_COMPILER("-C", false, false, true, false, false),
TO_REMOTE_VM("-R", false, false, false, true, false),;
final String optionFlag;
final boolean onlyOne;
final boolean passFlag;
final boolean toCompiler;
final boolean toRemoteVm;
final boolean showOption;
private OptionKind(String optionFlag, boolean onlyOne) {
this(optionFlag, onlyOne, true, true, true);
this(optionFlag, onlyOne, true, true, true, true);
}
private OptionKind(String optionFlag, boolean onlyOne, boolean passFlag,
boolean toCompiler, boolean toRemoteVm) {
private OptionKind(String optionFlag, boolean onlyOne, boolean passFlag, boolean toCompiler, boolean toRemoteVm, boolean showOption) {
this.optionFlag = optionFlag;
this.onlyOne = onlyOne;
this.passFlag = passFlag;
this.toCompiler = toCompiler;
this.toRemoteVm = toRemoteVm;
this.showOption= showOption;
}
}
@ -314,8 +318,8 @@ public class JShellTool implements MessageHandler {
return selectOptions(e -> e.getKey().toCompiler);
}
String[] commonOptions() {
return selectOptions(e -> e.getKey().passFlag);
String[] shownOptions() {
return selectOptions(e -> e.getKey().showOption);
}
void addAll(OptionKind kind, Collection<String> vals) {
@ -348,6 +352,7 @@ public class JShellTool implements MessageHandler {
private final OptionSpec<String> argModulePath = parser.accepts("module-path").withRequiredArg();
private final OptionSpec<String> argAddModules = parser.accepts("add-modules").withRequiredArg();
private final OptionSpec<String> argAddExports = parser.accepts("add-exports").withRequiredArg();
private final OptionSpecBuilder argEnablePreview = parser.accepts("enable-preview");
private final NonOptionArgumentSpec<String> argNonOptions = parser.nonOptions();
private Options opts = new Options();
@ -449,6 +454,13 @@ public class JShellTool implements MessageHandler {
.map(mp -> mp.contains("=") ? mp : mp + "=ALL-UNNAMED")
.collect(toList())
);
if (options.has(argEnablePreview)) {
opts.addAll(OptionKind.ENABLE_PREVIEW, List.of(
OptionKind.ENABLE_PREVIEW.optionFlag));
opts.addAll(OptionKind.SOURCE_RELEASE, List.of(
OptionKind.SOURCE_RELEASE.optionFlag,
System.getProperty("java.specification.version")));
}
if (failed) {
exitCode = 1;
@ -1062,6 +1074,7 @@ public class JShellTool implements MessageHandler {
builder.executionEngine(executionControlSpec);
}
state = builder.build();
InternalDebugControl.setDebugFlags(state, debugFlags);
shutdownSubscription = state.onShutdown((JShell deadState) -> {
if (deadState == state) {
hardmsg("jshell.msg.terminated");
@ -2234,11 +2247,10 @@ public class JShellTool implements MessageHandler {
InternalDebugControl.setDebugFlags(state, debug ? DBG_GEN : 0);
fluff("Debugging %s", debug ? "on" : "off");
} else {
int flags = 0;
for (char ch : arg.toCharArray()) {
switch (ch) {
case '0':
flags = 0;
debugFlags = 0;
debug = false;
fluff("Debugging off");
break;
@ -2247,36 +2259,41 @@ public class JShellTool implements MessageHandler {
fluff("REPL tool debugging on");
break;
case 'g':
flags |= DBG_GEN;
debugFlags |= DBG_GEN;
fluff("General debugging on");
break;
case 'f':
flags |= DBG_FMGR;
debugFlags |= DBG_FMGR;
fluff("File manager debugging on");
break;
case 'c':
flags |= DBG_COMPA;
debugFlags |= DBG_COMPA;
fluff("Completion analysis debugging on");
break;
case 'd':
flags |= DBG_DEP;
debugFlags |= DBG_DEP;
fluff("Dependency debugging on");
break;
case 'e':
flags |= DBG_EVNT;
debugFlags |= DBG_EVNT;
fluff("Event debugging on");
break;
case 'w':
flags |= DBG_WRAP;
debugFlags |= DBG_WRAP;
fluff("Wrap debugging on");
break;
case 'b':
cmdout.printf("RemoteVM Options: %s\nCompiler options: %s\n",
Arrays.toString(options.remoteVmOptions()),
Arrays.toString(options.compilerOptions()));
break;
default:
error("Unknown debugging option: %c", ch);
fluff("Use: 0 r g f c d e w");
fluff("Use: 0 r g f c d e w b");
return false;
}
}
InternalDebugControl.setDebugFlags(state, flags);
InternalDebugControl.setDebugFlags(state, debugFlags);
}
return true;
}
@ -3112,7 +3129,7 @@ public class JShellTool implements MessageHandler {
if (rawargs.trim().isEmpty()) {
// No arguments, display current settings (as option flags)
StringBuilder sb = new StringBuilder();
for (String a : options.commonOptions()) {
for (String a : options.shownOptions()) {
sb.append(
a.startsWith("-")
? sb.length() > 0

@ -205,6 +205,7 @@ where possible options include:\n\
\ --add-modules <module>(,<module>)*\n\
\ Specify modules to resolve, or all modules on the\n\
\ module path if <module> is ALL-MODULE-PATHs\n\
\ --enable-preview Allow code to depend on preview features of this release\n\
\ --startup <file> One run replacement for the startup definitions\n\
\ --no-startup Do not run the startup definitions\n\
\ --feedback <mode> Specify the initial feedback mode. The mode may be\n\

@ -82,7 +82,6 @@ import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.Resolve;
import com.sun.tools.javac.parser.Parser;
import com.sun.tools.javac.parser.ParserFactory;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
@ -91,6 +90,7 @@ import com.sun.tools.javac.util.Context.Factory;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
import com.sun.tools.javac.util.Names;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_FMGR;
import jdk.jshell.Snippet.Status;
/**
@ -202,6 +202,7 @@ class TaskFactory {
.map(in -> sh.sourceToFileObject(fileManager, in))
.collect(Collectors.toList());
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
state.debug(DBG_FMGR, "Task (%s %s) Options: %s\n", this, compilationUnits, allOptions);
return javacTaskPool.getTask(null, fileManager, diagnostics, allOptions, null,
compilationUnits, task -> {
JavacTaskImpl jti = (JavacTaskImpl) task;

@ -0,0 +1,93 @@
/*
* Copyright (c) 2018, 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 8199193
* @summary Tests for the --enable-preview option
* @run testng ToolEnablePreviewTest
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
public class ToolEnablePreviewTest extends ReplToolTesting {
@Test
public void testOptionDebug() {
String release = System.getProperty("java.specification.version");
test(
(a) -> assertCommand(a, "/debug b",
"RemoteVM Options: []\n"
+ "Compiler options: []"),
(a) -> assertCommand(a, "/env --enable-preview",
"| Setting new options and restoring state."),
(a) -> assertCommandCheckOutput(a, "/debug b", s -> {
assertTrue(s.contains("RemoteVM Options: [--enable-preview]"));
assertTrue(s.contains("Compiler options: [-source, " + release + ", --enable-preview]")
|| s.contains("Compiler options: [--enable-preview, -source, " + release + "]"),
"\nExpected -- " + "Compiler options: [-source, " + release + ", --enable-preview]"
+ "\nOr -- " + "Compiler options: [--enable-preview, -source, " + release + "]"
+ "\nBut got -- " + s);
})
);
}
@Test
public void testCommandLineFlag() {
String release = System.getProperty("java.specification.version");
test(new String[] {"--enable-preview"},
(a) -> assertCommandCheckOutput(a, "/debug b", s -> {
assertTrue(s.contains("RemoteVM Options: [--enable-preview]"));
assertTrue(s.contains("Compiler options: [-source, " + release + ", --enable-preview]")
|| s.contains("Compiler options: [--enable-preview, -source, " + release + "]"),
"\nExpected -- " + "Compiler options: [-source, " + release + ", --enable-preview]"
+ "\nOr -- " + "Compiler options: [--enable-preview, -source, " + release + "]"
+ "\nBut got -- " + s);
})
);
}
@Test
public void testCompilerTestFlagEnv() {
test(new String[] {"-C", "-XDforcePreview"},
(a) -> assertCommandOutputContains(a, "Function<Integer,Integer> f = i -> i + i",
"Error", "preview feature"),
(a) -> assertCommand(a, "/env --enable-preview",
"| Setting new options and restoring state."),
(a) -> assertCommandOutputContains(a, "Function<Integer,Integer> f = i -> i + i",
"f ==> ")
);
}
@Test
public void testCompilerTestFlag() {
test(new String[] {"-C", "-XDforcePreview", "--enable-preview"},
(a) -> assertCommandOutputContains(a, "Function<Integer,Integer> f = i -> i + i",
"f ==> "),
(a) -> assertCommandOutputContains(a, "f.apply(2)", "==> 4")
);
}
}