Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

define static method #1850

Merged
merged 1 commit into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading