Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
with:
platforms: arm64
- name: Build wheels
uses: pypa/cibuildwheel@v3.1.4
uses: pypa/cibuildwheel@v3.2.0
with:
package-dir: bindings/py
env:
Expand Down Expand Up @@ -68,7 +68,7 @@ jobs:
set CGO_ENABLED=1
make -C bindings/py compile
- name: Build wheels
uses: pypa/cibuildwheel@v3.1.4
uses: pypa/cibuildwheel@v3.2.0
with:
package-dir: bindings/py
env:
Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
export MACOSX_DEPLOYMENT_TARGET=10.9
make -C bindings/py compile
- name: Build wheels
uses: pypa/cibuildwheel@v3.1.4
uses: pypa/cibuildwheel@v3.2.0
with:
package-dir: bindings/py
env:
Expand Down Expand Up @@ -152,7 +152,7 @@ jobs:
mkdir dist
mv artifacts/*/* dist/
- name: Upload to GitHub Release
uses: softprops/action-gh-release@v2.3.2
uses: softprops/action-gh-release@v2.3.3
with:
files: bindings/py/dist/*
- name: Publish to PyPI
Expand Down
61 changes: 56 additions & 5 deletions js/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -969,13 +969,10 @@ func (m *jsMinifier) minifyExpr(i js.IExpr, prec js.OpPrec) {
expr = &js.BinaryExpr{op, v, &js.LiteralExpr{js.NullToken, nullBytes}}
}

m.minifyExpr(expr.X, precLeft)
if expr.Op == js.GtToken && m.prev[len(m.prev)-1] == '-' {
// 0 < len(m.prev) always
m.write(spaceBytes)
} else if expr.Op == js.EqEqEqToken || expr.Op == js.NotEqEqToken {
if expr.Op == js.EqEqEqToken || expr.Op == js.NotEqEqToken {
if left, ok := expr.X.(*js.UnaryExpr); ok && left.Op == js.TypeofToken {
if right, ok := expr.Y.(*js.LiteralExpr); ok && right.TokenType == js.StringToken {
// typeof a === "string" => typeof a == "string"
if expr.Op == js.EqEqEqToken {
expr.Op = js.EqEqToken
} else {
Expand All @@ -984,13 +981,54 @@ func (m *jsMinifier) minifyExpr(i js.IExpr, prec js.OpPrec) {
}
} else if right, ok := expr.Y.(*js.UnaryExpr); ok && right.Op == js.TypeofToken {
if left, ok := expr.X.(*js.LiteralExpr); ok && left.TokenType == js.StringToken {
// "string" === typeof a => "string" == typeof a
if expr.Op == js.EqEqEqToken {
expr.Op = js.EqEqToken
} else {
expr.Op = js.NotEqToken
}
}
}
} else if expr.Op == js.EqToken {
if left, ok := expr.X.(*js.Var); ok {
if right, ok := expr.Y.(*js.BinaryExpr); ok {
var y js.IExpr
var varLeft bool
if v, ok := right.X.(*js.Var); ok && v == left {
y = right.Y
varLeft = true
} else if v, ok := right.Y.(*js.Var); ok && v == left {
y = right.X
}
if y != nil {
if lit, ok := y.(*js.LiteralExpr); ok && (right.Op == js.AddToken || varLeft && right.Op == js.SubToken) && lit.TokenType == js.IntegerToken && len(lit.Data) == 1 && lit.Data[0] == '1' {
if right.Op == js.AddToken {
// a=a+1 => ++a
m.write(plusPlusBytes)
m.minifyExpr(left, js.OpUnary)
break
} else {
// a=a-1 => --a
m.write(minMinBytes)
m.minifyExpr(left, js.OpUnary)
break
}
} else if right.Op == js.AddToken || right.Op == js.SubToken || right.Op == js.MulToken || right.Op == js.DivToken || right.Op == js.ModToken || right.Op == js.ExpToken || right.Op == js.LtLtToken || right.Op == js.GtGtToken || right.Op == js.GtGtGtToken || right.Op == js.BitAndToken || right.Op == js.BitOrToken || right.Op == js.BitXorToken || right.Op == js.AndToken || right.Op == js.OrToken || right.Op == js.NullishToken {
// a=a+b => a+=b
m.minifyExpr(left, js.OpLHS)
m.write(right.Op.Bytes())
m.write(equalBytes)
m.minifyExpr(y, js.OpAssign)
break
}
}
}
}
}
m.minifyExpr(expr.X, precLeft)
if expr.Op == js.GtToken && m.prev[len(m.prev)-1] == '-' {
// 0 < len(m.prev) always
m.write(spaceBytes)
}
m.write(expr.Op.Bytes())
if expr.Op == js.AddToken {
Expand Down Expand Up @@ -1294,6 +1332,19 @@ func (m *jsMinifier) minifyExpr(i js.IExpr, prec js.OpPrec) {
break
}
}
} else if bytes.Equal(dot.Y.Data, []byte("sqrt")) {
// Math.sqrt(x) => x**.5
if len(expr.Args.List) == 1 {
if js.OpExp < prec {
m.write(openParenBytes)
}
m.minifyExpr(&js.GroupExpr{expr.Args.List[0].Value}, js.OpUpdate)
m.write([]byte("**.5"))
if js.OpExp < prec {
m.write(closeParenBytes)
}
break
}
}
}
}
Expand Down
17 changes: 12 additions & 5 deletions js/js_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestJS(t *testing.T) {
{`0x0D`, `13`},
{`0x0d`, `13`},
{`0x0dn`, `13n`},
{`0x53DCAA254718n`, `0x53DCAA254718n`},
//{`123456787654321`, `0x704885f926b1`},
//{`4294967295`, `0xFFFFFFFF`}, // better GZIP
{`+ +x`, `+ +x`},
Expand Down Expand Up @@ -474,10 +475,10 @@ func TestJS(t *testing.T) {
{`a=false**2`, `a=(!1)**2`},
{`a=(++b)**2`, `a=++b**2`},
{`a=(a||b)&&c`, `a=(a||b)&&c`},
{`a=a||(b&&c)`, `a=a||b&&c`},
{`a=a||(b&&c)`, `a||=b&&c`},
{`a=(a&&b)||c`, `a=a&&b||c`},
{`a=a&&(b||c)`, `a=a&&(b||c)`},
{`a=a&&(b&&c)`, `a=a&&b&&c`},
{`a=a&&(b||c)`, `a&&=b||c`},
{`a=a&&(b&&c)`, `a&&=b&&c`},
{`a=c&&(a??b)`, `a=c&&(a??b)`},
{`a=(a||b)??(c||d)`, `a=(a||b)??(c||d)`},
{`a=(a&&b)??(c&&d)`, `a=(a&&b)??(c&&d)`},
Expand Down Expand Up @@ -579,8 +580,6 @@ func TestJS(t *testing.T) {
{`f(...a,...b)`, `f(...a,...b)`},

// expressions
//{`a=a+5`, `a+=5`},
//{`a=5+a`, `a+=5`},
{`a?true:false`, `!!a`},
{`a==b?true:false`, `a==b`},
{`!a?true:false`, `!a`},
Expand Down Expand Up @@ -677,6 +676,12 @@ func TestJS(t *testing.T) {
{`(a===null||a===undefined)?undefined:a.#b`, `a?.#b`},
{`(((a===null)||(a===undefined)))?undefined:a()`, `a?.()`},
//{`(a.b===null||a.b===undefined)?undefined:a.b()`, `a.b?.()`},
{`a=1+a`, `++a`},
{`a=a-1`, `--a`},
{`a=a+5`, `a+=5`},
{`a=5+a`, `a+=5`},
{`a=a+b`, `a+=b`},
{`a=a^b`, `a^=b`},

// other
{`async function g(){await x+y}`, `async function g(){await x+y}`},
Expand All @@ -703,6 +708,8 @@ func TestJS(t *testing.T) {
{`Math.trunc(x)`, `x|0`},
{`Math.pow(a,b)`, `a**b`},
{`Math.pow(-a,b)`, `(-a)**b`},
{`Math.sqrt(a)`, `a**.5`},
{`++Math.sqrt(a*5)`, `++((a*5)**.5)`},
{`isNaN(x)`, `isNaN(x)`},
{`Number(undefined)`, `NaN`},
{`Number(null)`, `0`},
Expand Down
28 changes: 13 additions & 15 deletions js/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ var (
newlineBytes = []byte("\n")
starBytes = []byte("*")
plusBytes = []byte("+")
plusPlusBytes = []byte("++")
minMinBytes = []byte("--")
expBytes = []byte("**")
bitOrBytes = []byte("|")
colonBytes = []byte(":")
Expand Down Expand Up @@ -1370,20 +1372,18 @@ func removeUnderscoresAndSuffix(b []byte) ([]byte, bool) {
return b, false
}

func decimalNumber(b []byte, prec int) []byte {
var suffix bool
b, suffix = removeUnderscoresAndSuffix(b)
func decimalNumber(num []byte, prec int) []byte {
b, suffix := removeUnderscoresAndSuffix(num)
if suffix {
return append(b, 'n')
}
return minify.Number(b, prec)
}

func binaryNumber(b []byte, prec int) []byte {
var suffix bool
b, suffix = removeUnderscoresAndSuffix(b)
func binaryNumber(num []byte, prec int) []byte {
b, suffix := removeUnderscoresAndSuffix(num)
if len(b) <= 2 || 65 < len(b) {
return b
return num
}
var n int64
for _, c := range b[2:] {
Expand All @@ -1403,11 +1403,10 @@ func binaryNumber(b []byte, prec int) []byte {
return minify.Number(b, prec)
}

func octalNumber(b []byte, prec int) []byte {
var suffix bool
b, suffix = removeUnderscoresAndSuffix(b)
func octalNumber(num []byte, prec int) []byte {
b, suffix := removeUnderscoresAndSuffix(num)
if len(b) <= 2 || 23 < len(b) {
return b
return num
}
var n int64
for _, c := range b[2:] {
Expand All @@ -1427,11 +1426,10 @@ func octalNumber(b []byte, prec int) []byte {
return minify.Number(b, prec)
}

func hexadecimalNumber(b []byte, prec int) []byte {
var suffix bool
b, suffix = removeUnderscoresAndSuffix(b)
func hexadecimalNumber(num []byte, prec int) []byte {
b, suffix := removeUnderscoresAndSuffix(num)
if len(b) <= 2 || 12 < len(b) || len(b) == 12 && ('D' < b[2] && b[2] <= 'F' || 'd' < b[2]) {
return b
return num
}
var n int64
for _, c := range b[2:] {
Expand Down
Loading