Skip to content

Commit

Permalink
fix corner cases in semicolons (#5879)
Browse files Browse the repository at this point in the history
fixes #5878
  • Loading branch information
alexlamsl authored Jul 14, 2024
1 parent 0a33da4 commit 008edfb
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 7 deletions.
15 changes: 11 additions & 4 deletions lib/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,9 @@ function OutputStream(options) {
if (line_fixed || flush) flush_mappings();
} : noop;

var require_semicolon = makePredicate("( [ + * / - , .");
var stat_end_chars = makePredicate("; }");
var asi_skip_chars = makePredicate("( [ + * / - , . `");
var asi_skip_words = makePredicate("in instanceof");

function require_space(prev, ch, str) {
return is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
Expand Down Expand Up @@ -295,8 +297,8 @@ function OutputStream(options) {
var prev = last.slice(-1);
if (might_need_semicolon) {
might_need_semicolon = false;
if (prev == ":" && ch == "}" || prev != ";" && (!ch || ";}".indexOf(ch) < 0)) {
var need_semicolon = require_semicolon[ch];
if (prev != ";" && !stat_end_chars[ch]) {
var need_semicolon = asi_skip_chars[ch] || asi_skip_words[str];
if (need_semicolon || options.semicolons) {
output += ";";
current_col++;
Expand Down Expand Up @@ -941,7 +943,12 @@ function OutputStream(options) {
DEFPRINT(AST_LabeledStatement, function(output) {
this.label.print(output);
output.colon();
this.body.print(output);
var body = this.body;
if (body instanceof AST_EmptyStatement) {
output.force_semicolon();
} else {
body.print(output);
}
});
DEFPRINT(AST_SimpleStatement, function(output) {
this.body.print(output);
Expand Down
65 changes: 65 additions & 0 deletions test/compress/classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4112,3 +4112,68 @@ issue_5876_2: {
]
node_version: ">=12"
}

issue_5878_1: {
beautify = {
semicolons: false,
}
input: {
new class {
p = {};
in = console.log("PASS");
}();
}
expect_exact: 'new class{p={};in=console.log("PASS")}\n'
expect_stdout: "PASS"
node_version: ">=12"
}

issue_5878_2: {
beautify = {
semicolons: false,
}
input: {
class A {
static p = console.log("PASS");
instanceof() {}
}
}
expect_exact: 'class A{static p=console.log("PASS");instanceof(){}}'
expect_stdout: "PASS"
node_version: ">=12"
}

issue_5878_3: {
beautify = {
semicolons: false,
}
input: {
new class {
p;
in = console.log("PASS");
}();
}
expect_exact: 'new class{p;in=console.log("PASS")}\n'
expect_stdout: "PASS"
node_version: ">=12"
}

issue_5878_4: {
beautify = {
semicolons: false,
}
input: {
"use strict";
console.log(typeof class {
f() {}
instanceof() {}
});
}
expect_exact: [
'"use strict"',
"console.log(typeof class{f(){}instanceof(){}})",
"",
]
expect_stdout: "function"
node_version: ">=4"
}
38 changes: 38 additions & 0 deletions test/compress/labels.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,41 @@ issue_5524: {
}
expect_stdout: "PASS"
}

issue_5878_1: {
beautify = {
semicolons: false,
}
input: {
console.log("PASS");
L:;
}
expect_exact: 'console.log("PASS")\nL:;'
expect_stdout: "PASS"
}

issue_5878_2: {
beautify = {
semicolons: false,
}
input: {
L: ;
L: console.log("PASS");
}
expect_exact: 'L:;L:console.log("PASS")\n'
expect_stdout: "PASS"
}

issue_5878_3: {
beautify = {
semicolons: false,
}
input: {
if (console.log("PASS"))
A:;
else
B:;
}
expect_exact: 'if(console.log("PASS"))A:;else B:;'
expect_stdout: "PASS"
}
12 changes: 12 additions & 0 deletions test/compress/regexp.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,3 +489,15 @@ reset_state_between_evaluate: {
}
expect_stdout: "PASS"
}

issue_5878: {
beautify = {
semicolons: false,
}
input: {
console.log("PASS");
/b/.exec({});
}
expect_exact: 'console.log("PASS");/b/.exec({})\n'
expect_stdout: "PASS"
}
13 changes: 13 additions & 0 deletions test/compress/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -769,3 +769,16 @@ issue_5199: {
expect_stdout: "undefined"
node_version: ">=4"
}

issue_5878: {
beautify = {
semicolons: false,
}
input: {
console.log("PASS");
`42`;
}
expect_exact: 'console.log("PASS");`42`\n'
expect_stdout: "PASS"
node_version: ">=4"
}
4 changes: 2 additions & 2 deletions test/sandbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ exports.patch_module_statements = function(code, module) {
return "";
}).replace(/\bexport(?:\s*\{[^{}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
if (/^export\s+default/.test(match)) has_default = "function _uglify_export_default_() {}";
if (!header) return "";
if (!header) return ";";
if (header.length == 1) return "0, " + header;
var name = "_uglify_export_default_";
if (/^class\b/.test(header)) do {
Expand All @@ -85,7 +85,7 @@ exports.patch_module_statements = function(code, module) {
"} = new Proxy(Object.create(null), { get(_, value) { return { value }; } });",
].join(""));
}
return "";
return ";";
});
imports.push("");
return strict_mode + has_default + imports.join("\n") + code;
Expand Down
3 changes: 2 additions & 1 deletion test/ufuzz/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2173,7 +2173,8 @@ function log_suspects(minify_options, component) {
var defs = default_options[component];
var toplevel = sandbox.has_toplevel(minify_options);
var suspects = Object.keys(defs).filter(function(name) {
var flip = component == "compress" && name == "keep_fargs";
var flip = component == "compress" && name == "keep_fargs"
|| component == "output" && name == "semicolons";
if (flip !== (name in options ? options : defs)[name]) {
var m = JSON.parse(JSON.stringify(minify_options));
var o = JSON.parse(JSON.stringify(options));
Expand Down
3 changes: 3 additions & 0 deletions test/ufuzz/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
{
"ie": true,
"module": false,
"output": {
"semicolons": false
},
"toplevel": true
},
{
Expand Down

0 comments on commit 008edfb

Please sign in to comment.