elearning/Frontend-Learner/node_modules/eslint-plugin-unicorn/rules/prefer-bigint-literals.js
2026-01-13 10:48:02 +07:00

129 lines
2.6 KiB
JavaScript

import {
isCallExpression,
isStringLiteral,
} from './ast/index.js';
const MESSAGE_ID_ERROR = 'prefer-bigint-literals/error';
const MESSAGE_ID_SUGGESTION = 'prefer-bigint-literals/suggestion';
const messages = {
[MESSAGE_ID_ERROR]: 'Prefer using bigint literal over `BigInt(…)`.',
[MESSAGE_ID_SUGGESTION]: 'Replace with {{replacement}}.',
};
const canUseNumericLiteralRaw = numericLiteral => {
const raw = numericLiteral.raw.replaceAll('_', '').toLowerCase();
if (raw.includes('.')) {
return false;
}
const {value} = numericLiteral;
for (const {prefix, base} of [
{prefix: '0b', base: 2},
{prefix: '0o', base: 8},
{prefix: '0x', base: 16},
]) {
if (raw.startsWith(prefix)) {
return raw.slice(2) === value.toString(base);
}
}
if (raw.includes('e')) {
return false;
}
return raw === String(value);
};
function getReplacement(valueNode) {
if (isStringLiteral(valueNode)) {
const raw = valueNode.raw.slice(1, -1);
try {
BigInt(raw);
} catch {
return;
}
return {shouldUseSuggestion: false, text: `${raw.trimEnd()}n`};
}
const {value, raw} = valueNode;
if (!Number.isInteger(value)) {
return;
}
let bigint;
try {
bigint = BigInt(value);
} catch {
return;
}
const shouldUseSuggestion = !canUseNumericLiteralRaw(valueNode);
const text = shouldUseSuggestion ? `${bigint}n` : `${raw}n`;
return {shouldUseSuggestion, text};
}
/** @param {import('eslint').Rule.RuleContext} context */
const create = context => ({
CallExpression(callExpression) {
if (!isCallExpression(callExpression, {
name: 'BigInt',
argumentsLength: 1,
optional: false,
})) {
return;
}
const [valueNode] = callExpression.arguments;
const replacement = getReplacement(valueNode);
if (!replacement) {
return;
}
const problem = {
node: callExpression,
messageId: MESSAGE_ID_ERROR,
};
const {shouldUseSuggestion, text} = replacement;
/** @param {import('eslint').Rule.RuleFixer} fixer */
const fix = fixer => fixer.replaceText(callExpression, text);
if (shouldUseSuggestion || context.sourceCode.getCommentsInside(callExpression).length > 0) {
problem.suggest = [
{
messageId: MESSAGE_ID_SUGGESTION,
data: {
replacement: text.length < 20 ? `\`${text}\`` : 'a bigint literal',
},
fix,
},
];
} else {
problem.fix = fix;
}
return problem;
},
});
/** @type {import('eslint').Rule.RuleModule} */
const config = {
create,
meta: {
type: 'suggestion',
docs: {
description: 'Prefer `BigInt` literals over the constructor.',
recommended: 'unopinionated',
},
fixable: 'code',
hasSuggestions: true,
messages,
},
};
export default config;