diff --git a/cl/compile_test.go b/cl/compile_test.go index 6ffe12996..acec2b7fd 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -4406,3 +4406,112 @@ func (this *Rect) test() { } `, "Rect.gopx") } + +func TestOverload(t *testing.T) { + gopClTest(t, ` +import "github.com/goplus/gop/cl/internal/overload/foo" + +type Mesh struct { +} + +func (p *Mesh) Name() string { + return "hello" +} + +var ( + m1 = &Mesh{} + m2 = &Mesh{} +) + +foo.onKey "hello", => { +} +foo.onKey "hello", key => { +} +foo.onKey ["1"], => { +} +foo.onKey ["2"], key => { +} +foo.onKey [m1,m2], => { +} +foo.onKey [m1,m2], key => { +} +foo.onKey ["a"], ["b"], key => { +} +foo.onKey ["a"], [m1,m2], key => { +} +foo.onKey ["a"],nil,key => { +} +n := &foo.N{} +n.onKey "hello", => { +} +n.onKey "hello", key => { +} +n.onKey ["1"], => { +} +n.onKey ["2"], key => { +} +n.onKey [m1,m2], => { +} +n.onKey [m1,m2], key => { +} +n.onKey ["a"], ["b"], key => { +} +n.onKey ["a"], [m1,m2], key => { +} +n.onKey ["a"],nil,key => { +} +`, `package main + +import foo "github.com/goplus/gop/cl/internal/overload/foo" + +type Mesh struct { +} + +func (p *Mesh) Name() string { + return "hello" +} + +var m1 = &Mesh{} +var m2 = &Mesh{} + +func main() { + foo.OnKey__0("hello", func() { + }) + foo.OnKey__1("hello", func(key string) { + }) + foo.OnKey__2([]string{"1"}, func() { + }) + foo.OnKey__3([]string{"2"}, func(key string) { + }) + foo.OnKey__4([]foo.Mesher{m1, m2}, func() { + }) + foo.OnKey__5([]foo.Mesher{m1, m2}, func(key foo.Mesher) { + }) + foo.OnKey__6([]string{"a"}, []string{"b"}, func(key string) { + }) + foo.OnKey__7([]string{"a"}, []foo.Mesher{m1, m2}, func(key string) { + }) + foo.OnKey__6([]string{"a"}, nil, func(key string) { + }) + n := &foo.N{} + n.OnKey__0("hello", func() { + }) + n.OnKey__1("hello", func(key string) { + }) + n.OnKey__2([]string{"1"}, func() { + }) + n.OnKey__3([]string{"2"}, func(key string) { + }) + n.OnKey__4([]foo.Mesher{m1, m2}, func() { + }) + n.OnKey__5([]foo.Mesher{m1, m2}, func(key foo.Mesher) { + }) + n.OnKey__6([]string{"a"}, []string{"b"}, func(key string) { + }) + n.OnKey__7([]string{"a"}, []foo.Mesher{m1, m2}, func(key string) { + }) + n.OnKey__6([]string{"a"}, nil, func(key string) { + }) +} +`) +} diff --git a/cl/expr.go b/cl/expr.go index 2412d6f6f..6349d347d 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -430,6 +430,7 @@ func compilePkgRef(ctx *blockCtx, at *gox.PkgRef, x *ast.Ident, flags, pkgKind i } type fnType struct { + next *fnType params *types.Tuple n1 int variadic bool @@ -472,8 +473,15 @@ func (p *fnType) initWith(fnt types.Type, idx, nin int) { p.inited = true if t, ok := fnt.(*gox.TypeType); ok { p.initTypeType(t) - } else if t := gox.CheckSignature(fnt, idx, nin); t != nil { - p.init(t) + } else if t := gox.CheckSignatures(fnt, idx, nin); t != nil { + p.init(t[0]) + for i := 1; i < len(t); i++ { + fn := &fnType{} + fn.inited = true + fn.init(t[i]) + p.next = fn + p = p.next + } } } @@ -496,7 +504,6 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) { default: compileExpr(ctx, fn) } - var fn fnType var fnt = ctx.cb.Get(-1).Type var flags gox.InstrFlags var ellipsis = v.Ellipsis != gotoken.NoPos @@ -506,6 +513,27 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) { if (inFlags & clCallWithTwoValue) != 0 { flags |= gox.InstrFlagTwoValue } + var fn *fnType = &fnType{} + for fn != nil { + err := compileCallArgs(fn, fnt, ctx, v, ellipsis, flags) + if err == nil { + break + } + if fn.next == nil { + panic(err) + } + fn = fn.next + } +} + +func compileCallArgs(fn *fnType, fnt types.Type, ctx *blockCtx, v *ast.CallExpr, ellipsis bool, flags gox.InstrFlags) (err error) { + n := ctx.cb.InternalStack().Len() + defer func() { + if v := recover(); v != nil { + err = v.(error) + ctx.cb.InternalStack().SetLen(n) + } + }() for i, arg := range v.Args { switch expr := arg.(type) { case *ast.LambdaExpr: @@ -520,34 +548,31 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) { fn.initWith(fnt, i, -1) compileCompositeLit(ctx, expr, fn.arg(i, ellipsis), true) case *ast.SliceLit: - if len(v.Args) == 1 { - fn.initWith(fnt, i, -2) - t := fn.arg(i, ellipsis) - switch t.(type) { - case *types.Slice: - case *types.Named: - if _, ok := getUnderlying(ctx, t).(*types.Slice); !ok { - t = nil - } - default: + fn.initWith(fnt, i, -2) + t := fn.arg(i, ellipsis) + switch t.(type) { + case *types.Slice: + case *types.Named: + if _, ok := getUnderlying(ctx, t).(*types.Slice); !ok { t = nil } - typetype := fn.typetype && t != nil - if typetype { - ctx.cb.InternalStack().Pop() - } - compileSliceLit(ctx, expr, t) - if typetype { - return - } - } else { - compileSliceLit(ctx, expr, nil) + default: + t = nil + } + typetype := fn.typetype && t != nil + if typetype { + ctx.cb.InternalStack().Pop() + } + compileSliceLit(ctx, expr, t) + if typetype { + return } default: compileExpr(ctx, arg) } } ctx.cb.CallWith(len(v.Args), flags, v) + return } type clLambaFlag string @@ -862,6 +887,7 @@ func compileSliceLit(ctx *blockCtx, v *ast.SliceLit, typ types.Type) { } else { ctx.cb.SliceLit(typ, n) } + return } func compileRangeExpr(ctx *blockCtx, v *ast.RangeExpr) { diff --git a/cl/internal/overload/foo/foo.go b/cl/internal/overload/foo/foo.go new file mode 100644 index 000000000..ec75b1fc4 --- /dev/null +++ b/cl/internal/overload/foo/foo.go @@ -0,0 +1,58 @@ +package foo + +const GopPackage = true + +type Mesher interface { + Name() string +} + +type N struct { +} + +func (m *N) OnKey__0(a string, fn func()) { +} + +func (m *N) OnKey__1(a string, fn func(key string)) { +} + +func (m *N) OnKey__2(a []string, fn func()) { +} + +func (m *N) OnKey__3(a []string, fn func(key string)) { +} + +func (m *N) OnKey__4(a []Mesher, fn func()) { +} + +func (m *N) OnKey__5(a []Mesher, fn func(key Mesher)) { +} + +func (m *N) OnKey__6(a []string, b []string, fn func(key string)) { +} + +func (m *N) OnKey__7(a []string, b []Mesher, fn func(key string)) { +} + +func OnKey__0(a string, fn func()) { +} + +func OnKey__1(a string, fn func(key string)) { +} + +func OnKey__2(a []string, fn func()) { +} + +func OnKey__3(a []string, fn func(key string)) { +} + +func OnKey__4(a []Mesher, fn func()) { +} + +func OnKey__5(a []Mesher, fn func(key Mesher)) { +} + +func OnKey__6(a []string, b []string, fn func(key string)) { +} + +func OnKey__7(a []string, b []Mesher, fn func(key string)) { +} diff --git a/go.mod b/go.mod index 55a6de2de..c433c26ea 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/goplus/c2go v0.7.13 - github.com/goplus/gox v1.11.36 + github.com/goplus/gox v1.11.37 github.com/goplus/libc v0.3.13 github.com/goplus/mod v0.10.1 github.com/qiniu/x v1.11.9 diff --git a/go.sum b/go.sum index ee4f911d2..807da170d 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,8 @@ github.com/goplus/c2go v0.7.13 h1:188dkHVVS3Qn/cwFtFwNgvlgjY2tBrZRjugv8icolt4= github.com/goplus/c2go v0.7.13/go.mod h1:s5NULWzUKi3erd3l4ahvpq+3qDGOvMjGb00a5o3h6zk= github.com/goplus/gox v1.11.21/go.mod h1:wRCRSNukie4cDqADF4w0Btc2Gk6V3p3V6hI5+rsVqa8= github.com/goplus/gox v1.11.32/go.mod h1:hdKq5ghywtKWnBJNQNVBkPITmWCqCFRwwd2LTYTfg2U= -github.com/goplus/gox v1.11.36 h1:OUkGM117o1WwOf2SB2DZHHHTOybOXbqu8BrSL95cXZE= -github.com/goplus/gox v1.11.36/go.mod h1:l1p0XjHQoFhQQZqEtJjMt8o0CuvS3iE5PIGwwTHsgQ4= +github.com/goplus/gox v1.11.37 h1:8oAXjokhvttO/4NZgfAJ02GE9OivbX2VSsEJWu3fGng= +github.com/goplus/gox v1.11.37/go.mod h1:NkgUJWIjKxrhUwM4bgyUt3ZE0WlTunqfksMzrbnh7V8= github.com/goplus/libc v0.3.13 h1:2yHG8ghezBTK3Da7Fw1lNiitmt+Va+RzwKJ5GuqypCQ= github.com/goplus/libc v0.3.13/go.mod h1:xqG4/g3ilKBE/UDn5vkaE7RRQPQPyspj7ecuMuvlQJ8= github.com/goplus/mod v0.9.12/go.mod h1:YoPIowz71rnLLROA4YG0AC8bzDtPRyMaQwgTRLr8ri4= @@ -86,6 +86,6 @@ golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= -golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/tools v0.11.1 h1:ojD5zOW8+7dOGzdnNgersm8aPfcDjhMp12UfG93NIMc= +golang.org/x/tools v0.11.1/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=