From b0555a123a208b24f14d03add0d992a846c1dd89 Mon Sep 17 00:00:00 2001 From: Anthony Van de Gejuchte Date: Sat, 11 Jun 2016 21:41:16 +0200 Subject: [PATCH] Fix newline handling after yield YieldExpressions can only be defined as: * `yield` * `yield` [no nlb] AssignmentExpression * `yield` [no nlb] `*` AssignmentExpression --- lib/parse.js | 24 +++++++++++++++--------- test/mocha/yield.js | 16 ++++++++++++++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lib/parse.js b/lib/parse.js index 14da6b01..da8cb506 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1174,17 +1174,23 @@ function parse($TEXT, options) { var has_expression = true; var tmp; - // Get expression behind yield, default to value `undefined` stored as `null` in ast - // Expression must start on same line, yield* has a mandatory expression - if (is("operator", "*")) { - star = true; - next(); - if (S.token.nlb) { - unexpected(S.prev); - } - } else if (can_insert_semicolon() || + // Attempt to get expression or star (and then the mandatory expression) + // behind yield on the same line. + // + // If nothing follows on the same line of the yieldExpression, + // it should default to the value `undefined` for yield to return. + // In that case, the `undefined` stored as `null` in ast. + // + // Note 1: It isn't allowed for yield* to close without an expression + // Note 2: If there is a nlb between yield and star, it is interpret as + // yield * + if (can_insert_semicolon() || (is("punc") && PUNC_AFTER_EXPRESSION(S.token.value))) { has_expression = false; + + } else if (is("operator", "*")) { + star = true; + next(); } return new AST_Yield({ diff --git a/test/mocha/yield.js b/test/mocha/yield.js index cd4cce52..b105ef60 100644 --- a/test/mocha/yield.js +++ b/test/mocha/yield.js @@ -20,8 +20,20 @@ describe("Yield", function() { assert.throws(test, expect); }); - it("Should not allow yield* followed by a newline in generators", function() { - var js = "function* test() {yield*\n123;}"; + it("Should not allow yield* followed by a semicolon in generators", function() { + var js = "function* test() {yield*\n;}"; + var test = function() { + UglifyJS.parse(js); + } + var expect = function(e) { + return e instanceof UglifyJS.JS_Parse_Error && + e.message === "Unexpected token: punc (;)"; + } + assert.throws(test, expect); + }); + + it("Should not allow yield with next token star on next line", function() { + var js = "function* test() {yield\n*123;}"; var test = function() { UglifyJS.parse(js); }