123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- 'use strict';
- const {
- matches,
- methodCallSelector,
- newExpressionSelector,
- callExpressionSelector,
- } = require('./selectors/index.js');
- const {fixSpaceAroundKeyword} = require('./fix/index.js');
- const MESSAGE_ID_DEFAULT = 'prefer-date';
- const MESSAGE_ID_METHOD = 'prefer-date-now-over-methods';
- const MESSAGE_ID_NUMBER = 'prefer-date-now-over-number-data-object';
- const messages = {
- [MESSAGE_ID_DEFAULT]: 'Prefer `Date.now()` over `new Date()`.',
- [MESSAGE_ID_METHOD]: 'Prefer `Date.now()` over `Date#{{method}}()`.',
- [MESSAGE_ID_NUMBER]: 'Prefer `Date.now()` over `Number(new Date())`.',
- };
- const createNewDateSelector = path => newExpressionSelector({path, name: 'Date', argumentsLength: 0});
- const operatorsSelector = (...operators) => matches(operators.map(operator => `[operator="${operator}"]`));
- // `new Date()`
- const newDateSelector = createNewDateSelector();
- // `new Date().{getTime,valueOf}()`
- const methodsSelector = [
- methodCallSelector({
- methods: ['getTime', 'valueOf'],
- argumentsLength: 0,
- }),
- createNewDateSelector('callee.object'),
- ].join('');
- // `{Number,BigInt}(new Date())`
- const builtinObjectSelector = [
- callExpressionSelector({names: ['Number', 'BigInt'], argumentsLength: 1}),
- createNewDateSelector('arguments.0'),
- ].join('');
- // https://github.com/estree/estree/blob/master/es5.md#unaryoperator
- const unaryExpressionsSelector = [
- 'UnaryExpression',
- operatorsSelector('+', '-'),
- createNewDateSelector('argument'),
- ].join('');
- const assignmentExpressionSelector = [
- 'AssignmentExpression',
- operatorsSelector('-=', '*=', '/=', '%=', '**='),
- '>',
- `${newDateSelector}.right`,
- ].join('');
- const binaryExpressionSelector = [
- 'BinaryExpression',
- operatorsSelector('-', '*', '/', '%', '**'),
- // Both `left` and `right` properties
- '>',
- newDateSelector,
- ].join('');
- const getProblem = (node, problem, sourceCode) => ({
- node,
- messageId: MESSAGE_ID_DEFAULT,
- * fix(fixer) {
- yield fixer.replaceText(node, 'Date.now()');
- if (node.type === 'UnaryExpression') {
- yield * fixSpaceAroundKeyword(fixer, node, sourceCode);
- }
- },
- ...problem,
- });
- /** @param {import('eslint').Rule.RuleContext} context */
- const create = context => ({
- [methodsSelector](node) {
- const method = node.callee.property;
- return getProblem(node, {
- node: method,
- messageId: MESSAGE_ID_METHOD,
- data: {method: method.name},
- });
- },
- [builtinObjectSelector](node) {
- const {name} = node.callee;
- if (name === 'Number') {
- return getProblem(node, {
- messageId: MESSAGE_ID_NUMBER,
- });
- }
- return getProblem(node.arguments[0]);
- },
- [unaryExpressionsSelector](node) {
- return getProblem(
- node.operator === '-' ? node.argument : node,
- {},
- context.getSourceCode(),
- );
- },
- [assignmentExpressionSelector](node) {
- return getProblem(node);
- },
- [binaryExpressionSelector](node) {
- return getProblem(node);
- },
- });
- /** @type {import('eslint').Rule.RuleModule} */
- module.exports = {
- create,
- meta: {
- type: 'suggestion',
- docs: {
- description: 'Prefer `Date.now()` to get the number of milliseconds since the Unix Epoch.',
- },
- fixable: 'code',
- messages,
- },
- };
|