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.
This commit is contained in:
Greg 2019-05-09 08:52:35 -04:00
parent ea34821fe6
commit cccbfbbc00
3 changed files with 58 additions and 26 deletions

View File

@ -18,31 +18,33 @@ func nsmgr() {
0, 0,
nil, nil,
) )
w.SetTitle(ns.NSStringWithGoString("Hi World")) nst := ns.NSStringWithGoString
w.SetTitle(nst("Hi World"))
w.MakeKeyAndOrderFront(w) w.MakeKeyAndOrderFront(w)
w.SetAlphaValue(0.85) w.SetAlphaValue(0.85)
m1 := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("Main")) m1 := ns.NSMenuAlloc().InitWithTitle(nst("Main"))
appItem := ns.NSMenuItemAlloc() appItem := ns.NSMenuItemAlloc()
fileItem := ns.NSMenuItemAlloc() fileItem := ns.NSMenuItemAlloc()
m1.AddItem(appItem) m1.AddItem(appItem)
m1.AddItem(fileItem) m1.AddItem(fileItem)
appMenu := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("App")) appMenu := ns.NSMenuAlloc().InitWithTitle(nst("App"))
fileMenu := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("File")) fileMenu := ns.NSMenuAlloc().InitWithTitle(nst("File"))
m1.SetSubmenu(appMenu, appItem) m1.SetSubmenu(appMenu, appItem)
m1.SetSubmenu(fileMenu, fileItem) m1.SetSubmenu(fileMenu, fileItem)
s := ns.NSStringWithGoString("") s := ns.NSStringWithGoString("")
appMenu.AddItemWithTitle(ns.NSStringWithGoString("About"), nil, s) appMenu.AddItemWithTitle(nst("About"), nil, s)
appMenu.AddItemWithTitle(ns.NSStringWithGoString("Preferences"), nil, s) appMenu.AddItemWithTitle(nst("Preferences"), nil, s)
appMenu.AddItemWithTitle(ns.NSStringWithGoString("Quit"),ns.Selector("terminate:"), ns.NSStringWithGoString("q")) appMenu.AddItemWithTitle(nst("Quit"),ns.Selector("terminate:"), nst("q"))
a.SetMainMenu(m1) a.SetMainMenu(m1)
fileMenu.AddItemWithTitle(ns.NSStringWithGoString("Open"), nil, s) fileMenu.AddItemWithTitle(nst("Open"), nil, s)
fileMenu.AddItemWithTitle(ns.NSStringWithGoString("New"), nil, s) fileMenu.AddItemWithTitle(nst("New"), nil, s)
a.SetMainMenu(m1) 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) w.ContentView().AddSubview(&b1.NSView,ns.NSWindowAbove,nil)
a.Run() a.Run()
} }

View File

