[Pkg-javascript-commits] [uglifyjs] 25/50: improve keyword-related parser errors (#1941)
Jonas Smedegaard
dr at jones.dk
Thu Aug 17 23:06:45 UTC 2017
This is an automated email from the git hooks/post-receive script.
js pushed a commit to branch master
in repository uglifyjs.
commit ecb63ad8bc07f024b3517762434ab941d7c4d0e7
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Mon May 15 23:02:55 2017 +0800
improve keyword-related parser errors (#1941)
fixes #1937
---
lib/parse.js | 61 ++++++--
test/input/invalid/else.js | 1 +
test/input/invalid/return.js | 1 +
test/mocha/cli.js | 360 +++++++++++++++++++++++--------------------
4 files changed, 241 insertions(+), 182 deletions(-)
diff --git a/lib/parse.js b/lib/parse.js
index edd55e7..b9911fa 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -803,17 +803,16 @@ function parse($TEXT, options) {
};
var statement = embed_tokens(function() {
- var tmp;
handle_regexp();
switch (S.token.type) {
case "string":
if (S.in_directives) {
- tmp = peek();
+ var token = peek();
if (S.token.raw.indexOf("\\") == -1
- && (tmp.nlb
- || is_token(tmp, "eof")
- || is_token(tmp, "punc", ";")
- || is_token(tmp, "punc", "}"))) {
+ && (token.nlb
+ || is_token(token, "eof")
+ || is_token(token, "punc", ";")
+ || is_token(token, "punc", "}"))) {
S.input.add_directive(S.token.value);
} else {
S.in_directives = false;
@@ -852,75 +851,103 @@ function parse($TEXT, options) {
}
case "keyword":
- switch (tmp = S.token.value, next(), tmp) {
+ switch (S.token.value) {
case "break":
+ next();
return break_cont(AST_Break);
case "continue":
+ next();
return break_cont(AST_Continue);
case "debugger":
+ next();
semicolon();
return new AST_Debugger();
case "do":
+ next();
+ var body = in_loop(statement);
+ expect_token("keyword", "while");
+ var condition = parenthesised();
+ semicolon(true);
return new AST_Do({
- body : in_loop(statement),
- condition : (expect_token("keyword", "while"), tmp = parenthesised(), semicolon(true), tmp)
+ body : body,
+ condition : condition
});
case "while":
+ next();
return new AST_While({
condition : parenthesised(),
body : in_loop(statement)
});
case "for":
+ next();
return for_();
case "function":
+ next();
return function_(AST_Defun);
case "if":
+ next();
return if_();
case "return":
if (S.in_function == 0 && !options.bare_returns)
croak("'return' outside of function");
+ next();
+ var value = null;
+ if (is("punc", ";")) {
+ next();
+ } else if (!can_insert_semicolon()) {
+ value = expression(true);
+ semicolon();
+ }
return new AST_Return({
- value: ( is("punc", ";")
- ? (next(), null)
- : can_insert_semicolon()
- ? null
- : (tmp = expression(true), semicolon(), tmp) )
+ value: value
});
case "switch":
+ next();
return new AST_Switch({
expression : parenthesised(),
body : in_loop(switch_body_)
});
case "throw":
+ next();
if (S.token.nlb)
croak("Illegal newline after 'throw'");
+ var value = expression(true);
+ semicolon();
return new AST_Throw({
- value: (tmp = expression(true), semicolon(), tmp)
+ value: value
});
case "try":
+ next();
return try_();
case "var":
- return tmp = var_(), semicolon(), tmp;
+ next();
+ var node = var_();
+ semicolon();
+ return node;
case "const":
- return tmp = const_(), semicolon(), tmp;
+ next();
+ var node = const_();
+ semicolon();
+ return node;
case "with":
if (S.input.has_directive("use strict")) {
croak("Strict mode may not include a with statement");
}
+ next();
return new AST_With({
expression : parenthesised(),
body : statement()
diff --git a/test/input/invalid/else.js b/test/input/invalid/else.js
new file mode 100644
index 0000000..89e8e50
--- /dev/null
+++ b/test/input/invalid/else.js
@@ -0,0 +1 @@
+if (0) else 1;
diff --git a/test/input/invalid/return.js b/test/input/invalid/return.js
new file mode 100644
index 0000000..d232c62
--- /dev/null
+++ b/test/input/invalid/return.js
@@ -0,0 +1 @@
+return 42;
diff --git a/test/mocha/cli.js b/test/mocha/cli.js
index d5c9585..9b3b637 100644
--- a/test/mocha/cli.js
+++ b/test/mocha/cli.js
@@ -51,15 +51,15 @@ describe("bin/uglifyjs", function () {
});
});
it("Should append source map to output when using --source-map-inline", function (done) {
- var command = uglifyjscmd + ' test/input/issue-1323/sample.js --source-map-inline';
+ var command = uglifyjscmd + ' test/input/issue-1323/sample.js --source-map-inline';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
- "//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=\n");
- done();
- });
+ assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
+ "//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=\n");
+ done();
+ });
});
it("should not append source map to output when not using --source-map-inline", function (done) {
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
@@ -72,84 +72,84 @@ describe("bin/uglifyjs", function () {
});
});
it("Should work with --keep-fnames (mangle only)", function (done) {
- var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
+ var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
- done();
- });
+ assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
+ done();
+ });
});
it("Should work with --keep-fnames (mangle & compress)", function (done) {
- var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
+ var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
- done();
- });
+ assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
+ done();
+ });
});
it("Should work with keep_fnames under mangler options", function (done) {
- var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fnames=true';
+ var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fnames=true';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
- done();
- });
+ assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
+ done();
+ });
});
it("Should work with --define (simple)", function (done) {
- var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
+ var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, "console.log(5);\n");
- done();
- });
+ assert.strictEqual(stdout, "console.log(5);\n");
+ done();
+ });
});
it("Should work with --define (nested)", function (done) {
- var command = uglifyjscmd + ' test/input/global_defs/nested.js --define C.D=5,C.V=3 -c';
+ var command = uglifyjscmd + ' test/input/global_defs/nested.js --define C.D=5,C.V=3 -c';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, "console.log(3,5);\n");
- done();
- });
+ assert.strictEqual(stdout, "console.log(3,5);\n");
+ done();
+ });
});
it("Should work with --define (AST_Node)", function (done) {
- var command = uglifyjscmd + ' test/input/global_defs/simple.js --define console.log=stdout.println -c';
+ var command = uglifyjscmd + ' test/input/global_defs/simple.js --define console.log=stdout.println -c';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, "stdout.println(D);\n");
- done();
- });
+ assert.strictEqual(stdout, "stdout.println(D);\n");
+ done();
+ });
});
it("Should work with `--beautify`", function (done) {
- var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
+ var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, readFileSync("test/input/issue-1482/default.js", "utf8"));
- done();
- });
+ assert.strictEqual(stdout, readFileSync("test/input/issue-1482/default.js", "utf8"));
+ done();
+ });
});
it("Should work with `--beautify bracketize`", function (done) {
- var command = uglifyjscmd + ' test/input/issue-1482/input.js -b bracketize';
+ var command = uglifyjscmd + ' test/input/issue-1482/input.js -b bracketize';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, readFileSync("test/input/issue-1482/bracketize.js", "utf8"));
- done();
- });
+ assert.strictEqual(stdout, readFileSync("test/input/issue-1482/bracketize.js", "utf8"));
+ done();
+ });
});
it("Should process inline source map", function(done) {
var command = uglifyjscmd + ' test/input/issue-520/input.js -mc toplevel --in-source-map inline --source-map-inline';
@@ -252,133 +252,163 @@ describe("bin/uglifyjs", function () {
});
});
it("Should support hyphen as shorthand", function(done) {
- var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep-fnames=true';
+ var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep-fnames=true';
- exec(command, function (err, stdout) {
- if (err) throw err;
+ exec(command, function (err, stdout) {
+ if (err) throw err;
- assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
- done();
- });
+ assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
+ done();
+ });
});
it("Should throw syntax error (5--)", function(done) {
- var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
-
- exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stdout, "");
- assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
- "Parse error at test/input/invalid/assign_1.js:1,18",
- "console.log(1 || 5--);",
- " ^",
- "SyntaxError: Invalid use of -- operator"
- ].join("\n"));
- done();
- });
+ var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/assign_1.js:1,18",
+ "console.log(1 || 5--);",
+ " ^",
+ "SyntaxError: Invalid use of -- operator"
+ ].join("\n"));
+ done();
+ });
});
it("Should throw syntax error (Math.random() /= 2)", function(done) {
- var command = uglifyjscmd + ' test/input/invalid/assign_2.js';
-
- exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stdout, "");
- assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
- "Parse error at test/input/invalid/assign_2.js:1,32",
- "console.log(2 || (Math.random() /= 2));",
- " ^",
- "SyntaxError: Invalid assignment"
- ].join("\n"));
- done();
- });
+ var command = uglifyjscmd + ' test/input/invalid/assign_2.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/assign_2.js:1,32",
+ "console.log(2 || (Math.random() /= 2));",
+ " ^",
+ "SyntaxError: Invalid assignment"
+ ].join("\n"));
+ done();
+ });
});
it("Should throw syntax error (++this)", function(done) {
- var command = uglifyjscmd + ' test/input/invalid/assign_3.js';
-
- exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stdout, "");
- assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
- "Parse error at test/input/invalid/assign_3.js:1,17",
- "console.log(3 || ++this);",
- " ^",
- "SyntaxError: Invalid use of ++ operator"
- ].join("\n"));
- done();
- });
+ var command = uglifyjscmd + ' test/input/invalid/assign_3.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/assign_3.js:1,17",
+ "console.log(3 || ++this);",
+ " ^",
+ "SyntaxError: Invalid use of ++ operator"
+ ].join("\n"));
+ done();
+ });
});
it("Should throw syntax error (++null)", function(done) {
- var command = uglifyjscmd + ' test/input/invalid/assign_4.js';
-
- exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stdout, "");
- assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
- "Parse error at test/input/invalid/assign_4.js:1,0",
- "++null",
- "^",
- "SyntaxError: Invalid use of ++ operator"
- ].join("\n"));
- done();
- });
+ var command = uglifyjscmd + ' test/input/invalid/assign_4.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/assign_4.js:1,0",
+ "++null",
+ "^",
+ "SyntaxError: Invalid use of ++ operator"
+ ].join("\n"));
+ done();
+ });
});
it("Should throw syntax error (a.=)", function(done) {
- var command = uglifyjscmd + ' test/input/invalid/dot_1.js';
-
- exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stdout, "");
- assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
- "Parse error at test/input/invalid/dot_1.js:1,2",
- "a.=",
- " ^",
- "SyntaxError: Unexpected token: operator (=)"
- ].join("\n"));
- done();
- });
+ var command = uglifyjscmd + ' test/input/invalid/dot_1.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/dot_1.js:1,2",
+ "a.=",
+ " ^",
+ "SyntaxError: Unexpected token: operator (=)"
+ ].join("\n"));
+ done();
+ });
});
it("Should throw syntax error (%.a)", function(done) {
- var command = uglifyjscmd + ' test/input/invalid/dot_2.js';
-
- exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stdout, "");
- assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
- "Parse error at test/input/invalid/dot_2.js:1,0",
- "%.a;",
- "^",
- "SyntaxError: Unexpected token: operator (%)"
- ].join("\n"));
- done();
- });
+ var command = uglifyjscmd + ' test/input/invalid/dot_2.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/dot_2.js:1,0",
+ "%.a;",
+ "^",
+ "SyntaxError: Unexpected token: operator (%)"
+ ].join("\n"));
+ done();
+ });
});
it("Should throw syntax error (a./();)", function(done) {
- var command = uglifyjscmd + ' test/input/invalid/dot_3.js';
-
- exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stdout, "");
- assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
- "Parse error at test/input/invalid/dot_3.js:1,2",
- "a./();",
- " ^",
- "SyntaxError: Unexpected token: operator (/)"
- ].join("\n"));
- done();
- });
+ var command = uglifyjscmd + ' test/input/invalid/dot_3.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/dot_3.js:1,2",
+ "a./();",
+ " ^",
+ "SyntaxError: Unexpected token: operator (/)"
+ ].join("\n"));
+ done();
+ });
});
it("Should throw syntax error ({%: 1})", function(done) {
- var command = uglifyjscmd + ' test/input/invalid/object.js';
-
- exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stdout, "");
- assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
- "Parse error at test/input/invalid/object.js:1,13",
- "console.log({%: 1});",
- " ^",
- "SyntaxError: Unexpected token: operator (%)"
- ].join("\n"));
- done();
- });
+ var command = uglifyjscmd + ' test/input/invalid/object.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/object.js:1,13",
+ "console.log({%: 1});",
+ " ^",
+ "SyntaxError: Unexpected token: operator (%)"
+ ].join("\n"));
+ done();
+ });
+ });
+ it("Should throw syntax error (else)", function(done) {
+ var command = uglifyjscmd + ' test/input/invalid/else.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/else.js:1,7",
+ "if (0) else 1;",
+ " ^",
+ "SyntaxError: Unexpected token: keyword (else)"
+ ].join("\n"));
+ done();
+ });
+ });
+ it("Should throw syntax error (return)", function(done) {
+ var command = uglifyjscmd + ' test/input/invalid/return.js';
+
+ exec(command, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.strictEqual(stdout, "");
+ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
+ "Parse error at test/input/invalid/return.js:1,0",
+ "return 42;",
+ "^",
+ "SyntaxError: 'return' outside of function"
+ ].join("\n"));
+ done();
+ });
});
});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git
More information about the Pkg-javascript-commits
mailing list