Skip to content

Commit b267927

Browse files
committed
fix(#74): correct exponentiation precedence
Closes #74.
1 parent 6e56162 commit b267927

File tree

5 files changed

+25
-12
lines changed

5 files changed

+25
-12
lines changed

docs/demo/astring.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/demo/astring.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/astring.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,13 @@ function expressionNeedsParenthesis(node, parentNode, isRightHand) {
113113
const parentNodePrecedence = EXPRESSIONS_PRECEDENCE[parentNode.type]
114114
if (nodePrecedence !== parentNodePrecedence) {
115115
// Different node types
116-
return nodePrecedence < parentNodePrecedence
116+
return (
117+
(!isRightHand &&
118+
nodePrecedence === 15 &&
119+
parentNodePrecedence === 14 &&
120+
parentNode.operator === '**') ||
121+
nodePrecedence < parentNodePrecedence
122+
)
117123
}
118124
if (nodePrecedence !== 13 && nodePrecedence !== 14) {
119125
// Not a `LogicalExpression` or `BinaryExpression`
@@ -843,17 +849,16 @@ export const baseGenerator = {
843849
this[node.right.type](node.right, state)
844850
},
845851
BinaryExpression: (BinaryExpression = function(node, state) {
846-
if (node.operator === 'in') {
852+
const isIn = node.operator === 'in'
853+
if (isIn) {
847854
// Avoids confusion in `for` loops initializers
848855
state.write('(')
849-
formatBinaryExpressionPart(state, node.left, node, false)
850-
state.write(' ' + node.operator + ' ')
851-
formatBinaryExpressionPart(state, node.right, node, true)
856+
}
857+
formatBinaryExpressionPart(state, node.left, node, false)
858+
state.write(' ' + node.operator + ' ')
859+
formatBinaryExpressionPart(state, node.right, node, true)
860+
if (isIn) {
852861
state.write(')')
853-
} else {
854-
formatBinaryExpressionPart(state, node.left, node, false)
855-
state.write(' ' + node.operator + ' ')
856-
formatBinaryExpressionPart(state, node.right, node, true)
857862
}
858863
}),
859864
LogicalExpression: BinaryExpression,

src/tests/fixtures/syntax/precedence.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ var r = (/ab+c/i).exec('abc');
2424
a = b ** 2 * 3;
2525
c = (d ** 2) ** 3;
2626
e = f ** 2 ** 3;
27+
e = (+2) ** 3;
28+
e = 2 ** +3;
2729
f = a + (b = 3);
2830
g = 1 && (() => {});
2931
g = (() => {}) && 1;

src/tests/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ test('Syntax check', assert => {
3939
files.forEach(filename => {
4040
const code = readFile(path.join(dirname, filename))
4141
const ast = parse(code, options)
42-
assert.is(generate(ast), code, filename.substring(0, filename.length - 3))
42+
assert.is(
43+
generate(ast),
44+
code,
45+
filename.substring(0, filename.length - 3),
46+
'Generates code with the expected format',
47+
)
4348
})
4449
})
4550

@@ -60,6 +65,7 @@ test('Tree comparison', assert => {
6065
formattedAst,
6166
ast,
6267
filename.substring(0, filename.length - 3),
68+
'Generates code with the same meaning',
6369
)
6470
})
6571
})

0 commit comments

Comments
 (0)