diff --git a/builtin_test.go b/builtin_test.go index d7a3cd56..852934d6 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -407,7 +407,7 @@ func TestContract(t *testing.T) { pkg := NewPackage("", "foo", nil) at := types.NewPackage("foo", "foo") foo := pkg.Import("github.com/goplus/gogen/internal/foo") - tfoo := foo.Ref("Foo").Type() + tfoo := foo.Ref("Foo5").Type() tarr := types.NewArray(tyInt, 10) testcases := []struct { Contract @@ -1699,7 +1699,7 @@ func TestAliasTypeMethod(t *testing.T) { pkg := NewPackage("", "foo", nil) at := types.NewPackage("foo", "foo") foo := pkg.Import("github.com/goplus/gogen/internal/foo") - tfoo := foo.Ref("Foo").Type() + tfoo := foo.Ref("Foo5").Type() testcases := []struct { Contract typ types.Type @@ -1737,7 +1737,7 @@ func TestAliasContract(t *testing.T) { pkg := NewPackage("", "foo", nil) at := types.NewPackage("foo", "foo") foo := pkg.Import("github.com/goplus/gogen/internal/foo") - tfoo := foo.Ref("Foo").Type() + tfoo := foo.Ref("Foo5").Type() tarr := types.NewArray(tyInt, 10) testcases := []struct { Contract diff --git a/error_msg_test.go b/error_msg_test.go index 5bccafc1..40d407bd 100644 --- a/error_msg_test.go +++ b/error_msg_test.go @@ -396,38 +396,27 @@ func TestErrDefineVar(t *testing.T) { } func TestErrForRange(t *testing.T) { - codeErrorTest(t, `./foo.gop:1:17: can't use return/continue/break/goto in for range of udt.XGo_Enum(callback)`, + codeErrorTest(t, `./foo.gop:1:17: cannot range over v (type *github.com/goplus/gogen/internal/foo.Foo3)`, func(pkg *gogen.Package) { foo := pkg.Import("github.com/goplus/gogen/internal/foo") - bar := foo.Ref("Foo2").Type() + bar := foo.Ref("Foo3").Type() v := newParam(pkg, token.NoPos, "v", types.NewPointer(bar)) pkg.NewFunc(nil, "foo", types.NewTuple(v), nil, false).BodyStart(pkg). ForRange("a", "b"). Val(v, source("v", 1, 9)). RangeAssignThen(position(1, 17)). - Return(0). End(). End() }) - codeErrorTest(t, `./foo.gop:1:17: cannot range over v (type *github.com/goplus/gogen/internal/foo.Foo4)`, + codeErrorTest(t, `./foo.gop:1:17: cannot range over v (type bool)`, func(pkg *gogen.Package) { - foo := pkg.Import("github.com/goplus/gogen/internal/foo") - bar := foo.Ref("Foo4").Type() - v := newParam(pkg, token.NoPos, "v", types.NewPointer(bar)) + bar := types.Typ[types.Bool] + v := newParam(pkg, token.NoPos, "v", bar) pkg.NewFunc(nil, "foo", types.NewTuple(v), nil, false).BodyStart(pkg). + NewVar(bar, "a", "b"). ForRange(). - Val(v, source("v", 1, 9)). - RangeAssignThen(position(1, 17)). - End(). - End() - }) - codeErrorTest(t, `./foo.gop:1:17: cannot range over v (type *github.com/goplus/gogen/internal/foo.Foo3)`, - func(pkg *gogen.Package) { - foo := pkg.Import("github.com/goplus/gogen/internal/foo") - bar := foo.Ref("Foo3").Type() - v := newParam(pkg, token.NoPos, "v", types.NewPointer(bar)) - pkg.NewFunc(nil, "foo", types.NewTuple(v), nil, false).BodyStart(pkg). - ForRange("a", "b"). + VarRef("a"). + VarRef("b"). Val(v, source("v", 1, 9)). RangeAssignThen(position(1, 17)). End(). diff --git a/internal/foo/foo.go b/internal/foo/foo.go index f529c371..83613c73 100644 --- a/internal/foo/foo.go +++ b/internal/foo/foo.go @@ -103,22 +103,15 @@ func (p *Bar3) XGo_Enum() barIt3 { // ----------------------------------------------------------------------------- -type Foo struct { -} - -func (p *Foo) XGo_Enum(c func(v string)) { -} - -func (a Foo) XGo_Add(b Foo) Foo { - return Foo{} +type Foo5 struct { } -// ----------------------------------------------------------------------------- - -type Foo2 struct { +func (p Foo5) XGo_Enum() iter.Seq2[int, string] { + return nil } -func (p Foo2) XGo_Enum(c func(k int, v string)) { +func (p Foo5) XGo_Add(b Foo5) Foo5 { + return Foo5{} } // ----------------------------------------------------------------------------- @@ -126,26 +119,7 @@ func (p Foo2) XGo_Enum(c func(k int, v string)) { type Foo3 struct { } -func (p Foo3) XGo_Enum(c func(k int, v string)) int { - return 0 -} - -// ----------------------------------------------------------------------------- - -type Foo4 struct { -} - -func (p Foo4) XGo_Enum(c func()) { -} - -// ----------------------------------------------------------------------------- - -type Foo5 struct { -} - -func (p Foo5) XGo_Enum() iter.Seq2[int, string] { - return nil -} +func (p Foo3) XGo_Enum(int) {} // ----------------------------------------------------------------------------- diff --git a/stmt.go b/stmt.go index 85e29853..33eef7a5 100644 --- a/stmt.go +++ b/stmt.go @@ -673,28 +673,9 @@ func (p *forRangeStmt) checkUdt(cb *CodeBuilder, o *types.Named) ([]types.Type, params := sig.Params() switch params.Len() { case 0: + // fnIter := obj.XGo_Enum() or // iter := obj.XGo_Enum() // key, val, ok := iter.Next() - case 1: - // obj.XGo_Enum(func(key K, val V) { ... }) - if enumRet.Len() != 0 { - return nil, false - } - typ := params.At(0).Type() - if t, ok := typ.(*types.Signature); ok && t.Results().Len() == 0 { - kv := t.Params() - n := kv.Len() - if n > 0 { - p.kvt = []types.Type{kv.At(0).Type(), nil} - if n > 1 { - n = 2 - p.kvt[1] = kv.At(1).Type() - } - p.udt = -n - return p.kvt, true - } - } - fallthrough default: return nil, false } @@ -797,4 +778,4 @@ func (p *forRangeStmt) End(cb *CodeBuilder, src ast.Node) { emitForRangeStmt(cb, p, stmts, flows) } -// ---------------------------------------------------------------------------- \ No newline at end of file +// ---------------------------------------------------------------------------- diff --git a/util_gengo.go b/util_gengo.go index fb2cca0c..71b0f43b 100644 --- a/util_gengo.go +++ b/util_gengo.go @@ -1137,7 +1137,7 @@ func emitForRangeStmt(cb *CodeBuilder, p *forRangeStmt, stmts []ast.Stmt, flows } p.stmt.Body = p.handleFor(&ast.BlockStmt{List: stmts}, 1) cb.emitStmt(p.stmt) - } else if n > 0 { + } else { cb.stk.Push(p.x) cb.MemberVal(p.enumName, 0).Call(0) callEnum := cb.stk.Pop().Val @@ -1187,44 +1187,6 @@ func emitForRangeStmt(cb *CodeBuilder, p *forRangeStmt, stmts []ast.Stmt, flows Body: p.handleFor(&ast.BlockStmt{List: body}, 2), } cb.emitStmt(stmt) - } else { - /* - X.XGo_Enum(func(k K, v V) { - ... - }) - */ - if flows != 0 { - cb.panicCodeError(p.stmt.For, p.stmt.For, cantUseFlowsInForRange) - } - n = -n - def := p.stmt.Tok == token.DEFINE - args := make([]*ast.Field, n) - if def { - args[0] = &ast.Field{ - Names: []*ast.Ident{p.stmt.Key.(*ast.Ident)}, - Type: toType(cb.pkg, p.kvt[0]), - } - if n > 1 { - args[1] = &ast.Field{ - Names: []*ast.Ident{p.stmt.Value.(*ast.Ident)}, - Type: toType(cb.pkg, p.kvt[1]), - } - } - } else { - panic("TODO: for range udt assign") - } - stmt := &ast.ExprStmt{ - X: &ast.CallExpr{ - Fun: &ast.SelectorExpr{X: p.stmt.X, Sel: ident(p.enumName)}, - Args: []ast.Expr{ - &ast.FuncLit{ - Type: &ast.FuncType{Params: &ast.FieldList{List: args}}, - Body: p.handleFor(&ast.BlockStmt{List: stmts}, -1), - }, - }, - }, - } - cb.emitStmt(stmt) } } diff --git a/xgo_test.go b/xgo_test.go index f1e6d9fe..028a0ab6 100644 --- a/xgo_test.go +++ b/xgo_test.go @@ -794,6 +794,9 @@ func TestForRangeUDT(t *testing.T) { pkg.NewFunc(nil, "bar", types.NewTuple(v), nil, false).BodyStart(pkg). ForRange("_", "val").Val(v).RangeAssignThen(token.NoPos). Val(pkg.Import("fmt").Ref("Println")).Val(ctxRef(pkg, "val")).Call(1).EndStmt(). + SetBodyHandler(func(body *target.BlockStmt, kind int) { + gogen.InsertStmtFront(body, &target.ExprStmt{X: ast.NewIdent("__sched__")}) + }). End().End() domTest(t, pkg, `package main @@ -804,6 +807,7 @@ import ( func bar(v foo.NodeSet) { for _xgo_it := v.Gop_Enum(); ; { + __sched__ var _xgo_ok bool _, val, _xgo_ok := _xgo_it.Next() if !_xgo_ok { @@ -966,59 +970,6 @@ func bar(v foo.NodeSet) { `) } -func TestForRangeUDT4(t *testing.T) { - pkg := newMainPackage() - foo := pkg.Import("github.com/goplus/gogen/internal/foo") - bar := foo.Ref("Foo").Type() - v := newParam(pkg, token.NoPos, "v", types.NewPointer(bar)) - pkg.NewFunc(nil, "bar", types.NewTuple(v), nil, false).BodyStart(pkg). - ForRange("elem").Val(v).RangeAssignThen(token.NoPos). - Val(pkg.Import("fmt").Ref("Println")).Val(ctxRef(pkg, "elem")).Call(1).EndStmt(). - SetBodyHandler(func(body *target.BlockStmt, kind int) { - gogen.InsertStmtFront(body, &target.ExprStmt{X: ast.NewIdent("__sched__")}) - }). - End().End() - domTest(t, pkg, `package main - -import ( - "fmt" - "github.com/goplus/gogen/internal/foo" -) - -func bar(v *foo.Foo) { - v.XGo_Enum(func(elem string) { - __sched__ - fmt.Println(elem) - }) -} -`) -} - -func TestForRangeUDT5(t *testing.T) { - pkg := newMainPackage() - foo := pkg.Import("github.com/goplus/gogen/internal/foo") - bar := foo.Ref("Foo2").Type() - v := newParam(pkg, token.NoPos, "v", types.NewPointer(bar)) - pkg.NewFunc(nil, "bar", types.NewTuple(v), nil, false).BodyStart(pkg). - ForRange("key", "elem").Val(v).RangeAssignThen(token.NoPos). - Val(pkg.Import("fmt").Ref("Println")).Val(ctxRef(pkg, "key")).Val(ctxRef(pkg, "elem")). - Call(2).EndStmt(). - End().End() - domTest(t, pkg, `package main - -import ( - "fmt" - "github.com/goplus/gogen/internal/foo" -) - -func bar(v *foo.Foo2) { - v.XGo_Enum(func(key int, elem string) { - fmt.Println(key, elem) - }) -} -`) -} - func TestForRangeUDT6(t *testing.T) { pkg := newMainPackage() os := pkg.Import("os")