8199193: jshell tool: Add support for preview features
authorrfield
Mon, 23 Apr 2018 09:01:03 -0700
changeset 49856 5f63af8f9d7f
parent 49855 3739e9a5b6b5
child 49857 31e07291ae29
8199193: jshell tool: Add support for preview features Reviewed-by: sundar
src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java
src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties
src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java
test/langtools/jdk/jshell/ToolEnablePreviewTest.java
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Mon Apr 23 17:45:05 2018 +0200
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Mon Apr 23 09:01:03 2018 -0700
@@ -209,6 +209,7 @@
     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 @@
         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 @@
             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 @@
         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 @@
                     .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 @@
             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 @@
             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 @@
                         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 @@
         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
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Mon Apr 23 17:45:05 2018 +0200
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Mon Apr 23 09:01:03 2018 -0700
@@ -205,6 +205,7 @@
 \    --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\
--- a/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Mon Apr 23 17:45:05 2018 +0200
+++ b/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Mon Apr 23 09:01:03 2018 -0700
@@ -82,7 +82,6 @@
 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.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 @@
                             .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;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/jshell/ToolEnablePreviewTest.java	Mon Apr 23 09:01:03 2018 -0700
@@ -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")
+        );
+    }
+
+}