tools: add polyfilled option to prefer-primordials rule

PR-URL: https://github.com/nodejs/node/pull/55318
Reviewed-By: Michaël Zasso <targos@protonmail.com>
This commit is contained in:
Antoine du Hamel 2024-10-17 12:37:54 +02:00 committed by GitHub
parent e2242b4e25
commit 5e5af2947f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 0 deletions

View File

@ -177,6 +177,22 @@ new RuleTester({
options: [{ name: 'Symbol' }], options: [{ name: 'Symbol' }],
errors: [{ message: /const { SymbolIterator } = primordials/ }] errors: [{ message: /const { SymbolIterator } = primordials/ }]
}, },
{
code: `
const { SymbolAsyncDispose } = primordials;
const a = { [SymbolAsyncDispose] () {} }
`,
options: [{ name: 'Symbol', polyfilled: ['asyncDispose', 'dispose'] }],
errors: [{ message: /const { SymbolAsyncDispose } = require\("internal\/util"\)/ }]
},
{
code: `
const { SymbolDispose } = primordials;
const a = { [SymbolDispose] () {} }
`,
options: [{ name: 'Symbol', polyfilled: ['asyncDispose', 'dispose'] }],
errors: [{ message: /const { SymbolDispose } = require\("internal\/util"\)/ }]
},
{ {
code: ` code: `
const { ObjectDefineProperty, Symbol } = primordials; const { ObjectDefineProperty, Symbol } = primordials;

View File

@ -74,6 +74,7 @@ module.exports = {
meta: { meta: {
messages: { messages: {
error: 'Use `const { {{name}} } = primordials;` instead of the global.', error: 'Use `const { {{name}} } = primordials;` instead of the global.',
errorPolyfill: 'Use `const { {{name}} } = require("internal/util");` instead of the primordial.',
}, },
schema: { schema: {
type: 'array', type: 'array',
@ -88,6 +89,10 @@ module.exports = {
items: { type: 'string' }, items: { type: 'string' },
}, },
into: { type: 'string' }, into: { type: 'string' },
polyfilled: {
type: 'array',
items: { type: 'string' },
},
}, },
additionalProperties: false, additionalProperties: false,
}, },
@ -99,6 +104,7 @@ module.exports = {
const nameMap = new Map(); const nameMap = new Map();
const renameMap = new Map(); const renameMap = new Map();
const polyfilledSet = new Set();
for (const option of context.options) { for (const option of context.options) {
const names = option.ignore || []; const names = option.ignore || [];
@ -109,6 +115,11 @@ module.exports = {
if (option.into) { if (option.into) {
renameMap.set(option.name, option.into); renameMap.set(option.name, option.into);
} }
if (option.polyfilled) {
for (const propertyName of option.polyfilled) {
polyfilledSet.add(`${option.name}${propertyName[0].toUpperCase()}${propertyName.slice(1)}`);
}
}
} }
let reported; let reported;
@ -186,6 +197,17 @@ module.exports = {
}, },
VariableDeclarator(node) { VariableDeclarator(node) {
const name = node.init?.name; const name = node.init?.name;
if (name === 'primordials' && node.id.type === 'ObjectPattern') {
const name = node.id.properties.find(({ key }) => polyfilledSet.has(key.name))?.key.name;
if (name) {
context.report({
node,
messageId: 'errorPolyfill',
data: { name },
});
return;
}
}
if (name !== undefined && isTarget(nameMap, name) && if (name !== undefined && isTarget(nameMap, name) &&
node.id.type === 'Identifier' && node.id.type === 'Identifier' &&
!globalScope.set.get(name)?.defs.length) { !globalScope.set.get(name)?.defs.length) {