@ -250,18 +250,15 @@ func (t *Type) GoTypeDecl() string {
case "", "Void": case "", "Void":
return "" return ""
default: default:
extra := t.Node.CtypeSimplified()
var cgt string var cgt string
if td := tp.Typedef(); td != nil { if td := tp.Typedef(); td != nil {
cgt = td.CGoType() cgt = td.CGoType()
extra = "typedef " + td.Node.Ctype()
} else { } else {
cgt = tp.CGoType() cgt = tp.CGoType()
} }
return fmt.Sprintf(` return fmt.Sprintf(`
//%s (%s)
type %s %s type %s %s
`,t.Node.Ctype(),extra,gt,cgt) `,gt,cgt)
} }
} }
@ -276,21 +273,19 @@ func (t *Type) GoInterfaceDecl() string {
if super == "" { if super == "" {
goInterfaces[gt] = true goInterfaces[gt] = true
return fmt.Sprintf(` return fmt.Sprintf(`
//%s (%s)
type %s interface { type %s interface {
Ptr() unsafe.Pointer Ptr() unsafe.Pointer
} }
`,t.Node.Ctype(),t.BaseType().GoType(),gt) `,gt)
} }
if IsGoInterface(super) { if IsGoInterface(super) {
super = "Id" super = "Id"
} }
return fmt.Sprintf(` return fmt.Sprintf(`
//%s (%s)
type %s struct { %s } type %s struct { %s }
func (o *%s) Ptr() unsafe.Pointer { return unsafe.Pointer(o) } func (o *%s) Ptr() unsafe.Pointer { return unsafe.Pointer(o) }
func (o *Id) %s() *%s { return (*%s)(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 { func (t *Type) IsFunctionPtr() bool {

View File

@ -507,6 +507,9 @@ func (w *Wrapper) processType(tp *types.Type) {
} }
if w.Processed[gt] { return } if w.Processed[gt] { return }
w.Processed[gt] = true w.Processed[gt] = true
if gt == "NSObject" {
w.ObjectHelpers()
}
if gt == "Char" { if gt == "Char" {
w.CharHelpers() w.CharHelpers()
} }
@ -528,6 +531,27 @@ func (w *Wrapper) processType(tp *types.Type) {
w.goTypes.WriteString(bt.GoTypeDecl()) 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() { func (w *Wrapper) CharHelpers() {
w.goHelpers.WriteString(` w.goHelpers.WriteString(`
func CharWithGoString(s string) *Char { func CharWithGoString(s string) *Char {
@ -588,8 +612,14 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) {
return return
} }
gname := strings.Title(m.Name) gname := strings.Title(m.Name)
receiver := ""
switch { switch {
case !m.ClassMethod: case !m.ClassMethod:
if types.IsGoInterface(m.GoClass) {
receiver = "(o *Id) "
} else {
receiver = "(o *" + m.GoClass + ") "
}
case m.Type.GoType() != "*" + m.GoClass: case m.Type.GoType() != "*" + m.GoClass:
gname = m.GoClass + gname gname = m.GoClass + gname
default: default:
@ -606,10 +636,6 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) {
gname = m.GoClass + gname[lens1-i:] gname = m.GoClass + gname[lens1-i:]
} }
} }
receiver := ""
if !m.ClassMethod {
receiver = "(o *" + m.GoClass + ") "
}
cname := m.Name cname := m.Name
if m.Class != "" { if m.Class != "" {
cname = m.Class + "_" + cname cname = m.Class + "_" + cname
@ -642,9 +668,8 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) {
gname = "Get" + gname gname = "Get" + gname
} }
w.goCode.WriteString(fmt.Sprintf(` w.goCode.WriteString(fmt.Sprintf(`
//%s
func %s%s(%s) %s { func %s%s(%s) %s {
`,m.Type.CType(),receiver,gname,gplist,grtype)) `,receiver,gname,gplist,grtype))
lparm := len(tps)-1 lparm := len(tps)-1
if len(tps) > 0 && tps[lparm].Variadic { if len(tps) > 0 && tps[lparm].Variadic {
vn := ns[lparm] vn := ns[lparm]
@ -658,7 +683,7 @@ func %s%s(%s) %s {
`,vn,w.VaArgs,vn,vn)) `,vn,w.VaArgs,vn,vn))
} }
w.goCode.WriteString(` ` + w.goCode.WriteString(` ` +
types.GoToC(cname,ns,m.Type,tps) + "\n}\n\n") types.GoToC(cname,ns,m.Type,tps) + "\n}\n")
cret := "" cret := ""
if !m.isVoid() { if !m.isVoid() {
@ -787,12 +812,22 @@ func %sAlloc() *%s {
} }
`,i.GoName,i.GoName,i.GoName,i.Name)) `,i.GoName,i.GoName,i.GoName,i.Name))
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(` w.cCode.WriteString(fmt.Sprintf(`
void* void*
%sAlloc() { %sAlloc() {
return [%s alloc]; return [%s alloc];
} }
`, i.Name, i.Name)) `, i.Name, i.Name))
}
//FIXME: sort properties //FIXME: sort properties
for _,p := range i.Properties { for _,p := range i.Properties {