Skip to content

Commit

Permalink
fix parser bugs & CLI reporting (#1827)
Browse files Browse the repository at this point in the history
fixes #1825
  • Loading branch information
alexlamsl committed May 15, 2017
1 parent 87f8a48 commit 4027a0c
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 26 deletions.
16 changes: 8 additions & 8 deletions bin/uglifyjs
Expand Up @@ -367,19 +367,19 @@ var index = 0;
if (ex instanceof UglifyJS.JS_Parse_Error) {
print_error("Parse error at " + file + ":" + ex.line + "," + ex.col);
var col = ex.col;
var line = code.split(/\r?\n/)[ex.line - (col ? 1 : 2)];
var lines = code.split(/\r?\n/);
var line = lines[ex.line - 1];
if (!line && !col) {
line = lines[ex.line - 2];
col = line.length;
}
if (line) {
if (col > 40) {
line = line.slice(col - 40);
col = 40;
}
if (col) {
print_error(line.slice(0, 80));
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
} else {
print_error(line.slice(-40));
print_error(line.slice(-40).replace(/\S/g, " ") + "^");
}
print_error(line.slice(0, 80));
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
}
print_error(ex.stack);
process.exit(1);
Expand Down
27 changes: 11 additions & 16 deletions lib/parse.js
Expand Up @@ -111,7 +111,7 @@ var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u20

var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));

var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));

var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));

Expand Down Expand Up @@ -1354,14 +1354,15 @@ function parse($TEXT, options) {

function as_property_name() {
var tmp = S.token;
next();
switch (tmp.type) {
case "operator":
if (!KEYWORDS(tmp.value)) unexpected();
case "num":
case "string":
case "name":
case "operator":
case "keyword":
case "atom":
next();
return tmp.value;
default:
unexpected();
Expand All @@ -1370,16 +1371,9 @@ function parse($TEXT, options) {

function as_name() {
var tmp = S.token;
if (tmp.type != "name") unexpected();
next();
switch (tmp.type) {
case "name":
case "operator":
case "keyword":
case "atom":
return tmp.value;
default:
unexpected();
}
return tmp.value;
};

function _make_symbol(type) {
Expand Down Expand Up @@ -1440,24 +1434,25 @@ function parse($TEXT, options) {
if (is("operator") && UNARY_PREFIX(start.value)) {
next();
handle_regexp();
var ex = make_unary(AST_UnaryPrefix, start.value, maybe_unary(allow_calls));
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
ex.start = start;
ex.end = prev();
return ex;
}
var val = expr_atom(allow_calls);
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
val = make_unary(AST_UnaryPostfix, S.token.value, val);
val = make_unary(AST_UnaryPostfix, S.token, val);
val.start = start;
val.end = S.token;
next();
}
return val;
};

function make_unary(ctor, op, expr) {
function make_unary(ctor, token, expr) {
var op = token.value;
if ((op == "++" || op == "--") && !is_assignable(expr))
croak("Invalid use of " + op + " operator", null, ctor === AST_UnaryPrefix ? expr.start.col - 1 : null);
croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
return new ctor({ operator: op, expression: expr });
};

Expand Down
1 change: 1 addition & 0 deletions test/input/invalid/assign_4.js
@@ -0,0 +1 @@
++null
1 change: 1 addition & 0 deletions test/input/invalid/dot_1.js
@@ -0,0 +1 @@
a.=
1 change: 1 addition & 0 deletions test/input/invalid/dot_2.js
@@ -0,0 +1 @@
%.a;
1 change: 1 addition & 0 deletions test/input/invalid/dot_3.js
@@ -0,0 +1 @@
a./();
1 change: 1 addition & 0 deletions test/input/invalid/object.js
@@ -0,0 +1 @@
console.log({%: 1});
79 changes: 77 additions & 2 deletions test/mocha/cli.js
Expand Up @@ -298,12 +298,87 @@ describe("bin/uglifyjs", function () {
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,18",
"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();
});
});
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();
});
});
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();
});
});
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();
});
});
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();
});
});
});

0 comments on commit 4027a0c

Please sign in to comment.