Skip to content

Commit

Permalink
improve comment formatting logic (#4794)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl committed Mar 17, 2021
1 parent 9fc0ff5 commit 7d595e2
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 71 deletions.
81 changes: 30 additions & 51 deletions lib/output.js
Expand Up @@ -347,6 +347,7 @@ function OutputStream(options) {
};

var indent = options.beautify ? function(half) {
if (need_newline_indented) print("\n");
print(repeat_string(" ", half ? indentation - (options.indent_level >> 1) : indentation));
} : noop;

Expand Down Expand Up @@ -450,6 +451,27 @@ function OutputStream(options) {
return /^ *$/.test(OUTPUT.slice(index + 1));
}

function pad_comment(token, force) {
if (need_newline_indented) return;
if (token.nlb && (force || !has_nlb())) {
need_newline_indented = true;
} else if (force) {
need_space = true;
}
}

function print_comment(comment) {
var value = comment.value.replace(/[@#]__PURE__/g, " ");
if (/^\s*$/.test(value) && !/^\s*$/.test(comment.value)) return false;
if (/comment[134]/.test(comment.type)) {
print("//" + value);
need_newline_indented = true;
} else if (comment.type == "comment2") {
print("/*" + value + "*/");
}
return true;
}

function prepend_comments(node) {
var self = this;
var scan = node instanceof AST_Exit && node.value;
Expand Down Expand Up @@ -489,37 +511,12 @@ function OutputStream(options) {
}

comments = comments.filter(comment_filter, node);
if (comments.length == 0) return;
var last_nlb = has_nlb();
comments.forEach(function(c, i) {
if (!last_nlb) {
if (c.nlb) {
print("\n");
indent();
last_nlb = true;
} else if (i > 0) {
space();
}
}
var value = c.value.replace(/[@#]__PURE__/g, " ");
if (/^\s*$/.test(value)) return;
if (/comment[134]/.test(c.type)) {
print("//" + value + "\n");
indent();
last_nlb = true;
} else if (c.type == "comment2") {
print("/*" + value + "*/");
last_nlb = false;
}
var printed = false;
comments.forEach(function(comment, index) {
pad_comment(comment, index);
if (print_comment(comment)) printed = true;
});
if (!last_nlb) {
if (node.start.nlb) {
print("\n");
indent();
} else {
space();
}
}
if (printed) pad_comment(node.start, true);

function dump(node) {
var token = node.start;
Expand Down Expand Up @@ -549,27 +546,9 @@ function OutputStream(options) {
}))) return;
comments._dumped = self;
var insert = OUTPUT.length;
comments.filter(comment_filter, node).forEach(function(c, i) {
need_space = false;
if (need_newline_indented) {
print("\n");
indent();
need_newline_indented = false;
} else if (c.nlb && (i > 0 || !has_nlb())) {
print("\n");
indent();
} else if (i > 0 || !tail) {
space();
}
var value = c.value.replace(/[@#]__PURE__/g, " ");
if (/^\s*$/.test(value)) return;
if (/comment[134]/.test(c.type)) {
print("//" + value);
need_newline_indented = true;
} else if (c.type == "comment2") {
print("/*" + value + "*/");
need_space = true;
}
comments.filter(comment_filter, node).forEach(function(comment, index) {
pad_comment(comment, index || !tail);
print_comment(comment);
});
if (OUTPUT.length > insert) newline_insert = insert;
}
Expand Down
4 changes: 2 additions & 2 deletions test/compress/annotations.js
Expand Up @@ -193,7 +193,7 @@ issue_2705_3: {
}
expect_exact: [
"new h.x(1).y(2).z(3);",
"new i.x(1).y(2).z(3);",
"/* */new i.x(1).y(2).z(3);",
"new j.x(1).y(2).z(3);",
"new k.x(1).y(2).z(3);",
"new l.x(1).y(2).z(3);",
Expand Down Expand Up @@ -246,7 +246,7 @@ issue_2705_6: {
}
expect_exact: [
"x(),y();",
"new(a()||b())(c(),d());",
"/* */new(a()||b())(c(),d());",
]
}

Expand Down
6 changes: 3 additions & 3 deletions test/mocha/cli.js
Expand Up @@ -29,23 +29,23 @@ describe("bin/uglifyjs", function() {
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n\n");
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n");
done();
});
});
it("Should be able to filter comments correctly with `--comment <RegExp>`", function(done) {
var command = uglifyjscmd + ' test/input/comments/filter.js --comments /r/';
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n\n");
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n");
done();
});
});
it("Should be able to filter comments correctly with just `--comment`", function(done) {
var command = uglifyjscmd + ' test/input/comments/filter.js --comments';
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "/*@preserve*/\n\n");
assert.strictEqual(stdout, "/*@preserve*/\n");
done();
});
});
Expand Down
24 changes: 9 additions & 15 deletions test/mocha/comments.js
Expand Up @@ -392,12 +392,12 @@ describe("comments", function() {
describe("comment filters", function() {
it("Should be able to filter comments by passing regexp", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8");
});

it("Should be able to filter comments with the 'all' option", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8");
});

it("Should be able to filter commments with the 'some' option", function() {
Expand All @@ -410,39 +410,34 @@ describe("comments", function() {
var f = function(node, comment) {
return comment.value.length === 8;
};

assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.\n");
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.");
});

it("Should be able to filter comments by passing regex in string format", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8");
});

it("Should be able to get the comment and comment type when using a function", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
var f = function(node, comment) {
return comment.type == "comment1" || comment.type == "comment3";
};

assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6\n");
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6");
});

it("Should be able to filter comments by passing a boolean", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");

assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8");
assert.strictEqual(ast.print_to_string({comments: false}), "");
});

it("Should never be able to filter comment5 (shebangs)", function() {
var ast = UglifyJS.parse("#!Random comment\n//test1\n/*test2*/");
var f = function(node, comment) {
assert.strictEqual(comment.type === "comment5", false);

return true;
};

assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/");
});

Expand All @@ -453,24 +448,23 @@ describe("comments", function() {

it("Should have no problem on multiple calls", function() {
const options = {
comments: /ok/
comments: /ok/,
};

assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
});

it("Should handle shebang and preamble correctly", function() {
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
output: { preamble: "/* Build */" }
output: { preamble: "/* Build */" },
}).code;
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
});

it("Should handle preamble without shebang correctly", function() {
var code = UglifyJS.minify("var x = 10;", {
output: { preamble: "/* Build */" }
output: { preamble: "/* Build */" },
}).code;
assert.strictEqual(code, "/* Build */\nvar x=10;");
});
Expand Down

0 comments on commit 7d595e2

Please sign in to comment.