From 08616254cd4a7cc573c9d400b5134bf31afdddce Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Mon, 6 May 2024 02:11:44 -0400 Subject: [PATCH] printer: preserve single-line status of block body --- .../bundler_tests/snapshots/snapshots_dce.txt | 34 +- .../snapshots/snapshots_default.txt | 369 ++++------- .../snapshots/snapshots_lower.txt | 36 +- .../snapshots/snapshots_splitting.txt | 9 +- .../snapshots/snapshots_tsconfig.txt | 21 +- internal/js_ast/js_ast.go | 50 +- internal/js_parser/js_parser.go | 32 +- internal/js_parser/js_parser_lower_test.go | 2 +- internal/js_parser/js_parser_test.go | 590 +++++++++--------- internal/js_parser/ts_parser_test.go | 28 +- internal/js_printer/js_printer.go | 56 +- internal/js_printer/js_printer_test.go | 36 +- scripts/js-api-tests.js | 8 +- 13 files changed, 565 insertions(+), 706 deletions(-) diff --git a/internal/bundler_tests/snapshots/snapshots_dce.txt b/internal/bundler_tests/snapshots/snapshots_dce.txt index 8e363e6d178..80eb2aacd83 100644 --- a/internal/bundler_tests/snapshots/snapshots_dce.txt +++ b/internal/bundler_tests/snapshots/snapshots_dce.txt @@ -660,8 +660,7 @@ TestDCETypeOfEqualsString ---------- /out.js ---------- (() => { // entry.js - if (false) - console.log(hasBar); + if (false) console.log(hasBar); })(); ================================================================================ @@ -814,16 +813,12 @@ function testStmts() { do var b; while (x); - for (var c; ; ) - ; - for (var d in x) - ; - for (var e of x) - ; + for (var c; ; ) ; + for (var d in x) ; + for (var e of x) ; if (x) var f; - if (!x) - var g; + if (!x) var g; var h, i; } testReturn(); @@ -865,14 +860,10 @@ export { TestDropLabels ---------- /out.js ---------- // entry.js -keep_1: - require("foo1"); +keep_1: require("foo1"); exports.bar = function() { - if (x) - ; - if (y) - keep_2: - require("bar2"); + if (x) ; + if (y) keep_2: require("bar2"); }; ================================================================================ @@ -915,8 +906,7 @@ foo(); console.log(foo()); console.log((foo(), void 0)); console.log((foo(), void 0)); -for (; void 0; ) - ; +for (; void 0; ) ; foo(); foo(); foo(); @@ -1060,11 +1050,9 @@ export let shouldBeWrapped = [ TestInlineFunctionCallForInitDecl ---------- /out/entry.js ---------- // entry.js -for (y = void 0; !1; ) - ; +for (y = void 0; !1; ) ; var y; -for (z = 123; !1; ) - ; +for (z = 123; !1; ) ; var z; ================================================================================ diff --git a/internal/bundler_tests/snapshots/snapshots_default.txt b/internal/bundler_tests/snapshots/snapshots_default.txt index 06d867e79fb..1b921d955a8 100644 --- a/internal/bundler_tests/snapshots/snapshots_default.txt +++ b/internal/bundler_tests/snapshots/snapshots_default.txt @@ -598,58 +598,48 @@ for ( /*foo*/ a; ; -) - ; +) ; for ( ; /*foo*/ a; -) - ; +) ; for ( ; ; /*foo*/ a -) - ; +) ; for ( /*foo*/ a in b -) - ; +) ; for ( a in /*foo*/ b -) - ; +) ; for ( /*foo*/ a of b -) - ; +) ; for ( a of /*foo*/ b -) - ; +) ; if ( /*foo*/ a -) - ; +) ; with ( /*foo*/ a -) - ; +) ; while ( /*foo*/ a -) - ; +) ; do { } while ( /*foo*/ @@ -859,24 +849,18 @@ TestConstWithLet console.log(1); console.log(2); unknownFn(3); -for (let c = x; ; ) - console.log(c); -for (let d in x) - console.log(d); -for (let e of x) - console.log(e); +for (let c = x; ; ) console.log(c); +for (let d in x) console.log(d); +for (let e of x) console.log(e); ================================================================================ TestConstWithLetNoBundle ---------- /out.js ---------- const a = 1; console.log(1), console.log(2), unknownFn(3); -for (const c = x; ; ) - console.log(c); -for (const d in x) - console.log(d); -for (const e of x) - console.log(e); +for (const c = x; ; ) console.log(c); +for (const d in x) console.log(d); +for (const e of x) console.log(e); ================================================================================ TestConstWithLetNoMangle @@ -888,12 +872,9 @@ if (true) { const b = 2; console.log(b); } -for (const c = x; ; ) - console.log(c); -for (const d in x) - console.log(d); -for (const e of x) - console.log(e); +for (const c = x; ; ) console.log(c); +for (const d in x) console.log(d); +for (const e of x) console.log(e); ================================================================================ TestDecoratorPrintingCJS @@ -2789,23 +2770,17 @@ var [fn = /* @__PURE__ */ __name(function() { var { fn = /* @__PURE__ */ __name(function() { }, "fn") } = {}; for (var [fn = /* @__PURE__ */ __name(function() { -}, "fn")] = []; ; ) - ; +}, "fn")] = []; ; ) ; for (var { fn = /* @__PURE__ */ __name(function() { -}, "fn") } = {}; ; ) - ; +}, "fn") } = {}; ; ) ; for (var [fn = /* @__PURE__ */ __name(function() { -}, "fn")] in obj) - ; +}, "fn")] in obj) ; for (var { fn = /* @__PURE__ */ __name(function() { -}, "fn") } in obj) - ; +}, "fn") } in obj) ; for (var [fn = /* @__PURE__ */ __name(function() { -}, "fn")] of obj) - ; +}, "fn")] of obj) ; for (var { fn = /* @__PURE__ */ __name(function() { -}, "fn") } of obj) - ; +}, "fn") } of obj) ; function foo([fn2 = /* @__PURE__ */ __name(function() { }, "fn")]) { } @@ -5196,22 +5171,19 @@ TestMinifySiblingLabelsNoBundle ---------- /out.js ---------- a: { b: { - if (x) - break b; + if (x) break b; break a; } } a: { b: { - if (x) - break b; + if (x) break b; break a; } } a: { b: { - if (x) - break b; + if (x) break b; break a; } } @@ -5711,22 +5683,19 @@ TestRenameLabelsNoBundle ---------- /out.js ---------- foo: { bar: { - if (x) - break bar; + if (x) break bar; break foo; } } foo2: { bar2: { - if (x) - break bar2; + if (x) break bar2; break foo2; } } foo: { bar: { - if (x) - break bar; + if (x) break bar; break foo; } } @@ -6595,29 +6564,22 @@ await init_entry(); TestTopLevelAwaitCJSDeadBranch ---------- /out.js ---------- // entry.js -if (false) - foo; -if (false) - for (foo of bar) - ; +if (false) foo; +if (false) for (foo of bar) ; ================================================================================ TestTopLevelAwaitESM ---------- /out.js ---------- // entry.js await foo; -for await (foo of bar) - ; +for await (foo of bar) ; ================================================================================ TestTopLevelAwaitESMDeadBranch ---------- /out.js ---------- // entry.js -if (false) - await foo; -if (false) - for await (foo of bar) - ; +if (false) await foo; +if (false) for await (foo of bar) ; ================================================================================ TestTopLevelAwaitForbiddenRequireDeadBranch @@ -6627,9 +6589,7 @@ TestTopLevelAwaitForbiddenRequireDeadBranch var c_exports = {}; var init_c = __esm({ "c.js"() { - if (false) - for (let x of y) - ; + if (false) for (let x of y) ; } }); @@ -6657,9 +6617,7 @@ TestTopLevelAwaitForbiddenRequireDeadBranch init_b(); init_c(); init_entry(); - if (false) - for (let x of y) - ; + if (false) for (let x of y) ; } }); init_entry(); @@ -6670,63 +6628,46 @@ TestTopLevelAwaitIIFEDeadBranch ---------- /out.js ---------- (() => { // entry.js - if (false) - foo; - if (false) - for (foo of bar) - ; + if (false) foo; + if (false) for (foo of bar) ; })(); ================================================================================ TestTopLevelAwaitNoBundle ---------- /out.js ---------- await foo; -for await (foo of bar) - ; +for await (foo of bar) ; ================================================================================ TestTopLevelAwaitNoBundleCommonJSDeadBranch ---------- /out.js ---------- -if (false) - foo; -if (false) - for (foo of bar) - ; +if (false) foo; +if (false) for (foo of bar) ; ================================================================================ TestTopLevelAwaitNoBundleDeadBranch ---------- /out.js ---------- -if (false) - await foo; -if (false) - for await (foo of bar) - ; +if (false) await foo; +if (false) for await (foo of bar) ; ================================================================================ TestTopLevelAwaitNoBundleESM ---------- /out.js ---------- await foo; -for await (foo of bar) - ; +for await (foo of bar) ; ================================================================================ TestTopLevelAwaitNoBundleESMDeadBranch ---------- /out.js ---------- -if (false) - await foo; -if (false) - for await (foo of bar) - ; +if (false) await foo; +if (false) for await (foo of bar) ; ================================================================================ TestTopLevelAwaitNoBundleIIFEDeadBranch ---------- /out.js ---------- (() => { - if (false) - foo; - if (false) - for (foo of bar) - ; + if (false) foo; + if (false) for (foo of bar) ; })(); ================================================================================ @@ -6795,29 +6736,22 @@ TestUseStrictDirectiveMinifyNoBundle TestVarRelocatingBundle ---------- /out/top-level.js ---------- // top-level.js -for (; 0; ) - ; +for (; 0; ) ; var b; -for ({ c, x: [d] } = {}; 0; ) - ; +for ({ c, x: [d] } = {}; 0; ) ; var c; var d; -for (e of []) - ; +for (e of []) ; var e; -for ({ f, x: [g] } of []) - ; +for ({ f, x: [g] } of []) ; var f; var g; -for (h in {}) - ; +for (h in {}) ; var h; i = 1; -for (i in {}) - ; +for (i in {}) ; var i; -for ({ j, x: [k] } in {}) - ; +for ({ j, x: [k] } in {}) ; var j; var k; @@ -6827,21 +6761,14 @@ if (true) { let l = function() { }; l2 = l; - for (; 0; ) - ; - for ({ c, x: [d] } = {}; 0; ) - ; - for (e of []) - ; - for ({ f, x: [g] } of []) - ; - for (h in {}) - ; + for (; 0; ) ; + for ({ c, x: [d] } = {}; 0; ) ; + for (e of []) ; + for ({ f, x: [g] } of []) ; + for (h in {}) ; i = 1; - for (i in {}) - ; - for ({ j, x: [k] } in {}) - ; + for (i in {}) ; + for ({ j, x: [k] } in {}) ; } var a; var b; @@ -6860,39 +6787,26 @@ var l2; // let.js if (true) { let a; - for (let b; 0; ) - ; - for (let { c, x: [d] } = {}; 0; ) - ; - for (let e of []) - ; - for (let { f, x: [g] } of []) - ; - for (let h in {}) - ; - for (let { j, x: [k] } in {}) - ; + for (let b; 0; ) ; + for (let { c, x: [d] } = {}; 0; ) ; + for (let e of []) ; + for (let { f, x: [g] } of []) ; + for (let h in {}) ; + for (let { j, x: [k] } in {}) ; } ---------- /out/function.js ---------- // function.js function x() { var a; - for (var b; 0; ) - ; - for (var { c, x: [d] } = {}; 0; ) - ; - for (var e of []) - ; - for (var { f, x: [g] } of []) - ; - for (var h in {}) - ; + for (var b; 0; ) ; + for (var { c, x: [d] } = {}; 0; ) ; + for (var e of []) ; + for (var { f, x: [g] } of []) ; + for (var h in {}) ; i = 1; - for (var i in {}) - ; - for (var { j, x: [k] } in {}) - ; + for (var i in {}) ; + for (var { j, x: [k] } in {}) ; function l() { } } @@ -6906,21 +6820,14 @@ function x() { }; var l = l2; var a; - for (var b; 0; ) - ; - for (var { c, x: [d] } = {}; 0; ) - ; - for (var e of []) - ; - for (var { f, x: [g] } of []) - ; - for (var h in {}) - ; + for (var b; 0; ) ; + for (var { c, x: [d] } = {}; 0; ) ; + for (var e of []) ; + for (var { f, x: [g] } of []) ; + for (var h in {}) ; i = 1; - for (var i in {}) - ; - for (var { j, x: [k] } in {}) - ; + for (var i in {}) ; + for (var { j, x: [k] } in {}) ; } } x(); @@ -6929,21 +6836,14 @@ x(); TestVarRelocatingNoBundle ---------- /out/top-level.js ---------- var a; -for (var b; 0; ) - ; -for (var { c, x: [d] } = {}; 0; ) - ; -for (var e of []) - ; -for (var { f, x: [g] } of []) - ; -for (var h in {}) - ; +for (var b; 0; ) ; +for (var { c, x: [d] } = {}; 0; ) ; +for (var e of []) ; +for (var { f, x: [g] } of []) ; +for (var h in {}) ; i = 1; -for (var i in {}) - ; -for (var { j, x: [k] } in {}) - ; +for (var i in {}) ; +for (var { j, x: [k] } in {}) ; function l() { } @@ -6953,58 +6853,38 @@ if (true) { }; var l2 = l; var a; - for (var b; 0; ) - ; - for (var { c, x: [d] } = {}; 0; ) - ; - for (var e of []) - ; - for (var { f, x: [g] } of []) - ; - for (var h in {}) - ; + for (var b; 0; ) ; + for (var { c, x: [d] } = {}; 0; ) ; + for (var e of []) ; + for (var { f, x: [g] } of []) ; + for (var h in {}) ; i = 1; - for (var i in {}) - ; - for (var { j, x: [k] } in {}) - ; + for (var i in {}) ; + for (var { j, x: [k] } in {}) ; } ---------- /out/let.js ---------- if (true) { let a; - for (let b; 0; ) - ; - for (let { c, x: [d] } = {}; 0; ) - ; - for (let e of []) - ; - for (let { f, x: [g] } of []) - ; - for (let h in {}) - ; - for (let { j, x: [k] } in {}) - ; + for (let b; 0; ) ; + for (let { c, x: [d] } = {}; 0; ) ; + for (let e of []) ; + for (let { f, x: [g] } of []) ; + for (let h in {}) ; + for (let { j, x: [k] } in {}) ; } ---------- /out/function.js ---------- function x() { var a; - for (var b; 0; ) - ; - for (var { c, x: [d] } = {}; 0; ) - ; - for (var e of []) - ; - for (var { f, x: [g] } of []) - ; - for (var h in {}) - ; + for (var b; 0; ) ; + for (var { c, x: [d] } = {}; 0; ) ; + for (var e of []) ; + for (var { f, x: [g] } of []) ; + for (var h in {}) ; i = 1; - for (var i in {}) - ; - for (var { j, x: [k] } in {}) - ; + for (var i in {}) ; + for (var { j, x: [k] } in {}) ; function l() { } } @@ -7017,21 +6897,14 @@ function x() { }; var l = l2; var a; - for (var b; 0; ) - ; - for (var { c, x: [d] } = {}; 0; ) - ; - for (var e of []) - ; - for (var { f, x: [g] } of []) - ; - for (var h in {}) - ; + for (var b; 0; ) ; + for (var { c, x: [d] } = {}; 0; ) ; + for (var e of []) ; + for (var { f, x: [g] } of []) ; + for (var h in {}) ; i = 1; - for (var i in {}) - ; - for (var { j, x: [k] } in {}) - ; + for (var i in {}) ; + for (var { j, x: [k] } in {}) ; } } x(); @@ -7214,10 +7087,8 @@ TestWithStatementTaintingNoBundle let t = 5; hoisted++; t++; - if (1) - outer++; - if (0) - outerDead++; + if (1) outer++; + if (0) outerDead++; } if (1) { hoisted++; diff --git a/internal/bundler_tests/snapshots/snapshots_lower.txt b/internal/bundler_tests/snapshots/snapshots_lower.txt index deb16099df5..cbdd555eeea 100644 --- a/internal/bundler_tests/snapshots/snapshots_lower.txt +++ b/internal/bundler_tests/snapshots/snapshots_lower.txt @@ -3502,13 +3502,11 @@ TestLowerStrictModeSyntax // for-in.js if (test) { a = b; - for (a in {}) - ; + for (a in {}) ; } var a; x = y; -for (x in {}) - ; +for (x in {}) ; var x; ================================================================================ @@ -4239,20 +4237,16 @@ function bar() { } ---------- /out/loops.js ---------- -for (using a of b) - c(() => a); +for (using a of b) c(() => a); if (nested) { - for (using a of b) - c(() => a); + for (using a of b) c(() => a); } function foo() { - for (using a of b) - c(() => a); + for (using a of b) c(() => a); } function bar() { return __async(this, null, function* () { - for (using a of b) - c(() => a); + for (using a of b) c(() => a); for (var _d of e) { var _stack = []; try { @@ -4648,8 +4642,7 @@ assign = __objRest({}, []); var x2 = __objRest(_s, []); } }); x = __objRest(x, []); -for (x = __objRest(x, []); 0; ) - ; +for (x = __objRest(x, []); 0; ) ; console.log((x = __objRest(_t = x, []), _t)); console.log((_v = _u = { x }, { x } = _v, xx = __objRest(_v, ["x"]), _u)); console.log(({ x: _x } = _w = { x }, xx = __objRest(_x, []), _w)); @@ -4685,14 +4678,10 @@ for (const { ...for_in_const } in { abc }) { } for (let { ...for_in_let } in { abc }) { } -for (var { ...for_in_var } in { abc }) - ; -for (const { ...for_of_const } of [{}]) - ; -for (let { ...for_of_let } of [{}]) - x(); -for (var { ...for_of_var } of [{}]) - x(); +for (var { ...for_in_var } in { abc }) ; +for (const { ...for_of_const } of [{}]) ; +for (let { ...for_of_let } of [{}]) x(); +for (var { ...for_of_var } of [{}]) x(); for (const { ...for_const } = {}; x; x = null) { } for (let { ...for_let } = {}; x; x = null) { @@ -4709,8 +4698,7 @@ for ({ ...x } = {}; x; x = null) { ({ obj_method({ ...x2 }) { } }); ({ ...x } = x); -for ({ ...x } = x; 0; ) - ; +for ({ ...x } = x; 0; ) ; console.log({ ...x } = x); console.log({ x, ...xx } = { x }); console.log({ x: { ...xx } } = { x }); diff --git a/internal/bundler_tests/snapshots/snapshots_splitting.txt b/internal/bundler_tests/snapshots/snapshots_splitting.txt index da0de38d5f7..5493fb756b1 100644 --- a/internal/bundler_tests/snapshots/snapshots_splitting.txt +++ b/internal/bundler_tests/snapshots/snapshots_splitting.txt @@ -128,15 +128,15 @@ TestSplittingCrossChunkAssignmentDependencies ---------- /out/a.js ---------- import { setValue -} from "./chunk-RPIUS5UE.js"; +} from "./chunk-3GNPIT25.js"; // a.js setValue(123); ---------- /out/b.js ---------- -import "./chunk-RPIUS5UE.js"; +import "./chunk-3GNPIT25.js"; ----------- /out/chunk-RPIUS5UE.js ---------- +---------- /out/chunk-3GNPIT25.js ---------- // shared.js var observer; var value; @@ -145,8 +145,7 @@ function getValue() { } function setValue(next) { value = next; - if (observer) - observer(); + if (observer) observer(); } sideEffects(getValue); diff --git a/internal/bundler_tests/snapshots/snapshots_tsconfig.txt b/internal/bundler_tests/snapshots/snapshots_tsconfig.txt index f9616bf8aca..b9885e3e7a8 100644 --- a/internal/bundler_tests/snapshots/snapshots_tsconfig.txt +++ b/internal/bundler_tests/snapshots/snapshots_tsconfig.txt @@ -163,14 +163,10 @@ var foo3 = "shimFoo"; var bar3 = "shimBar"; // Users/user/project/src/main.ts -if (foo2 !== "foo") - throw "fail: foo"; -if (bar2 !== "bar") - throw "fail: bar"; -if (foo3 !== "shimFoo") - throw "fail: shimFoo"; -if (bar3 !== "shimBar") - throw "fail: shimBar"; +if (foo2 !== "foo") throw "fail: foo"; +if (bar2 !== "bar") throw "fail: bar"; +if (foo3 !== "shimFoo") throw "fail: shimFoo"; +if (bar3 !== "shimBar") throw "fail: shimBar"; ================================================================================ TestTsconfigIgnoredTargetSilent @@ -755,8 +751,7 @@ TestTsconfigWithStatementAlwaysStrictFalse ---------- /Users/user/project/out.js ---------- (() => { // Users/user/project/src/entry.ts - with (x) - y; + with (x) y; })(); ================================================================================ @@ -764,8 +759,7 @@ TestTsconfigWithStatementStrictFalse ---------- /Users/user/project/out.js ---------- (() => { // Users/user/project/src/entry.ts - with (x) - y; + with (x) y; })(); ================================================================================ @@ -773,6 +767,5 @@ TestTsconfigWithStatementStrictTrueAlwaysStrictFalse ---------- /Users/user/project/out.js ---------- (() => { // Users/user/project/src/entry.ts - with (x) - y; + with (x) y; })(); diff --git a/internal/js_ast/js_ast.go b/internal/js_ast/js_ast.go index dacdce1b5b3..f44f1f83b2f 100644 --- a/internal/js_ast/js_ast.go +++ b/internal/js_ast/js_ast.go @@ -1067,34 +1067,40 @@ type SClass struct { } type SLabel struct { - Stmt Stmt - Name ast.LocRef + Stmt Stmt + Name ast.LocRef + IsSingleLineStmt bool } type SIf struct { - Test Expr - Yes Stmt - NoOrNil Stmt + Test Expr + Yes Stmt + NoOrNil Stmt + IsSingleLineYes bool + IsSingleLineNo bool } type SFor struct { - InitOrNil Stmt // May be a SConst, SLet, SVar, or SExpr - TestOrNil Expr - UpdateOrNil Expr - Body Stmt + InitOrNil Stmt // May be a SConst, SLet, SVar, or SExpr + TestOrNil Expr + UpdateOrNil Expr + Body Stmt + IsSingleLineBody bool } type SForIn struct { - Init Stmt // May be a SConst, SLet, SVar, or SExpr - Value Expr - Body Stmt + Init Stmt // May be a SConst, SLet, SVar, or SExpr + Value Expr + Body Stmt + IsSingleLineBody bool } type SForOf struct { - Init Stmt // May be a SConst, SLet, SVar, or SExpr - Value Expr - Body Stmt - Await logger.Range + Init Stmt // May be a SConst, SLet, SVar, or SExpr + Value Expr + Body Stmt + Await logger.Range + IsSingleLineBody bool } type SDoWhile struct { @@ -1103,14 +1109,16 @@ type SDoWhile struct { } type SWhile struct { - Test Expr - Body Stmt + Test Expr + Body Stmt + IsSingleLineBody bool } type SWith struct { - Value Expr - Body Stmt - BodyLoc logger.Loc + Value Expr + Body Stmt + BodyLoc logger.Loc + IsSingleLineBody bool } type Catch struct { diff --git a/internal/js_parser/js_parser.go b/internal/js_parser/js_parser.go index 96309d0c690..10b1f159e44 100644 --- a/internal/js_parser/js_parser.go +++ b/internal/js_parser/js_parser.go @@ -7265,13 +7265,16 @@ func (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt { p.lexer.Expect(js_lexer.TOpenParen) test := p.parseExpr(js_ast.LLowest) p.lexer.Expect(js_lexer.TCloseParen) + isSingleLineYes := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace yes := p.parseStmt(parseStmtOpts{lexicalDecl: lexicalDeclAllowFnInsideIf}) var noOrNil js_ast.Stmt + var isSingleLineNo bool if p.lexer.Token == js_lexer.TElse { p.lexer.Next() + isSingleLineNo = !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace noOrNil = p.parseStmt(parseStmtOpts{lexicalDecl: lexicalDeclAllowFnInsideIf}) } - return js_ast.Stmt{Loc: loc, Data: &js_ast.SIf{Test: test, Yes: yes, NoOrNil: noOrNil}} + return js_ast.Stmt{Loc: loc, Data: &js_ast.SIf{Test: test, Yes: yes, NoOrNil: noOrNil, IsSingleLineYes: isSingleLineYes, IsSingleLineNo: isSingleLineNo}} case js_lexer.TDo: p.lexer.Next() @@ -7293,8 +7296,9 @@ func (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt { p.lexer.Expect(js_lexer.TOpenParen) test := p.parseExpr(js_ast.LLowest) p.lexer.Expect(js_lexer.TCloseParen) + isSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace body := p.parseStmt(parseStmtOpts{}) - return js_ast.Stmt{Loc: loc, Data: &js_ast.SWhile{Test: test, Body: body}} + return js_ast.Stmt{Loc: loc, Data: &js_ast.SWhile{Test: test, Body: body, IsSingleLineBody: isSingleLineBody}} case js_lexer.TWith: p.lexer.Next() @@ -7307,10 +7311,11 @@ func (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt { // within the body from being renamed. Renaming them might change the // semantics of the code. p.pushScopeForParsePass(js_ast.ScopeWith, bodyLoc) + isSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace body := p.parseStmt(parseStmtOpts{}) p.popScope() - return js_ast.Stmt{Loc: loc, Data: &js_ast.SWith{Value: test, BodyLoc: bodyLoc, Body: body}} + return js_ast.Stmt{Loc: loc, Data: &js_ast.SWith{Value: test, BodyLoc: bodyLoc, Body: body, IsSingleLineBody: isSingleLineBody}} case js_lexer.TSwitch: p.lexer.Next() @@ -7542,8 +7547,9 @@ func (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt { p.lexer.Next() value := p.parseExpr(js_ast.LComma) p.lexer.Expect(js_lexer.TCloseParen) + isSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace body := p.parseStmt(parseStmtOpts{}) - return js_ast.Stmt{Loc: loc, Data: &js_ast.SForOf{Await: awaitRange, Init: initOrNil, Value: value, Body: body}} + return js_ast.Stmt{Loc: loc, Data: &js_ast.SForOf{Await: awaitRange, Init: initOrNil, Value: value, Body: body, IsSingleLineBody: isSingleLineBody}} } // Detect for-in loops @@ -7561,8 +7567,9 @@ func (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt { p.lexer.Next() value := p.parseExpr(js_ast.LLowest) p.lexer.Expect(js_lexer.TCloseParen) + isSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace body := p.parseStmt(parseStmtOpts{}) - return js_ast.Stmt{Loc: loc, Data: &js_ast.SForIn{Init: initOrNil, Value: value, Body: body}} + return js_ast.Stmt{Loc: loc, Data: &js_ast.SForIn{Init: initOrNil, Value: value, Body: body, IsSingleLineBody: isSingleLineBody}} } p.lexer.Expect(js_lexer.TSemicolon) @@ -7588,12 +7595,14 @@ func (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt { } p.lexer.Expect(js_lexer.TCloseParen) + isSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace body := p.parseStmt(parseStmtOpts{}) return js_ast.Stmt{Loc: loc, Data: &js_ast.SFor{ - InitOrNil: initOrNil, - TestOrNil: testOrNil, - UpdateOrNil: updateOrNil, - Body: body, + InitOrNil: initOrNil, + TestOrNil: testOrNil, + UpdateOrNil: updateOrNil, + Body: body, + IsSingleLineBody: isSingleLineBody, }} case js_lexer.TImport: @@ -7915,8 +7924,9 @@ func (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt { if opts.lexicalDecl == lexicalDeclAllowAll || opts.lexicalDecl == lexicalDeclAllowFnInsideLabel { nestedOpts.lexicalDecl = lexicalDeclAllowFnInsideLabel } + isSingleLineStmt := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace stmt := p.parseStmt(nestedOpts) - return js_ast.Stmt{Loc: loc, Data: &js_ast.SLabel{Name: name, Stmt: stmt}} + return js_ast.Stmt{Loc: loc, Data: &js_ast.SLabel{Name: name, Stmt: stmt, IsSingleLineStmt: isSingleLineStmt}} } if p.options.ts.Parse { @@ -10515,7 +10525,7 @@ func (p *parser) visitAndAppendStmt(stmts []js_ast.Stmt, stmt js_ast.Stmt) []js_ } // "while (a) {}" => "for (;a;) {}" - forS := &js_ast.SFor{TestOrNil: testOrNil, Body: s.Body} + forS := &js_ast.SFor{TestOrNil: testOrNil, Body: s.Body, IsSingleLineBody: s.IsSingleLineBody} mangleFor(forS) stmt = js_ast.Stmt{Loc: stmt.Loc, Data: forS} } diff --git a/internal/js_parser/js_parser_lower_test.go b/internal/js_parser/js_parser_lower_test.go index 0c29abfb2da..e6f1e2ccc2b 100644 --- a/internal/js_parser/js_parser_lower_test.go +++ b/internal/js_parser/js_parser_lower_test.go @@ -770,7 +770,7 @@ func TestForAwait(t *testing.T) { err = ": ERROR: Top-level await is not available in the configured target environment\n" expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "for await (x of y) ;", err) expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) for await (x of y) ;", err) - expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) for await (x of y) ;", "if (false)\n for (x of y)\n ;\n") + expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) for await (x of y) ;", "if (false) for (x of y) ;\n") expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "with (x) y; if (false) for await (x of y) ;", ": ERROR: With statements cannot be used in an ECMAScript module\n"+ ": NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n") diff --git a/internal/js_parser/js_parser_test.go b/internal/js_parser/js_parser_test.go index d0549fddc43..86c4790fec4 100644 --- a/internal/js_parser/js_parser_test.go +++ b/internal/js_parser/js_parser_test.go @@ -277,7 +277,7 @@ func TestComments(t *testing.T) { expectPrinted(t, "x\n/**/-->\ny", "x;\ny;\n") expectPrinted(t, "x/*\n*/-->\ny", "x;\ny;\n") expectPrinted(t, "x\n/**/ /**/-->\ny", "x;\ny;\n") - expectPrinted(t, "if(x-->y)z", "if (x-- > y)\n z;\n") + expectPrinted(t, "if(x-->y)z", "if (x-- > y) z;\n") } func TestStrictMode(t *testing.T) { @@ -341,7 +341,7 @@ func TestStrictMode(t *testing.T) { expectParseError(t, "'\\09'; export {}", ": ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\n"+why) expectParseError(t, "'\\009'; export {}", ": ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\n"+why) - expectPrinted(t, "with (x) y", "with (x)\n y;\n") + expectPrinted(t, "with (x) y", "with (x) y;\n") expectParseError(t, "'use strict'; with (x) y", ": ERROR: With statements cannot be used in strict mode\n"+useStrict) expectParseError(t, "with (x) y; export {}", ": ERROR: With statements cannot be used in an ECMAScript module\n"+why) @@ -349,7 +349,7 @@ func TestStrictMode(t *testing.T) { expectParseError(t, "'use strict'; delete x", ": ERROR: Delete of a bare identifier cannot be used in strict mode\n"+useStrict) expectParseError(t, "delete x; export {}", ": ERROR: Delete of a bare identifier cannot be used in an ECMAScript module\n"+why) - expectPrinted(t, "for (var x = y in z) ;", "x = y;\nfor (var x in z)\n ;\n") + expectPrinted(t, "for (var x = y in z) ;", "x = y;\nfor (var x in z) ;\n") expectParseError(t, "'use strict'; for (var x = y in z) ;", ": ERROR: Variable initializers inside for-in loops cannot be used in strict mode\n"+useStrict) expectParseError(t, "for (var x = y in z) ; export {}", @@ -478,17 +478,17 @@ func TestStrictMode(t *testing.T) { classNote := ": NOTE: All code inside a class is implicitly in strict mode\n" - expectPrinted(t, "function f() { 'use strict' } with (x) y", "function f() {\n \"use strict\";\n}\nwith (x)\n y;\n") - expectPrinted(t, "with (x) y; function f() { 'use strict' }", "with (x)\n y;\nfunction f() {\n \"use strict\";\n}\n") - expectPrinted(t, "class f {} with (x) y", "class f {\n}\nwith (x)\n y;\n") - expectPrinted(t, "with (x) y; class f {}", "with (x)\n y;\nclass f {\n}\n") - expectPrinted(t, "`use strict`; with (x) y", "`use strict`;\nwith (x)\n y;\n") - expectPrinted(t, "{ 'use strict'; with (x) y }", "{\n \"use strict\";\n with (x)\n y;\n}\n") - expectPrinted(t, "if (0) { 'use strict'; with (x) y }", "if (0) {\n \"use strict\";\n with (x)\n y;\n}\n") - expectPrinted(t, "while (0) { 'use strict'; with (x) y }", "while (0) {\n \"use strict\";\n with (x)\n y;\n}\n") - expectPrinted(t, "try { 'use strict'; with (x) y } catch {}", "try {\n \"use strict\";\n with (x)\n y;\n} catch {\n}\n") - expectPrinted(t, "try {} catch { 'use strict'; with (x) y }", "try {\n} catch {\n \"use strict\";\n with (x)\n y;\n}\n") - expectPrinted(t, "try {} finally { 'use strict'; with (x) y }", "try {\n} finally {\n \"use strict\";\n with (x)\n y;\n}\n") + expectPrinted(t, "function f() { 'use strict' } with (x) y", "function f() {\n \"use strict\";\n}\nwith (x) y;\n") + expectPrinted(t, "with (x) y; function f() { 'use strict' }", "with (x) y;\nfunction f() {\n \"use strict\";\n}\n") + expectPrinted(t, "class f {} with (x) y", "class f {\n}\nwith (x) y;\n") + expectPrinted(t, "with (x) y; class f {}", "with (x) y;\nclass f {\n}\n") + expectPrinted(t, "`use strict`; with (x) y", "`use strict`;\nwith (x) y;\n") + expectPrinted(t, "{ 'use strict'; with (x) y }", "{\n \"use strict\";\n with (x) y;\n}\n") + expectPrinted(t, "if (0) { 'use strict'; with (x) y }", "if (0) {\n \"use strict\";\n with (x) y;\n}\n") + expectPrinted(t, "while (0) { 'use strict'; with (x) y }", "while (0) {\n \"use strict\";\n with (x) y;\n}\n") + expectPrinted(t, "try { 'use strict'; with (x) y } catch {}", "try {\n \"use strict\";\n with (x) y;\n} catch {\n}\n") + expectPrinted(t, "try {} catch { 'use strict'; with (x) y }", "try {\n} catch {\n \"use strict\";\n with (x) y;\n}\n") + expectPrinted(t, "try {} finally { 'use strict'; with (x) y }", "try {\n} finally {\n \"use strict\";\n with (x) y;\n}\n") expectParseError(t, "\"use strict\"; with (x) y", ": ERROR: With statements cannot be used in strict mode\n"+useStrict) expectParseError(t, "function f() { 'use strict'; with (x) y }", ": ERROR: With statements cannot be used in strict mode\n"+useStrict) expectParseError(t, "function f() { 'use strict'; function y() { with (x) y } }", ": ERROR: With statements cannot be used in strict mode\n"+useStrict) @@ -514,14 +514,14 @@ func TestStrictMode(t *testing.T) { tlaKeyword := ": ERROR: With statements cannot be used in an ECMAScript module\n" + ": NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n" - expectPrinted(t, "import(x); with (y) z", "import(x);\nwith (y)\n z;\n") - expectPrinted(t, "import('x'); with (y) z", "import(\"x\");\nwith (y)\n z;\n") - expectPrinted(t, "with (y) z; import(x)", "with (y)\n z;\nimport(x);\n") - expectPrinted(t, "with (y) z; import('x')", "with (y)\n z;\nimport(\"x\");\n") - expectPrinted(t, "(import(x)); with (y) z", "import(x);\nwith (y)\n z;\n") - expectPrinted(t, "(import('x')); with (y) z", "import(\"x\");\nwith (y)\n z;\n") - expectPrinted(t, "with (y) z; (import(x))", "with (y)\n z;\nimport(x);\n") - expectPrinted(t, "with (y) z; (import('x'))", "with (y)\n z;\nimport(\"x\");\n") + expectPrinted(t, "import(x); with (y) z", "import(x);\nwith (y) z;\n") + expectPrinted(t, "import('x'); with (y) z", "import(\"x\");\nwith (y) z;\n") + expectPrinted(t, "with (y) z; import(x)", "with (y) z;\nimport(x);\n") + expectPrinted(t, "with (y) z; import('x')", "with (y) z;\nimport(\"x\");\n") + expectPrinted(t, "(import(x)); with (y) z", "import(x);\nwith (y) z;\n") + expectPrinted(t, "(import('x')); with (y) z", "import(\"x\");\nwith (y) z;\n") + expectPrinted(t, "with (y) z; (import(x))", "with (y) z;\nimport(x);\n") + expectPrinted(t, "with (y) z; (import('x'))", "with (y) z;\nimport(\"x\");\n") expectParseError(t, "import.meta; with (y) z", importMeta) expectParseError(t, "with (y) z; import.meta", importMeta) @@ -695,7 +695,7 @@ func TestAwait(t *testing.T) { err := ": ERROR: Top-level await is not available in the configured target environment\n" expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "await x;", err) expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) await x;", err) - expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) await x;", "if (false)\n x;\n") + expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) await x;", "if (false) x;\n") expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "with (x) y; if (false) await x;", ": ERROR: With statements cannot be used in an ECMAScript module\n"+ ": NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n") @@ -823,17 +823,17 @@ func TestDecls(t *testing.T) { expectParseError(t, "function f(([]) = []) {}", ": ERROR: Expected identifier but found \"(\"\n") expectParseError(t, "function f(({}) = {}) {}", ": ERROR: Expected identifier but found \"(\"\n") - expectPrinted(t, "for (x in y) ;", "for (x in y)\n ;\n") - expectPrinted(t, "for ([] in y) ;", "for ([] in y)\n ;\n") - expectPrinted(t, "for ({} in y) ;", "for ({} in y)\n ;\n") - expectPrinted(t, "for ((x) in y) ;", "for (x in y)\n ;\n") + expectPrinted(t, "for (x in y) ;", "for (x in y) ;\n") + expectPrinted(t, "for ([] in y) ;", "for ([] in y) ;\n") + expectPrinted(t, "for ({} in y) ;", "for ({} in y) ;\n") + expectPrinted(t, "for ((x) in y) ;", "for (x in y) ;\n") expectParseError(t, "for (([]) in y) ;", ": ERROR: Invalid assignment target\n") expectParseError(t, "for (({}) in y) ;", ": ERROR: Invalid assignment target\n") - expectPrinted(t, "for (x of y) ;", "for (x of y)\n ;\n") - expectPrinted(t, "for ([] of y) ;", "for ([] of y)\n ;\n") - expectPrinted(t, "for ({} of y) ;", "for ({} of y)\n ;\n") - expectPrinted(t, "for ((x) of y) ;", "for (x of y)\n ;\n") + expectPrinted(t, "for (x of y) ;", "for (x of y) ;\n") + expectPrinted(t, "for ([] of y) ;", "for ([] of y) ;\n") + expectPrinted(t, "for ({} of y) ;", "for ({} of y) ;\n") + expectPrinted(t, "for ((x) of y) ;", "for (x of y) ;\n") expectParseError(t, "for (([]) of y) ;", ": ERROR: Invalid assignment target\n") expectParseError(t, "for (({}) of y) ;", ": ERROR: Invalid assignment target\n") @@ -891,26 +891,26 @@ func TestFor(t *testing.T) { expectParseError(t, "for (; in x) ;", ": ERROR: Unexpected \"in\"\n") expectParseError(t, "for (; of x) ;", ": ERROR: Expected \";\" but found \"x\"\n") expectParseError(t, "for (; in; ) ;", ": ERROR: Unexpected \"in\"\n") - expectPrinted(t, "for (; of; ) ;", "for (; of; )\n ;\n") - - expectPrinted(t, "for (a in b) ;", "for (a in b)\n ;\n") - expectPrinted(t, "for (var a in b) ;", "for (var a in b)\n ;\n") - expectPrinted(t, "for (let a in b) ;", "for (let a in b)\n ;\n") - expectPrinted(t, "for (const a in b) ;", "for (const a in b)\n ;\n") - expectPrinted(t, "for (a in b, c) ;", "for (a in b, c)\n ;\n") - expectPrinted(t, "for (a in b = c) ;", "for (a in b = c)\n ;\n") - expectPrinted(t, "for (var a in b, c) ;", "for (var a in b, c)\n ;\n") - expectPrinted(t, "for (var a in b = c) ;", "for (var a in b = c)\n ;\n") + expectPrinted(t, "for (; of; ) ;", "for (; of; ) ;\n") + + expectPrinted(t, "for (a in b) ;", "for (a in b) ;\n") + expectPrinted(t, "for (var a in b) ;", "for (var a in b) ;\n") + expectPrinted(t, "for (let a in b) ;", "for (let a in b) ;\n") + expectPrinted(t, "for (const a in b) ;", "for (const a in b) ;\n") + expectPrinted(t, "for (a in b, c) ;", "for (a in b, c) ;\n") + expectPrinted(t, "for (a in b = c) ;", "for (a in b = c) ;\n") + expectPrinted(t, "for (var a in b, c) ;", "for (var a in b, c) ;\n") + expectPrinted(t, "for (var a in b = c) ;", "for (var a in b = c) ;\n") expectParseError(t, "for (var a, b in b) ;", ": ERROR: for-in loops must have a single declaration\n") expectParseError(t, "for (let a, b in b) ;", ": ERROR: for-in loops must have a single declaration\n") expectParseError(t, "for (const a, b in b) ;", ": ERROR: for-in loops must have a single declaration\n") - expectPrinted(t, "for (a of b) ;", "for (a of b)\n ;\n") - expectPrinted(t, "for (var a of b) ;", "for (var a of b)\n ;\n") - expectPrinted(t, "for (let a of b) ;", "for (let a of b)\n ;\n") - expectPrinted(t, "for (const a of b) ;", "for (const a of b)\n ;\n") - expectPrinted(t, "for (a of b = c) ;", "for (a of b = c)\n ;\n") - expectPrinted(t, "for (var a of b = c) ;", "for (var a of b = c)\n ;\n") + expectPrinted(t, "for (a of b) ;", "for (a of b) ;\n") + expectPrinted(t, "for (var a of b) ;", "for (var a of b) ;\n") + expectPrinted(t, "for (let a of b) ;", "for (let a of b) ;\n") + expectPrinted(t, "for (const a of b) ;", "for (const a of b) ;\n") + expectPrinted(t, "for (a of b = c) ;", "for (a of b = c) ;\n") + expectPrinted(t, "for (var a of b = c) ;", "for (var a of b = c) ;\n") expectParseError(t, "for (a of b, c) ;", ": ERROR: Expected \")\" but found \",\"\n") expectParseError(t, "for (var a of b, c) ;", ": ERROR: Expected \")\" but found \",\"\n") expectParseError(t, "for (var a, b of b) ;", ": ERROR: for-of loops must have a single declaration\n") @@ -918,15 +918,15 @@ func TestFor(t *testing.T) { expectParseError(t, "for (const a, b of b) ;", ": ERROR: for-of loops must have a single declaration\n") // Avoid the initializer starting with "let" token - expectPrinted(t, "for ((let) of bar);", "for ((let) of bar)\n ;\n") - expectPrinted(t, "for ((let).foo of bar);", "for ((let).foo of bar)\n ;\n") - expectPrinted(t, "for ((let.foo) of bar);", "for ((let).foo of bar)\n ;\n") - expectPrinted(t, "for ((let``.foo) of bar);", "for ((let)``.foo of bar)\n ;\n") + expectPrinted(t, "for ((let) of bar);", "for ((let) of bar) ;\n") + expectPrinted(t, "for ((let).foo of bar);", "for ((let).foo of bar) ;\n") + expectPrinted(t, "for ((let.foo) of bar);", "for ((let).foo of bar) ;\n") + expectPrinted(t, "for ((let``.foo) of bar);", "for ((let)``.foo of bar) ;\n") expectParseError(t, "for (let.foo of bar);", ": ERROR: \"let\" must be wrapped in parentheses to be used as an expression here:\n") expectParseError(t, "for (let().foo of bar);", ": ERROR: \"let\" must be wrapped in parentheses to be used as an expression here:\n") expectParseError(t, "for (let``.foo of bar);", ": ERROR: \"let\" must be wrapped in parentheses to be used as an expression here:\n") - expectPrinted(t, "for (var x = 0 in y) ;", "x = 0;\nfor (var x in y)\n ;\n") // This is a weird special-case + expectPrinted(t, "for (var x = 0 in y) ;", "x = 0;\nfor (var x in y) ;\n") // This is a weird special-case expectParseError(t, "for (let x = 0 in y) ;", ": ERROR: for-in loop variables cannot have an initializer\n") expectParseError(t, "for (const x = 0 in y) ;", ": ERROR: for-in loop variables cannot have an initializer\n") expectParseError(t, "for (var x = 0 of y) ;", ": ERROR: for-of loop variables cannot have an initializer\n") @@ -948,25 +948,25 @@ func TestFor(t *testing.T) { expectParseError(t, "for (const {x} = y of z) ;", ": ERROR: for-of loop variables cannot have an initializer\n") // Make sure "in" rules are enabled - expectPrinted(t, "for (var x = () => a in b);", "x = () => a;\nfor (var x in b)\n ;\n") - expectPrinted(t, "for (var x = a + b in c);", "x = a + b;\nfor (var x in c)\n ;\n") + expectPrinted(t, "for (var x = () => a in b);", "x = () => a;\nfor (var x in b) ;\n") + expectPrinted(t, "for (var x = a + b in c);", "x = a + b;\nfor (var x in c) ;\n") // Make sure "in" rules are disabled - expectPrinted(t, "for (var x = `${y in z}`;;);", "for (var x = `${y in z}`; ; )\n ;\n") - expectPrinted(t, "for (var {[x in y]: z} = {};;);", "for (var { [x in y]: z } = {}; ; )\n ;\n") - expectPrinted(t, "for (var {x = y in z} = {};;);", "for (var { x = y in z } = {}; ; )\n ;\n") - expectPrinted(t, "for (var [x = y in z] = {};;);", "for (var [x = y in z] = {}; ; )\n ;\n") - expectPrinted(t, "for (var {x: y = z in w} = {};;);", "for (var { x: y = z in w } = {}; ; )\n ;\n") - expectPrinted(t, "for (var x = (a in b);;);", "for (var x = (a in b); ; )\n ;\n") - expectPrinted(t, "for (var x = [a in b];;);", "for (var x = [a in b]; ; )\n ;\n") - expectPrinted(t, "for (var x = y(a in b);;);", "for (var x = y(a in b); ; )\n ;\n") - expectPrinted(t, "for (var x = {y: a in b};;);", "for (var x = { y: a in b }; ; )\n ;\n") - expectPrinted(t, "for (a ? b in c : d;;);", "for (a ? b in c : d; ; )\n ;\n") - expectPrinted(t, "for (var x = () => { a in b };;);", "for (var x = () => {\n a in b;\n}; ; )\n ;\n") - expectPrinted(t, "for (var x = async () => { a in b };;);", "for (var x = async () => {\n a in b;\n}; ; )\n ;\n") - expectPrinted(t, "for (var x = function() { a in b };;);", "for (var x = function() {\n a in b;\n}; ; )\n ;\n") - expectPrinted(t, "for (var x = async function() { a in b };;);", "for (var x = async function() {\n a in b;\n}; ; )\n ;\n") - expectPrinted(t, "for (var x = class { [a in b]() {} };;);", "for (var x = class {\n [a in b]() {\n }\n}; ; )\n ;\n") + expectPrinted(t, "for (var x = `${y in z}`;;);", "for (var x = `${y in z}`; ; ) ;\n") + expectPrinted(t, "for (var {[x in y]: z} = {};;);", "for (var { [x in y]: z } = {}; ; ) ;\n") + expectPrinted(t, "for (var {x = y in z} = {};;);", "for (var { x = y in z } = {}; ; ) ;\n") + expectPrinted(t, "for (var [x = y in z] = {};;);", "for (var [x = y in z] = {}; ; ) ;\n") + expectPrinted(t, "for (var {x: y = z in w} = {};;);", "for (var { x: y = z in w } = {}; ; ) ;\n") + expectPrinted(t, "for (var x = (a in b);;);", "for (var x = (a in b); ; ) ;\n") + expectPrinted(t, "for (var x = [a in b];;);", "for (var x = [a in b]; ; ) ;\n") + expectPrinted(t, "for (var x = y(a in b);;);", "for (var x = y(a in b); ; ) ;\n") + expectPrinted(t, "for (var x = {y: a in b};;);", "for (var x = { y: a in b }; ; ) ;\n") + expectPrinted(t, "for (a ? b in c : d;;);", "for (a ? b in c : d; ; ) ;\n") + expectPrinted(t, "for (var x = () => { a in b };;);", "for (var x = () => {\n a in b;\n}; ; ) ;\n") + expectPrinted(t, "for (var x = async () => { a in b };;);", "for (var x = async () => {\n a in b;\n}; ; ) ;\n") + expectPrinted(t, "for (var x = function() { a in b };;);", "for (var x = function() {\n a in b;\n}; ; ) ;\n") + expectPrinted(t, "for (var x = async function() { a in b };;);", "for (var x = async function() {\n a in b;\n}; ; ) ;\n") + expectPrinted(t, "for (var x = class { [a in b]() {} };;);", "for (var x = class {\n [a in b]() {\n }\n}; ; ) ;\n") expectParseError(t, "for (var x = class extends a in b {};;);", ": ERROR: Expected \"{\" but found \"in\"\n") errorText := `: WARNING: This assignment will throw because "x" is a constant @@ -994,11 +994,11 @@ func TestFor(t *testing.T) { expectParseError(t, "for (const x of y) x++", errorText) expectPrinted(t, "async of => {}", "async (of) => {\n};\n") - expectPrinted(t, "for ((async) of []) ;", "for ((async) of [])\n ;\n") - expectPrinted(t, "for (async.x of []) ;", "for (async.x of [])\n ;\n") - expectPrinted(t, "for (async of => {};;) ;", "for (async (of) => {\n}; ; )\n ;\n") - expectPrinted(t, "for (\\u0061sync of []) ;", "for ((async) of [])\n ;\n") - expectPrinted(t, "for await (async of []) ;", "for await (async of [])\n ;\n") + expectPrinted(t, "for ((async) of []) ;", "for ((async) of []) ;\n") + expectPrinted(t, "for (async.x of []) ;", "for (async.x of []) ;\n") + expectPrinted(t, "for (async of => {};;) ;", "for (async (of) => {\n}; ; ) ;\n") + expectPrinted(t, "for (\\u0061sync of []) ;", "for ((async) of []) ;\n") + expectPrinted(t, "for await (async of []) ;", "for await (async of []) ;\n") expectParseError(t, "for (async of []) ;", ": ERROR: For loop initializers cannot start with \"async of\"\n") expectParseError(t, "for (async o\\u0066 []) ;", ": ERROR: Expected \";\" but found \"o\\\\u0066\"\n") expectParseError(t, "for await (async of => {}) ;", ": ERROR: Expected \"of\" but found \")\"\n") @@ -1009,7 +1009,7 @@ func TestFor(t *testing.T) { err := ": ERROR: Top-level await is not available in the configured target environment\n" expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "for await (x of y);", err) expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) for await (x of y);", err) - expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) for await (x of y);", "if (false)\n for (x of y)\n ;\n") + expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) for await (x of y);", "if (false) for (x of y) ;\n") expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "with (x) y; if (false) for await (x of y);", ": ERROR: With statements cannot be used in an ECMAScript module\n"+ ": NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n") @@ -1172,7 +1172,7 @@ func TestASI(t *testing.T) { expectPrinted(t, "0\n[1]", "0[1];\n") expectPrinted(t, "0\n(1)", "0(1);\n") expectPrinted(t, "new x\n(1)", "new x(1);\n") - expectPrinted(t, "while (true) break\nx", "while (true)\n break;\nx;\n") + expectPrinted(t, "while (true) break\nx", "while (true) break;\nx;\n") expectPrinted(t, "x\n!y", "x;\n!y;\n") expectPrinted(t, "x\n++y", "x;\n++y;\n") expectPrinted(t, "x\n--y", "x;\n--y;\n") @@ -1192,12 +1192,12 @@ func TestASI(t *testing.T) { expectParseError(t, "(async\n() => {})", ": ERROR: Expected \")\" but found \"=>\"\n") expectParseError(t, "(async\nfunction foo() {})", ": ERROR: Expected \")\" but found \"function\"\n") - expectPrinted(t, "if (0) let\nx = 0", "if (0)\n let;\nx = 0;\n") - expectPrinted(t, "if (0) let\n{x}", "if (0)\n let;\n{\n x;\n}\n") + expectPrinted(t, "if (0) let\nx = 0", "if (0) let;\nx = 0;\n") + expectPrinted(t, "if (0) let\n{x}", "if (0) let;\n{\n x;\n}\n") expectParseError(t, "if (0) let\n{x} = 0", ": ERROR: Unexpected \"=\"\n") expectParseError(t, "if (0) let\n[x] = 0", ": ERROR: Cannot use a declaration in a single-statement context\n") - expectPrinted(t, "function *foo() { if (0) let\nyield 0 }", "function* foo() {\n if (0)\n let;\n yield 0;\n}\n") - expectPrinted(t, "async function foo() { if (0) let\nawait 0 }", "async function foo() {\n if (0)\n let;\n await 0;\n}\n") + expectPrinted(t, "function *foo() { if (0) let\nyield 0 }", "function* foo() {\n if (0) let;\n yield 0;\n}\n") + expectPrinted(t, "async function foo() { if (0) let\nawait 0 }", "async function foo() {\n if (0) let;\n await 0;\n}\n") expectPrinted(t, "let\nx = 0", "let x = 0;\n") expectPrinted(t, "let\n{x} = 0", "let { x } = 0;\n") @@ -1222,11 +1222,11 @@ func TestLocal(t *testing.T) { expectParseError(t, "let\nlet = 0", ": ERROR: Cannot use \"let\" as an identifier here:\n") expectParseError(t, "const\nlet = 0", ": ERROR: Cannot use \"let\" as an identifier here:\n") - expectPrinted(t, "for (var let in x) ;", "for (var let in x)\n ;\n") + expectPrinted(t, "for (var let in x) ;", "for (var let in x) ;\n") expectParseError(t, "for (let let in x) ;", ": ERROR: Cannot use \"let\" as an identifier here:\n") expectParseError(t, "for (const let in x) ;", ": ERROR: Cannot use \"let\" as an identifier here:\n") - expectPrinted(t, "for (var let of x) ;", "for (var let of x)\n ;\n") + expectPrinted(t, "for (var let of x) ;", "for (var let of x) ;\n") expectParseError(t, "for (let let of x) ;", ": ERROR: Cannot use \"let\" as an identifier here:\n") expectParseError(t, "for (const let of x) ;", ": ERROR: Cannot use \"let\" as an identifier here:\n") @@ -1409,7 +1409,7 @@ func TestQuotedProperty(t *testing.T) { } func TestLexicalDecl(t *testing.T) { - expectPrinted(t, "if (1) var x", "if (1)\n var x;\n") + expectPrinted(t, "if (1) var x", "if (1) var x;\n") expectPrinted(t, "if (1) function x() {}", "if (1) {\n let x = function() {\n };\n var x = x;\n}\n") expectPrinted(t, "if (1) {} else function x() {}", "if (1) {\n} else {\n let x = function() {\n };\n var x = x;\n}\n") expectPrinted(t, "switch (1) { case 1: const x = 1 }", "switch (1) {\n case 1:\n const x = 1;\n}\n") @@ -1451,7 +1451,7 @@ func TestLexicalDecl(t *testing.T) { expectPrinted(t, "function f() {}", "function f() {\n}\n") expectPrinted(t, "{function f() {}} let f", "{\n let f = function() {\n };\n}\nlet f;\n") expectPrinted(t, "if (1) function f() {} let f", "if (1) {\n let f = function() {\n };\n}\nlet f;\n") - expectPrinted(t, "if (0) ; else function f() {} let f", "if (0)\n ;\nelse {\n let f = function() {\n };\n}\nlet f;\n") + expectPrinted(t, "if (0) ; else function f() {} let f", "if (0) ;\nelse {\n let f = function() {\n };\n}\nlet f;\n") expectPrinted(t, "x: function f() {}", "x: {\n let f = function() {\n };\n var f = f;\n}\n") expectPrinted(t, "{function* f() {}} let f", "{\n function* f() {\n }\n}\nlet f;\n") expectPrinted(t, "{async function f() {}} let f", "{\n async function f() {\n }\n}\nlet f;\n") @@ -1824,11 +1824,11 @@ func TestSuperCall(t *testing.T) { expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { c(); super() } }", "class A extends B {\n constructor() {\n c();\n super();\n __publicField(this, \"x\", 1);\n }\n}\n") expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); if (c) throw c } }", - "class A extends B {\n constructor() {\n super();\n __publicField(this, \"x\", 1);\n if (c)\n throw c;\n }\n}\n") + "class A extends B {\n constructor() {\n super();\n __publicField(this, \"x\", 1);\n if (c) throw c;\n }\n}\n") expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); switch (c) { case 0: throw c } } }", "class A extends B {\n constructor() {\n super();\n __publicField(this, \"x\", 1);\n switch (c) {\n case 0:\n throw c;\n }\n }\n}\n") expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); while (!c) throw c } }", - "class A extends B {\n constructor() {\n super();\n __publicField(this, \"x\", 1);\n for (; !c; )\n throw c;\n }\n}\n") + "class A extends B {\n constructor() {\n super();\n __publicField(this, \"x\", 1);\n for (; !c; ) throw c;\n }\n}\n") expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); return c } }", "class A extends B {\n constructor() {\n super();\n __publicField(this, \"x\", 1);\n return c;\n }\n}\n") expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); throw c } }", @@ -2275,7 +2275,7 @@ func TestAsync(t *testing.T) { // Top-level await expectPrinted(t, "await foo;", "await foo;\n") - expectPrinted(t, "for await(foo of bar);", "for await (foo of bar)\n ;\n") + expectPrinted(t, "for await(foo of bar);", "for await (foo of bar) ;\n") expectParseError(t, "function foo() { await foo }", friendlyAwaitErrorWithNote) expectParseError(t, "function foo() { for await(foo of bar); }", ": ERROR: Cannot use \"await\" outside an async function\n") expectPrinted(t, "function foo(x = await) {}", "function foo(x = await) {\n}\n") @@ -2316,8 +2316,8 @@ func TestAsync(t *testing.T) { expectParseError(t, "for await(x in y);", ": ERROR: Expected \"of\" but found \"in\"\n") expectParseError(t, "async function foo(){for await(;;);}", ": ERROR: Unexpected \";\"\n") expectParseError(t, "async function foo(){for await(let x;;);}", ": ERROR: Expected \"of\" but found \";\"\n") - expectPrinted(t, "async function foo(){for await(x of y);}", "async function foo() {\n for await (x of y)\n ;\n}\n") - expectPrinted(t, "async function foo(){for await(let x of y);}", "async function foo() {\n for await (let x of y)\n ;\n}\n") + expectPrinted(t, "async function foo(){for await(x of y);}", "async function foo() {\n for await (x of y) ;\n}\n") + expectPrinted(t, "async function foo(){for await(let x of y);}", "async function foo() {\n for await (let x of y) ;\n}\n") // Await as an identifier expectPrinted(t, "(function await() {})", "(function await() {\n});\n") @@ -2347,27 +2347,27 @@ func TestAsync(t *testing.T) { } func TestLabels(t *testing.T) { - expectPrinted(t, "{a:b}", "{\n a:\n b;\n}\n") + expectPrinted(t, "{a:b}", "{\n a: b;\n}\n") expectPrinted(t, "({a:b})", "({ a: b });\n") expectParseError(t, "while (1) break x", ": ERROR: There is no containing label named \"x\"\n") expectParseError(t, "while (1) continue x", ": ERROR: There is no containing label named \"x\"\n") - expectPrinted(t, "x: y: z: 1", "x:\n y:\n z:\n 1;\n") - expectPrinted(t, "x: 1; y: 2; x: 3", "x:\n 1;\ny:\n 2;\nx:\n 3;\n") - expectPrinted(t, "x: (() => { x: 1; })()", "x:\n (() => {\n x:\n 1;\n })();\n") - expectPrinted(t, "x: ({ f() { x: 1; } }).f()", "x:\n ({ f() {\n x:\n 1;\n } }).f();\n") - expectPrinted(t, "x: (function() { x: 1; })()", "x:\n (function() {\n x:\n 1;\n })();\n") + expectPrinted(t, "x: y: z: 1", "x: y: z: 1;\n") + expectPrinted(t, "x: 1; y: 2; x: 3", "x: 1;\ny: 2;\nx: 3;\n") + expectPrinted(t, "x: (() => { x: 1; })()", "x: (() => {\n x: 1;\n})();\n") + expectPrinted(t, "x: ({ f() { x: 1; } }).f()", "x: ({ f() {\n x: 1;\n} }).f();\n") + expectPrinted(t, "x: (function() { x: 1; })()", "x: (function() {\n x: 1;\n})();\n") expectParseError(t, "x: y: x: 1", ": ERROR: Duplicate label \"x\"\n: NOTE: The original label \"x\" is here:\n") - expectPrinted(t, "x: break x", "x:\n break x;\n") + expectPrinted(t, "x: break x", "x: break x;\n") expectPrinted(t, "x: { break x; foo() }", "x: {\n break x;\n foo();\n}\n") expectPrinted(t, "x: { y: { z: { foo(); break x; } } }", "x: {\n y: {\n z: {\n foo();\n break x;\n }\n }\n}\n") expectPrinted(t, "x: { class X { static { new X } } }", "x: {\n class X {\n static {\n new X();\n }\n }\n}\n") expectPrintedMangle(t, "x: break x", "") expectPrintedMangle(t, "x: { break x; foo() }", "") - expectPrintedMangle(t, "y: while (foo()) x: { break x; foo() }", "for (; foo(); )\n ;\n") - expectPrintedMangle(t, "y: while (foo()) x: { break y; foo() }", "y:\n for (; foo(); )\n break y;\n") + expectPrintedMangle(t, "y: while (foo()) x: { break x; foo() }", "for (; foo(); ) ;\n") + expectPrintedMangle(t, "y: while (foo()) x: { break y; foo() }", "y: for (; foo(); ) break y;\n") expectPrintedMangle(t, "x: { y: { z: { foo(); break x; } } }", "x: {\n foo();\n break x;\n}\n") expectPrintedMangle(t, "x: { class X { static { new X } } }", "{\n class X {\n static {\n new X();\n }\n }\n}\n") } @@ -3147,7 +3147,7 @@ func TestCatch(t *testing.T) { expectPrinted(t, "try { function e() {} } catch (e) {}", "try {\n let e = function() {\n };\n var e = e;\n} catch (e) {\n}\n") expectPrinted(t, "try {} catch (e) { { function e() {} } }", "try {\n} catch (e) {\n {\n let e = function() {\n };\n var e = e;\n }\n}\n") expectPrinted(t, "try {} catch (e) { if (1) function e() {} }", "try {\n} catch (e) {\n if (1) {\n let e = function() {\n };\n var e = e;\n }\n}\n") - expectPrinted(t, "try {} catch (e) { if (0) ; else function e() {} }", "try {\n} catch (e) {\n if (0)\n ;\n else {\n let e = function() {\n };\n var e = e;\n }\n}\n") + expectPrinted(t, "try {} catch (e) { if (0) ; else function e() {} }", "try {\n} catch (e) {\n if (0) ;\n else {\n let e = function() {\n };\n var e = e;\n }\n}\n") expectPrinted(t, "try {} catch ({ e }) { { function e() {} } }", "try {\n} catch ({ e }) {\n {\n let e = function() {\n };\n var e = e;\n }\n}\n") errorText := `: ERROR: The symbol "e" has already been declared @@ -3345,43 +3345,43 @@ func TestWarningLogicalOperator(t *testing.T) { } func TestMangleFor(t *testing.T) { - expectPrintedMangle(t, "var a; while (1) ;", "for (var a; ; )\n ;\n") - expectPrintedMangle(t, "let a; while (1) ;", "let a;\nfor (; ; )\n ;\n") - expectPrintedMangle(t, "const a=0; while (1) ;", "const a = 0;\nfor (; ; )\n ;\n") + expectPrintedMangle(t, "var a; while (1) ;", "for (var a; ; ) ;\n") + expectPrintedMangle(t, "let a; while (1) ;", "let a;\nfor (; ; ) ;\n") + expectPrintedMangle(t, "const a=0; while (1) ;", "const a = 0;\nfor (; ; ) ;\n") - expectPrintedMangle(t, "var a; for (var b;;) ;", "for (var a, b; ; )\n ;\n") - expectPrintedMangle(t, "let a; for (let b;;) ;", "let a;\nfor (let b; ; )\n ;\n") - expectPrintedMangle(t, "const a=0; for (const b = 1;;) ;", "const a = 0;\nfor (const b = 1; ; )\n ;\n") + expectPrintedMangle(t, "var a; for (var b;;) ;", "for (var a, b; ; ) ;\n") + expectPrintedMangle(t, "let a; for (let b;;) ;", "let a;\nfor (let b; ; ) ;\n") + expectPrintedMangle(t, "const a=0; for (const b = 1;;) ;", "const a = 0;\nfor (const b = 1; ; ) ;\n") - expectPrintedMangle(t, "export var a; while (1) ;", "export var a;\nfor (; ; )\n ;\n") - expectPrintedMangle(t, "export let a; while (1) ;", "export let a;\nfor (; ; )\n ;\n") - expectPrintedMangle(t, "export const a=0; while (1) ;", "export const a = 0;\nfor (; ; )\n ;\n") + expectPrintedMangle(t, "export var a; while (1) ;", "export var a;\nfor (; ; ) ;\n") + expectPrintedMangle(t, "export let a; while (1) ;", "export let a;\nfor (; ; ) ;\n") + expectPrintedMangle(t, "export const a=0; while (1) ;", "export const a = 0;\nfor (; ; ) ;\n") - expectPrintedMangle(t, "export var a; for (var b;;) ;", "export var a;\nfor (var b; ; )\n ;\n") - expectPrintedMangle(t, "export let a; for (let b;;) ;", "export let a;\nfor (let b; ; )\n ;\n") - expectPrintedMangle(t, "export const a=0; for (const b = 1;;) ;", "export const a = 0;\nfor (const b = 1; ; )\n ;\n") + expectPrintedMangle(t, "export var a; for (var b;;) ;", "export var a;\nfor (var b; ; ) ;\n") + expectPrintedMangle(t, "export let a; for (let b;;) ;", "export let a;\nfor (let b; ; ) ;\n") + expectPrintedMangle(t, "export const a=0; for (const b = 1;;) ;", "export const a = 0;\nfor (const b = 1; ; ) ;\n") - expectPrintedMangle(t, "var a; for (let b;;) ;", "var a;\nfor (let b; ; )\n ;\n") - expectPrintedMangle(t, "let a; for (const b=0;;) ;", "let a;\nfor (const b = 0; ; )\n ;\n") - expectPrintedMangle(t, "const a=0; for (var b;;) ;", "const a = 0;\nfor (var b; ; )\n ;\n") + expectPrintedMangle(t, "var a; for (let b;;) ;", "var a;\nfor (let b; ; ) ;\n") + expectPrintedMangle(t, "let a; for (const b=0;;) ;", "let a;\nfor (const b = 0; ; ) ;\n") + expectPrintedMangle(t, "const a=0; for (var b;;) ;", "const a = 0;\nfor (var b; ; ) ;\n") - expectPrintedMangle(t, "a(); while (1) ;", "for (a(); ; )\n ;\n") - expectPrintedMangle(t, "a(); for (b();;) ;", "for (a(), b(); ; )\n ;\n") + expectPrintedMangle(t, "a(); while (1) ;", "for (a(); ; ) ;\n") + expectPrintedMangle(t, "a(); for (b();;) ;", "for (a(), b(); ; ) ;\n") - expectPrintedMangle(t, "for (; ;) if (x) break;", "for (; !x; )\n ;\n") - expectPrintedMangle(t, "for (; ;) if (!x) break;", "for (; x; )\n ;\n") - expectPrintedMangle(t, "for (; a;) if (x) break;", "for (; a && !x; )\n ;\n") - expectPrintedMangle(t, "for (; a;) if (!x) break;", "for (; a && x; )\n ;\n") + expectPrintedMangle(t, "for (; ;) if (x) break;", "for (; !x; ) ;\n") + expectPrintedMangle(t, "for (; ;) if (!x) break;", "for (; x; ) ;\n") + expectPrintedMangle(t, "for (; a;) if (x) break;", "for (; a && !x; ) ;\n") + expectPrintedMangle(t, "for (; a;) if (!x) break;", "for (; a && x; ) ;\n") expectPrintedMangle(t, "for (; ;) { if (x) break; y(); }", "for (; !x; )\n y();\n") expectPrintedMangle(t, "for (; a;) { if (x) break; y(); }", "for (; a && !x; )\n y();\n") - expectPrintedMangle(t, "for (; ;) if (x) break; else y();", "for (; !x; )\n y();\n") - expectPrintedMangle(t, "for (; a;) if (x) break; else y();", "for (; a && !x; )\n y();\n") + expectPrintedMangle(t, "for (; ;) if (x) break; else y();", "for (; !x; ) y();\n") + expectPrintedMangle(t, "for (; a;) if (x) break; else y();", "for (; a && !x; ) y();\n") expectPrintedMangle(t, "for (; ;) { if (x) break; else y(); z(); }", "for (; !x; )\n y(), z();\n") expectPrintedMangle(t, "for (; a;) { if (x) break; else y(); z(); }", "for (; a && !x; )\n y(), z();\n") - expectPrintedMangle(t, "for (; ;) if (x) y(); else break;", "for (; x; )\n y();\n") - expectPrintedMangle(t, "for (; ;) if (!x) y(); else break;", "for (; !x; )\n y();\n") - expectPrintedMangle(t, "for (; a;) if (x) y(); else break;", "for (; a && x; )\n y();\n") - expectPrintedMangle(t, "for (; a;) if (!x) y(); else break;", "for (; a && !x; )\n y();\n") + expectPrintedMangle(t, "for (; ;) if (x) y(); else break;", "for (; x; ) y();\n") + expectPrintedMangle(t, "for (; ;) if (!x) y(); else break;", "for (; !x; ) y();\n") + expectPrintedMangle(t, "for (; a;) if (x) y(); else break;", "for (; a && x; ) y();\n") + expectPrintedMangle(t, "for (; a;) if (!x) y(); else break;", "for (; a && !x; ) y();\n") expectPrintedMangle(t, "for (; ;) { if (x) y(); else break; z(); }", "for (; x; ) {\n y();\n z();\n}\n") expectPrintedMangle(t, "for (; a;) { if (x) y(); else break; z(); }", "for (; a && x; ) {\n y();\n z();\n}\n") } @@ -3390,7 +3390,7 @@ func TestMangleLoopJump(t *testing.T) { // Trim after jump expectPrintedMangle(t, "while (x) { if (1) break; z(); }", "for (; x; )\n break;\n") expectPrintedMangle(t, "while (x) { if (1) continue; z(); }", "for (; x; )\n ;\n") - expectPrintedMangle(t, "foo: while (a) while (x) { if (1) continue foo; z(); }", "foo:\n for (; a; )\n for (; x; )\n continue foo;\n") + expectPrintedMangle(t, "foo: while (a) while (x) { if (1) continue foo; z(); }", "foo: for (; a; ) for (; x; )\n continue foo;\n") expectPrintedMangle(t, "while (x) { y(); if (1) break; z(); }", "for (; x; ) {\n y();\n break;\n}\n") expectPrintedMangle(t, "while (x) { y(); if (1) continue; z(); }", "for (; x; )\n y();\n") expectPrintedMangle(t, "while (x) { y(); debugger; if (1) continue; z(); }", "for (; x; ) {\n y();\n debugger;\n}\n") @@ -3401,12 +3401,12 @@ func TestMangleLoopJump(t *testing.T) { expectPrintedMangle(t, "while (x) { debugger; if (1) { if (1) continue; z() } }", "for (; x; )\n debugger;\n") // Trim trailing continue - expectPrintedMangle(t, "while (x()) continue", "for (; x(); )\n ;\n") + expectPrintedMangle(t, "while (x()) continue", "for (; x(); ) ;\n") expectPrintedMangle(t, "while (x) { y(); continue }", "for (; x; )\n y();\n") expectPrintedMangle(t, "while (x) { if (y) { z(); continue } }", "for (; x; )\n if (y) {\n z();\n continue;\n }\n") expectPrintedMangle(t, "label: while (x) while (y) { z(); continue label }", - "label:\n for (; x; )\n for (; y; ) {\n z();\n continue label;\n }\n") + "label: for (; x; ) for (; y; ) {\n z();\n continue label;\n}\n") // Optimize implicit continue expectPrintedMangle(t, "while (x) { if (y) continue; z(); }", "for (; x; )\n y || z();\n") @@ -3418,7 +3418,7 @@ func TestMangleLoopJump(t *testing.T) { // Do not optimize implicit continue for statements that care about scope expectPrintedMangle(t, "while (x) { if (y) continue; function y() {} }", "for (; x; ) {\n let y = function() {\n };\n var y = y;\n}\n") - expectPrintedMangle(t, "while (x) { if (y) continue; let y }", "for (; x; ) {\n if (y)\n continue;\n let y;\n}\n") + expectPrintedMangle(t, "while (x) { if (y) continue; let y }", "for (; x; ) {\n if (y) continue;\n let y;\n}\n") expectPrintedMangle(t, "while (x) { if (y) continue; var y }", "for (; x; )\n if (!y)\n var y;\n") } @@ -3430,7 +3430,7 @@ func TestMangleUndefined(t *testing.T) { expectPrintedNormalAndMangle(t, "const x = undefined", "const x = void 0;\n", "const x = void 0;\n") expectPrintedNormalAndMangle(t, "let x = undefined", "let x = void 0;\n", "let x;\n") expectPrintedNormalAndMangle(t, "var x = undefined", "var x = void 0;\n", "var x = void 0;\n") - expectPrintedNormalAndMangle(t, "function foo(a) { if (!a) return undefined; a() }", "function foo(a) {\n if (!a)\n return void 0;\n a();\n}\n", "function foo(a) {\n a && a();\n}\n") + expectPrintedNormalAndMangle(t, "function foo(a) { if (!a) return undefined; a() }", "function foo(a) {\n if (!a) return void 0;\n a();\n}\n", "function foo(a) {\n a && a();\n}\n") // These should not be transformed expectPrintedNormalAndMangle(t, "delete undefined", "delete undefined;\n", "delete undefined;\n") @@ -3441,8 +3441,8 @@ func TestMangleUndefined(t *testing.T) { expectPrintedNormalAndMangle(t, "undefined = 1", "undefined = 1;\n", "undefined = 1;\n") expectPrintedNormalAndMangle(t, "[undefined] = 1", "[undefined] = 1;\n", "[undefined] = 1;\n") expectPrintedNormalAndMangle(t, "({x: undefined} = 1)", "({ x: undefined } = 1);\n", "({ x: undefined } = 1);\n") - expectPrintedNormalAndMangle(t, "with (x) y(undefined); z(undefined)", "with (x)\n y(undefined);\nz(void 0);\n", "with (x)\n y(undefined);\nz(void 0);\n") - expectPrintedNormalAndMangle(t, "with (x) while (i) y(undefined); z(undefined)", "with (x)\n while (i)\n y(undefined);\nz(void 0);\n", "with (x)\n for (; i; )\n y(undefined);\nz(void 0);\n") + expectPrintedNormalAndMangle(t, "with (x) y(undefined); z(undefined)", "with (x) y(undefined);\nz(void 0);\n", "with (x) y(undefined);\nz(void 0);\n") + expectPrintedNormalAndMangle(t, "with (x) while (i) y(undefined); z(undefined)", "with (x) while (i) y(undefined);\nz(void 0);\n", "with (x) for (; i; ) y(undefined);\nz(void 0);\n") } func TestMangleIndex(t *testing.T) { @@ -3600,7 +3600,7 @@ func TestMangleNot(t *testing.T) { expectPrintedNormalAndMangle(t, "a = !(b != c)", "a = !(b != c);\n", "a = b == c;\n") expectPrintedNormalAndMangle(t, "a = !(b === c)", "a = !(b === c);\n", "a = b !== c;\n") expectPrintedNormalAndMangle(t, "a = !(b !== c)", "a = !(b !== c);\n", "a = b === c;\n") - expectPrintedNormalAndMangle(t, "if (!(a, b)) return c", "if (!(a, b))\n return c;\n", "if (a, !b)\n return c;\n") + expectPrintedNormalAndMangle(t, "if (!(a, b)) return c", "if (!(a, b)) return c;\n", "if (a, !b) return c;\n") // These can't be mangled due to NaN and other special cases expectPrintedNormalAndMangle(t, "a = !(b < c)", "a = !(b < c);\n", "a = !(b < c);\n") @@ -3804,46 +3804,46 @@ func TestMangleIf(t *testing.T) { expectPrintedNormalAndMangle(t, "!!a ? b() : c()", "!!a ? b() : c();\n", "a ? b() : c();\n") expectPrintedNormalAndMangle(t, "!!!a ? b() : c()", "!!!a ? b() : c();\n", "a ? c() : b();\n") - expectPrintedNormalAndMangle(t, "if (1) a(); else b()", "if (1)\n a();\nelse\n b();\n", "a();\n") - expectPrintedNormalAndMangle(t, "if (0) a(); else b()", "if (0)\n a();\nelse\n b();\n", "b();\n") - expectPrintedNormalAndMangle(t, "if (a) b(); else c()", "if (a)\n b();\nelse\n c();\n", "a ? b() : c();\n") - expectPrintedNormalAndMangle(t, "if (!a) b(); else c()", "if (!a)\n b();\nelse\n c();\n", "a ? c() : b();\n") - expectPrintedNormalAndMangle(t, "if (!!a) b(); else c()", "if (!!a)\n b();\nelse\n c();\n", "a ? b() : c();\n") - expectPrintedNormalAndMangle(t, "if (!!!a) b(); else c()", "if (!!!a)\n b();\nelse\n c();\n", "a ? c() : b();\n") - - expectPrintedNormalAndMangle(t, "if (1) a()", "if (1)\n a();\n", "a();\n") - expectPrintedNormalAndMangle(t, "if (0) a()", "if (0)\n a();\n", "") - expectPrintedNormalAndMangle(t, "if (a) b()", "if (a)\n b();\n", "a && b();\n") - expectPrintedNormalAndMangle(t, "if (!a) b()", "if (!a)\n b();\n", "a || b();\n") - expectPrintedNormalAndMangle(t, "if (!!a) b()", "if (!!a)\n b();\n", "a && b();\n") - expectPrintedNormalAndMangle(t, "if (!!!a) b()", "if (!!!a)\n b();\n", "a || b();\n") - - expectPrintedNormalAndMangle(t, "if (1) {} else a()", "if (1) {\n} else\n a();\n", "") - expectPrintedNormalAndMangle(t, "if (0) {} else a()", "if (0) {\n} else\n a();\n", "a();\n") - expectPrintedNormalAndMangle(t, "if (a) {} else b()", "if (a) {\n} else\n b();\n", "a || b();\n") - expectPrintedNormalAndMangle(t, "if (!a) {} else b()", "if (!a) {\n} else\n b();\n", "a && b();\n") - expectPrintedNormalAndMangle(t, "if (!!a) {} else b()", "if (!!a) {\n} else\n b();\n", "a || b();\n") - expectPrintedNormalAndMangle(t, "if (!!!a) {} else b()", "if (!!!a) {\n} else\n b();\n", "a && b();\n") - - expectPrintedNormalAndMangle(t, "if (a) {} else throw b", "if (a) {\n} else\n throw b;\n", "if (!a)\n throw b;\n") - expectPrintedNormalAndMangle(t, "if (!a) {} else throw b", "if (!a) {\n} else\n throw b;\n", "if (a)\n throw b;\n") - expectPrintedNormalAndMangle(t, "a(); if (b) throw c", "a();\nif (b)\n throw c;\n", "if (a(), b)\n throw c;\n") - expectPrintedNormalAndMangle(t, "if (a) if (b) throw c", "if (a) {\n if (b)\n throw c;\n}\n", "if (a && b)\n throw c;\n") + expectPrintedNormalAndMangle(t, "if (1) a(); else b()", "if (1) a();\nelse b();\n", "a();\n") + expectPrintedNormalAndMangle(t, "if (0) a(); else b()", "if (0) a();\nelse b();\n", "b();\n") + expectPrintedNormalAndMangle(t, "if (a) b(); else c()", "if (a) b();\nelse c();\n", "a ? b() : c();\n") + expectPrintedNormalAndMangle(t, "if (!a) b(); else c()", "if (!a) b();\nelse c();\n", "a ? c() : b();\n") + expectPrintedNormalAndMangle(t, "if (!!a) b(); else c()", "if (!!a) b();\nelse c();\n", "a ? b() : c();\n") + expectPrintedNormalAndMangle(t, "if (!!!a) b(); else c()", "if (!!!a) b();\nelse c();\n", "a ? c() : b();\n") + + expectPrintedNormalAndMangle(t, "if (1) a()", "if (1) a();\n", "a();\n") + expectPrintedNormalAndMangle(t, "if (0) a()", "if (0) a();\n", "") + expectPrintedNormalAndMangle(t, "if (a) b()", "if (a) b();\n", "a && b();\n") + expectPrintedNormalAndMangle(t, "if (!a) b()", "if (!a) b();\n", "a || b();\n") + expectPrintedNormalAndMangle(t, "if (!!a) b()", "if (!!a) b();\n", "a && b();\n") + expectPrintedNormalAndMangle(t, "if (!!!a) b()", "if (!!!a) b();\n", "a || b();\n") + + expectPrintedNormalAndMangle(t, "if (1) {} else a()", "if (1) {\n} else a();\n", "") + expectPrintedNormalAndMangle(t, "if (0) {} else a()", "if (0) {\n} else a();\n", "a();\n") + expectPrintedNormalAndMangle(t, "if (a) {} else b()", "if (a) {\n} else b();\n", "a || b();\n") + expectPrintedNormalAndMangle(t, "if (!a) {} else b()", "if (!a) {\n} else b();\n", "a && b();\n") + expectPrintedNormalAndMangle(t, "if (!!a) {} else b()", "if (!!a) {\n} else b();\n", "a || b();\n") + expectPrintedNormalAndMangle(t, "if (!!!a) {} else b()", "if (!!!a) {\n} else b();\n", "a && b();\n") + + expectPrintedNormalAndMangle(t, "if (a) {} else throw b", "if (a) {\n} else throw b;\n", "if (!a)\n throw b;\n") + expectPrintedNormalAndMangle(t, "if (!a) {} else throw b", "if (!a) {\n} else throw b;\n", "if (a)\n throw b;\n") + expectPrintedNormalAndMangle(t, "a(); if (b) throw c", "a();\nif (b) throw c;\n", "if (a(), b) throw c;\n") + expectPrintedNormalAndMangle(t, "if (a) if (b) throw c", "if (a) {\n if (b) throw c;\n}\n", "if (a && b) throw c;\n") expectPrintedMangle(t, "if (true) { let a = b; if (c) throw d }", - "{\n let a = b;\n if (c)\n throw d;\n}\n") + "{\n let a = b;\n if (c) throw d;\n}\n") expectPrintedMangle(t, "if (true) { if (a) throw b; if (c) throw d }", - "if (a)\n throw b;\nif (c)\n throw d;\n") + "if (a) throw b;\nif (c) throw d;\n") expectPrintedMangle(t, "if (false) throw a; else { let b = c; if (d) throw e }", - "{\n let b = c;\n if (d)\n throw e;\n}\n") + "{\n let b = c;\n if (d) throw e;\n}\n") expectPrintedMangle(t, "if (false) throw a; else { if (b) throw c; if (d) throw e }", - "if (b)\n throw c;\nif (d)\n throw e;\n") + "if (b) throw c;\nif (d) throw e;\n") expectPrintedMangle(t, "if (a) { if (b) throw c; else { let d = e; if (f) throw g } }", - "if (a) {\n if (b)\n throw c;\n {\n let d = e;\n if (f)\n throw g;\n }\n}\n") + "if (a) {\n if (b) throw c;\n {\n let d = e;\n if (f) throw g;\n }\n}\n") expectPrintedMangle(t, "if (a) { if (b) throw c; else if (d) throw e; else if (f) throw g }", - "if (a) {\n if (b)\n throw c;\n if (d)\n throw e;\n if (f)\n throw g;\n}\n") + "if (a) {\n if (b) throw c;\n if (d) throw e;\n if (f) throw g;\n}\n") expectPrintedNormalAndMangle(t, "a = b ? true : false", "a = b ? true : false;\n", "a = !!b;\n") expectPrintedNormalAndMangle(t, "a = b ? false : true", "a = b ? false : true;\n", "a = !b;\n") @@ -3955,43 +3955,43 @@ func TestMangleIf(t *testing.T) { expectPrintedNormalAndMangle(t, "return a && ((b && c) && (d && e))", "return a && (b && c && (d && e));\n", "return a && b && c && d && e;\n") expectPrintedNormalAndMangle(t, "return a || ((b || c) || (d || e))", "return a || (b || c || (d || e));\n", "return a || b || c || d || e;\n") expectPrintedNormalAndMangle(t, "return a ?? ((b ?? c) ?? (d ?? e))", "return a ?? (b ?? c ?? (d ?? e));\n", "return a ?? b ?? c ?? d ?? e;\n") - expectPrintedNormalAndMangle(t, "if (a) if (b) if (c) d", "if (a) {\n if (b) {\n if (c)\n d;\n }\n}\n", "a && b && c && d;\n") - expectPrintedNormalAndMangle(t, "if (!a) if (!b) if (!c) d", "if (!a) {\n if (!b) {\n if (!c)\n d;\n }\n}\n", "a || b || c || d;\n") + expectPrintedNormalAndMangle(t, "if (a) if (b) if (c) d", "if (a) {\n if (b) {\n if (c) d;\n }\n}\n", "a && b && c && d;\n") + expectPrintedNormalAndMangle(t, "if (!a) if (!b) if (!c) d", "if (!a) {\n if (!b) {\n if (!c) d;\n }\n}\n", "a || b || c || d;\n") expectPrintedNormalAndMangle(t, "let a, b, c; return a != null ? a : b != null ? b : c", "let a, b, c;\nreturn a != null ? a : b != null ? b : c;\n", "let a, b, c;\nreturn a ?? b ?? c;\n") - expectPrintedMangle(t, "if (a) return c; if (b) return d;", "if (a)\n return c;\nif (b)\n return d;\n") - expectPrintedMangle(t, "if (a) return c; if (b) return c;", "if (a || b)\n return c;\n") - expectPrintedMangle(t, "if (a) return c; if (b) return;", "if (a)\n return c;\nif (b)\n return;\n") - expectPrintedMangle(t, "if (a) return; if (b) return c;", "if (a)\n return;\nif (b)\n return c;\n") - expectPrintedMangle(t, "if (a) return; if (b) return;", "if (a || b)\n return;\n") - expectPrintedMangle(t, "if (a) throw c; if (b) throw d;", "if (a)\n throw c;\nif (b)\n throw d;\n") - expectPrintedMangle(t, "if (a) throw c; if (b) throw c;", "if (a || b)\n throw c;\n") + expectPrintedMangle(t, "if (a) return c; if (b) return d;", "if (a) return c;\nif (b) return d;\n") + expectPrintedMangle(t, "if (a) return c; if (b) return c;", "if (a || b) return c;\n") + expectPrintedMangle(t, "if (a) return c; if (b) return;", "if (a) return c;\nif (b) return;\n") + expectPrintedMangle(t, "if (a) return; if (b) return c;", "if (a) return;\nif (b) return c;\n") + expectPrintedMangle(t, "if (a) return; if (b) return;", "if (a || b) return;\n") + expectPrintedMangle(t, "if (a) throw c; if (b) throw d;", "if (a) throw c;\nif (b) throw d;\n") + expectPrintedMangle(t, "if (a) throw c; if (b) throw c;", "if (a || b) throw c;\n") expectPrintedMangle(t, "while (x) { if (a) break; if (b) break; }", "for (; x && !(a || b); )\n ;\n") expectPrintedMangle(t, "while (x) { if (a) continue; if (b) continue; }", "for (; x; )\n a || b;\n") - expectPrintedMangle(t, "while (x) { debugger; if (a) break; if (b) break; }", "for (; x; ) {\n debugger;\n if (a || b)\n break;\n}\n") + expectPrintedMangle(t, "while (x) { debugger; if (a) break; if (b) break; }", "for (; x; ) {\n debugger;\n if (a || b) break;\n}\n") expectPrintedMangle(t, "while (x) { debugger; if (a) continue; if (b) continue; }", "for (; x; ) {\n debugger;\n a || b;\n}\n") expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) break x; if (b) break y; }", - "x:\n for (; x; )\n y:\n for (; y; ) {\n if (a)\n break x;\n if (b)\n break y;\n }\n") + "x: for (; x; ) y: for (; y; ) {\n if (a) break x;\n if (b) break y;\n}\n") expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) continue x; if (b) continue y; }", - "x:\n for (; x; )\n y:\n for (; y; ) {\n if (a)\n continue x;\n if (b)\n continue y;\n }\n") + "x: for (; x; ) y: for (; y; ) {\n if (a) continue x;\n if (b) continue y;\n}\n") expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) break x; if (b) break x; }", - "x:\n for (; x; )\n for (; y; )\n if (a || b)\n break x;\n") + "x: for (; x; ) for (; y; )\n if (a || b) break x;\n") expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) continue x; if (b) continue x; }", - "x:\n for (; x; )\n for (; y; )\n if (a || b)\n continue x;\n") + "x: for (; x; ) for (; y; )\n if (a || b) continue x;\n") expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) break y; if (b) break y; }", - "for (; x; )\n y:\n for (; y; )\n if (a || b)\n break y;\n") + "for (; x; ) y: for (; y; )\n if (a || b) break y;\n") expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) continue y; if (b) continue y; }", - "for (; x; )\n y:\n for (; y; )\n if (a || b)\n continue y;\n") + "for (; x; ) y: for (; y; )\n if (a || b) continue y;\n") - expectPrintedNormalAndMangle(t, "if (x ? y : 0) foo()", "if (x ? y : 0)\n foo();\n", "x && y && foo();\n") - expectPrintedNormalAndMangle(t, "if (x ? y : 1) foo()", "if (x ? y : 1)\n foo();\n", "(!x || y) && foo();\n") - expectPrintedNormalAndMangle(t, "if (x ? 0 : y) foo()", "if (x ? 0 : y)\n foo();\n", "!x && y && foo();\n") - expectPrintedNormalAndMangle(t, "if (x ? 1 : y) foo()", "if (x ? 1 : y)\n foo();\n", "(x || y) && foo();\n") + expectPrintedNormalAndMangle(t, "if (x ? y : 0) foo()", "if (x ? y : 0) foo();\n", "x && y && foo();\n") + expectPrintedNormalAndMangle(t, "if (x ? y : 1) foo()", "if (x ? y : 1) foo();\n", "(!x || y) && foo();\n") + expectPrintedNormalAndMangle(t, "if (x ? 0 : y) foo()", "if (x ? 0 : y) foo();\n", "!x && y && foo();\n") + expectPrintedNormalAndMangle(t, "if (x ? 1 : y) foo()", "if (x ? 1 : y) foo();\n", "(x || y) && foo();\n") - expectPrintedNormalAndMangle(t, "if (x ? y : 0) ; else foo()", "if (x ? y : 0)\n ;\nelse\n foo();\n", "x && y || foo();\n") - expectPrintedNormalAndMangle(t, "if (x ? y : 1) ; else foo()", "if (x ? y : 1)\n ;\nelse\n foo();\n", "!x || y || foo();\n") - expectPrintedNormalAndMangle(t, "if (x ? 0 : y) ; else foo()", "if (x ? 0 : y)\n ;\nelse\n foo();\n", "!x && y || foo();\n") - expectPrintedNormalAndMangle(t, "if (x ? 1 : y) ; else foo()", "if (x ? 1 : y)\n ;\nelse\n foo();\n", "x || y || foo();\n") + expectPrintedNormalAndMangle(t, "if (x ? y : 0) ; else foo()", "if (x ? y : 0) ;\nelse foo();\n", "x && y || foo();\n") + expectPrintedNormalAndMangle(t, "if (x ? y : 1) ; else foo()", "if (x ? y : 1) ;\nelse foo();\n", "!x || y || foo();\n") + expectPrintedNormalAndMangle(t, "if (x ? 0 : y) ; else foo()", "if (x ? 0 : y) ;\nelse foo();\n", "!x && y || foo();\n") + expectPrintedNormalAndMangle(t, "if (x ? 1 : y) ; else foo()", "if (x ? 1 : y) ;\nelse foo();\n", "x || y || foo();\n") expectPrintedNormalAndMangle(t, "(x ? y : 0) && foo();", "(x ? y : 0) && foo();\n", "x && y && foo();\n") expectPrintedNormalAndMangle(t, "(x ? y : 1) && foo();", "(x ? y : 1) && foo();\n", "(!x || y) && foo();\n") @@ -4003,59 +4003,59 @@ func TestMangleIf(t *testing.T) { expectPrintedNormalAndMangle(t, "(x ? 0 : y) || foo();", "(x ? 0 : y) || foo();\n", "!x && y || foo();\n") expectPrintedNormalAndMangle(t, "(x ? 1 : y) || foo();", "(x ? 1 : y) || foo();\n", "x || y || foo();\n") - expectPrintedNormalAndMangle(t, "if (!!a || !!b) throw 0", "if (!!a || !!b)\n throw 0;\n", "if (a || b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (!!a && !!b) throw 0", "if (!!a && !!b)\n throw 0;\n", "if (a && b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (!!a ? !!b : !!c) throw 0", "if (!!a ? !!b : !!c)\n throw 0;\n", "if (a ? b : c)\n throw 0;\n") - - expectPrintedNormalAndMangle(t, "if ((a + b) !== 0) throw 0", "if (a + b !== 0)\n throw 0;\n", "if (a + b !== 0)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a | b) !== 0) throw 0", "if ((a | b) !== 0)\n throw 0;\n", "if (a | b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a & b) !== 0) throw 0", "if ((a & b) !== 0)\n throw 0;\n", "if (a & b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a ^ b) !== 0) throw 0", "if ((a ^ b) !== 0)\n throw 0;\n", "if (a ^ b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a << b) !== 0) throw 0", "if (a << b !== 0)\n throw 0;\n", "if (a << b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a >> b) !== 0) throw 0", "if (a >> b !== 0)\n throw 0;\n", "if (a >> b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a >>> b) !== 0) throw 0", "if (a >>> b !== 0)\n throw 0;\n", "if (a >>> b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (+a !== 0) throw 0", "if (+a !== 0)\n throw 0;\n", "if (+a != 0)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (~a !== 0) throw 0", "if (~a !== 0)\n throw 0;\n", "if (~a)\n throw 0;\n") - - expectPrintedNormalAndMangle(t, "if (0 != (a + b)) throw 0", "if (0 != a + b)\n throw 0;\n", "if (a + b != 0)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 != (a | b)) throw 0", "if (0 != (a | b))\n throw 0;\n", "if (a | b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 != (a & b)) throw 0", "if (0 != (a & b))\n throw 0;\n", "if (a & b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 != (a ^ b)) throw 0", "if (0 != (a ^ b))\n throw 0;\n", "if (a ^ b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 != (a << b)) throw 0", "if (0 != a << b)\n throw 0;\n", "if (a << b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 != (a >> b)) throw 0", "if (0 != a >> b)\n throw 0;\n", "if (a >> b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 != (a >>> b)) throw 0", "if (0 != a >>> b)\n throw 0;\n", "if (a >>> b)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 != +a) throw 0", "if (0 != +a)\n throw 0;\n", "if (+a != 0)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 != ~a) throw 0", "if (0 != ~a)\n throw 0;\n", "if (~a)\n throw 0;\n") - - expectPrintedNormalAndMangle(t, "if ((a + b) === 0) throw 0", "if (a + b === 0)\n throw 0;\n", "if (a + b === 0)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a | b) === 0) throw 0", "if ((a | b) === 0)\n throw 0;\n", "if (!(a | b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a & b) === 0) throw 0", "if ((a & b) === 0)\n throw 0;\n", "if (!(a & b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a ^ b) === 0) throw 0", "if ((a ^ b) === 0)\n throw 0;\n", "if (!(a ^ b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a << b) === 0) throw 0", "if (a << b === 0)\n throw 0;\n", "if (!(a << b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a >> b) === 0) throw 0", "if (a >> b === 0)\n throw 0;\n", "if (!(a >> b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if ((a >>> b) === 0) throw 0", "if (a >>> b === 0)\n throw 0;\n", "if (!(a >>> b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (+a === 0) throw 0", "if (+a === 0)\n throw 0;\n", "if (+a == 0)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (~a === 0) throw 0", "if (~a === 0)\n throw 0;\n", "if (!~a)\n throw 0;\n") - - expectPrintedNormalAndMangle(t, "if (0 == (a + b)) throw 0", "if (0 == a + b)\n throw 0;\n", "if (a + b == 0)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 == (a | b)) throw 0", "if (0 == (a | b))\n throw 0;\n", "if (!(a | b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 == (a & b)) throw 0", "if (0 == (a & b))\n throw 0;\n", "if (!(a & b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 == (a ^ b)) throw 0", "if (0 == (a ^ b))\n throw 0;\n", "if (!(a ^ b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 == (a << b)) throw 0", "if (0 == a << b)\n throw 0;\n", "if (!(a << b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 == (a >> b)) throw 0", "if (0 == a >> b)\n throw 0;\n", "if (!(a >> b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 == (a >>> b)) throw 0", "if (0 == a >>> b)\n throw 0;\n", "if (!(a >>> b))\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 == +a) throw 0", "if (0 == +a)\n throw 0;\n", "if (+a == 0)\n throw 0;\n") - expectPrintedNormalAndMangle(t, "if (0 == ~a) throw 0", "if (0 == ~a)\n throw 0;\n", "if (!~a)\n throw 0;\n") + expectPrintedNormalAndMangle(t, "if (!!a || !!b) throw 0", "if (!!a || !!b) throw 0;\n", "if (a || b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (!!a && !!b) throw 0", "if (!!a && !!b) throw 0;\n", "if (a && b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (!!a ? !!b : !!c) throw 0", "if (!!a ? !!b : !!c) throw 0;\n", "if (a ? b : c) throw 0;\n") + + expectPrintedNormalAndMangle(t, "if ((a + b) !== 0) throw 0", "if (a + b !== 0) throw 0;\n", "if (a + b !== 0) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a | b) !== 0) throw 0", "if ((a | b) !== 0) throw 0;\n", "if (a | b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a & b) !== 0) throw 0", "if ((a & b) !== 0) throw 0;\n", "if (a & b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a ^ b) !== 0) throw 0", "if ((a ^ b) !== 0) throw 0;\n", "if (a ^ b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a << b) !== 0) throw 0", "if (a << b !== 0) throw 0;\n", "if (a << b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a >> b) !== 0) throw 0", "if (a >> b !== 0) throw 0;\n", "if (a >> b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a >>> b) !== 0) throw 0", "if (a >>> b !== 0) throw 0;\n", "if (a >>> b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (+a !== 0) throw 0", "if (+a !== 0) throw 0;\n", "if (+a != 0) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (~a !== 0) throw 0", "if (~a !== 0) throw 0;\n", "if (~a) throw 0;\n") + + expectPrintedNormalAndMangle(t, "if (0 != (a + b)) throw 0", "if (0 != a + b) throw 0;\n", "if (a + b != 0) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 != (a | b)) throw 0", "if (0 != (a | b)) throw 0;\n", "if (a | b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 != (a & b)) throw 0", "if (0 != (a & b)) throw 0;\n", "if (a & b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 != (a ^ b)) throw 0", "if (0 != (a ^ b)) throw 0;\n", "if (a ^ b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 != (a << b)) throw 0", "if (0 != a << b) throw 0;\n", "if (a << b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 != (a >> b)) throw 0", "if (0 != a >> b) throw 0;\n", "if (a >> b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 != (a >>> b)) throw 0", "if (0 != a >>> b) throw 0;\n", "if (a >>> b) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 != +a) throw 0", "if (0 != +a) throw 0;\n", "if (+a != 0) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 != ~a) throw 0", "if (0 != ~a) throw 0;\n", "if (~a) throw 0;\n") + + expectPrintedNormalAndMangle(t, "if ((a + b) === 0) throw 0", "if (a + b === 0) throw 0;\n", "if (a + b === 0) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a | b) === 0) throw 0", "if ((a | b) === 0) throw 0;\n", "if (!(a | b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a & b) === 0) throw 0", "if ((a & b) === 0) throw 0;\n", "if (!(a & b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a ^ b) === 0) throw 0", "if ((a ^ b) === 0) throw 0;\n", "if (!(a ^ b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a << b) === 0) throw 0", "if (a << b === 0) throw 0;\n", "if (!(a << b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a >> b) === 0) throw 0", "if (a >> b === 0) throw 0;\n", "if (!(a >> b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if ((a >>> b) === 0) throw 0", "if (a >>> b === 0) throw 0;\n", "if (!(a >>> b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (+a === 0) throw 0", "if (+a === 0) throw 0;\n", "if (+a == 0) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (~a === 0) throw 0", "if (~a === 0) throw 0;\n", "if (!~a) throw 0;\n") + + expectPrintedNormalAndMangle(t, "if (0 == (a + b)) throw 0", "if (0 == a + b) throw 0;\n", "if (a + b == 0) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 == (a | b)) throw 0", "if (0 == (a | b)) throw 0;\n", "if (!(a | b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 == (a & b)) throw 0", "if (0 == (a & b)) throw 0;\n", "if (!(a & b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 == (a ^ b)) throw 0", "if (0 == (a ^ b)) throw 0;\n", "if (!(a ^ b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 == (a << b)) throw 0", "if (0 == a << b) throw 0;\n", "if (!(a << b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 == (a >> b)) throw 0", "if (0 == a >> b) throw 0;\n", "if (!(a >> b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 == (a >>> b)) throw 0", "if (0 == a >>> b) throw 0;\n", "if (!(a >>> b)) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 == +a) throw 0", "if (0 == +a) throw 0;\n", "if (+a == 0) throw 0;\n") + expectPrintedNormalAndMangle(t, "if (0 == ~a) throw 0", "if (0 == ~a) throw 0;\n", "if (!~a) throw 0;\n") } func TestMangleWrapToAvoidAmbiguousElse(t *testing.T) { - expectPrintedMangle(t, "if (a) { if (b) return c } else return d", "if (a) {\n if (b)\n return c;\n} else\n return d;\n") - expectPrintedMangle(t, "if (a) while (1) { if (b) return c } else return d", "if (a) {\n for (; ; )\n if (b)\n return c;\n} else\n return d;\n") - expectPrintedMangle(t, "if (a) for (;;) { if (b) return c } else return d", "if (a) {\n for (; ; )\n if (b)\n return c;\n} else\n return d;\n") - expectPrintedMangle(t, "if (a) for (x in y) { if (b) return c } else return d", "if (a) {\n for (x in y)\n if (b)\n return c;\n} else\n return d;\n") - expectPrintedMangle(t, "if (a) for (x of y) { if (b) return c } else return d", "if (a) {\n for (x of y)\n if (b)\n return c;\n} else\n return d;\n") - expectPrintedMangle(t, "if (a) with (x) { if (b) return c } else return d", "if (a) {\n with (x)\n if (b)\n return c;\n} else\n return d;\n") - expectPrintedMangle(t, "if (a) x: { if (b) break x } else return c", "if (a) {\n x:\n if (b)\n break x;\n} else\n return c;\n") + expectPrintedMangle(t, "if (a) { if (b) return c } else return d", "if (a) {\n if (b) return c;\n} else return d;\n") + expectPrintedMangle(t, "if (a) while (1) { if (b) return c } else return d", "if (a) {\n for (; ; )\n if (b) return c;\n} else return d;\n") + expectPrintedMangle(t, "if (a) for (;;) { if (b) return c } else return d", "if (a) {\n for (; ; )\n if (b) return c;\n} else return d;\n") + expectPrintedMangle(t, "if (a) for (x in y) { if (b) return c } else return d", "if (a) {\n for (x in y)\n if (b) return c;\n} else return d;\n") + expectPrintedMangle(t, "if (a) for (x of y) { if (b) return c } else return d", "if (a) {\n for (x of y)\n if (b) return c;\n} else return d;\n") + expectPrintedMangle(t, "if (a) with (x) { if (b) return c } else return d", "if (a) {\n with (x)\n if (b) return c;\n} else return d;\n") + expectPrintedMangle(t, "if (a) x: { if (b) break x } else return c", "if (a) {\n x:\n if (b) break x;\n} else return c;\n") } func TestMangleOptionalChain(t *testing.T) { @@ -4189,8 +4189,8 @@ func TestMangleBooleanWithSideEffects(t *testing.T) { expectPrintedMangle(t, "y(x && "+value+" ? y : z)", "y((x, z));\n") expectPrintedMangle(t, "y(x || "+value+" ? y : z)", "y(x ? y : z);\n") - expectPrintedMangle(t, "while ("+value+") x()", "for (; false; )\n x();\n") - expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; false; )\n x();\n") + expectPrintedMangle(t, "while ("+value+") x()", "for (; false; ) x();\n") + expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; false; ) x();\n") } for _, value := range truthyNoSideEffects { @@ -4209,8 +4209,8 @@ func TestMangleBooleanWithSideEffects(t *testing.T) { expectPrintedMangle(t, "y(x && "+value+" ? y : z)", "y(x ? y : z);\n") expectPrintedMangle(t, "y(x || "+value+" ? y : z)", "y((x, y));\n") - expectPrintedMangle(t, "while ("+value+") x()", "for (; ; )\n x();\n") - expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; ; )\n x();\n") + expectPrintedMangle(t, "while ("+value+") x()", "for (; ; ) x();\n") + expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; ; ) x();\n") } falsyHasSideEffects := []string{"void foo()"} @@ -4227,8 +4227,8 @@ func TestMangleBooleanWithSideEffects(t *testing.T) { expectPrintedMangle(t, "if (x || "+value+") y; else z", "x || "+value+" ? y : z;\n") expectPrintedMangle(t, "y(x || "+value+" ? y : z)", "y(x || "+value+" ? y : z);\n") - expectPrintedMangle(t, "while ("+value+") x()", "for (; "+value+"; )\n x();\n") - expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; "+value+"; )\n x();\n") + expectPrintedMangle(t, "while ("+value+") x()", "for (; "+value+"; ) x();\n") + expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; "+value+"; ) x();\n") } for _, value := range truthyHasSideEffects { @@ -4242,8 +4242,8 @@ func TestMangleBooleanWithSideEffects(t *testing.T) { expectPrintedMangle(t, "if (x && "+value+") y; else z", "x && "+value+" ? y : z;\n") expectPrintedMangle(t, "y(x && "+value+" ? y : z)", "y(x && "+value+" ? y : z);\n") - expectPrintedMangle(t, "while ("+value+") x()", "for (; "+value+"; )\n x();\n") - expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; "+value+"; )\n x();\n") + expectPrintedMangle(t, "while ("+value+") x()", "for (; "+value+"; ) x();\n") + expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; "+value+"; ) x();\n") } } @@ -4290,39 +4290,39 @@ func TestMangleReturn(t *testing.T) { expectPrintedMangle(t, "function x() { if (y) { if (z) return; } }", "function x() {\n y && z;\n}\n") expectPrintedMangle(t, "function x() { if (y) { if (z) return; w(); } }", - "function x() {\n if (y) {\n if (z)\n return;\n w();\n }\n}\n") + "function x() {\n if (y) {\n if (z) return;\n w();\n }\n}\n") expectPrintedMangle(t, "function foo(x) { if (!x.y) {} else return x }", "function foo(x) {\n if (x.y)\n return x;\n}\n") expectPrintedMangle(t, "function foo(x) { if (!x.y) return undefined; return x }", "function foo(x) {\n if (x.y)\n return x;\n}\n") // Do not optimize implicit return for statements that care about scope - expectPrintedMangle(t, "function x() { if (y) return; function y() {} }", "function x() {\n if (y)\n return;\n function y() {\n }\n}\n") - expectPrintedMangle(t, "function x() { if (y) return; let y }", "function x() {\n if (y)\n return;\n let y;\n}\n") + expectPrintedMangle(t, "function x() { if (y) return; function y() {} }", "function x() {\n if (y) return;\n function y() {\n }\n}\n") + expectPrintedMangle(t, "function x() { if (y) return; let y }", "function x() {\n if (y) return;\n let y;\n}\n") expectPrintedMangle(t, "function x() { if (y) return; var y }", "function x() {\n if (!y)\n var y;\n}\n") } func TestMangleThrow(t *testing.T) { expectPrintedNormalAndMangle(t, "function foo() { a = b; if (a) throw a; if (b) c = b; throw c; }", - "function foo() {\n a = b;\n if (a)\n throw a;\n if (b)\n c = b;\n throw c;\n}\n", + "function foo() {\n a = b;\n if (a) throw a;\n if (b) c = b;\n throw c;\n}\n", "function foo() {\n throw a = b, a || (b && (c = b), c);\n}\n") expectPrintedNormalAndMangle(t, "function foo() { if (!a) throw b; throw c; }", - "function foo() {\n if (!a)\n throw b;\n throw c;\n}\n", + "function foo() {\n if (!a) throw b;\n throw c;\n}\n", "function foo() {\n throw a ? c : b;\n}\n") - expectPrintedNormalAndMangle(t, "if (1) throw a(); else throw b()", "if (1)\n throw a();\nelse\n throw b();\n", "throw a();\n") - expectPrintedNormalAndMangle(t, "if (0) throw a(); else throw b()", "if (0)\n throw a();\nelse\n throw b();\n", "throw b();\n") - expectPrintedNormalAndMangle(t, "if (a) throw b(); else throw c()", "if (a)\n throw b();\nelse\n throw c();\n", "throw a ? b() : c();\n") - expectPrintedNormalAndMangle(t, "if (!a) throw b(); else throw c()", "if (!a)\n throw b();\nelse\n throw c();\n", "throw a ? c() : b();\n") - expectPrintedNormalAndMangle(t, "if (!!a) throw b(); else throw c()", "if (!!a)\n throw b();\nelse\n throw c();\n", "throw a ? b() : c();\n") - expectPrintedNormalAndMangle(t, "if (!!!a) throw b(); else throw c()", "if (!!!a)\n throw b();\nelse\n throw c();\n", "throw a ? c() : b();\n") + expectPrintedNormalAndMangle(t, "if (1) throw a(); else throw b()", "if (1) throw a();\nelse throw b();\n", "throw a();\n") + expectPrintedNormalAndMangle(t, "if (0) throw a(); else throw b()", "if (0) throw a();\nelse throw b();\n", "throw b();\n") + expectPrintedNormalAndMangle(t, "if (a) throw b(); else throw c()", "if (a) throw b();\nelse throw c();\n", "throw a ? b() : c();\n") + expectPrintedNormalAndMangle(t, "if (!a) throw b(); else throw c()", "if (!a) throw b();\nelse throw c();\n", "throw a ? c() : b();\n") + expectPrintedNormalAndMangle(t, "if (!!a) throw b(); else throw c()", "if (!!a) throw b();\nelse throw c();\n", "throw a ? b() : c();\n") + expectPrintedNormalAndMangle(t, "if (!!!a) throw b(); else throw c()", "if (!!!a) throw b();\nelse throw c();\n", "throw a ? c() : b();\n") - expectPrintedNormalAndMangle(t, "if (1) throw a(); throw b()", "if (1)\n throw a();\nthrow b();\n", "throw a();\n") - expectPrintedNormalAndMangle(t, "if (0) throw a(); throw b()", "if (0)\n throw a();\nthrow b();\n", "throw b();\n") - expectPrintedNormalAndMangle(t, "if (a) throw b(); throw c()", "if (a)\n throw b();\nthrow c();\n", "throw a ? b() : c();\n") - expectPrintedNormalAndMangle(t, "if (!a) throw b(); throw c()", "if (!a)\n throw b();\nthrow c();\n", "throw a ? c() : b();\n") - expectPrintedNormalAndMangle(t, "if (!!a) throw b(); throw c()", "if (!!a)\n throw b();\nthrow c();\n", "throw a ? b() : c();\n") - expectPrintedNormalAndMangle(t, "if (!!!a) throw b(); throw c()", "if (!!!a)\n throw b();\nthrow c();\n", "throw a ? c() : b();\n") + expectPrintedNormalAndMangle(t, "if (1) throw a(); throw b()", "if (1) throw a();\nthrow b();\n", "throw a();\n") + expectPrintedNormalAndMangle(t, "if (0) throw a(); throw b()", "if (0) throw a();\nthrow b();\n", "throw b();\n") + expectPrintedNormalAndMangle(t, "if (a) throw b(); throw c()", "if (a) throw b();\nthrow c();\n", "throw a ? b() : c();\n") + expectPrintedNormalAndMangle(t, "if (!a) throw b(); throw c()", "if (!a) throw b();\nthrow c();\n", "throw a ? c() : b();\n") + expectPrintedNormalAndMangle(t, "if (!!a) throw b(); throw c()", "if (!!a) throw b();\nthrow c();\n", "throw a ? b() : c();\n") + expectPrintedNormalAndMangle(t, "if (!!!a) throw b(); throw c()", "if (!!!a) throw b();\nthrow c();\n", "throw a ? c() : b();\n") } func TestMangleInitializer(t *testing.T) { @@ -4794,7 +4794,7 @@ func TestMangleUnusedFunctionExpressionNames(t *testing.T) { expectPrintedNormalAndMangle(t, "x = function y() {}", "x = function y() {\n};\n", "x = function() {\n};\n") expectPrintedNormalAndMangle(t, "x = function y() { return y }", "x = function y() {\n return y;\n};\n", "x = function y() {\n return y;\n};\n") expectPrintedNormalAndMangle(t, "x = function y() { return eval('y') }", "x = function y() {\n return eval(\"y\");\n};\n", "x = function y() {\n return eval(\"y\");\n};\n") - expectPrintedNormalAndMangle(t, "x = function y() { if (0) return y }", "x = function y() {\n if (0)\n return y;\n};\n", "x = function() {\n};\n") + expectPrintedNormalAndMangle(t, "x = function y() { if (0) return y }", "x = function y() {\n if (0) return y;\n};\n", "x = function() {\n};\n") } func TestMangleClass(t *testing.T) { @@ -4814,7 +4814,7 @@ func TestMangleClass(t *testing.T) { func TestMangleUnusedClassExpressionNames(t *testing.T) { expectPrintedNormalAndMangle(t, "x = class y {}", "x = class y {\n};\n", "x = class {\n};\n") expectPrintedNormalAndMangle(t, "x = class y { foo() { return y } }", "x = class y {\n foo() {\n return y;\n }\n};\n", "x = class y {\n foo() {\n return y;\n }\n};\n") - expectPrintedNormalAndMangle(t, "x = class y { foo() { if (0) return y } }", "x = class y {\n foo() {\n if (0)\n return _y;\n }\n};\n", "x = class {\n foo() {\n }\n};\n") + expectPrintedNormalAndMangle(t, "x = class y { foo() { if (0) return y } }", "x = class y {\n foo() {\n if (0) return _y;\n }\n};\n", "x = class {\n foo() {\n }\n};\n") } func TestMangleUnused(t *testing.T) { @@ -5005,8 +5005,8 @@ func TestMangleUnused(t *testing.T) { expectPrintedNormalAndMangle(t, "(a + '') + (b + '')", "a + (b + \"\");\n", "a + (b + \"\");\n") // Make sure identifiers inside "with" statements are kept - expectPrintedNormalAndMangle(t, "with (a) []", "with (a)\n [];\n", "with (a)\n ;\n") - expectPrintedNormalAndMangle(t, "var a; with (b) a", "var a;\nwith (b)\n a;\n", "var a;\nwith (b)\n a;\n") + expectPrintedNormalAndMangle(t, "with (a) []", "with (a) [];\n", "with (a) ;\n") + expectPrintedNormalAndMangle(t, "var a; with (b) a", "var a;\nwith (b) a;\n", "var a;\nwith (b) a;\n") } func TestMangleInlineLocals(t *testing.T) { @@ -5155,14 +5155,14 @@ func TestMangleInlineLocals(t *testing.T) { check("let x = arg0; arg1(x);", "arg1(arg0);") check("let x = arg0; throw x;", "throw arg0;") check("let x = arg0; return x;", "return arg0;") - check("let x = arg0; if (x) return 1;", "if (arg0)\n return 1;") + check("let x = arg0; if (x) return 1;", "if (arg0) return 1;") check("let x = arg0; switch (x) { case 0: return 1; }", "switch (arg0) {\n case 0:\n return 1;\n}") check("let x = arg0; let y = x; return y + y;", "let y = arg0;\nreturn y + y;") // Loops must not be substituted into because they evaluate multiple times check("let x = arg0; do {} while (x);", "let x = arg0;\ndo\n ;\nwhile (x);") - check("let x = arg0; while (x) return 1;", "let x = arg0;\nfor (; x; )\n return 1;") - check("let x = arg0; for (; x; ) return 1;", "let x = arg0;\nfor (; x; )\n return 1;") + check("let x = arg0; while (x) return 1;", "let x = arg0;\nfor (; x; ) return 1;") + check("let x = arg0; for (; x; ) return 1;", "let x = arg0;\nfor (; x; ) return 1;") // Can substitute an expression without side effects into a branch due to optional chaining check("let x = arg0; return arg1?.[x];", "return arg1?.[arg0];") @@ -5263,12 +5263,12 @@ func TestTrimCodeInDeadControlFlow(t *testing.T) { expectPrintedMangle(t, "if (1) a(); else { let b }", "a();\n") expectPrintedMangle(t, "if (1) a(); else { throw b }", "a();\n") expectPrintedMangle(t, "if (1) a(); else { return b }", "a();\n") - expectPrintedMangle(t, "b: { if (x) a(); else { break b } }", "b:\n if (x)\n a();\n else\n break b;\n") + expectPrintedMangle(t, "b: { if (x) a(); else { break b } }", "b:\n if (x) a();\n else\n break b;\n") expectPrintedMangle(t, "b: { if (1) a(); else { break b } }", "a();\n") expectPrintedMangle(t, "b: { if (0) a(); else { break b } }", "") - expectPrintedMangle(t, "b: while (1) if (x) a(); else { continue b }", "b:\n for (; ; )\n if (x)\n a();\n else\n continue b;\n") - expectPrintedMangle(t, "b: while (1) if (1) a(); else { continue b }", "for (; ; )\n a();\n") - expectPrintedMangle(t, "b: while (1) if (0) a(); else { continue b }", "b:\n for (; ; )\n continue b;\n") + expectPrintedMangle(t, "b: while (1) if (x) a(); else { continue b }", "b: for (; ; ) if (x) a();\nelse\n continue b;\n") + expectPrintedMangle(t, "b: while (1) if (1) a(); else { continue b }", "for (; ; ) a();\n") + expectPrintedMangle(t, "b: while (1) if (0) a(); else { continue b }", "b: for (; ; ) continue b;\n") expectPrintedMangle(t, "if (1) a(); else { class b {} }", "a();\n") expectPrintedMangle(t, "if (1) a(); else { debugger }", "a();\n") expectPrintedMangle(t, "if (1) a(); else { switch (1) { case 1: b() } }", "a();\n") @@ -5278,15 +5278,15 @@ func TestTrimCodeInDeadControlFlow(t *testing.T) { expectPrintedMangle(t, "if (0) a(); else {let a = 1}", "{\n let a = 1;\n}\n") expectPrintedMangle(t, "if (1) a(); else {let a = 1}", "a();\n") - expectPrintedMangle(t, "if (1) a(); else { var a = b }", "if (1)\n a();\nelse\n var a;\n") - expectPrintedMangle(t, "if (1) a(); else { var [a] = b }", "if (1)\n a();\nelse\n var a;\n") - expectPrintedMangle(t, "if (1) a(); else { var {x: a} = b }", "if (1)\n a();\nelse\n var a;\n") + expectPrintedMangle(t, "if (1) a(); else { var a = b }", "if (1) a();\nelse\n var a;\n") + expectPrintedMangle(t, "if (1) a(); else { var [a] = b }", "if (1) a();\nelse\n var a;\n") + expectPrintedMangle(t, "if (1) a(); else { var {x: a} = b }", "if (1) a();\nelse\n var a;\n") expectPrintedMangle(t, "if (1) a(); else { var [] = b }", "a();\n") expectPrintedMangle(t, "if (1) a(); else { var {} = b }", "a();\n") - expectPrintedMangle(t, "if (1) a(); else { function a() {} }", "if (1)\n a();\nelse\n var a;\n") - expectPrintedMangle(t, "if (1) a(); else { for(;;){var a} }", "if (1)\n a();\nelse\n for (; ; )\n var a;\n") + expectPrintedMangle(t, "if (1) a(); else { function a() {} }", "if (1) a();\nelse\n var a;\n") + expectPrintedMangle(t, "if (1) a(); else { for(;;){var a} }", "if (1) a();\nelse\n for (; ; )\n var a;\n") expectPrintedMangle(t, "if (1) { a(); b() } else { var a; var b; }", "if (1)\n a(), b();\nelse\n var a, b;\n") - expectPrintedMangle(t, "if (1) a(); else { switch (1) { case 1: case 2: var a } }", "if (1)\n a();\nelse\n var a;\n") + expectPrintedMangle(t, "if (1) a(); else { switch (1) { case 1: case 2: var a } }", "if (1) a();\nelse\n var a;\n") } func TestPreservedComments(t *testing.T) { @@ -5798,8 +5798,8 @@ NOTE: Both "__source" and "__self" are set automatically by esbuild when using R ": NOTE: This file is implicitly in strict mode due to the JSX element here:\n" + "NOTE: When React's \"automatic\" JSX transform is enabled, using a JSX element automatically inserts an \"import\" statement at the top of the file " + "for the corresponding the JSX helper function. This means the file is considered an ECMAScript module, and all ECMAScript modules use strict mode.\n" - expectPrintedJSX(t, "with (x) y()", "with (x)\n y(/* @__PURE__ */ React.createElement(\"z\", null));\n") - expectPrintedJSXAutomatic(t, p, "with (x) y", "with (x)\n y;\n") + expectPrintedJSX(t, "with (x) y()", "with (x) y(/* @__PURE__ */ React.createElement(\"z\", null));\n") + expectPrintedJSXAutomatic(t, p, "with (x) y", "with (x) y;\n") expectParseErrorJSX(t, "with (x) y() // @jsxRuntime automatic", strictModeError) expectParseErrorJSXAutomatic(t, p, "with (x) y()", strictModeError) } @@ -6447,7 +6447,7 @@ func TestMangleCatch(t *testing.T) { expectPrintedMangle(t, "try { throw 1 } catch (x) { var x = 2; y(x) }", "try {\n throw 1;\n} catch (x) {\n var x = 2;\n y(x);\n}\n") expectPrintedMangle(t, "try { throw 1 } catch (x) { var x = 2 }", "try {\n throw 1;\n} catch (x) {\n var x = 2;\n}\n") expectPrintedMangle(t, "try { throw 1 } catch (x) { eval('x') }", "try {\n throw 1;\n} catch (x) {\n eval(\"x\");\n}\n") - expectPrintedMangle(t, "if (y) try { throw 1 } catch (x) {} else eval('x')", "if (y)\n try {\n throw 1;\n } catch {\n }\nelse\n eval(\"x\");\n") + expectPrintedMangle(t, "if (y) try { throw 1 } catch (x) {} else eval('x')", "if (y) try {\n throw 1;\n} catch {\n}\nelse eval(\"x\");\n") } func TestAutoPureForObjectCreate(t *testing.T) { @@ -6548,14 +6548,14 @@ func TestUsing(t *testing.T) { expectParseError(t, "using x = y, {z} = _", ": ERROR: Expected identifier but found \"{\"\n") expectParseError(t, "export using x = y", ": ERROR: Unexpected \"using\"\n") - expectPrinted(t, "for (using x = y;;) ;", "for (using x = y; ; )\n ;\n") - expectPrinted(t, "for (using x of y) ;", "for (using x of y)\n ;\n") - expectPrinted(t, "for (using of x) ;", "for (using of x)\n ;\n") - expectPrinted(t, "for (using of of) ;", "for (using of of)\n ;\n") - expectPrinted(t, "for (await using of of x) ;", "for (await using of of x)\n ;\n") - expectPrinted(t, "for (await using of of of) ;", "for (await using of of of)\n ;\n") - expectPrinted(t, "for await (using x of y) ;", "for await (using x of y)\n ;\n") - expectPrinted(t, "for await (using of x) ;", "for await (using of x)\n ;\n") + expectPrinted(t, "for (using x = y;;) ;", "for (using x = y; ; ) ;\n") + expectPrinted(t, "for (using x of y) ;", "for (using x of y) ;\n") + expectPrinted(t, "for (using of x) ;", "for (using of x) ;\n") + expectPrinted(t, "for (using of of) ;", "for (using of of) ;\n") + expectPrinted(t, "for (await using of of x) ;", "for (await using of of x) ;\n") + expectPrinted(t, "for (await using of of of) ;", "for (await using of of of) ;\n") + expectPrinted(t, "for await (using x of y) ;", "for await (using x of y) ;\n") + expectPrinted(t, "for await (using of x) ;", "for await (using of x) ;\n") expectParseError(t, "for (using of of x) ;", ": ERROR: Expected \")\" but found \"x\"\n") expectParseError(t, "for (using of of of) ;", ": ERROR: Expected \")\" but found \"of\"\n") expectParseError(t, "for (using x in y) ;", ": ERROR: \"using\" declarations are not allowed here\n") @@ -6582,8 +6582,8 @@ func TestUsing(t *testing.T) { expectPrinted(t, "await using x = y", "await using x = y;\n") expectPrinted(t, "await using x = y, z = _", "await using x = y, z = _;\n") - expectPrinted(t, "for (await using x of y) ;", "for (await using x of y)\n ;\n") - expectPrinted(t, "for await (await using x of y) ;", "for await (await using x of y)\n ;\n") + expectPrinted(t, "for (await using x of y) ;", "for (await using x of y) ;\n") + expectPrinted(t, "for await (await using x of y) ;", "for await (await using x of y) ;\n") expectPrinted(t, "function foo() { using x = y }", "function foo() {\n using x = y;\n}\n") expectPrinted(t, "foo = function() { using x = y }", "foo = function() {\n using x = y;\n};\n") @@ -6610,7 +6610,7 @@ func TestUsing(t *testing.T) { expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) { await using x = y }", err) expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) for (await using x of y) ;", err) expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) { await using x = y }", "if (false) {\n using x = y;\n}\n") - expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) for (await using x of y) ;", "if (false)\n for (using x of y)\n ;\n") + expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) for (await using x of y) ;", "if (false) for (using x of y) ;\n") expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "with (x) y; if (false) { await using x = y }", ": ERROR: With statements cannot be used in an ECMAScript module\n"+ ": NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n") diff --git a/internal/js_parser/ts_parser_test.go b/internal/js_parser/ts_parser_test.go index 8640bac4e80..511eb82c35b 100644 --- a/internal/js_parser/ts_parser_test.go +++ b/internal/js_parser/ts_parser_test.go @@ -2397,8 +2397,7 @@ class A extends (_a = B, x, _a) { expectPrintedAssignSemanticsTS(t, "class A extends B { constructor(public x = 1) { if (false) super(1); super(2); } }", `class A extends B { constructor(x = 1) { - if (false) - __super(1); + if (false) __super(1); super(2); this.x = x; } @@ -2412,8 +2411,7 @@ class A extends (_a = B, x, _a) { this.x = x; return this; }; - if (foo) - __super(1); + if (foo) __super(1); __super(2); } } @@ -2426,10 +2424,8 @@ class A extends (_a = B, x, _a) { this.x = x; return this; }; - if (foo) - __super(1); - else - __super(2); + if (foo) __super(1); + else __super(2); } } `) @@ -2637,9 +2633,9 @@ func TestTSInstantiationExpression(t *testing.T) { expectPrintedTS(t, "return Array < number > in x;", "return Array in x;\n") expectPrintedTS(t, "return Array < Array < number >> in x;", "return Array in x;\n") expectPrintedTS(t, "return Array < Array < number > > in x;", "return Array in x;\n") - expectPrintedTS(t, "for (var x = Array < number > in y) ;", "x = Array;\nfor (var x in y)\n ;\n") - expectPrintedTS(t, "for (var x = Array < Array < number >> in y) ;", "x = Array;\nfor (var x in y)\n ;\n") - expectPrintedTS(t, "for (var x = Array < Array < number > > in y) ;", "x = Array;\nfor (var x in y)\n ;\n") + expectPrintedTS(t, "for (var x = Array < number > in y) ;", "x = Array;\nfor (var x in y) ;\n") + expectPrintedTS(t, "for (var x = Array < Array < number >> in y) ;", "x = Array;\nfor (var x in y) ;\n") + expectPrintedTS(t, "for (var x = Array < Array < number > > in y) ;", "x = Array;\nfor (var x in y) ;\n") // See: https://github.com/microsoft/TypeScript/pull/49353 expectPrintedTS(t, "F<{}> 0", "F < {} > 0;\n") @@ -2668,9 +2664,9 @@ func TestTSImport(t *testing.T) { expectPrintedTS(t, "import * as ns from 'foo'; log(ns)", "import * as ns from \"foo\";\nlog(ns);\n") // Dead control flow must not affect usage tracking - expectPrintedTS(t, "import {x} from 'foo'; if (false) log(x)", "import \"foo\";\nif (false)\n log(x);\n") - expectPrintedTS(t, "import x from 'foo'; if (false) log(x)", "import \"foo\";\nif (false)\n log(x);\n") - expectPrintedTS(t, "import * as ns from 'foo'; if (false) log(ns)", "import \"foo\";\nif (false)\n log(ns);\n") + expectPrintedTS(t, "import {x} from 'foo'; if (false) log(x)", "import \"foo\";\nif (false) log(x);\n") + expectPrintedTS(t, "import x from 'foo'; if (false) log(x)", "import \"foo\";\nif (false) log(x);\n") + expectPrintedTS(t, "import * as ns from 'foo'; if (false) log(ns)", "import \"foo\";\nif (false) log(ns);\n") } // This is TypeScript-specific export syntax @@ -2678,7 +2674,7 @@ func TestTSExportEquals(t *testing.T) { // This use of the "export" keyword should not trigger strict mode because // this syntax works in CommonJS modules, not in ECMAScript modules expectPrintedTS(t, "export = []", "module.exports = [];\n") - expectPrintedTS(t, "export = []; with ({}) ;", "with ({})\n ;\nmodule.exports = [];\n") + expectPrintedTS(t, "export = []; with ({}) ;", "with ({}) ;\nmodule.exports = [];\n") } // This is TypeScript-specific import syntax @@ -2686,7 +2682,7 @@ func TestTSImportEquals(t *testing.T) { // This use of the "export" keyword should not trigger strict mode because // this syntax works in CommonJS modules, not in ECMAScript modules expectPrintedTS(t, "import x = require('y')", "const x = require(\"y\");\n") - expectPrintedTS(t, "import x = require('y'); with ({}) ;", "const x = require(\"y\");\nwith ({})\n ;\n") + expectPrintedTS(t, "import x = require('y'); with ({}) ;", "const x = require(\"y\");\nwith ({}) ;\n") expectPrintedTS(t, "import x = require('foo'); x()", "const x = require(\"foo\");\nx();\n") expectPrintedTS(t, "import x = require('foo')\nx()", "const x = require(\"foo\");\nx();\n") diff --git a/internal/js_printer/js_printer.go b/internal/js_printer/js_printer.go index a020798a939..d97f0827faa 100644 --- a/internal/js_printer/js_printer.go +++ b/internal/js_printer/js_printer.go @@ -287,6 +287,7 @@ type printer struct { binaryExprStack []binaryExprVisitor options Options builder sourcemap.ChunkBuilder + printNextIndentAsSpace bool stmtStart int exportDefaultStart int @@ -345,14 +346,22 @@ func (p *printer) addSourceMappingForName(loc logger.Loc, name string, ref ast.R } func (p *printer) printIndent() { - if !p.options.MinifyWhitespace { - indent := p.options.Indent - if p.options.LineLimit > 0 && indent*2 >= p.options.LineLimit { - indent = p.options.LineLimit / 2 - } - for i := 0; i < indent; i++ { - p.print(" ") - } + if p.options.MinifyWhitespace { + return + } + + if p.printNextIndentAsSpace { + p.print(" ") + p.printNextIndentAsSpace = false + return + } + + indent := p.options.Indent + if p.options.LineLimit > 0 && indent*2 >= p.options.LineLimit { + indent = p.options.LineLimit / 2 + } + for i := 0; i < indent; i++ { + p.print(" ") } } @@ -3630,11 +3639,14 @@ func (p *printer) printDecls(keyword string, decls []js_ast.Decl, flags printExp } } -func (p *printer) printBody(body js_ast.Stmt) { +func (p *printer) printBody(body js_ast.Stmt, isSingleLine bool) { if block, ok := body.Data.(*js_ast.SBlock); ok { p.printSpace() p.printBlock(body.Loc, *block) p.printNewline() + } else if isSingleLine { + p.printNextIndentAsSpace = true + p.printStmt(body, 0) } else { p.printNewline() p.options.Indent++ @@ -3752,10 +3764,7 @@ func (p *printer) printIf(s *js_ast.SIf) { p.printNewline() } } else { - p.printNewline() - p.options.Indent++ - p.printStmt(s.Yes, 0) - p.options.Indent-- + p.printBody(s.Yes, s.IsSingleLineYes) if no.Data != nil { p.printIndent() @@ -3774,10 +3783,7 @@ func (p *printer) printIf(s *js_ast.SIf) { } else if ifStmt, ok := no.Data.(*js_ast.SIf); ok { p.printIf(ifStmt) } else { - p.printNewline() - p.options.Indent++ - p.printStmt(no, 0) - p.options.Indent-- + p.printBody(no, s.IsSingleLineNo) } } } @@ -4326,7 +4332,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printIndent() } p.print(")") - p.printBody(s.Body) + p.printBody(s.Body, s.IsSingleLineBody) case *js_ast.SForOf: p.addSourceMapping(stmt.Loc) @@ -4367,7 +4373,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printIndent() } p.print(")") - p.printBody(s.Body) + p.printBody(s.Body, s.IsSingleLineBody) case *js_ast.SWhile: p.addSourceMapping(stmt.Loc) @@ -4388,7 +4394,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printExpr(s.Test, js_ast.LLowest, 0) } p.print(")") - p.printBody(s.Body) + p.printBody(s.Body, s.IsSingleLineBody) case *js_ast.SWith: p.addSourceMapping(stmt.Loc) @@ -4410,12 +4416,12 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { } p.print(")") p.withNesting++ - p.printBody(s.Body) + p.printBody(s.Body, s.IsSingleLineBody) p.withNesting-- case *js_ast.SLabel: // Avoid printing a source mapping that masks the one from the label - if !p.options.MinifyWhitespace && p.options.Indent > 0 { + if !p.options.MinifyWhitespace && (p.options.Indent > 0 || p.printNextIndentAsSpace) { p.addSourceMapping(stmt.Loc) p.printIndent() } @@ -4425,7 +4431,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.addSourceMappingForName(s.Name.Loc, name, s.Name.Ref) p.printIdentifier(name) p.print(":") - p.printBody(s.Stmt) + p.printBody(s.Stmt, s.IsSingleLineStmt) case *js_ast.STry: p.addSourceMapping(stmt.Loc) @@ -4519,7 +4525,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printIndent() } p.print(")") - p.printBody(s.Body) + p.printBody(s.Body, s.IsSingleLineBody) case *js_ast.SSwitch: p.addSourceMapping(stmt.Loc) @@ -4765,7 +4771,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { // Avoid printing a source mapping when the expression would print one in // the same spot. We don't want to accidentally mask the mapping it emits. - if !p.options.MinifyWhitespace && p.options.Indent > 0 { + if !p.options.MinifyWhitespace && (p.options.Indent > 0 || p.printNextIndentAsSpace) { p.addSourceMapping(stmt.Loc) p.printIndent() } diff --git a/internal/js_printer/js_printer_test.go b/internal/js_printer/js_printer_test.go index fed0c71a9d6..e45f4e1adae 100644 --- a/internal/js_printer/js_printer_test.go +++ b/internal/js_printer/js_printer_test.go @@ -519,24 +519,24 @@ func TestObject(t *testing.T) { func TestFor(t *testing.T) { // Make sure "in" expressions are forbidden in the right places - expectPrinted(t, "for ((a in b);;);", "for ((a in b); ; )\n ;\n") - expectPrinted(t, "for (a ? b : (c in d);;);", "for (a ? b : (c in d); ; )\n ;\n") - expectPrinted(t, "for ((a ? b : c in d).foo;;);", "for ((a ? b : c in d).foo; ; )\n ;\n") - expectPrinted(t, "for (var x = (a in b);;);", "for (var x = (a in b); ; )\n ;\n") - expectPrinted(t, "for (x = (a in b);;);", "for (x = (a in b); ; )\n ;\n") - expectPrinted(t, "for (x == (a in b);;);", "for (x == (a in b); ; )\n ;\n") - expectPrinted(t, "for (1 * (x == a in b);;);", "for (1 * (x == a in b); ; )\n ;\n") - expectPrinted(t, "for (a ? b : x = (c in d);;);", "for (a ? b : x = (c in d); ; )\n ;\n") - expectPrinted(t, "for (var x = y = (a in b);;);", "for (var x = y = (a in b); ; )\n ;\n") - expectPrinted(t, "for ([a in b];;);", "for ([a in b]; ; )\n ;\n") - expectPrinted(t, "for (x(a in b);;);", "for (x(a in b); ; )\n ;\n") - expectPrinted(t, "for (x[a in b];;);", "for (x[a in b]; ; )\n ;\n") - expectPrinted(t, "for (x?.[a in b];;);", "for (x?.[a in b]; ; )\n ;\n") - expectPrinted(t, "for ((x => a in b);;);", "for ((x) => (a in b); ; )\n ;\n") + expectPrinted(t, "for ((a in b);;);", "for ((a in b); ; ) ;\n") + expectPrinted(t, "for (a ? b : (c in d);;);", "for (a ? b : (c in d); ; ) ;\n") + expectPrinted(t, "for ((a ? b : c in d).foo;;);", "for ((a ? b : c in d).foo; ; ) ;\n") + expectPrinted(t, "for (var x = (a in b);;);", "for (var x = (a in b); ; ) ;\n") + expectPrinted(t, "for (x = (a in b);;);", "for (x = (a in b); ; ) ;\n") + expectPrinted(t, "for (x == (a in b);;);", "for (x == (a in b); ; ) ;\n") + expectPrinted(t, "for (1 * (x == a in b);;);", "for (1 * (x == a in b); ; ) ;\n") + expectPrinted(t, "for (a ? b : x = (c in d);;);", "for (a ? b : x = (c in d); ; ) ;\n") + expectPrinted(t, "for (var x = y = (a in b);;);", "for (var x = y = (a in b); ; ) ;\n") + expectPrinted(t, "for ([a in b];;);", "for ([a in b]; ; ) ;\n") + expectPrinted(t, "for (x(a in b);;);", "for (x(a in b); ; ) ;\n") + expectPrinted(t, "for (x[a in b];;);", "for (x[a in b]; ; ) ;\n") + expectPrinted(t, "for (x?.[a in b];;);", "for (x?.[a in b]; ; ) ;\n") + expectPrinted(t, "for ((x => a in b);;);", "for ((x) => (a in b); ; ) ;\n") // Make sure for-of loops with commas are wrapped in parentheses - expectPrinted(t, "for (let a in b, c);", "for (let a in b, c)\n ;\n") - expectPrinted(t, "for (let a of (b, c));", "for (let a of (b, c))\n ;\n") + expectPrinted(t, "for (let a in b, c);", "for (let a in b, c) ;\n") + expectPrinted(t, "for (let a of (b, c));", "for (let a of (b, c)) ;\n") } func TestFunction(t *testing.T) { @@ -568,8 +568,8 @@ func TestCommentsAndParentheses(t *testing.T) { expectPrinted(t, "export default (/* foo */ function f() {});", "export default (\n /* foo */\n function f() {\n }\n);\n") expectPrinted(t, "export default (/* foo */ class x {});", "export default (\n /* foo */\n class x {\n }\n);\n") expectPrinted(t, "x = () => (/* foo */ {});", "x = () => (\n /* foo */\n {}\n);\n") - expectPrinted(t, "for ((/* foo */ let).x of y) ;", "for (\n /* foo */\n (let).x of y\n)\n ;\n") - expectPrinted(t, "for (/* foo */ (let).x of y) ;", "for (\n /* foo */\n (let).x of y\n)\n ;\n") + expectPrinted(t, "for ((/* foo */ let).x of y) ;", "for (\n /* foo */\n (let).x of y\n) ;\n") + expectPrinted(t, "for (/* foo */ (let).x of y) ;", "for (\n /* foo */\n (let).x of y\n) ;\n") expectPrinted(t, "function *x() { yield (/* foo */ y) }", "function* x() {\n yield (\n /* foo */\n y\n );\n}\n") } diff --git a/scripts/js-api-tests.js b/scripts/js-api-tests.js index d2f9a792c35..7d5b847ca72 100644 --- a/scripts/js-api-tests.js +++ b/scripts/js-api-tests.js @@ -5858,12 +5858,12 @@ class Foo { async es6_import_to_esm({ esbuild }) { const { code } = await esbuild.transform(`import {exists} from "fs"; if (!exists) throw 'fail'`, { format: 'esm' }) - assert.strictEqual(code, `import { exists } from "fs";\nif (!exists)\n throw "fail";\n`) + assert.strictEqual(code, `import { exists } from "fs";\nif (!exists) throw "fail";\n`) }, async es6_import_star_to_esm({ esbuild }) { const { code } = await esbuild.transform(`import * as fs from "fs"; if (!fs.exists) throw 'fail'`, { format: 'esm' }) - assert.strictEqual(code, `import * as fs from "fs";\nif (!fs.exists)\n throw "fail";\n`) + assert.strictEqual(code, `import * as fs from "fs";\nif (!fs.exists) throw "fail";\n`) }, async es6_export_to_esm({ esbuild }) { @@ -6021,12 +6021,12 @@ class Foo { async keepDebugger({ esbuild }) { const { code } = await esbuild.transform(`if (x) debugger`, { drop: [] }) - assert.strictEqual(code, `if (x)\n debugger;\n`) + assert.strictEqual(code, `if (x) debugger;\n`) }, async dropDebugger({ esbuild }) { const { code } = await esbuild.transform(`if (x) debugger`, { drop: ['debugger'] }) - assert.strictEqual(code, `if (x)\n ;\n`) + assert.strictEqual(code, `if (x) ;\n`) }, async define({ esbuild }) {