diff --git a/acorn/src/expression.js b/acorn/src/expression.js index 32d92d9ae..0d1b3fa8a 100644 --- a/acorn/src/expression.js +++ b/acorn/src/expression.js @@ -221,7 +221,7 @@ pp.buildBinary = function(startPos, startLoc, left, right, op, logical) { // Parse unary operators, both prefix and postfix. -pp.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { +pp.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec) { let startPos = this.start, startLoc = this.startLoc, expr if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) { expr = this.parseAwait() @@ -231,7 +231,7 @@ pp.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { node.operator = this.value node.prefix = true this.next() - node.argument = this.parseMaybeUnary(null, true) + node.argument = this.parseMaybeUnary(null, true, update) this.checkExpressionErrors(refDestructuringErrors, true) if (update) this.checkLValSimple(node.argument) else if (this.strict && node.operator === "delete" && @@ -255,10 +255,14 @@ pp.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { } } - if (!sawUnary && this.eat(tt.starstar)) - return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) - else + if (!incDec && this.eat(tt.starstar)) { + if (sawUnary) + this.unexpected(this.lastTokStart) + else + return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) + } else { return expr + } } function isPrivateFieldAccess(node) { diff --git a/test/tests-asyncawait.js b/test/tests-asyncawait.js index e5ed2e7c5..7b0f4107c 100644 --- a/test/tests-asyncawait.js +++ b/test/tests-asyncawait.js @@ -3526,4 +3526,16 @@ testFail("abc: async function a() {}", "Unexpected token (1:5)", {ecmaVersion: 8 testFail("(async() => { await 4 ** 2 })()", "Unexpected token (1:22)", {ecmaVersion: 8}) +test("(async() => { await (4 ** 2) })()", {}, {ecmaVersion: 8}) + +testFail("async() => (await 1 ** 3)", "Unexpected token (1:20)", {ecmaVersion: 8}) + +test("async() => (await (1 ** 3))", {}, {ecmaVersion: 8}) + +testFail("async() => await 5 ** 6", "Unexpected token (1:19)", {ecmaVersion: 8}) + +test("async() => await (5 ** 6)", {}, {ecmaVersion: 8}) + +testFail("async() => await (5) ** 6", "Unexpected token (1:21)", {ecmaVersion: 8}) + testFail("4 + async() => 2", "Unexpected token (1:12)", {ecmaVersion: 8, loose: false}) diff --git a/test/tests-es7.js b/test/tests-es7.js index 4130cb22d..b5c251ce3 100644 --- a/test/tests-es7.js +++ b/test/tests-es7.js @@ -228,6 +228,8 @@ testFail("~3 ** 2;", "Unexpected token (1:3)", { ecmaVersion: 7 }); testFail("!1 ** 2;", "Unexpected token (1:3)", { ecmaVersion: 7 }); testFail("-2** 2;", "Unexpected token (1:2)", { ecmaVersion: 7 }); testFail("+2** 2;", "Unexpected token (1:2)", { ecmaVersion: 7 }); +testFail("-(i--) ** 2", "Unexpected token (1:7)", {ecmaVersion: 7}); +testFail("+(i--) ** 2", "Unexpected token (1:7)", {ecmaVersion: 7}); // make sure base operand check doesn't affect other operators test("-a * 5", {