Skip to content

Commit dc90c1e

Browse files
MrHensindresorhus
authored andcommitted
prefer-exponentiation-operator: Fix operator precedence bugs (#305)
1 parent 0f8d5b4 commit dc90c1e

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

rules/prefer-exponentiation-operator.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,34 @@ const isMathPow = node => {
1212
);
1313
};
1414

15-
const parseArgument = (context, arg) => {
16-
if (arg.type === 'Identifier') {
17-
return arg.name;
18-
}
15+
const parseArgument = (source, arg) => {
16+
const text = source.getText(arg);
1917

20-
return context.getSourceCode().getText(arg);
18+
switch (arg.type) {
19+
case 'Identifier':
20+
return arg.name;
21+
case 'Literal':
22+
return text;
23+
case 'CallExpression':
24+
return text;
25+
case 'UnaryExpression':
26+
return text;
27+
default:
28+
// Handle cases like Math.pow(2, 2-1);
29+
return `(${text})`;
30+
}
2131
};
2232

2333
const fix = (context, node, fixer) => {
24-
const base = parseArgument(context, node.arguments[0]);
25-
const exponent = parseArgument(context, node.arguments[1]);
34+
const source = context.getSourceCode();
35+
const comments = source.getCommentsInside(node);
36+
37+
if (comments && comments.length > 0) {
38+
return;
39+
}
40+
41+
const base = parseArgument(source, node.arguments[0]);
42+
const exponent = parseArgument(source, node.arguments[1]);
2643

2744
const replacement = `${base} ** ${exponent}`;
2845

test/prefer-exponentiation-operator.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ ruleTester.run('prefer-exponentiation-operator', rule, {
2424
{
2525
code: 'const x = Math.pow(-2, (2 - 4) +0 -0.2);',
2626
errors: [{message}],
27-
output: 'const x = -2 ** (2 - 4) +0 -0.2;'
27+
output: 'const x = -2 ** ((2 - 4) +0 -0.2);'
2828
},
2929
{
3030
code: 'const x = Math.pow(Math.pow(2, 4), 8);',
@@ -48,6 +48,36 @@ ruleTester.run('prefer-exponentiation-operator', rule, {
4848
code: 'const x = Math.pow(foo(), bar());',
4949
errors: [{message}],
5050
output: 'const x = foo() ** bar();'
51+
},
52+
{
53+
code: 'const x = Math.pow(-2, 2 - 4);',
54+
errors: [{message}],
55+
output: 'const x = -2 ** (2 - 4);'
56+
},
57+
{
58+
code: 'const x = Math.pow(4 - 2, 2 - 4);',
59+
errors: [{message}],
60+
output: 'const x = (4 - 2) ** (2 - 4);'
61+
},
62+
{
63+
code: 'const x = Math.pow(\n2,\n2);',
64+
errors: [{message}],
65+
output: 'const x = 2 ** 2;'
66+
},
67+
{
68+
code: 'const x = Math.pow(\n2,2 +\n2);',
69+
errors: [{message}],
70+
output: 'const x = 2 ** (2 +\n2);'
71+
},
72+
{
73+
code: 'const x = Math.pow(\n2, // foo\n2);',
74+
errors: [{message}],
75+
output: 'const x = Math.pow(\n2, // foo\n2);'
76+
},
77+
{
78+
code: 'const x = Math.pow(// foo\n2, 2);',
79+
errors: [{message}],
80+
output: 'const x = Math.pow(// foo\n2, 2);'
5181
}
5282
]
5383
});

0 commit comments

Comments
 (0)