Skip to content

Commit

Permalink
fold equality checks after cross-module inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed May 24, 2024
1 parent d7a8bf3 commit 1b29ac7
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 16 deletions.
2 changes: 1 addition & 1 deletion internal/bundler_tests/bundler_dce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3138,7 +3138,7 @@ func TestConstValueInliningDirectEval(t *testing.T) {
})
}

func TestCrossModuleConstantFolding(t *testing.T) {
func TestCrossModuleConstantFoldingNumber(t *testing.T) {
dce_suite.expectBundled(t, bundled{
files: map[string]string{
"/enum-constants.ts": `
Expand Down
18 changes: 9 additions & 9 deletions internal/bundler_tests/snapshots/snapshots_dce.txt
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ function foo() {
}

================================================================================
TestCrossModuleConstantFolding
TestCrossModuleConstantFoldingNumber
---------- /out/enum-entry.js ----------
// enum-entry.ts
console.log([
Expand All @@ -278,10 +278,10 @@ console.log([
!1,
!0,
!1,
3 /* a */ == 6 /* b */,
3 /* a */ != 6 /* b */,
3 /* a */ === 6 /* b */,
3 /* a */ !== 6 /* b */
!1,
!0,
!1,
!0
], [
12,
3,
Expand Down Expand Up @@ -316,10 +316,10 @@ console.log([
!1,
!0,
!1,
3 == 6,
3 != 6,
3 === 6,
3 !== 6
!1,
!0,
!1,
!0
], [
12,
3,
Expand Down
26 changes: 24 additions & 2 deletions internal/js_ast/js_ast_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1133,9 +1133,15 @@ func approximatePrintedIntCharCount(intValue float64) int {
return count
}

func ShouldFoldBinaryArithmeticWhenMinifying(binary *EBinary) bool {
func ShouldFoldBinaryOperatorWhenMinifying(binary *EBinary) bool {
switch binary.Op {
case
// Equality tests should always result in smaller code when folded
BinOpLooseEq,
BinOpLooseNe,
BinOpStrictEq,
BinOpStrictNe,

// Minification always folds right signed shift operations since they are
// unlikely to result in larger output. Note: ">>>" could result in
// bigger output such as "-1 >>> 0" becoming "4294967295".
Expand Down Expand Up @@ -1203,7 +1209,7 @@ func ShouldFoldBinaryArithmeticWhenMinifying(binary *EBinary) bool {

// This function intentionally avoids mutating the input AST so it can be
// called after the AST has been frozen (i.e. after parsing ends).
func FoldBinaryArithmetic(loc logger.Loc, e *EBinary) Expr {
func FoldBinaryOperator(loc logger.Loc, e *EBinary) Expr {
switch e.Op {
case BinOpAdd:
if left, right, ok := extractNumericValues(e.Left, e.Right); ok {
Expand Down Expand Up @@ -1296,6 +1302,22 @@ func FoldBinaryArithmetic(loc logger.Loc, e *EBinary) Expr {
if left, right, ok := extractStringValues(e.Left, e.Right); ok {
return Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) >= 0}}
}

case BinOpLooseEq, BinOpStrictEq:
if left, right, ok := extractNumericValues(e.Left, e.Right); ok {
return Expr{Loc: loc, Data: &EBoolean{Value: left == right}}
}
if left, right, ok := extractStringValues(e.Left, e.Right); ok {
return Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) == 0}}
}

case BinOpLooseNe, BinOpStrictNe:
if left, right, ok := extractNumericValues(e.Left, e.Right); ok {
return Expr{Loc: loc, Data: &EBoolean{Value: left != right}}
}
if left, right, ok := extractStringValues(e.Left, e.Right); ok {
return Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) != 0}}
}
}

return Expr{}
Expand Down
4 changes: 2 additions & 2 deletions internal/js_parser/js_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -15319,8 +15319,8 @@ func (v *binaryExprVisitor) visitRightAndFinish(p *parser) js_ast.Expr {
}
}

if p.shouldFoldTypeScriptConstantExpressions || (p.options.minifySyntax && js_ast.ShouldFoldBinaryArithmeticWhenMinifying(e)) {
if result := js_ast.FoldBinaryArithmetic(v.loc, e); result.Data != nil {
if p.shouldFoldTypeScriptConstantExpressions || (p.options.minifySyntax && js_ast.ShouldFoldBinaryOperatorWhenMinifying(e)) {
if result := js_ast.FoldBinaryOperator(v.loc, e); result.Data != nil {
return result
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/js_printer/js_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -1805,8 +1805,8 @@ func (p *printer) lateConstantFoldUnaryOrBinaryExpr(expr js_ast.Expr) js_ast.Exp
binary := &js_ast.EBinary{Op: e.Op, Left: left, Right: right}

// Only fold certain operations (just like the parser)
if js_ast.ShouldFoldBinaryArithmeticWhenMinifying(binary) {
if result := js_ast.FoldBinaryArithmetic(expr.Loc, binary); result.Data != nil {
if js_ast.ShouldFoldBinaryOperatorWhenMinifying(binary) {
if result := js_ast.FoldBinaryOperator(expr.Loc, binary); result.Data != nil {
return result
}
}
Expand Down

0 comments on commit 1b29ac7

Please sign in to comment.