Skip to content

Commit

Permalink
Merge pull request #1850 from xushiwei/q
Browse files Browse the repository at this point in the history
define static method
  • Loading branch information
xushiwei committed Apr 9, 2024
2 parents 22d7207 + 2b4184f commit 570665d
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 16 deletions.
43 changes: 31 additions & 12 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -888,19 +888,19 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge

preloadFuncDecl := func(d *ast.FuncDecl) {
if ctx.classRecv != nil { // in class file (.spx/.gmx)
if d.Recv == nil {
if recv := d.Recv; recv == nil || len(recv.List) == 0 {
d.Recv = ctx.classRecv
d.IsClass = true
}
}
name := d.Name
fname := name.Name
if d.Recv == nil {
name := d.Name
fn := func() {
old, _ := p.SetCurFile(goFile, true)
defer p.RestoreCurFile(old)
loadFunc(ctx, nil, d, genFnBody)
loadFunc(ctx, nil, fname, d, genFnBody)
}
fname := name.Name
if fname == "init" {
if genFnBody {
if debugLoad {
Expand All @@ -918,18 +918,30 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge
}
}
}
} else {
if name, ok := getRecvTypeName(parent, d.Recv, true); ok {
} else if tname, ok := getRecvTypeName(parent, d.Recv, true); ok {
if d.Static {
if debugLoad {
log.Printf("==> Preload method %s.%s\n", name, d.Name.Name)
log.Printf("==> Preload static method %s.%s\n", tname, fname)
}
ld := getTypeLoader(parent, syms, token.NoPos, name)
fname = staticMethod(tname, fname)
fn := func() {
old, _ := p.SetCurFile(goFile, true)
defer p.RestoreCurFile(old)
loadFunc(ctx, nil, fname, d, genFnBody)
}
initLoader(parent, syms, name.Pos(), fname, fn, genFnBody)
ctx.lbinames = append(ctx.lbinames, fname)
} else {
if debugLoad {
log.Printf("==> Preload method %s.%s\n", tname, fname)
}
ld := getTypeLoader(parent, syms, token.NoPos, tname)
fn := func() {
old, _ := p.SetCurFile(goFile, true)
defer p.RestoreCurFile(old)
doInitType(ld)
recv := toRecv(ctx, d.Recv)
loadFunc(ctx, recv, d, genFnBody)
loadFunc(ctx, recv, fname, d, genFnBody)
}
ld.methods = append(ld.methods, fn)
}
Expand Down Expand Up @@ -1169,6 +1181,14 @@ func overloadName(recv *ast.Ident, name string, isOp bool) string {
return "Gopo" + sep + typ + name
}

func staticMethod(tname, name string) string {
sep := "_"
if strings.ContainsRune(name, '_') || strings.ContainsRune(tname, '_') {
sep = "__"
}
return "Gops" + sep + tname + sep + name
}

func stringLit(val string) *ast.BasicLit {
return &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(val)}
}
Expand All @@ -1186,8 +1206,7 @@ func aliasType(pkg *types.Package, pos token.Pos, name string, typ types.Type) {
pkg.Scope().Insert(o)
}

func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
name := d.Name.Name
func loadFunc(ctx *blockCtx, recv *types.Var, name string, d *ast.FuncDecl, genBody bool) {
if debugLoad {
if recv == nil {
log.Println("==> Load func", name)
Expand Down Expand Up @@ -1235,7 +1254,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
commentFunc(ctx, fn, d)
if rec := ctx.recorder(); rec != nil {
rec.Def(d.Name, fn.Func)
if recv == nil && d.Name.Name != "_" {
if recv == nil && name != "_" {
ctx.fileScope.Insert(fn.Func)
}
}
Expand Down
24 changes: 24 additions & 0 deletions cl/compile_gop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1541,3 +1541,27 @@ func main() {
}
`)
}

func TestStaticMethod(t *testing.T) {
gopClTest(t, `
type foo int
func foo.New(a int) *foo {
return new(foo)
}
func foo._add() *foo {
return new(foo)
}
`, `package main
type foo int
func Gops_foo_New(a int) *foo {
return new(foo)
}
func Gops__foo___add() *foo {
return new(foo)
}
`)
}
10 changes: 6 additions & 4 deletions printer/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2015,13 +2015,15 @@ func (p *printer) funcDecl(d *ast.FuncDecl) {
// different line (all whitespace preceding the FUNC is emitted only when the
// FUNC is emitted).
startCol := p.out.Column - len("func ")
if d.Recv != nil && !d.IsClass {
if d.Recv != nil {
if d.Static { // static method
if list := d.Recv.List; len(list) > 0 {
p.expr(list[0].Type)
if !d.IsClass {
if list := d.Recv.List; len(list) > 0 {
p.expr(list[0].Type)
}
}
p.print(token.PERIOD)
} else {
} else if !d.IsClass {
p.parameters(d.Recv) // method: print receiver
p.print(blank)
}
Expand Down

0 comments on commit 570665d

Please sign in to comment.