From f2396ee60c46d87a0296e6aa8be1562e9a5e912f Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sun, 25 Mar 2018 20:13:54 -0700 Subject: [PATCH] repl: hide top-level await feature behind a flag PR-URL: https://github.com/nodejs/node/pull/19604 Refs: https://github.com/nodejs/node/pull/17807 Refs: https://github.com/nodejs/node/pull/15566#issuecomment-353428430 Reviewed-By: Gus Caplan --- doc/api/repl.md | 19 +++++++++++++++++++ lib/repl.js | 11 +++++++++-- src/node.cc | 12 ++++++++++++ src/node_config.cc | 3 +++ src/node_internals.h | 5 +++++ test/parallel/test-repl-top-level-await.js | 2 +- 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/doc/api/repl.md b/doc/api/repl.md index 46f3e1e0acb509..3a5134d1e24c0e 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -179,6 +179,25 @@ Error: foo 'foo' ``` +#### `await` keyword + +With the `--experimental-repl-await` command line option specified, +experimental support for the `await` keyword is enabled. + + +```js +> await Promise.resolve(123) +123 +> await Promise.reject(new Error('REPL await')) +Error: REPL await + at repl:1:45 +> const timeout = util.promisify(setTimeout); +undefined +> const old = Date.now(); await timeout(1000); console.log(Date.now() - old); +1002 +undefined +``` + ### Custom Evaluation Functions When a new `repl.REPLServer` is created, a custom evaluation function may be diff --git a/lib/repl.js b/lib/repl.js index 412fc2e7b86061..2bef57fa100170 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -47,7 +47,6 @@ const { makeRequireFunction, addBuiltinLibsToObject } = require('internal/modules/cjs/helpers'); -const { processTopLevelAwait } = require('internal/repl/await'); const internalUtil = require('internal/util'); const { isTypedArray } = require('internal/util/types'); const util = require('util'); @@ -69,6 +68,10 @@ const { ERR_SCRIPT_EXECUTION_INTERRUPTED } = require('internal/errors').codes; const { sendInspectorCommand } = require('internal/util/inspector'); +const { experimentalREPLAwait } = process.binding('config'); + +// Lazy-loaded. +let processTopLevelAwait; const parentModule = module; const replMap = new WeakMap(); @@ -225,7 +228,11 @@ function REPLServer(prompt, wrappedCmd = true; } - if (code.includes('await')) { + if (experimentalREPLAwait && code.includes('await')) { + if (processTopLevelAwait === undefined) { + ({ processTopLevelAwait } = require('internal/repl/await')); + } + const potentialWrappedCode = processTopLevelAwait(code); if (potentialWrappedCode !== null) { code = potentialWrappedCode; diff --git a/src/node.cc b/src/node.cc index 099fba35a872d5..6acad6870d81da 100644 --- a/src/node.cc +++ b/src/node.cc @@ -243,6 +243,11 @@ bool config_experimental_modules = false; // that is used by lib/vm.js bool config_experimental_vm_modules = false; +// Set in node.cc by ParseArgs when --experimental-repl-await is used. +// Used in node_config.cc to set a constant on process.binding('config') +// that is used by lib/repl.js. +bool config_experimental_repl_await = false; + // Set in node.cc by ParseArgs when --loader is used. // Used in node_config.cc to set a constant on process.binding('config') // that is used by lib/internal/bootstrap/node.js @@ -3463,6 +3468,10 @@ static void PrintHelp() { #if defined(NODE_HAVE_I18N_SUPPORT) " --experimental-modules experimental ES Module support\n" " and caching modules\n" +#endif // defined(NODE_HAVE_I18N_SUPPORT) + " --experimental-repl-await experimental await keyword support\n" + " in REPL\n" +#if defined(NODE_HAVE_I18N_SUPPORT) " --experimental-vm-modules experimental ES Module support\n" " in vm module\n" #endif // defined(NODE_HAVE_I18N_SUPPORT) @@ -3622,6 +3631,7 @@ static void CheckIfAllowedInEnv(const char* exe, bool is_env, // Node options, sorted in `node --help` order for ease of comparison. "--enable-fips", "--experimental-modules", + "--experimental-repl-await", "--experimental-vm-modules", "--expose-http2", // keep as a non-op through v9.x "--force-fips", @@ -3819,6 +3829,8 @@ static void ParseArgs(int* argc, new_v8_argc += 1; } else if (strcmp(arg, "--experimental-vm-modules") == 0) { config_experimental_vm_modules = true; + } else if (strcmp(arg, "--experimental-repl-await") == 0) { + config_experimental_repl_await = true; } else if (strcmp(arg, "--loader") == 0) { const char* module = argv[index + 1]; if (!config_experimental_modules) { diff --git a/src/node_config.cc b/src/node_config.cc index 055a9b0ae46887..e2b2662abd0e80 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -89,6 +89,9 @@ static void Initialize(Local target, if (config_experimental_vm_modules) READONLY_BOOLEAN_PROPERTY("experimentalVMModules"); + if (config_experimental_repl_await) + READONLY_BOOLEAN_PROPERTY("experimentalREPLAwait"); + if (config_pending_deprecation) READONLY_BOOLEAN_PROPERTY("pendingDeprecation"); diff --git a/src/node_internals.h b/src/node_internals.h index 8cc1aa1a8fec40..492a36296fb498 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -181,6 +181,11 @@ extern bool config_experimental_modules; // that is used by lib/vm.js extern bool config_experimental_vm_modules; +// Set in node.cc by ParseArgs when --experimental-repl-await is used. +// Used in node_config.cc to set a constant on process.binding('config') +// that is used by lib/repl.js. +extern bool config_experimental_repl_await; + // Set in node.cc by ParseArgs when --loader is used. // Used in node_config.cc to set a constant on process.binding('config') // that is used by lib/internal/bootstrap/node.js diff --git a/test/parallel/test-repl-top-level-await.js b/test/parallel/test-repl-top-level-await.js index a7edb66a81a1f8..91f5758c210a36 100644 --- a/test/parallel/test-repl-top-level-await.js +++ b/test/parallel/test-repl-top-level-await.js @@ -7,7 +7,7 @@ const repl = require('repl'); common.crashOnUnhandledRejection(); -// Flags: --expose-internals +// Flags: --expose-internals --experimental-repl-await const PROMPT = 'await repl > ';