From cccbfbbc00cfdcf17d0d4c62e99ddf3bd559737d Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 9 May 2019 08:52:35 -0400 Subject: [PATCH] Autorelease all objective-C objects constructed using "alloc". Clean up type-related comments in generated code. Do not use pointers to Go interfaces as receivers, use pointer to Id instead. --- examples/app/main.go | 22 ++++++++++--------- types/convert.go | 11 +++------- wrap/main.go | 51 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 26 deletions(-) diff --git a/examples/app/main.go b/examples/app/main.go index 404cedc..d21e5a8 100644 --- a/examples/app/main.go +++ b/examples/app/main.go @@ -18,31 +18,33 @@ func nsmgr() { 0, nil, ) - w.SetTitle(ns.NSStringWithGoString("Hi World")) + nst := ns.NSStringWithGoString + w.SetTitle(nst("Hi World")) w.MakeKeyAndOrderFront(w) w.SetAlphaValue(0.85) - m1 := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("Main")) + m1 := ns.NSMenuAlloc().InitWithTitle(nst("Main")) appItem := ns.NSMenuItemAlloc() fileItem := ns.NSMenuItemAlloc() m1.AddItem(appItem) m1.AddItem(fileItem) - appMenu := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("App")) - fileMenu := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("File")) + appMenu := ns.NSMenuAlloc().InitWithTitle(nst("App")) + fileMenu := ns.NSMenuAlloc().InitWithTitle(nst("File")) m1.SetSubmenu(appMenu, appItem) m1.SetSubmenu(fileMenu, fileItem) s := ns.NSStringWithGoString("") - appMenu.AddItemWithTitle(ns.NSStringWithGoString("About"), nil, s) - appMenu.AddItemWithTitle(ns.NSStringWithGoString("Preferences"), nil, s) - appMenu.AddItemWithTitle(ns.NSStringWithGoString("Quit"),ns.Selector("terminate:"), ns.NSStringWithGoString("q")) + appMenu.AddItemWithTitle(nst("About"), nil, s) + appMenu.AddItemWithTitle(nst("Preferences"), nil, s) + appMenu.AddItemWithTitle(nst("Quit"),ns.Selector("terminate:"), nst("q")) a.SetMainMenu(m1) - fileMenu.AddItemWithTitle(ns.NSStringWithGoString("Open"), nil, s) - fileMenu.AddItemWithTitle(ns.NSStringWithGoString("New"), nil, s) + fileMenu.AddItemWithTitle(nst("Open"), nil, s) + fileMenu.AddItemWithTitle(nst("New"), nil, s) a.SetMainMenu(m1) - b1 := ns.NSButtonWithTitle(ns.NSStringWithGoString("push"),s,nil) + b1 := ns.NSButtonWithTitle(nst("push"),s,nil) + b1.SetFrame(ns.NSMakeRect(0,550,100,50)) w.ContentView().AddSubview(&b1.NSView,ns.NSWindowAbove,nil) a.Run() } diff --git a/types/convert.go b/types/convert.go index 721c7bf..d8ec381 100644 --- a/types/convert.go +++ b/types/convert.go @@ -250,18 +250,15 @@ func (t *Type) GoTypeDecl() string { case "", "Void": return "" default: - extra := t.Node.CtypeSimplified() var cgt string if td := tp.Typedef(); td != nil { cgt = td.CGoType() - extra = "typedef " + td.Node.Ctype() } else { cgt = tp.CGoType() } return fmt.Sprintf(` -//%s (%s) type %s %s -`,t.Node.Ctype(),extra,gt,cgt) +`,gt,cgt) } } @@ -276,21 +273,19 @@ func (t *Type) GoInterfaceDecl() string { if super == "" { goInterfaces[gt] = true return fmt.Sprintf(` -//%s (%s) type %s interface { Ptr() unsafe.Pointer } -`,t.Node.Ctype(),t.BaseType().GoType(),gt) +`,gt) } if IsGoInterface(super) { super = "Id" } return fmt.Sprintf(` -//%s (%s) type %s struct { %s } func (o *%s) Ptr() unsafe.Pointer { return unsafe.Pointer(o) } func (o *Id) %s() *%s { return (*%s)(unsafe.Pointer(o)) } -`,t.Node.Ctype(),t.BaseType().GoType(),gt,super,gt,gt,gt,gt) +`,gt,super,gt,gt,gt,gt) } func (t *Type) IsFunctionPtr() bool { diff --git a/wrap/main.go b/wrap/main.go index 1f28975..dd41e1d 100644 --- a/wrap/main.go +++ b/wrap/main.go @@ -507,6 +507,9 @@ func (w *Wrapper) processType(tp *types.Type) { } if w.Processed[gt] { return } w.Processed[gt] = true + if gt == "NSObject" { + w.ObjectHelpers() + } if gt == "Char" { w.CharHelpers() } @@ -528,6 +531,27 @@ func (w *Wrapper) processType(tp *types.Type) { w.goTypes.WriteString(bt.GoTypeDecl()) } +func (w *Wrapper) ObjectHelpers() { + w.goHelpers.WriteString(` +func (o *Id) Release() { + C.release(unsafe.Pointer(o)) +} +func (o *Id) Autorelease() { + C.autorelease(unsafe.Pointer(o)) +} +`) + w.cCode.WriteString(` +void +release(void* obj) { + [(NSObject*)obj release]; +} +void +autorelease(void* obj) { + [(NSObject*)obj autorelease]; +} +`) +} + func (w *Wrapper) CharHelpers() { w.goHelpers.WriteString(` func CharWithGoString(s string) *Char { @@ -588,8 +612,14 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) { return } gname := strings.Title(m.Name) + receiver := "" switch { case !m.ClassMethod: + if types.IsGoInterface(m.GoClass) { + receiver = "(o *Id) " + } else { + receiver = "(o *" + m.GoClass + ") " + } case m.Type.GoType() != "*" + m.GoClass: gname = m.GoClass + gname default: @@ -606,10 +636,6 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) { gname = m.GoClass + gname[lens1-i:] } } - receiver := "" - if !m.ClassMethod { - receiver = "(o *" + m.GoClass + ") " - } cname := m.Name if m.Class != "" { cname = m.Class + "_" + cname @@ -642,9 +668,8 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) { gname = "Get" + gname } w.goCode.WriteString(fmt.Sprintf(` -//%s func %s%s(%s) %s { -`,m.Type.CType(),receiver,gname,gplist,grtype)) +`,receiver,gname,gplist,grtype)) lparm := len(tps)-1 if len(tps) > 0 && tps[lparm].Variadic { vn := ns[lparm] @@ -658,7 +683,7 @@ func %s%s(%s) %s { `,vn,w.VaArgs,vn,vn)) } w.goCode.WriteString(` ` + - types.GoToC(cname,ns,m.Type,tps) + "\n}\n\n") + types.GoToC(cname,ns,m.Type,tps) + "\n}\n") cret := "" if !m.isVoid() { @@ -787,12 +812,22 @@ func %sAlloc() *%s { } `,i.GoName,i.GoName,i.GoName,i.Name)) - w.cCode.WriteString(fmt.Sprintf(` + if i.Name != "NSAutoreleasePool" { + w.cCode.WriteString(fmt.Sprintf(` +void* +%sAlloc() { + return [[%s alloc] autorelease]; +} +`, i.Name, i.Name)) + } else { + //who autoreleases the autorelease pools? + w.cCode.WriteString(fmt.Sprintf(` void* %sAlloc() { return [%s alloc]; } `, i.Name, i.Name)) + } //FIXME: sort properties for _,p := range i.Properties {