mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
lib: add bound apply variants of varargs primordials
Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: https://github.com/nodejs/node/pull/37005 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
1 parent
029d1fd797
commit
728fee22e9
3 files changed
+60
-10
No files matched your search
@@ -21,10 +21,36 @@ const {
|
||||
// `uncurryThis` is equivalent to `func => Function.prototype.call.bind(func)`.
|
||||
// It is using `bind.bind(call)` to avoid using `Function.prototype.bind`
|
||||
// and `Function.prototype.call` after it may have been mutated by users.
|
||||
const { bind, call } = Function.prototype;
|
||||
const { apply, bind, call } = Function.prototype;
|
||||
const uncurryThis = bind.bind(call);
|
||||
primordials.uncurryThis = uncurryThis;
|
||||
|
||||
// `applyBind` is equivalent to `func => Function.prototype.apply.bind(func)`.
|
||||
// It is using `bind.bind(apply)` to avoid using `Function.prototype.bind`
|
||||
// and `Function.prototype.apply` after it may have been mutated by users.
|
||||
const applyBind = bind.bind(apply);
|
||||
primordials.applyBind = applyBind;
|
||||
|
||||
// Methods that accept a variable number of arguments, and thus it's useful to
|
||||
// also create `${prefix}${key}Apply`, which uses `Function.prototype.apply`,
|
||||
// instead of `Function.prototype.call`, and thus doesn't require iterator
|
||||
// destructuring.
|
||||
const varargsMethods = [
|
||||
// 'ArrayPrototypeConcat' is omitted, because it performs the spread
|
||||
// on its own for arrays and array-likes with a truthy
|
||||
// @@isConcatSpreadable symbol property.
|
||||
'ArrayOf',
|
||||
'ArrayPrototypePush',
|
||||
'ArrayPrototypeUnshift',
|
||||
// 'FunctionPrototypeCall' is omitted, since there's 'ReflectApply'
|
||||
// and 'FunctionPrototypeApply'.
|
||||
'MathHypot',
|
||||
'MathMax',
|
||||
'MathMin',
|
||||
'StringPrototypeConcat',
|
||||
'TypedArrayOf',
|
||||
];
|
||||
|
||||
function getNewKey(key) {
|
||||
return typeof key === 'symbol' ?
|
||||
`Symbol${key.description[7].toUpperCase()}${key.description.slice(8)}` :
|
||||
@@ -51,7 +77,13 @@ function copyPropsRenamed(src, dest, prefix) {
|
||||
if ('get' in desc) {
|
||||
copyAccessor(dest, prefix, newKey, desc);
|
||||
} else {
|
||||
ReflectDefineProperty(dest, `${prefix}${newKey}`, desc);
|
||||
const name = `${prefix}${newKey}`;
|
||||
ReflectDefineProperty(dest, name, desc);
|
||||
if (varargsMethods.includes(name)) {
|
||||
ReflectDefineProperty(dest, `${name}Apply`, {
|
||||
value: applyBind(desc.value, src),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,10 +95,18 @@ function copyPropsRenamedBound(src, dest, prefix) {
|
||||
if ('get' in desc) {
|
||||
copyAccessor(dest, prefix, newKey, desc);
|
||||
} else {
|
||||
if (typeof desc.value === 'function') {
|
||||
desc.value = desc.value.bind(src);
|
||||
const { value } = desc;
|
||||
if (typeof value === 'function') {
|
||||
desc.value = value.bind(src);
|
||||
}
|
||||
|
||||
const name = `${prefix}${newKey}`;
|
||||
ReflectDefineProperty(dest, name, desc);
|
||||
if (varargsMethods.includes(name)) {
|
||||
ReflectDefineProperty(dest, `${name}Apply`, {
|
||||
value: applyBind(value, src),
|
||||
});
|
||||
}
|
||||
ReflectDefineProperty(dest, `${prefix}${newKey}`, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,10 +118,18 @@ function copyPrototype(src, dest, prefix) {
|
||||
if ('get' in desc) {
|
||||
copyAccessor(dest, prefix, newKey, desc);
|
||||
} else {
|
||||
if (typeof desc.value === 'function') {
|
||||
desc.value = uncurryThis(desc.value);
|
||||
const { value } = desc;
|
||||
if (typeof value === 'function') {
|
||||
desc.value = uncurryThis(value);
|
||||
}
|
||||
|
||||
const name = `${prefix}${newKey}`;
|
||||
ReflectDefineProperty(dest, name, desc);
|
||||
if (varargsMethods.includes(name)) {
|
||||
ReflectDefineProperty(dest, `${name}Apply`, {
|
||||
value: applyBind(value),
|
||||
});
|
||||
}
|
||||
ReflectDefineProperty(dest, `${prefix}${newKey}`, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ const {
|
||||
ArrayPrototypeFilter,
|
||||
ArrayPrototypeForEach,
|
||||
ArrayPrototypePush,
|
||||
ArrayPrototypePushApply,
|
||||
ArrayPrototypeSort,
|
||||
ArrayPrototypeUnshift,
|
||||
BigIntPrototypeValueOf,
|
||||
@@ -665,7 +666,7 @@ function getKeys(value, showHidden) {
|
||||
if (showHidden) {
|
||||
keys = ObjectGetOwnPropertyNames(value);
|
||||
if (symbols.length !== 0)
|
||||
ArrayPrototypePush(keys, ...symbols);
|
||||
ArrayPrototypePushApply(keys, symbols);
|
||||
} else {
|
||||
// This might throw if `value` is a Module Namespace Object from an
|
||||
// unevaluated module, but we don't want to perform the actual type
|
||||
@@ -681,7 +682,7 @@ function getKeys(value, showHidden) {
|
||||
}
|
||||
if (symbols.length !== 0) {
|
||||
const filter = (key) => ObjectPrototypePropertyIsEnumerable(value, key);
|
||||
ArrayPrototypePush(keys, ...ArrayPrototypeFilter(symbols, filter));
|
||||
ArrayPrototypePushApply(keys, ArrayPrototypeFilter(symbols, filter));
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
|
||||
@@ -1313,6 +1313,7 @@ function complete(line, callback) {
|
||||
if (!this.useGlobal) {
|
||||
// When the context is not `global`, builtins are not own
|
||||
// properties of it.
|
||||
// `globalBuiltins` is a `SafeSet`, not an Array-like.
|
||||
ArrayPrototypePush(contextOwnNames, ...globalBuiltins);
|
||||
}
|
||||
ArrayPrototypePush(completionGroups, contextOwnNames);
|
||||
|
||||
Reference in new issue
Block a user