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 06703da131c301..a7977dc72fb781 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(); @@ -226,7 +229,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 6f946ab3ad1cc7..462728c4af358a 100644 --- a/src/node.cc +++ b/src/node.cc @@ -244,6 +244,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 @@ -3468,6 +3473,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) @@ -3627,6 +3636,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", @@ -3823,6 +3833,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 0542bff1d65186..35ac019c53df11 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -85,6 +85,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 > ';