Skip to content

Commit 815fbec

Browse files
addaleaxtargos
authored andcommitted
repl: do not include legacy getter/setter methods in completion
For every object that inherits from `Object.prototype`, the REPL includes the `Object.prototype` methods in its autocompletion. This is already a little noisy, but in particular, this also includes the legacy `__defineGetter__` family of methods; since those are deprecated and not in practical use anymore, it helps reduce noise a bit to remove them. This commit does not remove `__proto__` as it is a little more popular and, despite its downsides, a slightly more convenient way to access the prototype of an object in the REPL than `Object.getPrototypeOf(...)`. PR-URL: #39576 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 93bbaa0 commit 815fbec

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

‎lib/repl.js‎

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,11 +1188,31 @@ function isIdentifier(str) {
11881188
returntrue;
11891189
}
11901190

1191+
functionisNotLegacyObjectPrototypeMethod(str){
1192+
returnisIdentifier(str)&&
1193+
str!=='__defineGetter__'&&
1194+
str!=='__defineSetter__'&&
1195+
str!=='__lookupGetter__'&&
1196+
str!=='__lookupSetter__';
1197+
}
1198+
11911199
functionfilteredOwnPropertyNames(obj){
11921200
if(!obj)return[];
1201+
// `Object.prototype` is the only non-contrived object that fulfills
1202+
// `Object.getPrototypeOf(X) === null &&
1203+
// Object.getPrototypeOf(Object.getPrototypeOf(X.constructor)) === X`.
1204+
letisObjectPrototype=false;
1205+
if(ObjectGetPrototypeOf(obj)===null){
1206+
constctorDescriptor=ObjectGetOwnPropertyDescriptor(obj,'constructor');
1207+
if(ctorDescriptor&&ctorDescriptor.value){
1208+
constctorProto=ObjectGetPrototypeOf(ctorDescriptor.value);
1209+
isObjectPrototype=ctorProto&&ObjectGetPrototypeOf(ctorProto)===obj;
1210+
}
1211+
}
11931212
constfilter=ALL_PROPERTIES|SKIP_SYMBOLS;
1194-
returnArrayPrototypeFilter(getOwnNonIndexProperties(obj,filter),
1195-
isIdentifier);
1213+
returnArrayPrototypeFilter(
1214+
getOwnNonIndexProperties(obj,filter),
1215+
isObjectPrototype ? isNotLegacyObjectPrototypeMethod : isIdentifier);
11961216
}
11971217

11981218
functiongetGlobalLexicalScopeNames(contextId){

‎test/parallel/test-repl-tab-complete.js‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,18 @@ testMe.complete('obj.', common.mustCall((error, data) => {
443443
assert(data[0].includes('obj.key'));
444444
}));
445445

446+
// Make sure tab completion does not include __defineSetter__ and friends.
447+
putIn.run(['.clear']);
448+
449+
putIn.run(['var obj = {};']);
450+
testMe.complete('obj.',common.mustCall(function(error,data){
451+
assert.strictEqual(data[0].includes('obj.__defineGetter__'),false);
452+
assert.strictEqual(data[0].includes('obj.__defineSetter__'),false);
453+
assert.strictEqual(data[0].includes('obj.__lookupGetter__'),false);
454+
assert.strictEqual(data[0].includes('obj.__lookupSetter__'),false);
455+
assert.strictEqual(data[0].includes('obj.__proto__'),true);
456+
}));
457+
446458
// Tab completion for files/directories
447459
{
448460
putIn.run(['.clear']);

0 commit comments

Comments
 (0)