| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | 'use strict';const {GlobalReferenceTracker} = require('./utils/global-reference-tracker.js');const {replaceReferenceIdentifier} = require('./fix/index.js');const {fixSpaceAroundKeyword} = require('./fix/index.js');const MESSAGE_ID_ERROR = 'error';const MESSAGE_ID_SUGGESTION = 'suggestion';const messages = {	[MESSAGE_ID_ERROR]: 'Prefer `Number.{{property}}` over `{{description}}`.',	[MESSAGE_ID_SUGGESTION]: 'Replace `{{description}}` with `Number.{{property}}`.',};const globalObjects = {	// Safe to replace with `Number` properties	parseInt: true,	parseFloat: true,	NaN: true,	Infinity: true,	// Unsafe to replace with `Number` properties	isNaN: false,	isFinite: false,};const isNegative = node => {	const {parent} = node;	return parent.type === 'UnaryExpression' && parent.operator === '-' && parent.argument === node;};function checkProperty({node, path: [name]}, sourceCode) {	const {parent} = node;	let property = name;	if (name === 'Infinity') {		property = isNegative(node) ? 'NEGATIVE_INFINITY' : 'POSITIVE_INFINITY';	}	const problem = {		node,		messageId: MESSAGE_ID_ERROR,		data: {			description: name,			property,		},	};	if (property === 'NEGATIVE_INFINITY') {		problem.node = parent;		problem.data.description = '-Infinity';		problem.fix = function * (fixer) {			yield fixer.replaceText(parent, 'Number.NEGATIVE_INFINITY');			yield * fixSpaceAroundKeyword(fixer, parent, sourceCode);		};		return problem;	}	const fix = fixer => replaceReferenceIdentifier(node, `Number.${property}`, fixer, sourceCode);	const isSafeToFix = globalObjects[name];	if (isSafeToFix) {		problem.fix = fix;	} else {		problem.suggest = [			{				messageId: MESSAGE_ID_SUGGESTION,				fix,			},		];	}	return problem;}/** @param {import('eslint').Rule.RuleContext} context */const create = context => {	const {		checkInfinity,	} = {		checkInfinity: true,		...context.options[0],	};	const sourceCode = context.getSourceCode();	let objects = Object.keys(globalObjects);	if (!checkInfinity) {		objects = objects.filter(name => name !== 'Infinity');	}	const tracker = new GlobalReferenceTracker({		objects,		handle: reference => checkProperty(reference, sourceCode),	});	return tracker.createListeners(context);};const schema = [	{		type: 'object',		additionalProperties: false,		properties: {			checkInfinity: {				type: 'boolean',				default: true,			},		},	},];/** @type {import('eslint').Rule.RuleModule} */module.exports = {	create,	meta: {		type: 'suggestion',		docs: {			description: 'Prefer `Number` static properties over global ones.',		},		fixable: 'code',		hasSuggestions: true,		schema,		messages,	},};
 |