repl: fix autocomplete when useGlobal is false

This fixes two issues in the REPL when it is started with a new context
(useGlobal option set to `false`):
- The `primordials` object does not contain all builtins, so the
  filtering based on property names from `primordials` was wrong.
- The autocompleter did not take builtin names into account because
  they are not properties of the context object.

A list of all global builtin names is created lazily when needed. It is
used for filtering for the copy and for adding those names to the
autocompleter list.

Fixes: https://github.com/nodejs/node/issues/30792

PR-URL: https://github.com/nodejs/node/pull/30883
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: David Carlier <devnexen@gmail.com>
This commit is contained in:
Michaël Zasso 2019-12-10 15:37:32 +01:00 committed by Rich Trott
parent e490b2ca90
commit 8e58c7557b

View File

@ -119,6 +119,9 @@ const { setImmediate } = require('timers');
// Lazy-loaded.
let processTopLevelAwait;
const globalBuiltins =
new Set(vm.runInNewContext('Object.getOwnPropertyNames(globalThis)'));
const parentModule = module;
const replMap = new WeakMap();
const domainSet = new WeakSet();
@ -935,8 +938,8 @@ REPLServer.prototype.createContext = function() {
context = vm.createContext();
});
for (const name of ObjectGetOwnPropertyNames(global)) {
// Only set properties on the context that do not exist as primordial.
if (!(name in primordials)) {
// Only set properties that do not already exist as a global builtin.
if (!globalBuiltins.has(name)) {
ObjectDefineProperty(context, name,
ObjectGetOwnPropertyDescriptor(global, name));
}
@ -1283,8 +1286,14 @@ function complete(line, callback) {
completionGroups.push(
filteredOwnPropertyNames.call(this, contextProto));
}
completionGroups.push(
filteredOwnPropertyNames.call(this, this.context));
const contextOwnNames =
filteredOwnPropertyNames.call(this, this.context);
if (!this.useGlobal) {
// When the context is not `global`, builtins are not own
// properties of it.
contextOwnNames.push(...globalBuiltins);
}
completionGroups.push(contextOwnNames);
if (filter !== '') addCommonWords(completionGroups);
completionGroupsLoaded();
} else {