Bug fixes and clean up how methods are added to an interface from
superclasses and protocols. Ensure that "Unavailable" attributes are handled properly.
This commit is contained in:
parent
9a4fabda24
commit
b0139b9aa8
|
@ -55,6 +55,8 @@ func discoverServices(p ns.CBPeripheral, e ns.NSError) {
|
||||||
case serv.UUID().IsEqualTo(ns.CBUUIDWithGoString("180A")):
|
case serv.UUID().IsEqualTo(ns.CBUUIDWithGoString("180A")):
|
||||||
fmt.Printf("--device information service\n")
|
fmt.Printf("--device information service\n")
|
||||||
p.DiscoverCharacteristics(ns.NSArray{}, serv)
|
p.DiscoverCharacteristics(ns.NSArray{}, serv)
|
||||||
|
default:
|
||||||
|
fmt.Printf("--unknown service\n")
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
|
@ -38,4 +38,4 @@ delegates:
|
||||||
- peripheralDidUpdateValueForCharacteristic
|
- peripheralDidUpdateValueForCharacteristic
|
||||||
|
|
||||||
pragma: [ clang diagnostic ignored "-Wformat-security" ]
|
pragma: [ clang diagnostic ignored "-Wformat-security" ]
|
||||||
autorelease: true
|
gogc: true
|
||||||
|
|
|
@ -50,7 +50,7 @@ func memtest2() {
|
||||||
|
|
||||||
o2 := ns.NSStringWithGoString("two string") // does not leak
|
o2 := ns.NSStringWithGoString("two string") // does not leak
|
||||||
|
|
||||||
arr := ns.NSArrayWithObjects(o1,o2)
|
arr := ns.NSArrayAlloc().InitWithObjects(o1,o2)
|
||||||
_ = arr
|
_ = arr
|
||||||
|
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
|
|
192
wrap/main.go
192
wrap/main.go
|
@ -147,6 +147,7 @@ type Method struct {
|
||||||
Type *types.Type
|
Type *types.Type
|
||||||
ClassMethod bool
|
ClassMethod bool
|
||||||
Parameters []*Parameter
|
Parameters []*Parameter
|
||||||
|
Unavailable bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//Fully disambiguated method name (m.GoName + all parameter names)
|
//Fully disambiguated method name (m.GoName + all parameter names)
|
||||||
|
@ -360,6 +361,7 @@ func (w *Wrapper) AddInterface(n *ast.ObjCInterfaceDecl) {
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf("ast.ObjCInterfaceDecl: %s\n", n.Name)
|
fmt.Printf("ast.ObjCInterfaceDecl: %s\n", n.Name)
|
||||||
}
|
}
|
||||||
|
//fmt.Printf("AddInterface(%s)\n",n.Name)
|
||||||
w.addIntCat(n.Name, n.Children())
|
w.addIntCat(n.Name, n.Children())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +373,7 @@ func (w *Wrapper) AddCategory(n *ast.ObjCCategoryDecl) {
|
||||||
if len(ns) > 0 {
|
if len(ns) > 0 {
|
||||||
switch x := ns[0].(type) {
|
switch x := ns[0].(type) {
|
||||||
case *ast.ObjCInterface:
|
case *ast.ObjCInterface:
|
||||||
|
//fmt.Printf("AddCategory(%s) -> %s\n",n.Name, x.Name)
|
||||||
w.addIntCat(x.Name, ns[1:])
|
w.addIntCat(x.Name, ns[1:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -466,12 +469,13 @@ func (w *Wrapper) AddMethod(p *MethodCollection, x *ast.ObjCMethodDecl) {
|
||||||
Class: p.Class,
|
Class: p.Class,
|
||||||
GoClass: strings.Title(p.Class),
|
GoClass: strings.Title(p.Class),
|
||||||
ClassMethod: x.ClassMethod,
|
ClassMethod: x.ClassMethod,
|
||||||
|
Unavailable: false,
|
||||||
}
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf(" -- Method %s\n", m.Name)
|
fmt.Printf(" -- Method %s\n", m.Name)
|
||||||
}
|
}
|
||||||
var avail bool
|
var avail bool
|
||||||
m.Parameters, avail = w.GetParms(x, p.Class)
|
m.Parameters, avail, m.Unavailable = w.GetParms(x, p.Class)
|
||||||
if avail {
|
if avail {
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf("%s: Adding %s (%d)\n", p.Class, m.Name, len(m.Parameters))
|
fmt.Printf("%s: Adding %s (%d)\n", p.Class, m.Name, len(m.Parameters))
|
||||||
|
@ -556,18 +560,6 @@ func (w *Wrapper) addIntCat(name string, ns []ast.Node) {
|
||||||
i.ClassMethods = NewMethodCollection(name)
|
i.ClassMethods = NewMethodCollection(name)
|
||||||
i.Protocols = []string{}
|
i.Protocols = []string{}
|
||||||
i.ProcessedInstanceMethods = map[string]bool{}
|
i.ProcessedInstanceMethods = map[string]bool{}
|
||||||
/*
|
|
||||||
m := &Method{
|
|
||||||
Name: "class",
|
|
||||||
GoName: "Class",
|
|
||||||
Class: i.Name,
|
|
||||||
GoClass: i.Name,
|
|
||||||
Type: types.NewTypeFromString("Class",i.Name),
|
|
||||||
ClassMethod: true,
|
|
||||||
Parameters: []*Parameter{},
|
|
||||||
}
|
|
||||||
i.ClassMethods.Methods = []*Method{m}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
avail := (*Avail)(&[]AvailAttr{})
|
avail := (*Avail)(&[]AvailAttr{})
|
||||||
mcc := NewMethodCollection(name)
|
mcc := NewMethodCollection(name)
|
||||||
|
@ -641,52 +633,13 @@ func (w *Wrapper) addIntCat(name string, ns []ast.Node) {
|
||||||
i.InstanceMethods.Methods = append(i.InstanceMethods.Methods, mci.Methods...)
|
i.InstanceMethods.Methods = append(i.InstanceMethods.Methods, mci.Methods...)
|
||||||
i.Protocols = append(i.Protocols, prots...)
|
i.Protocols = append(i.Protocols, prots...)
|
||||||
|
|
||||||
//Add class methods from super class
|
|
||||||
var supmethods func(*Interface, string)
|
|
||||||
supmethods = func(i *Interface, s string) {
|
|
||||||
if sup, ok := w.Interfaces[s]; !ok {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
//depth first
|
|
||||||
supmethods(i, types.Super(s))
|
|
||||||
for _, m := range sup.ClassMethods.Methods {
|
|
||||||
m2 := &Method{
|
|
||||||
Name: m.Name,
|
|
||||||
GoName: m.GoName,
|
|
||||||
Class: i.Name,
|
|
||||||
GoClass: i.GoName,
|
|
||||||
Type: m.Type.CloneToClass(i.Name),
|
|
||||||
ClassMethod: true,
|
|
||||||
Parameters: []*Parameter{},
|
|
||||||
}
|
|
||||||
for _, p := range m.Parameters {
|
|
||||||
p2 := &Parameter{
|
|
||||||
Pname: p.Pname,
|
|
||||||
Vname: p.Vname,
|
|
||||||
Type: p.Type.CloneToClass(i.Name),
|
|
||||||
}
|
|
||||||
m2.Parameters = append(m2.Parameters, p2)
|
|
||||||
}
|
|
||||||
found := false
|
|
||||||
longname := m2.LongName()
|
|
||||||
for n, x := range i.ClassMethods.Methods {
|
|
||||||
if x.LongName() == longname {
|
|
||||||
i.ClassMethods.Methods[n] = m2
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
i.ClassMethods.Methods = append(i.ClassMethods.Methods, m2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
supmethods(i, types.Super(i.Name))
|
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Println("Add interface ", i.Name)
|
fmt.Println("Add interface ", i.Name)
|
||||||
}
|
}
|
||||||
|
//fmt.Printf("Interface = %s %d class methods, %d instance methods\n", i.Name, len(i.ClassMethods.Methods), len(i.InstanceMethods.Methods))
|
||||||
Disambiguate(i.ClassMethods)
|
Disambiguate(i.ClassMethods)
|
||||||
Disambiguate(i.InstanceMethods)
|
Disambiguate(i.InstanceMethods)
|
||||||
|
//fmt.Printf("Interface = %s (disambiguated) %d class methods, %d instance methods\n", i.Name, len(i.ClassMethods.Methods), len(i.InstanceMethods.Methods))
|
||||||
w.Interfaces[i.Name] = i
|
w.Interfaces[i.Name] = i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,8 +688,9 @@ func (a *Avail) Available() bool {
|
||||||
//GetParms returns the parameters of a method declaration and a bool
|
//GetParms returns the parameters of a method declaration and a bool
|
||||||
//indicating whether the given method is available on MacOS and not
|
//indicating whether the given method is available on MacOS and not
|
||||||
//deprecated.
|
//deprecated.
|
||||||
func (w *Wrapper) GetParms(n ast.Node, class string) ([]*Parameter, bool) {
|
func (w *Wrapper) GetParms(n ast.Node, class string) ([]*Parameter, bool, bool) {
|
||||||
ret := make([]*Parameter, 0)
|
ret := make([]*Parameter, 0)
|
||||||
|
unavail := false
|
||||||
avail := (*Avail)(&[]AvailAttr{})
|
avail := (*Avail)(&[]AvailAttr{})
|
||||||
var parms []string
|
var parms []string
|
||||||
switch x := n.(type) {
|
switch x := n.(type) {
|
||||||
|
@ -768,7 +722,9 @@ func (w *Wrapper) GetParms(n ast.Node, class string) ([]*Parameter, bool) {
|
||||||
p.Type.Variadic = true
|
p.Type.Variadic = true
|
||||||
ret = append(ret, p)
|
ret = append(ret, p)
|
||||||
j++
|
j++
|
||||||
case *ast.AvailabilityAttr, *ast.UnavailableAttr, *ast.DeprecatedAttr:
|
case *ast.UnavailableAttr:
|
||||||
|
unavail = true
|
||||||
|
case *ast.AvailabilityAttr, *ast.DeprecatedAttr:
|
||||||
avail.Add(x)
|
avail.Add(x)
|
||||||
case *ast.Unknown:
|
case *ast.Unknown:
|
||||||
if Debug {
|
if Debug {
|
||||||
|
@ -778,9 +734,9 @@ func (w *Wrapper) GetParms(n ast.Node, class string) ([]*Parameter, bool) {
|
||||||
}
|
}
|
||||||
// check that the method is available for this OS and not deprecated
|
// check that the method is available for this OS and not deprecated
|
||||||
if !avail.Available() {
|
if !avail.Available() {
|
||||||
return nil, false
|
return nil, false, unavail
|
||||||
}
|
}
|
||||||
return ret, true
|
return ret, true, unavail
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Wrapper) AddTypedef(n, t string) {
|
func (w *Wrapper) AddTypedef(n, t string) {
|
||||||
|
@ -888,20 +844,7 @@ func (e NSEnumerator) ForIn(f func(Id) bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Wrapper) AutoreleaseHelpers() {
|
func (w *Wrapper) AutoreleaseHelpers() {
|
||||||
//not sure why this is not coming up automatically...
|
|
||||||
w.cCode.WriteString(`
|
|
||||||
void* _Nonnull
|
|
||||||
NSAutoreleasePool_init(void* o) {
|
|
||||||
return [(NSAutoreleasePool*)o init];
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
w.goHelpers.WriteString(`
|
w.goHelpers.WriteString(`
|
||||||
func (o NSAutoreleasePool) Init() NSAutoreleasePool {
|
|
||||||
ret := NSAutoreleasePool{}
|
|
||||||
ret.ptr = C.NSAutoreleasePool_init(o.Ptr())
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func Autoreleasepool(f func()) {
|
func Autoreleasepool(f func()) {
|
||||||
pool := NSAutoreleasePoolAlloc().Init()
|
pool := NSAutoreleasePoolAlloc().Init()
|
||||||
f()
|
f()
|
||||||
|
@ -960,6 +903,9 @@ func (w *Wrapper) _processMethod(m *Method, fun bool) {
|
||||||
if m.HasUnsupportedType() {
|
if m.HasUnsupportedType() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if m.Unavailable {
|
||||||
|
return
|
||||||
|
}
|
||||||
w.processType(m.Type)
|
w.processType(m.Type)
|
||||||
gname := m.GoName
|
gname := m.GoName
|
||||||
gname = strings.ReplaceAll(gname, "_", " ")
|
gname = strings.ReplaceAll(gname, "_", " ")
|
||||||
|
@ -1809,6 +1755,74 @@ func (o %s) Super%s(%s) %s {
|
||||||
w.goExports.WriteString(goexports.String())
|
w.goExports.WriteString(goexports.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Add class and instance methods from super class
|
||||||
|
func (w *Wrapper) AddSupermethods(i *Interface) {
|
||||||
|
var supmethods func(string)
|
||||||
|
procsups := func(mc, smc *MethodCollection) {
|
||||||
|
for _, m := range smc.Methods {
|
||||||
|
m2 := &Method{
|
||||||
|
Name: m.Name,
|
||||||
|
GoName: m.GoName,
|
||||||
|
Class: i.Name,
|
||||||
|
GoClass: i.GoName,
|
||||||
|
Type: m.Type.CloneToClass(i.Name),
|
||||||
|
ClassMethod: m.ClassMethod,
|
||||||
|
Parameters: []*Parameter{},
|
||||||
|
Unavailable: m.Unavailable,
|
||||||
|
}
|
||||||
|
for _, p := range m.Parameters {
|
||||||
|
p2 := &Parameter{
|
||||||
|
Pname: p.Pname,
|
||||||
|
Vname: p.Vname,
|
||||||
|
Type: p.Type.CloneToClass(i.Name),
|
||||||
|
}
|
||||||
|
m2.Parameters = append(m2.Parameters, p2)
|
||||||
|
}
|
||||||
|
mc.Methods = append(mc.Methods, m2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
supmethods = func(s string) {
|
||||||
|
if sup, ok := w.Interfaces[s]; !ok {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
procsups(i.ClassMethods, sup.ClassMethods)
|
||||||
|
procsups(i.InstanceMethods, sup.InstanceMethods)
|
||||||
|
// depth last
|
||||||
|
supmethods(types.Super(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
supmethods(types.Super(i.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add methods from a Protocol
|
||||||
|
func (w *Wrapper) AddProtocolMethods(i *Interface, p *Protocol) {
|
||||||
|
procmeths := func(mc, pmc *MethodCollection) {
|
||||||
|
for _, m := range pmc.Methods {
|
||||||
|
m2 := &Method{
|
||||||
|
Name: m.Name,
|
||||||
|
GoName: m.GoName,
|
||||||
|
Class: i.Name,
|
||||||
|
GoClass: i.GoName,
|
||||||
|
Type: m.Type.CloneToClass(i.Name),
|
||||||
|
ClassMethod: m.ClassMethod,
|
||||||
|
Parameters: []*Parameter{},
|
||||||
|
Unavailable: m.Unavailable,
|
||||||
|
}
|
||||||
|
for _, p := range m.Parameters {
|
||||||
|
p2 := &Parameter{
|
||||||
|
Pname: p.Pname,
|
||||||
|
Vname: p.Vname,
|
||||||
|
Type: p.Type.CloneToClass(i.Name),
|
||||||
|
}
|
||||||
|
m2.Parameters = append(m2.Parameters,p2)
|
||||||
|
}
|
||||||
|
mc.Methods = append(mc.Methods, m2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
procmeths(i.ClassMethods, p.ClassMethods)
|
||||||
|
procmeths(i.InstanceMethods, p.InstanceMethods)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Wrapper) Wrap(toproc []string) {
|
func (w *Wrapper) Wrap(toproc []string) {
|
||||||
if w.Package == "" {
|
if w.Package == "" {
|
||||||
w.Package = "ns"
|
w.Package = "ns"
|
||||||
|
@ -1847,13 +1861,7 @@ func (w *Wrapper) Wrap(toproc []string) {
|
||||||
if i.Name == "NSEnumerator" {
|
if i.Name == "NSEnumerator" {
|
||||||
w.EnumeratorHelpers()
|
w.EnumeratorHelpers()
|
||||||
}
|
}
|
||||||
/*gname := i.GoName
|
w.AddSupermethods(i)
|
||||||
if types.IsGoInterface(i.GoName) {
|
|
||||||
gname = "Id"
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
fmt.Printf("Interface %s: %d properties, %d class methods, %d instance methods\n",
|
|
||||||
i.Name, len(i.Properties), len(i.ClassMethods.Methods), len(i.InstanceMethods.Methods))
|
|
||||||
|
|
||||||
//FIXME: sort properties
|
//FIXME: sort properties
|
||||||
for _, p := range i.Properties {
|
for _, p := range i.Properties {
|
||||||
|
@ -1863,12 +1871,6 @@ func (w *Wrapper) Wrap(toproc []string) {
|
||||||
fmt.Printf(" property: %s (%s)\n", p.Name, p.Type.CType())
|
fmt.Printf(" property: %s (%s)\n", p.Name, p.Type.CType())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, m := range i.ClassMethods.Methods {
|
|
||||||
w.ProcessMethod(m)
|
|
||||||
}
|
|
||||||
for _, m := range i.InstanceMethods.Methods {
|
|
||||||
w.ProcessMethod(m)
|
|
||||||
}
|
|
||||||
// add methods for Protocols that this interface implements
|
// add methods for Protocols that this interface implements
|
||||||
for _, p := range i.Protocols {
|
for _, p := range i.Protocols {
|
||||||
prot, ok := w.Protocols[p]
|
prot, ok := w.Protocols[p]
|
||||||
|
@ -1876,12 +1878,22 @@ func (w *Wrapper) Wrap(toproc []string) {
|
||||||
fmt.Printf("Failed to find protocol %s for interface %s\n", p, i.Name)
|
fmt.Printf("Failed to find protocol %s for interface %s\n", p, i.Name)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
for _, m := range prot.ClassMethods.Methods {
|
w.AddProtocolMethods(i,prot)
|
||||||
w.ProcessMethodForClass(m, i.Name)
|
// for _, m := range prot.ClassMethods.Methods {
|
||||||
}
|
// w.ProcessMethodForClass(m, i.Name)
|
||||||
for _, m := range prot.InstanceMethods.Methods {
|
// }
|
||||||
w.ProcessMethodForClass(m, i.Name)
|
// for _, m := range prot.InstanceMethods.Methods {
|
||||||
}
|
// w.ProcessMethodForClass(m, i.Name)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
Disambiguate(i.ClassMethods)
|
||||||
|
Disambiguate(i.InstanceMethods)
|
||||||
|
fmt.Printf("Interface %s: %d properties, %d class methods, %d instance methods\n", i.Name, len(i.Properties), len(i.ClassMethods.Methods), len(i.InstanceMethods.Methods))
|
||||||
|
for _, m := range i.ClassMethods.Methods {
|
||||||
|
w.ProcessMethod(m)
|
||||||
|
}
|
||||||
|
for _, m := range i.InstanceMethods.Methods {
|
||||||
|
w.ProcessMethod(m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, m := range w.Functions {
|
for _, m := range w.Functions {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user