Repository: goplus/gop
Pull request #2086 (2025-01-29 03:56:22)

x/format: funcLitToLambdaExpr
format funclit to lambda expr
```
println(demo(func(n int) int {
	return n+100
}))

println(demo(func(n int) int {
	println(n)
	return n+100
}))

println(demo(func(n int) (v int) {
	return n+100
}))

demo2(300, func(n1, n2 int) int {
	return n1 + n2
})

demo2(300, func(int, int) int {
	println("hello")
	return 600
})
```
format to lambda ( skip named results )
```
println demo(n => n + 100)

println demo(n => {
	println n
	return n + 100
})

println demo(func(n int) (v int) {
	return n + 100
})

demo2 300, (n1, n2) => n1 + n2

demo2 300, (_, _) => {
	println "hello"
	return 600
}
```


Patch:
diff --git a/x/format/stmt_expr_or_type.go b/x/format/stmt_expr_or_type.go
index eb2a758e..99932392 100644
--- a/x/format/stmt_expr_or_type.go
+++ b/x/format/stmt_expr_or_type.go
@@ -168,9 +168,50 @@ func formatSliceExpr(ctx *formatCtx, v *ast.SliceExpr) {
 func formatCallExpr(ctx *formatCtx, v *ast.CallExpr) {
 	formatExpr(ctx, v.Fun, &v.Fun)
 	fncallStartingLowerCase(v)
+	for i, arg := range v.Args {
+		if fn, ok := arg.(*ast.FuncLit); ok {
+			funcLitToLambdaExpr(ctx, fn, &v.Args[i])
+		}
+	}
 	formatExprs(ctx, v.Args)
 }
 
+func funcLitToLambdaExpr(ctx *formatCtx, v *ast.FuncLit, ret *ast.Expr) {
+	nres, named := checkResult(v.Type.Results)
+	if len(named) > 0 {
+		return
+	}
+	var lsh []*ast.Ident
+	for _, p := range v.Type.Params.List {
+		if p.Names == nil {
+			lsh = append(lsh, ast.NewIdent("_"))
+		} else {
+			lsh = append(lsh, p.Names...)
+		}
+	}
+	if len(lsh) > 0 && len(v.Body.List) == 1 {
+		if stmt, ok := v.Body.List[0].(*ast.ReturnStmt); ok && len(stmt.Results) == nres {
+			*ret = &ast.LambdaExpr{First: v.Pos(), Last: v.Pos(), Lhs: lsh, Rhs: stmt.Results, LhsHasParen: len(lsh) > 1, RhsHasParen: len(stmt.Results) > 1}
+			return
+		}
+	}
+	*ret = &ast.LambdaExpr2{Lhs: lsh, Body: v.Body, LhsHasParen: len(lsh) > 1}
+}
+
+func checkResult(v *ast.FieldList) (nres int, named []*ast.Ident) {
+	if v != nil {
+		for _, f := range v.List {
+			if f.Names == nil {
+				nres++
+			} else {
+				nres += len(f.Names)
+				named = append(named, f.Names...)
+			}
+		}
+	}
+	return
+}
+
 func formatSelectorExpr(ctx *formatCtx, v *ast.SelectorExpr, ref *ast.Expr) {
 	switch x := v.X.(type) {
 	case *ast.Ident:


Test patch:
diff --git a/x/format/_testdata/collection/format.expect b/x/format/_testdata/collection/format.expect
index d4f69322..1db3a770 100644
--- a/x/format/_testdata/collection/format.expect
+++ b/x/format/_testdata/collection/format.expect
@@ -88,17 +88,11 @@ println Index(strs, "pear")
 
 println Include(strs, "grape")
 
-println Any(strs, func(v string) bool {
-	return strings.hasPrefix(v, "p")
-})
+println Any(strs, v => strings.hasPrefix(v, "p"))
 
-println All(strs, func(v string) bool {
-	return strings.hasPrefix(v, "p")
-})
+println All(strs, v => strings.hasPrefix(v, "p"))
 
-println Filter(strs, func(v string) bool {
-	return strings.contains(v, "e")
-})
+println Filter(strs, v => strings.contains(v, "e"))
 
 // The above examples all used anonymous functions,
 // but you can also use named functions of the correct
diff --git a/x/format/gopstyle_test.go b/x/format/gopstyle_test.go
index e2bb3e99..866e90ab 100644
--- a/x/format/gopstyle_test.go
+++ b/x/format/gopstyle_test.go
@@ -478,3 +478,58 @@ func f() {
 }
 `)
 }
+
+func TestLambdaFromFuncLit(t *testing.T) {
+	testFormat(t, "funclit to lambda", `package main
+println(demo(func(n int) int {
+	return n+100
+}))
+println(demo(func(n int) int {
+	return n+100
+}),200)
+demo1(100, func(n int) {
+	println(n)
+})
+demo1(100, func(int) {
+	println(100)
+})
+demo2(300, func(n1, n2 int) int {
+	return(n1 + n2)
+})
+demo2(300, func(int, int) int {
+	return -600
+})
+demo3(100,func(n1,n2 int)(int) {
+	return n1+n2,n1-n2
+},100)
+demo3(100,func(n1,n2 int)(v int) {
+	return n1+n2,n1-n2
+},100)
+demo4(100,func(n1,n2 int)(a,b int) {
+	println(a,b)
+	return n1+n2,n1-n2
+},100)
+`, `println demo(n => n + 100)
+println demo(n => n + 100), 200
+demo1 100, n => {
+	println n
+}
+demo1 100, _ => {
+	println 100
+}
+demo2 300, (n1, n2) => (n1 + n2)
+
+demo2 300, (_, _) => -600
+
+demo3 100, (n1, n2) => {
+	return n1 + n2, n1 - n2
+}, 100
+demo3 100, func(n1, n2 int) (v int) {
+	return n1 + n2, n1 - n2
+}, 100
+demo4 100, func(n1, n2 int) (a, b int) {
+	println a, b
+	return n1 + n2, n1 - n2
+}, 100
+`)
+}