-
-
Notifications
You must be signed in to change notification settings - Fork 353
/
prefer-date-now.js
114 lines (107 loc) · 2.81 KB
/
prefer-date-now.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
'use strict';
const getDocumentationUrl = require('./utils/get-documentation-url');
const methodSelector = require('./utils/method-selector');
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 => {
const prefix = path ? `${path}.` : '';
return [
`[${prefix}type="NewExpression"]`,
`[${prefix}callee.type="Identifier"]`,
`[${prefix}callee.name="Date"]`,
`[${prefix}arguments.length=0]`
].join('');
};
const operatorsSelector = (...operators) => `:matches(${
operators.map(operator => `[operator="${operator}"]`).join(', ')
})`;
const newDateSelector = createNewDateSelector();
const methodsSelector = [
methodSelector({
names: ['getTime', 'valueOf'],
length: 0
}),
createNewDateSelector('callee.object')
].join('');
const constructorsSelector = [
'CallExpression',
'[callee.type="Identifier"]',
':matches([callee.name="Number"], [callee.name="BigInt"])',
'[arguments.length=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 create = context => {
const report = (node, problem) => context.report({
node,
messageId: MESSAGE_ID_DEFAULT,
fix: fixer => fixer.replaceText(node, 'Date.now()'),
...problem
});
return {
[methodsSelector](node) {
const method = node.callee.property;
report(node, {
node: method,
messageId: MESSAGE_ID_METHOD,
data: {method: method.name}
});
},
[constructorsSelector](node) {
const {name} = node.callee;
if (name === 'Number') {
report(node, {
messageId: MESSAGE_ID_NUMBER
});
} else {
report(node.arguments[0]);
}
},
[unaryExpressionsSelector](node) {
report(node.operator === '-' ? node.argument : node);
},
[assignmentExpressionSelector](node) {
report(node);
},
[binaryExpressionSelector](node) {
report(node);
}
};
};
const schema = [];
module.exports = {
create,
meta: {
type: 'suggestion',
docs: {
url: getDocumentationUrl(__filename)
},
fixable: 'code',
schema,
messages
}
};