From c1fb3fc128955d35372f57f55661db525d7126da Mon Sep 17 00:00:00 2001 From: Taco de Wolff Date: Sat, 4 Jun 2022 12:53:53 -0400 Subject: [PATCH] JS: keep assignments with side-effects when removing let/const declaration in block, fixes #487 --- js/js_test.go | 1 + js/stmtlist.go | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/js/js_test.go b/js/js_test.go index 9310589daa..7f2fcf9cf1 100644 --- a/js/js_test.go +++ b/js/js_test.go @@ -770,6 +770,7 @@ func TestJS(t *testing.T) { {`var a=1;g();a=2;let b=3`, `var a=1;g(),a=2;let b=3`}, // #474 {`if(!(0<1&&1<2)){throw new Error()}`, `if(!(0<1&&1<2))throw new Error`}, // #479 {`class A{set x(e){}}`, `class A{set x(e){}}`}, // #481 + {`if(a){let b=c(d)}`, `a&&c(d)`}, // #487 } m := minify.New() diff --git a/js/stmtlist.go b/js/stmtlist.go index f9db9696a1..a1d3e2ef9f 100644 --- a/js/stmtlist.go +++ b/js/stmtlist.go @@ -111,12 +111,24 @@ func optimizeStmt(i js.IStmt) js.IStmt { // merge body and remove braces if it is not a lexical declaration blockStmt.List = optimizeStmtList(blockStmt.List, defaultBlock) if len(blockStmt.List) == 1 { - varDecl, isVarDecl := blockStmt.List[0].(*js.VarDecl) - _, isClassDecl := blockStmt.List[0].(*js.ClassDecl) - if !isClassDecl && (!isVarDecl || varDecl.TokenType == js.VarToken) { - return optimizeStmt(blockStmt.List[0]) + if _, ok := blockStmt.List[0].(*js.ClassDecl); ok { + return &js.EmptyStmt{} + } else if varDecl, ok := blockStmt.List[0].(*js.VarDecl); ok && varDecl.TokenType != js.VarToken { + // remove let or const declaration in otherwise empty scope, but keep assignments + exprs := []js.IExpr{} + for _, item := range varDecl.List { + if item.Default != nil && hasSideEffects(item.Default) { + exprs = append(exprs, item.Default) + } + } + if len(exprs) == 0 { + return &js.EmptyStmt{} + } else if len(exprs) == 1 { + return &js.ExprStmt{exprs[0]} + } + return &js.ExprStmt{&js.CommaExpr{exprs}} } - return &js.EmptyStmt{} + return optimizeStmt(blockStmt.List[0]) } else if len(blockStmt.List) == 0 { return &js.EmptyStmt{} }