MCPcopy
hub / github.com/tdewolff/minify / optimizeCondExpr

Method optimizeCondExpr

js/util.go:803–886  ·  view source on GitHub ↗
(expr *js.CondExpr, prec js.OpPrec)

Source from the content-addressed store, hash-verified

801}
802
803func (m *jsMinifier) optimizeCondExpr(expr *js.CondExpr, prec js.OpPrec) js.IExpr {
804 // remove double negative !! in condition, or switch cases for single negative !
805 if unary1, ok := expr.Cond.(*js.UnaryExpr); ok && unary1.Op == js.NotToken {
806 if unary2, ok := unary1.X.(*js.UnaryExpr); ok && unary2.Op == js.NotToken {
807 if isBooleanExpr(unary2.X) {
808 expr.Cond = unary2.X
809 }
810 } else {
811 expr.Cond = unary1.X
812 expr.X, expr.Y = expr.Y, expr.X
813 }
814 }
815
816 finalCond := finalExpr(expr.Cond)
817 if truthy, ok := isTruthy(expr.Cond); truthy && ok {
818 // if condition is truthy
819 return expr.X
820 } else if !truthy && ok {
821 // if condition is falsy
822 return expr.Y
823 } else if isEqualExpr(finalCond, expr.X) && (exprPrec(finalCond) < js.OpAssign || binaryLeftPrecMap[js.OrToken] <= exprPrec(finalCond)) && (exprPrec(expr.Y) < js.OpAssign || binaryRightPrecMap[js.OrToken] <= exprPrec(expr.Y)) {
824 // if condition is equal to true body
825 // for higher prec we need to add group parenthesis, and for lower prec we have parenthesis anyways. This only is shorter if len(expr.X) >= 3. isEqualExpr only checks for literal variables, which is a name will be minified to a one or two character name.
826 return &js.BinaryExpr{js.OrToken, groupExpr(expr.Cond, binaryLeftPrecMap[js.OrToken]), expr.Y}
827 } else if isEqualExpr(finalCond, expr.Y) && (exprPrec(finalCond) < js.OpAssign || binaryLeftPrecMap[js.AndToken] <= exprPrec(finalCond)) && (exprPrec(expr.X) < js.OpAssign || binaryRightPrecMap[js.AndToken] <= exprPrec(expr.X)) {
828 // if condition is equal to false body
829 // for higher prec we need to add group parenthesis, and for lower prec we have parenthesis anyways. This only is shorter if len(expr.X) >= 3. isEqualExpr only checks for literal variables, which is a name will be minified to a one or two character name.
830 return &js.BinaryExpr{js.AndToken, groupExpr(expr.Cond, binaryLeftPrecMap[js.AndToken]), expr.X}
831 } else if isEqualExpr(expr.X, expr.Y) {
832 // if true and false bodies are equal
833 return groupExpr(&js.CommaExpr{[]js.IExpr{expr.Cond, expr.X}}, prec)
834 } else {
835 if m.o.minVersion(2020) {
836 if nullishExpr, ok := toNullishExpr(expr); ok {
837 // no need to check whether left/right need to add groups, as the space saving is always more
838 return nullishExpr
839 }
840 }
841 callX, isCallX := expr.X.(*js.CallExpr)
842 callY, isCallY := expr.Y.(*js.CallExpr)
843 if isCallX && isCallY && len(callX.Args.List) == 1 && len(callY.Args.List) == 1 && !callX.Args.List[0].Rest && !callY.Args.List[0].Rest && isEqualExpr(callX.X, callY.X) {
844 expr.X = callX.Args.List[0].Value
845 expr.Y = callY.Args.List[0].Value
846 return &js.CallExpr{callX.X, js.Args{[]js.Arg{{expr, false}}}, js.OpCall, false} // recompress the conditional expression inside
847 }
848
849 // shorten when true and false bodies are true and false
850 trueX, falseX := isTrue(expr.X), isFalse(expr.X)
851 trueY, falseY := isTrue(expr.Y), isFalse(expr.Y)
852 if trueX && falseY || falseX && trueY {
853 return optimizeBooleanExpr(expr.Cond, falseX, prec)
854 } else if trueX || trueY {
855 // trueX != trueY
856 cond := optimizeBooleanExpr(expr.Cond, trueY, binaryLeftPrecMap[js.OrToken])
857 if trueY {
858 return &js.BinaryExpr{js.OrToken, cond, groupExpr(expr.X, binaryRightPrecMap[js.OrToken])}
859 } else {
860 return &js.BinaryExpr{js.OrToken, cond, groupExpr(expr.Y, binaryRightPrecMap[js.OrToken])}

Callers 1

minifyExprMethod · 0.95

Calls 12

isBooleanExprFunction · 0.85
finalExprFunction · 0.85
isTruthyFunction · 0.85
isEqualExprFunction · 0.85
exprPrecFunction · 0.85
groupExprFunction · 0.85
toNullishExprFunction · 0.85
lenFunction · 0.85
isTrueFunction · 0.85
isFalseFunction · 0.85
optimizeBooleanExprFunction · 0.85
minVersionMethod · 0.80

Tested by

no test coverage detected