Skip to content

Commit

Permalink
Merge pull request #1402 from visualfc/overload
Browse files Browse the repository at this point in the history
cl: overload func match check
  • Loading branch information
xushiwei authored Aug 20, 2023
2 parents 4ae9a43 + 92dc6bd commit ec464f3
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 28 deletions.
109 changes: 109 additions & 0 deletions cl/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
})
}
`)
}
72 changes: 49 additions & 23 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
}
}

Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
58 changes: 58 additions & 0 deletions cl/internal/overload/foo/foo.go
Original file line number Diff line number Diff line change
@@ -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)) {
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down Expand Up @@ -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=

0 comments on commit ec464f3

Please sign in to comment.