Skip to content

Commit

Permalink
update:support named function in classfile's overload decl
Browse files Browse the repository at this point in the history
  • Loading branch information
luoliwoshang committed May 22, 2024
1 parent 01bb888 commit 397272d
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 8 deletions.
37 changes: 29 additions & 8 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -1071,13 +1071,26 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge

case *ast.OverloadFuncDecl:
var recv *ast.Ident
if ctx.classRecv != nil { // in class file (.spx/.gmx)
if recv := d.Recv; recv == nil || len(recv.List) == 0 {
d.Recv = &ast.FieldList{
List: []*ast.Field{
{
Type: ctx.classRecv.List[0].Type.(*ast.StarExpr).X,
},
},
}
d.IsClass = true
}
}
if d.Recv != nil {
otyp, ok := d.Recv.List[0].Type.(*ast.Ident)
var ok bool
recv, ok = d.Recv.List[0].Type.(*ast.Ident)
if !ok {
ctx.handleErrorf(d.Recv.List[0].Type.Pos(), "invalid recv type %v", ctx.LoadExpr(d.Recv.List[0].Type))
break
}
recv = otyp
ctx.lbinames = append(ctx.lbinames, recv)
if ctx.rec != nil {
ctx.rec.ReferUse(recv, recv.Name)
}
Expand All @@ -1086,18 +1099,27 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge
exov := false
name := d.Name
LoopFunc:

for idx, fn := range d.Funcs {
switch expr := fn.(type) {
case *ast.Ident:
if d.Recv != nil && !d.Operator {
if d.Recv != nil && !d.Operator && !d.IsClass {
ctx.handleErrorf(expr.Pos(), "invalid method %v", ctx.LoadExpr(expr))
break LoopFunc
}
onames = append(onames, expr.Name)
ctx.lbinames = append(ctx.lbinames, expr.Name)
exov = true
if d.IsClass {
onames = append(onames, "."+expr.Name)
} else {
onames = append(onames, expr.Name)
ctx.lbinames = append(ctx.lbinames, expr.Name)
}
if ctx.rec != nil {
ctx.rec.ReferUse(expr, expr.Name)
if d.IsClass {
ctx.rec.ReferUse(expr, recv.Name+"."+expr.Name)
} else {
ctx.rec.ReferUse(expr, expr.Name)
}
}
case *ast.SelectorExpr:
if d.Recv == nil {
Expand All @@ -1111,14 +1133,13 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge
}

onames = append(onames, "."+expr.Sel.Name)
ctx.lbinames = append(ctx.lbinames, recv)
exov = true
if ctx.rec != nil {
ctx.rec.ReferUse(rtyp, rtyp.Name)
ctx.rec.ReferUse(expr.Sel, rtyp.Name+"."+expr.Sel.Name)
}
case *ast.FuncLit:
if d.Recv != nil && !d.Operator {
if d.Recv != nil && !d.Operator && !d.IsClass {
ctx.handleErrorf(expr.Pos(), "invalid method %v", ctx.LoadExpr(expr))
break LoopFunc
}
Expand Down
36 changes: 36 additions & 0 deletions cl/compile_spx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,42 @@ type foo struct {
`, "foo.gox")
}

func TestGopxOverload(t *testing.T) {
gopClTestFile(t, `
func addString(a, b string) string {
return a + b
}
func addInt(a, b int) int {
return a + b
}
func add = (
addInt
func(a, b float64) float64 {
return a + b
}
addString
)
`, `package main
const Gopo_Rect_add = ".addInt,,.addString"
type Rect struct {
}
func (this *Rect) addString(a string, b string) string {
return a + b
}
func (this *Rect) addInt(a int, b int) int {
return a + b
}
func (this *Rect) add__1(a float64, b float64) float64 {
return a + b
}
`, "Rect.gox")
}

func TestClassFileGopx(t *testing.T) {
gopClTestFile(t, `
var (
Expand Down
66 changes: 66 additions & 0 deletions x/typesutil/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2382,3 +2382,69 @@ func init() {
000: 12: 2 | add | func main.add(__gop_overload_args__ interface{_()})
001: 13: 2 | add | func main.add(__gop_overload_args__ interface{_()})`)
}

func TestGoxOverloadInfo(t *testing.T) {
testSpxInfo(t, "Rect.gox", `
func addInt(a, b int) int {
return a + b
}
func addString(a, b string) string {
return a + b
}
func add = (
addInt
func(a, b float64) float64 {
return a + b
}
addString
)
`, `== types ==
000: 0: 0 | ".addInt,,.addString" *ast.BasicLit | value : untyped string = ".addInt,,.addString" | constant
001: 0: 0 | Rect *ast.Ident | type : main.Rect | type
002: 2:18 | int *ast.Ident | type : int | type
003: 2:23 | int *ast.Ident | type : int | type
004: 3: 9 | a *ast.Ident | var : int | variable
005: 3: 9 | a + b *ast.BinaryExpr | value : int | value
006: 3:13 | b *ast.Ident | var : int | variable
007: 6:21 | string *ast.Ident | type : string | type
008: 6:29 | string *ast.Ident | type : string | type
009: 7: 9 | a *ast.Ident | var : string | variable
010: 7: 9 | a + b *ast.BinaryExpr | value : string | value
011: 7:13 | b *ast.Ident | var : string | variable
012: 12:12 | float64 *ast.Ident | type : float64 | type
013: 12:21 | float64 *ast.Ident | type : float64 | type
014: 13:10 | a *ast.Ident | var : float64 | variable
015: 13:10 | a + b *ast.BinaryExpr | value : float64 | value
016: 13:14 | b *ast.Ident | var : float64 | variable
== defs ==
000: 0: 0 | Gopo_Rect_add | const main.Gopo_Rect_add untyped string
001: 0: 0 | this | var this *main.Rect
002: 2: 6 | addInt | func (*main.Rect).addInt(a int, b int) int
003: 2:13 | a | var a int
004: 2:16 | b | var b int
005: 6: 6 | addString | func (*main.Rect).addString(a string, b string) string
006: 6:16 | a | var a string
007: 6:19 | b | var b string
008: 10: 6 | add | func (main.Rect).add(__gop_overload_args__ interface{_()})
009: 12: 2 | add__1 | func (*main.Rect).add__1(a float64, b float64) float64
010: 12: 7 | a | var a float64
011: 12:10 | b | var b float64
== uses ==
000: 0: 0 | Rect | type main.Rect struct{}
001: 2:18 | int | type int
002: 2:23 | int | type int
003: 3: 9 | a | var a int
004: 3:13 | b | var b int
005: 6:21 | string | type string
006: 6:29 | string | type string
007: 7: 9 | a | var a string
008: 7:13 | b | var b string
009: 11: 2 | addInt | func (*main.Rect).addInt(a int, b int) int
010: 12:12 | float64 | type float64
011: 12:21 | float64 | type float64
012: 13:10 | a | var a float64
013: 13:14 | b | var b float64
014: 15: 2 | addString | func (*main.Rect).addString(a string, b string) string`)
}

0 comments on commit 397272d

Please sign in to comment.