Skip to content

Commit 74b1b2d

Browse files
noftalyfisker
andauthored
prefer-math-trunc: Use suggestion instead of fix for x | 0 (#1014)
Co-authored-by: fisker Cheung <[email protected]>
1 parent b7cbd99 commit 74b1b2d

File tree

4 files changed

+238
-239
lines changed

4 files changed

+238
-239
lines changed

rules/prefer-math-trunc.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
const {hasSideEffect} = require('eslint-utils');
33
const getDocumentationUrl = require('./utils/get-documentation-url');
44

5-
const MESSAGE_ID_BITWISE = 'bitwise';
6-
const MESSAGE_ID_BITWISE_NOT = 'bitwiseNot';
5+
const ERROR_BITWISE = 'error-bitwise';
6+
const ERROR_BITWISE_NOT = 'error-bitwise-not';
7+
const SUGGESTION_BITWISE = 'suggestion-bitwise';
78
const messages = {
8-
[MESSAGE_ID_BITWISE]: 'Use `Math.trunc` instead of `{{operator}} {{value}}`.',
9-
[MESSAGE_ID_BITWISE_NOT]: 'Use `Math.trunc` instead of `~~`.'
9+
[ERROR_BITWISE]: 'Use `Math.trunc` instead of `{{operator}} {{value}}`.',
10+
[ERROR_BITWISE_NOT]: 'Use `Math.trunc` instead of `~~`.',
11+
[SUGGESTION_BITWISE]: 'Replace `{{operator}} {{value}}` with `Math.trunc`.'
1012
};
1113

1214
const createBitwiseNotSelector = (level, isNegative) => {
@@ -49,30 +51,45 @@ const create = context => {
4951

5052
const problem = {
5153
node,
52-
messageId: MESSAGE_ID_BITWISE,
54+
messageId: ERROR_BITWISE,
5355
data: {
5456
operator,
5557
value: right.raw
5658
}
5759
};
5860

5961
if (!isAssignment || !hasSideEffect(left, sourceCode)) {
60-
problem.fix = fixer => {
62+
const fix = fixer => {
6163
let fixed = mathTruncFunctionCall(left);
6264
if (isAssignment) {
6365
fixed = `${sourceCode.getText(left)} = ${fixed}`;
6466
}
6567

6668
return fixer.replaceText(node, fixed);
6769
};
70+
71+
if (operator === '|') {
72+
problem.suggest = [
73+
{
74+
messageId: SUGGESTION_BITWISE,
75+
data: {
76+
operator,
77+
value: right.raw
78+
},
79+
fix
80+
}
81+
];
82+
} else {
83+
problem.fix = fix;
84+
}
6885
}
6986

7087
context.report(problem);
7188
},
7289
[bitwiseNotUnaryExpressionSelector]: node => {
7390
context.report({
7491
node,
75-
messageId: MESSAGE_ID_BITWISE_NOT,
92+
messageId: ERROR_BITWISE_NOT,
7693
fix: fixer => fixer.replaceText(node, mathTruncFunctionCall(node.argument.argument))
7794
});
7895
}

test/prefer-math-trunc.js

Lines changed: 116 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {outdent} from 'outdent';
22
import {test} from './utils/test.js';
33

4-
test({
4+
test.visualize({
55
valid: [
66
'const foo = 1 | 1;',
77
'const foo = 0 | 1;',
@@ -24,129 +24,127 @@ test({
2424
foo |= 1; // comment 2 and 1.2 | 0
2525
`
2626
],
27-
invalid: []
28-
});
29-
30-
test.visualize([
31-
// Basic "bitwise OR with 0" case
32-
'const foo = 1.1 | 0;',
33-
'const foo = 111 | 0;',
34-
'const foo = (1 + 2 / 3.4) | 0;',
35-
'const foo = bar((1.4 | 0) + 2);',
36-
'const foo = (0, 1.4) | 0;',
27+
invalid: [
28+
// Basic "bitwise OR with 0" case
29+
'const foo = 1.1 | 0;',
30+
'const foo = 111 | 0;',
31+
'const foo = (1 + 2 / 3.4) | 0;',
32+
'const foo = bar((1.4 | 0) + 2);',
33+
'const foo = (0, 1.4) | 0;',
3734

38-
// Different "types" of 0
39-
'const foo = 1.4 | 0.;',
40-
'const foo = 1.4 | .0;',
41-
'const foo = 1.4 | 0.0000_0000_0000;',
42-
'const foo = 1.4 | 0b0;',
43-
'const foo = 1.4 | 0x0000_0000_0000;',
44-
'const foo = 1.4 | 0o0;',
35+
// Different "types" of 0
36+
'const foo = 1.4 | 0.;',
37+
'const foo = 1.4 | .0;',
38+
'const foo = 1.4 | 0.0000_0000_0000;',
39+
'const foo = 1.4 | 0b0;',
40+
'const foo = 1.4 | 0x0000_0000_0000;',
41+
'const foo = 1.4 | 0o0;',
4542

46-
// Multiple bitwise OR
47-
'const foo = 1.23 | 0 | 4;',
43+
// Multiple bitwise OR
44+
'const foo = 1.23 | 0 | 4;',
4845

49-
// Basic "bitwise NOT" case
50-
'const foo = ~~3.9;',
51-
'const foo = ~~111;',
52-
'const foo = ~~(1 + 2 / 3.4);',
53-
'const foo = ~~1 + 2 / 3.4;',
54-
'const foo = ~~(0, 1.4);',
55-
'const foo = ~~~10.01;',
56-
'const foo = ~~(~10.01);',
57-
'const foo = ~(~~10.01);',
58-
'const foo = ~~-10.01;',
59-
'const foo = ~~~~10.01;',
46+
// Basic "bitwise NOT" case
47+
'const foo = ~~3.9;',
48+
'const foo = ~~111;',
49+
'const foo = ~~(1 + 2 / 3.4);',
50+
'const foo = ~~1 + 2 / 3.4;',
51+
'const foo = ~~(0, 1.4);',
52+
'const foo = ~~~10.01;',
53+
'const foo = ~~(~10.01);',
54+
'const foo = ~(~~10.01);',
55+
'const foo = ~~-10.01;',
56+
'const foo = ~~~~10.01;',
6057

61-
// Other operators
62-
'const foo = bar >> 0;',
63-
'const foo = bar << 0;',
64-
'const foo = bar ^ 0;',
58+
// Other operators
59+
'const foo = bar >> 0;',
60+
'const foo = bar << 0;',
61+
'const foo = bar ^ 0;',
6562

66-
// Case with objects (MemberExpression and ChainExpression)
67-
outdent`
68-
const foo = {a: {b: {c: 3}}};
69-
const bar = a.b.c | 0;
70-
`,
71-
outdent`
72-
const foo = {a: {b: {c: 3}}};
73-
const bar = a.b?.c | 0;
74-
`,
75-
outdent`
76-
const foo = {a: {b: {c: 3}}};
77-
const bar = ~~a.b?.c;
78-
`,
79-
// With a variable
80-
outdent`
81-
const foo = 3;
82-
const bar = foo | 0;
83-
`,
84-
outdent`
85-
const foo = 3;
86-
const bar = ~~foo;
87-
`,
63+
// Case with objects (MemberExpression and ChainExpression)
64+
outdent`
65+
const foo = {a: {b: {c: 3}}};
66+
const bar = a.b.c | 0;
67+
`,
68+
outdent`
69+
const foo = {a: {b: {c: 3}}};
70+
const bar = a.b?.c | 0;
71+
`,
72+
outdent`
73+
const foo = {a: {b: {c: 3}}};
74+
const bar = ~~a.b?.c;
75+
`,
76+
// With a variable
77+
outdent`
78+
const foo = 3;
79+
const bar = foo | 0;
80+
`,
81+
outdent`
82+
const foo = 3;
83+
const bar = ~~foo;
84+
`,
8885

89-
// With an AssignmentExpression
90-
outdent`
91-
let foo = 2;
92-
foo |= 0;
93-
`,
94-
outdent`
95-
const foo = {a: {b: 3.4}};
96-
foo.a.b |= 0;
97-
`,
98-
outdent`
99-
const foo = 10.01;
100-
const bar = ~~foo;
101-
`,
102-
outdent`
103-
let foo = 10.01;
104-
foo >>= 0;
105-
`,
106-
outdent`
107-
let foo = 10.01;
108-
foo <<= 0;
109-
`,
110-
outdent`
111-
let foo = 10.01;
112-
foo ^= 0;
113-
`,
86+
// With an AssignmentExpression
87+
outdent`
88+
let foo = 2;
89+
foo |= 0;
90+
`,
91+
outdent`
92+
const foo = {a: {b: 3.4}};
93+
foo.a.b |= 0;
94+
`,
95+
outdent`
96+
const foo = 10.01;
97+
const bar = ~~foo;
98+
`,
99+
outdent`
100+
let foo = 10.01;
101+
foo >>= 0;
102+
`,
103+
outdent`
104+
let foo = 10.01;
105+
foo <<= 0;
106+
`,
107+
outdent`
108+
let foo = 10.01;
109+
foo ^= 0;
110+
`,
114111

115-
// With comments
116-
'const foo = /* first comment */ 3.4 | 0; // A B C',
117-
'const foo = /* first comment */ ~~3.4; // A B C',
118-
outdent`
119-
const foo = {a: {b: 3.4}};
120-
foo /* Comment 1 */ .a /* Comment 2 */ . /* Comment 3 */ b |= /* Comment 4 */ 0 /* Comment 5 */;
121-
`,
122-
outdent`
123-
const foo = {a: {b: 3.4}};
124-
const bar = /* Comment 1 */ ~~ a /* Comment 3 */ . /* Comment 4 */ b /* Comment 5 */;
125-
`,
126-
'const foo = /* will keep */ 3.4 /* will remove 1 */ | /* will remove 2 */ 0;',
127-
'const foo = /* will keep */ ~ /* will remove 1 */ ~ /* will remove 2 */ 3.4;',
128-
outdent`
129-
const foo = 3.4; // comment 1
130-
foo |= 0; // comment 2
131-
`,
132-
outdent`
133-
const foo = 3.4; // comment 1
134-
const bar = ~~foo; // comment 2
135-
`,
112+
// With comments
113+
'const foo = /* first comment */ 3.4 | 0; // A B C',
114+
'const foo = /* first comment */ ~~3.4; // A B C',
115+
outdent`
116+
const foo = {a: {b: 3.4}};
117+
foo /* Comment 1 */ .a /* Comment 2 */ . /* Comment 3 */ b |= /* Comment 4 */ 0 /* Comment 5 */;
118+
`,
119+
outdent`
120+
const foo = {a: {b: 3.4}};
121+
const bar = /* Comment 1 */ ~~ a /* Comment 3 */ . /* Comment 4 */ b /* Comment 5 */;
122+
`,
123+
'const foo = /* will keep */ 3.4 /* will remove 1 */ | /* will remove 2 */ 0;',
124+
'const foo = /* will keep */ ~ /* will remove 1 */ ~ /* will remove 2 */ 3.4;',
125+
outdent`
126+
const foo = 3.4; // comment 1
127+
foo |= 0; // comment 2
128+
`,
129+
outdent`
130+
const foo = 3.4; // comment 1
131+
const bar = ~~foo; // comment 2
132+
`,
136133

137-
// Multiple errors
138-
'const foo = ~~bar | 0;',
139-
'const foo = ~~(bar| 0);',
140-
'const foo = bar | 0 | 0;',
141-
'const foo = ~~~~((bar | 0 | 0) >> 0 >> 0 << 0 << 0 ^ 0 ^0);',
134+
// Multiple errors
135+
'const foo = ~~bar | 0;',
136+
'const foo = ~~(bar| 0);',
137+
'const foo = bar | 0 | 0;',
138+
'const foo = ~~~~((bar | 0 | 0) >> 0 >> 0 << 0 << 0 ^ 0 ^0);',
142139

143-
// Left-hand side has side effect
144-
outdent`
145-
const foo = Array.from({length: 10}, (_, index) => (index + 1) + (index + 1) /100);
146-
let i = 0;
147-
while (i < foo.length) {
148-
foo[i++] |= 0;
149-
}
150-
console.log(foo);
151-
`
152-
]);
140+
// Left-hand side has side effect
141+
outdent`
142+
const foo = Array.from({length: 10}, (_, index) => (index + 1) + (index + 1) /100);
143+
let i = 0;
144+
while (i < foo.length) {
145+
foo[i++] |= 0;
146+
}
147+
console.log(foo);
148+
`
149+
]
150+
});

0 commit comments

Comments
 (0)