diff --git a/acorn.js b/acorn.js index 8515d6d0b0..b3ee37430f 100644 --- a/acorn.js +++ b/acorn.js @@ -659,8 +659,8 @@ var b_stat = {token: "{", isExpr: false}, b_expr = {token: "{", isExpr: true}, b_tmpl = {token: "${", isExpr: true}; var p_stat = {token: "(", isExpr: false}, p_expr = {token: "(", isExpr: true}; - var q_tmpl = {token: "`", isExpr: true}; var j_oTag = {token: "...", isExpr: true}; + var q_tmpl = {token: "`", isExpr: true}, f_expr = {token: "function", isExpr: true}; function curTokContext() { return tokContext[tokContext.length - 1]; @@ -698,8 +698,14 @@ // Update context info if (type === _parenR || type === _braceR) { var out = tokContext.pop(); - tokExprAllowed = !(out && out.isExpr); - preserveSpace = out === b_tmpl || curTokContext() === j_expr; + if (out === b_tmpl) { + preserveSpace = true; + } else if (out === b_stat && curTokContext() === f_expr) { + tokContext.pop(); + tokExprAllowed = false; + } else { + tokExprAllowed = !(out && out.isExpr); + } } else if (type === _braceL) { tokContext.push(braceIsBlock(prevType) ? b_stat : b_expr); tokExprAllowed = true; @@ -714,7 +720,10 @@ // tokExprAllowed stays unchanged } else if (type.keyword && prevType == _dot) { tokExprAllowed = false; - } else if (tokExprAllowed && type == _function) { + } else if (type == _function) { + if (curTokContext() !== b_stat) { + tokContext.push(f_expr); + } tokExprAllowed = false; } else if (type === _backQuote) { if (curTokContext() === q_tmpl) { diff --git a/test/tests.js b/test/tests.js index 172eb1fb87..dee69bb4a3 100644 --- a/test/tests.js +++ b/test/tests.js @@ -28862,3 +28862,48 @@ test("#!/usr/bin/node\n;", {}, { end: 15 }] }); + +// https://github.com/marijnh/acorn/issues/204 +test("(function () {} / 1)", { + type: "Program", + body: [{ + type: "ExpressionStatement", + expression: { + type: "BinaryExpression", + left: { + type: "FunctionExpression", + id: null, + params: [], + body: { + type: "BlockStatement", + body: [] + } + }, + operator: "/", + right: {type: "Literal", value: 1} + } + }] +}); + +test("function f() {} / 1 /", { + type: "Program", + body: [ + { + type: "FunctionDeclaration", + id: {type: "Identifier", name: "f"}, + params: [], + body: { + type: "BlockStatement", + body: [] + } + }, + { + type: "ExpressionStatement", + expression: { + type: "Literal", + regex: {pattern: " 1 ", flags: ""}, + value: {} + } + } + ] +});