diff --git a/CHANGELOG.md b/CHANGELOG.md index 3134799f03..ad118e0e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,14 @@ See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog. ## 6.0.14 + * **Spec Compliancy** + * Update exponentiation operator precedence. + * Fix parser bug where arrow functions have a higher precedence than they should. * **Bug Fix** * Fix SystemJS module formatter exporting function parameters. * Ensure that invalid identifier JSX attribute keys are quoted when transforming to calls. * Fix ES3 property literal plugin. * Fix parameters after defaults in arrow functions refering to the wrong `arguments`. - * Fix parser bug where arrow functions have a higher precedence than they should. ## 6.0.13 diff --git a/packages/babylon/src/parser/expression.js b/packages/babylon/src/parser/expression.js index 677e78a1ed..6d2869f4b7 100644 --- a/packages/babylon/src/parser/expression.js +++ b/packages/babylon/src/parser/expression.js @@ -173,10 +173,18 @@ pp.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { let node = this.startNodeAt(leftStartPos, leftStartLoc); node.left = left; node.operator = this.state.value; + + if (node.operator === "**" && left.type === "UnaryExpression" && left.extra && !left.extra.parenthesizedArgument) { + this.raise(left.argument.start, "Illegal expression. Wrap left hand side or entire exponentiation in parentheses."); + } + let op = this.state.type; this.next(); - let startPos = this.state.start, startLoc = this.state.startLoc; + + let startPos = this.state.start; + let startLoc = this.state.startLoc; node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec, noIn); + this.finishNode(node, (op === tt.logicalOR || op === tt.logicalAND) ? "LogicalExpression" : "BinaryExpression"); return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); } @@ -188,17 +196,26 @@ pp.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { pp.parseMaybeUnary = function (refShorthandDefaultPos) { if (this.state.type.prefix) { - let node = this.startNode(), update = this.match(tt.incDec); + let node = this.startNode(); + let update = this.match(tt.incDec); node.operator = this.state.value; node.prefix = true; this.next(); + + let argType = this.state.type; + this.addExtra(node, "parenthesizedArgument", argType === tt.parenL); node.argument = this.parseMaybeUnary(); - if (refShorthandDefaultPos && refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start); + + if (refShorthandDefaultPos && refShorthandDefaultPos.start) { + this.unexpected(refShorthandDefaultPos.start); + } + if (update) { this.checkLVal(node.argument); } else if (this.state.strict && node.operator === "delete" && node.argument.type === "Identifier") { this.raise(node.start, "Deleting local variable in strict mode"); } + return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); } diff --git a/packages/babylon/test/fixtures/experimental/exponentiation-operator/options.json b/packages/babylon/test/fixtures/experimental/exponentiation-operator/options.json new file mode 100644 index 0000000000..d01676b6ba --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/exponentiation-operator/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["exponentiationOperator"] +} diff --git a/packages/babylon/test/fixtures/experimental/exponentiation-operator/unparenthesized-left/actual.js b/packages/babylon/test/fixtures/experimental/exponentiation-operator/unparenthesized-left/actual.js new file mode 100644 index 0000000000..065fc4dab2 --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/exponentiation-operator/unparenthesized-left/actual.js @@ -0,0 +1 @@ +-5 ** 6; diff --git a/packages/babylon/test/fixtures/experimental/exponentiation-operator/unparenthesized-left/options.json b/packages/babylon/test/fixtures/experimental/exponentiation-operator/unparenthesized-left/options.json new file mode 100644 index 0000000000..2c624e8cec --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/exponentiation-operator/unparenthesized-left/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Illegal expression. Wrap left hand side or entire exponentiation in parentheses. (1:1)" +}