util: add internal assignFunctionName() function

PR-URL: https://github.com/nodejs/node/pull/57916
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
LiviaMedeiros 2025-04-18 01:14:24 +08:00 committed by Node.js GitHub Bot
parent 9acf6af17c
commit 40a657b330
2 changed files with 56 additions and 1 deletions

View File

@ -41,6 +41,7 @@ const {
StringPrototypeToUpperCase,
Symbol,
SymbolFor,
SymbolPrototypeGetDescription,
SymbolReplace,
SymbolSplit,
} = primordials;
@ -906,10 +907,37 @@ const encodingsMap = { __proto__: null };
for (let i = 0; i < encodings.length; ++i)
encodingsMap[encodings[i]] = i;
/**
* Reassigns the .name property of a function.
* Should be used when function can't be initially defined with desired name
* or when desired name should include `#`, `[`, `]`, etc.
* @param {string | symbol} name
* @param {Function} fn
* @param {object} [descriptor]
* @returns {Function} the same function, renamed
*/
function assignFunctionName(name, fn, descriptor = kEmptyObject) {
if (typeof name !== 'string') {
const symbolDescription = SymbolPrototypeGetDescription(name);
assert(symbolDescription !== undefined, 'Attempted to name function after descriptionless Symbol');
name = `[${symbolDescription}]`;
}
return ObjectDefineProperty(fn, 'name', {
__proto__: null,
writable: false,
enumerable: false,
configurable: true,
...ObjectGetOwnPropertyDescriptor(fn, 'name'),
...descriptor,
value: name,
});
}
module.exports = {
getLazy,
assertCrypto,
assertTypeScript,
assignFunctionName,
cachedResult,
convertToValidSignal,
createClassWrapper,

View File

@ -4,7 +4,7 @@
require('../common');
const assert = require('assert');
const { types } = require('util');
const { isError } = require('internal/util');
const { assignFunctionName, isError } = require('internal/util');
const vm = require('vm');
// Special cased errors. Test the internal function which is used in
@ -35,3 +35,30 @@ const vm = require('vm');
assert(!(differentRealmErr instanceof Error));
assert(isError(differentRealmErr));
}
{
const nameMap = new Map([
[ 'meaningfulName', 'meaningfulName' ],
[ '', '' ],
[ Symbol.asyncIterator, '[Symbol.asyncIterator]' ],
[ Symbol('notWellKnownSymbol'), '[notWellKnownSymbol]' ],
]);
for (const fn of [
() => {},
function() {},
function value() {},
({ value() {} }).value,
new Function(),
Function(),
function() {}.bind(null),
class {},
class value {},
]) {
for (const [ stringOrSymbol, expectedName ] of nameMap) {
const namedFn = assignFunctionName(stringOrSymbol, fn);
assert.strictEqual(fn, namedFn);
assert.strictEqual(namedFn.name, expectedName);
assert.strictEqual(namedFn.bind(null).name, `bound ${expectedName}`);
}
}
}