Add constants for C enum types. Add NSEnumerator helper. Fix
bugs in Go class names. Add "Frameworks" option to nswrap.toml. Improve handling of ast.EnumDecl and ast.EnumConstantDecl.
This commit is contained in:
parent
9b71889a69
commit
758ea40679
|
@ -1,5 +1,9 @@
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// EnumConstantDecl is node represents a enum constant declaration.
|
// EnumConstantDecl is node represents a enum constant declaration.
|
||||||
type EnumConstantDecl struct {
|
type EnumConstantDecl struct {
|
||||||
Addr Address
|
Addr Address
|
||||||
|
@ -8,6 +12,7 @@ type EnumConstantDecl struct {
|
||||||
Referenced bool
|
Referenced bool
|
||||||
Name string
|
Name string
|
||||||
Type string
|
Type string
|
||||||
|
Type2 string
|
||||||
ChildNodes []Node
|
ChildNodes []Node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,18 +21,25 @@ func parseEnumConstantDecl(line string) *EnumConstantDecl {
|
||||||
`<(?P<position>.*)>
|
`<(?P<position>.*)>
|
||||||
( (?P<position2>[^ ]+))?
|
( (?P<position2>[^ ]+))?
|
||||||
( (?P<referenced>referenced))?
|
( (?P<referenced>referenced))?
|
||||||
(?P<name>.+)
|
(?P<name> \w+)
|
||||||
'(?P<type>.+?)'`,
|
(?P<type> '.*?')?
|
||||||
|
(?P<type2>:'.*?')?`,
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type2 := groups["type2"]
|
||||||
|
if type2 != "" {
|
||||||
|
type2 = type2[2 : len(type2)-1]
|
||||||
|
}
|
||||||
|
|
||||||
return &EnumConstantDecl{
|
return &EnumConstantDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: groups["position2"],
|
Position2: groups["position2"],
|
||||||
Referenced: len(groups["referenced"]) > 0,
|
Referenced: len(groups["referenced"]) > 0,
|
||||||
Name: groups["name"],
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
Type: groups["type"],
|
Type: removeQuotes(groups["type"]),
|
||||||
|
Type2: type2,
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,20 +10,34 @@ type EnumDecl struct {
|
||||||
Pos Position
|
Pos Position
|
||||||
Position2 string
|
Position2 string
|
||||||
Name string
|
Name string
|
||||||
|
Type string
|
||||||
|
Type2 string
|
||||||
ChildNodes []Node
|
ChildNodes []Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseEnumDecl(line string) *EnumDecl {
|
func parseEnumDecl(line string) *EnumDecl {
|
||||||
groups := groupsFromRegex(
|
groups := groupsFromRegex(
|
||||||
`(?:prev (?P<prev>0x[0-9a-f]+) )?<(?P<position>.*)>(?P<position2> .+:\d+)?(?P<name>.*)`,
|
`(?:prev (?P<prev>0x[0-9a-f]+) )?
|
||||||
|
<(?P<position>.*)>
|
||||||
|
(?P<position2> .+:\d+)?
|
||||||
|
(?P<name> \w+)?
|
||||||
|
(?P<type> '.*?')?
|
||||||
|
(?P<type2>:'.*')?`,
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type2 := groups["type2"]
|
||||||
|
if type2 != "" {
|
||||||
|
type2 = type2[2 : len(type2)-1]
|
||||||
|
}
|
||||||
|
|
||||||
return &EnumDecl{
|
return &EnumDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: groups["position2"],
|
Position2: groups["position2"],
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
|
Type: removeQuotes(groups["type"]),
|
||||||
|
Type2: type2,
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,4 +27,8 @@ func main() {
|
||||||
fmt.Println("Length(a2) = ",a2.Count())
|
fmt.Println("Length(a2) = ",a2.Count())
|
||||||
i1 := a.ObjectAtIndex(1).NSString()
|
i1 := a.ObjectAtIndex(1).NSString()
|
||||||
fmt.Println(i1.UTF8String())
|
fmt.Println(i1.UTF8String())
|
||||||
|
a.ObjectEnumerator().ForIn(func(o *ns.Id) bool {
|
||||||
|
fmt.Println(o.NSString().UTF8String())
|
||||||
|
return true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@ Classes = [
|
||||||
Functions = [
|
Functions = [
|
||||||
"NSMakeRange",
|
"NSMakeRange",
|
||||||
]
|
]
|
||||||
|
Enums = [
|
||||||
|
"CF.*",
|
||||||
|
]
|
||||||
SysImports = [ "Foundation/Foundation.h" ]
|
SysImports = [ "Foundation/Foundation.h" ]
|
||||||
Pragma = [ 'clang diagnostic ignored "-Wformat-security"' ]
|
Pragma = [ 'clang diagnostic ignored "-Wformat-security"' ]
|
||||||
VaArgs = 32
|
VaArgs = 32
|
||||||
|
|
6
main.go
6
main.go
|
@ -21,6 +21,8 @@ type conf struct {
|
||||||
InputFiles []string
|
InputFiles []string
|
||||||
Classes []string
|
Classes []string
|
||||||
Functions []string
|
Functions []string
|
||||||
|
Enums []string
|
||||||
|
Frameworks []string
|
||||||
Imports []string
|
Imports []string
|
||||||
SysImports []string
|
SysImports []string
|
||||||
Pragma []string
|
Pragma []string
|
||||||
|
@ -177,9 +179,9 @@ func Start() (err error) {
|
||||||
|
|
||||||
// build tree
|
// build tree
|
||||||
tree := buildTree(nodes, 0)
|
tree := buildTree(nodes, 0)
|
||||||
//unit := tree[0]
|
|
||||||
w := wrap.NewWrapper(Debug)
|
w := wrap.NewWrapper(Debug)
|
||||||
w.Package = Config.Package
|
w.Package = Config.Package
|
||||||
|
w.Frameworks(Config.Frameworks)
|
||||||
w.Import(Config.Imports)
|
w.Import(Config.Imports)
|
||||||
w.SysImport(Config.SysImports)
|
w.SysImport(Config.SysImports)
|
||||||
w.Pragma(Config.Pragma)
|
w.Pragma(Config.Pragma)
|
||||||
|
@ -200,6 +202,8 @@ func Start() (err error) {
|
||||||
if matches(x.Name,Config.Functions) {
|
if matches(x.Name,Config.Functions) {
|
||||||
w.AddFunction(x)
|
w.AddFunction(x)
|
||||||
}
|
}
|
||||||
|
case *ast.EnumDecl:
|
||||||
|
w.AddEnum(x,Config.Enums)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,6 @@ func (t *Type) PointsTo() *Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Wrap(s string) {
|
func Wrap(s string) {
|
||||||
// it is the pointers to this type that get wrapped
|
|
||||||
wrapped[s] = true
|
wrapped[s] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,11 +269,13 @@ type %s %s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) GoInterfaceDecl() string {
|
func (t *Type) GoInterfaceDecl() string {
|
||||||
|
ct := t.CType()
|
||||||
gt := t.GoType()
|
gt := t.GoType()
|
||||||
if gt[0] == '*' {
|
if gt[0] == '*' {
|
||||||
gt = gt[1:] // dereference wrapped types
|
gt = gt[1:] // dereference wrapped types
|
||||||
|
ct = ct[:len(ct)-1]
|
||||||
}
|
}
|
||||||
super := Super(gt)
|
super := Super(ct)
|
||||||
if super == "" {
|
if super == "" {
|
||||||
goInterfaces[gt] = true
|
goInterfaces[gt] = true
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
|
|
217
wrap/main.go
217
wrap/main.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -19,9 +20,13 @@ type Wrapper struct {
|
||||||
Package string
|
Package string
|
||||||
Interfaces map[string]*Interface
|
Interfaces map[string]*Interface
|
||||||
Functions map[string]*Method
|
Functions map[string]*Method
|
||||||
|
NamedEnums map[string]*Enum
|
||||||
|
AnonEnums []*Enum
|
||||||
|
|
||||||
|
cgoFlags strings.Builder // put cGo directives here
|
||||||
cCode strings.Builder // put cGo code here
|
cCode strings.Builder // put cGo code here
|
||||||
goTypes strings.Builder // put Go type declarations here
|
goTypes strings.Builder // put Go type declarations here
|
||||||
|
goConst strings.Builder // put Go constants (from C enums) here
|
||||||
goCode strings.Builder // put Go code here
|
goCode strings.Builder // put Go code here
|
||||||
goHelpers strings.Builder // put Go helper functions here
|
goHelpers strings.Builder // put Go helper functions here
|
||||||
Processed map[string]bool
|
Processed map[string]bool
|
||||||
|
@ -34,13 +39,14 @@ func NewWrapper(debug bool) *Wrapper {
|
||||||
ret := &Wrapper{
|
ret := &Wrapper{
|
||||||
Interfaces: map[string]*Interface{},
|
Interfaces: map[string]*Interface{},
|
||||||
Functions: map[string]*Method{},
|
Functions: map[string]*Method{},
|
||||||
|
NamedEnums: map[string]*Enum{},
|
||||||
|
AnonEnums: []*Enum{},
|
||||||
Processed: map[string]bool{},
|
Processed: map[string]bool{},
|
||||||
VaArgs: 16,
|
VaArgs: 16,
|
||||||
}
|
}
|
||||||
ret.cCode.WriteString(`/*
|
ret.cgoFlags.WriteString(fmt.Sprintf(`/*
|
||||||
#cgo CFLAGS: -x objective-c
|
#cgo CFLAGS: -x objective-c
|
||||||
#cgo LDFLAGS: -framework Foundation
|
`))
|
||||||
`)
|
|
||||||
ret.goTypes.WriteString(`
|
ret.goTypes.WriteString(`
|
||||||
type Id struct { }
|
type Id struct { }
|
||||||
func (o *Id) Ptr() unsafe.Pointer { return unsafe.Pointer(o) }
|
func (o *Id) Ptr() unsafe.Pointer { return unsafe.Pointer(o) }
|
||||||
|
@ -48,11 +54,19 @@ func (o *Id) Ptr() unsafe.Pointer { return unsafe.Pointer(o) }
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Frameworks(ss []string) {
|
||||||
|
if len(ss) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _,s := range ss {
|
||||||
|
w.cCode.WriteString(fmt.Sprintf("#import <%s/%s.h>\n",s,s))
|
||||||
|
}
|
||||||
|
w.cgoFlags.WriteString("#cgo LDFLAGS: -framework " + strings.Join(ss," -framework "))
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Wrapper) Import(ss []string) {
|
func (w *Wrapper) Import(ss []string) {
|
||||||
for _,s := range ss {
|
for _,s := range ss {
|
||||||
w.cCode.WriteString(`
|
w.cCode.WriteString("\n#import \"" + s + "\"\n")
|
||||||
#import "` + s + `"
|
|
||||||
`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +78,7 @@ func (w *Wrapper) SysImport(ss []string) {
|
||||||
|
|
||||||
func (w *Wrapper) Pragma(ss []string) {
|
func (w *Wrapper) Pragma(ss []string) {
|
||||||
for _,s := range ss {
|
for _,s := range ss {
|
||||||
w.cCode.WriteString("\n#pragma " + s + "\n")
|
w.cgoFlags.WriteString("\n#pragma " + s + "\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,12 +93,18 @@ type Parameter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Method struct {
|
type Method struct {
|
||||||
Name, Class string
|
Name, Class, GoClass string
|
||||||
Type *types.Type
|
Type *types.Type
|
||||||
ClassMethod bool
|
ClassMethod bool
|
||||||
Parameters []*Parameter
|
Parameters []*Parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Enum struct {
|
||||||
|
Name string
|
||||||
|
Type *types.Type
|
||||||
|
Constants []string
|
||||||
|
}
|
||||||
|
|
||||||
//isVoid() returns true if the method has no return value.
|
//isVoid() returns true if the method has no return value.
|
||||||
func (m Method) isVoid() bool {
|
func (m Method) isVoid() bool {
|
||||||
return m.Type.CType() == "void"
|
return m.Type.CType() == "void"
|
||||||
|
@ -149,6 +169,7 @@ func (w Wrapper) objcparamlist(m *Method) string {
|
||||||
//also a C/Objective-C reserved word.
|
//also a C/Objective-C reserved word.
|
||||||
var goreserved map[string]bool = map[string]bool{
|
var goreserved map[string]bool = map[string]bool{
|
||||||
"range": true,
|
"range": true,
|
||||||
|
"type": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Wrapper) gpntp(m *Method) ([]string,[]*types.Type,string) {
|
func (w *Wrapper) gpntp(m *Method) ([]string,[]*types.Type,string) {
|
||||||
|
@ -187,7 +208,7 @@ func (w *Wrapper) gpntp(m *Method) ([]string,[]*types.Type,string) {
|
||||||
|
|
||||||
|
|
||||||
type Interface struct {
|
type Interface struct {
|
||||||
Name string
|
Name, GoName string
|
||||||
Properties map[string]*Property
|
Properties map[string]*Property
|
||||||
Methods map[string]*Method
|
Methods map[string]*Method
|
||||||
}
|
}
|
||||||
|
@ -247,18 +268,69 @@ func (w *Wrapper) AddFunction(n *ast.FunctionDecl) {
|
||||||
w.Functions[n.Name] = m
|
w.Functions[n.Name] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME: copied from nswrap/main.go, should put this in a utils package
|
||||||
|
func matches(x string, rs []string) bool {
|
||||||
|
for _,r := range rs {
|
||||||
|
if m,_ := regexp.MatchString("^" + r + "$",x); m {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) AddEnum(n *ast.EnumDecl,rs []string) {
|
||||||
|
if n.Name != "" && !matches(n.Name,rs) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//fmt.Printf("Adding enum: (%s) %s\n",n.Type,n.Name)
|
||||||
|
var tp *types.Type
|
||||||
|
a := (*Avail)(&[]AvailAttr{})
|
||||||
|
if n.Type == "" {
|
||||||
|
tp = nil
|
||||||
|
} else {
|
||||||
|
tp = types.NewTypeFromString(n.Type,"")
|
||||||
|
//fmt.Printf(" type: %s\n",tp.CType())
|
||||||
|
}
|
||||||
|
e := &Enum{
|
||||||
|
Name: n.Name, // NOTE: may be empty string
|
||||||
|
Type: tp,
|
||||||
|
Constants: []string{},
|
||||||
|
}
|
||||||
|
for _,c := range n.Children() {
|
||||||
|
switch x := c.(type) {
|
||||||
|
case *ast.AvailabilityAttr, *ast.UnavailableAttr:
|
||||||
|
a.Add(x)
|
||||||
|
case *ast.EnumConstantDecl:
|
||||||
|
//fmt.Printf("*ast.EnumConstantDecl: (%s) '%s': %s\n",n.Type,n.Name,x.Name)
|
||||||
|
if n.Name == "" && !matches(x.Name,rs) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
e.Constants = append(e.Constants,x.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if a.Available() && len(e.Constants) > 0 {
|
||||||
|
if e.Name == "" {
|
||||||
|
w.AnonEnums = append(w.AnonEnums,e)
|
||||||
|
} else {
|
||||||
|
w.NamedEnums[e.Name] = e
|
||||||
|
}
|
||||||
|
//fmt.Printf(" added\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Wrapper) add(name string, ns []ast.Node) {
|
func (w *Wrapper) add(name string, ns []ast.Node) {
|
||||||
var i *Interface
|
var i *Interface
|
||||||
var ok bool
|
var ok bool
|
||||||
|
goname := types.NewTypeFromString(name,name).GoType()
|
||||||
|
types.Wrap(goname)
|
||||||
if i,ok = w.Interfaces[name]; !ok {
|
if i,ok = w.Interfaces[name]; !ok {
|
||||||
i = &Interface{
|
i = &Interface{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
GoName: goname,
|
||||||
Properties: map[string]*Property{},
|
Properties: map[string]*Property{},
|
||||||
Methods: map[string]*Method{},
|
Methods: map[string]*Method{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tp := types.NewTypeFromString(name,name)
|
|
||||||
types.Wrap(tp.GoType())
|
|
||||||
var avail bool
|
var avail bool
|
||||||
for _,c := range ns {
|
for _,c := range ns {
|
||||||
switch x := c.(type) {
|
switch x := c.(type) {
|
||||||
|
@ -278,6 +350,7 @@ func (w *Wrapper) add(name string, ns []ast.Node) {
|
||||||
Name: x.Name,
|
Name: x.Name,
|
||||||
Type: types.NewTypeFromString(x.Type,name),
|
Type: types.NewTypeFromString(x.Type,name),
|
||||||
Class: name,
|
Class: name,
|
||||||
|
GoClass: goname,
|
||||||
ClassMethod: x.ClassMethod,
|
ClassMethod: x.ClassMethod,
|
||||||
}
|
}
|
||||||
//fmt.Println(m.Type.Node.String())
|
//fmt.Println(m.Type.Node.String())
|
||||||
|
@ -314,6 +387,7 @@ func (w *Wrapper) add(name string, ns []ast.Node) {
|
||||||
m2 := &Method{
|
m2 := &Method{
|
||||||
Name: m.Name,
|
Name: m.Name,
|
||||||
Class: i.Name,
|
Class: i.Name,
|
||||||
|
GoClass: i.GoName,
|
||||||
Type: m.Type.CloneToClass(i.Name),
|
Type: m.Type.CloneToClass(i.Name),
|
||||||
ClassMethod: true,
|
ClassMethod: true,
|
||||||
Parameters: []*Parameter{},
|
Parameters: []*Parameter{},
|
||||||
|
@ -341,12 +415,40 @@ type AvailAttr struct {
|
||||||
Deprecated bool
|
Deprecated bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Avail []AvailAttr
|
||||||
|
|
||||||
|
func (a *Avail) Add(n ast.Node) {
|
||||||
|
switch x := n.(type) {
|
||||||
|
case *ast.AvailabilityAttr:
|
||||||
|
*a = append(*a, AvailAttr{
|
||||||
|
OS: x.OS,
|
||||||
|
Version: x.Version,
|
||||||
|
Deprecated: (x.Unknown1 != "0") || x.IsUnavailable,
|
||||||
|
})
|
||||||
|
case *ast.UnavailableAttr:
|
||||||
|
*a = append(*a, AvailAttr{
|
||||||
|
OS: "macos", Deprecated: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Avail) Available() bool {
|
||||||
|
if len(*a) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _,x := range *a {
|
||||||
|
if x.OS == "macos" && x.Deprecated == false {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
//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) {
|
||||||
ret := make([]*Parameter,0)
|
ret := make([]*Parameter,0)
|
||||||
avail := make([]AvailAttr,0)
|
avail := (*Avail)(&[]AvailAttr{})
|
||||||
var parms []string
|
var parms []string
|
||||||
switch x := n.(type) {
|
switch x := n.(type) {
|
||||||
case *ast.ObjCMethodDecl:
|
case *ast.ObjCMethodDecl:
|
||||||
|
@ -370,34 +472,14 @@ func (w *Wrapper) GetParms(n ast.Node,class string) ([]*Parameter,bool) {
|
||||||
j++
|
j++
|
||||||
case *ast.Variadic:
|
case *ast.Variadic:
|
||||||
ret[j-1].Type.Variadic = true
|
ret[j-1].Type.Variadic = true
|
||||||
case *ast.AvailabilityAttr:
|
case *ast.AvailabilityAttr, *ast.UnavailableAttr:
|
||||||
avail = append(avail,
|
avail.Add(x)
|
||||||
AvailAttr{
|
|
||||||
OS: x.OS,
|
|
||||||
Version: x.Version,
|
|
||||||
Deprecated: x.Unknown1 != "0",
|
|
||||||
})
|
|
||||||
//fmt.Println("AvailAttr ",avail,x)
|
|
||||||
case *ast.UnavailableAttr:
|
|
||||||
avail = append(avail,
|
|
||||||
AvailAttr{ OS: "macos", Deprecated: true })
|
|
||||||
case *ast.Unknown:
|
case *ast.Unknown:
|
||||||
if Debug { fmt.Printf("GetParms(): ast.Unknown: %s\n",x.Name) }
|
if Debug { fmt.Printf("GetParms(): ast.Unknown: %s\n",x.Name) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check that the method is available for this OS and not deprecated
|
// check that the method is available for this OS and not deprecated
|
||||||
a := func() bool {
|
if !avail.Available() {
|
||||||
if len(avail) == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _,x := range avail {
|
|
||||||
if x.OS == "macos" && x.Deprecated == false {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}()
|
|
||||||
if !a {
|
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
// check that we found the right number of parameters
|
// check that we found the right number of parameters
|
||||||
|
@ -436,13 +518,17 @@ func (w *Wrapper) processType(tp *types.Type) {
|
||||||
if gt == "Char" {
|
if gt == "Char" {
|
||||||
w.CharHelpers()
|
w.CharHelpers()
|
||||||
}
|
}
|
||||||
|
if gt == "NSEnumerator" {
|
||||||
|
w.EnumeratorHelpers()
|
||||||
|
}
|
||||||
if bt.IsFunction() {
|
if bt.IsFunction() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
super := types.Super(gt)
|
super := types.Super(gt)
|
||||||
if super != "" {
|
if super != "" {
|
||||||
types.Wrap(super)
|
tp := types.NewTypeFromString(super,"")
|
||||||
w.processType(types.NewTypeFromString(super,""))
|
types.Wrap(tp.GoType())
|
||||||
|
w.processType(tp)
|
||||||
}
|
}
|
||||||
w.goTypes.WriteString(bt.GoTypeDecl())
|
w.goTypes.WriteString(bt.GoTypeDecl())
|
||||||
}
|
}
|
||||||
|
@ -463,6 +549,15 @@ func (c *Char) String() string {
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) EnumeratorHelpers() {
|
||||||
|
w.goHelpers.WriteString(`
|
||||||
|
func (e *NSEnumerator) ForIn(f func(*Id) bool) {
|
||||||
|
for o := e.NextObject(); o != nil; o = e.NextObject() {
|
||||||
|
if !f(o) { break }
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Wrapper) ProcessMethod(m *Method) {
|
func (w *Wrapper) ProcessMethod(m *Method) {
|
||||||
w._processMethod(m,false)
|
w._processMethod(m,false)
|
||||||
}
|
}
|
||||||
|
@ -481,9 +576,9 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) {
|
||||||
gname := strings.Title(m.Name)
|
gname := strings.Title(m.Name)
|
||||||
switch {
|
switch {
|
||||||
case !m.ClassMethod:
|
case !m.ClassMethod:
|
||||||
gname = "(o *" + m.Class + ") " + gname
|
gname = "(o *" + m.GoClass + ") " + gname
|
||||||
case m.Type.GoType() != "*" + m.Class:
|
case m.Type.GoType() != "*" + m.GoClass:
|
||||||
gname = m.Class + gname
|
gname = m.GoClass + gname
|
||||||
default:
|
default:
|
||||||
lens1 := len(m.Class)
|
lens1 := len(m.Class)
|
||||||
i := 0
|
i := 0
|
||||||
|
@ -492,9 +587,9 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) {
|
||||||
if m.Class[i:] == gname[:lens1 - i] { break }
|
if m.Class[i:] == gname[:lens1 - i] { break }
|
||||||
}
|
}
|
||||||
if lens1 - i >= len(gname) {
|
if lens1 - i >= len(gname) {
|
||||||
gname = m.Class + gname
|
gname = m.GoClass + gname
|
||||||
} else {
|
} else {
|
||||||
gname = m.Class + gname[lens1-i:]
|
gname = m.GoClass + gname[lens1-i:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cname := m.Name
|
cname := m.Name
|
||||||
|
@ -511,6 +606,9 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) {
|
||||||
if types.IsGoInterface(grtype) {
|
if types.IsGoInterface(grtype) {
|
||||||
grtype = "*Id"
|
grtype = "*Id"
|
||||||
}
|
}
|
||||||
|
if gname == grtype { // avoid name conflicts between methods and types
|
||||||
|
gname = "Get" + gname
|
||||||
|
}
|
||||||
w.goCode.WriteString(fmt.Sprintf(`
|
w.goCode.WriteString(fmt.Sprintf(`
|
||||||
//%s
|
//%s
|
||||||
func %s(%s) %s {
|
func %s(%s) %s {
|
||||||
|
@ -538,7 +636,7 @@ func %s(%s) %s {
|
||||||
if m.ClassMethod {
|
if m.ClassMethod {
|
||||||
cobj = m.Class
|
cobj = m.Class
|
||||||
} else {
|
} else {
|
||||||
cobj = "(id)o"
|
cobj = "(" + m.Class + "*)o"
|
||||||
}
|
}
|
||||||
cns,cntps := w.cparamlist(m)
|
cns,cntps := w.cparamlist(m)
|
||||||
_ = cns
|
_ = cns
|
||||||
|
@ -563,6 +661,25 @@ func %s(%s) %s {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) ProcessEnum(e *Enum) {
|
||||||
|
gtp := ""
|
||||||
|
if e.Type != nil {
|
||||||
|
gtp = e.Type.GoType()
|
||||||
|
if !w.Processed[gtp] {
|
||||||
|
w.goTypes.WriteString(fmt.Sprintf(`
|
||||||
|
type %s C.%s
|
||||||
|
`,gtp,e.Type.CType()))
|
||||||
|
w.Processed[gtp] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gtp = gtp + " "
|
||||||
|
for _,c := range e.Constants {
|
||||||
|
w.goConst.WriteString(fmt.Sprintf(`
|
||||||
|
const %s %s= C.%s
|
||||||
|
`,c,gtp,c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Wrapper) Wrap(toproc []string) {
|
func (w *Wrapper) Wrap(toproc []string) {
|
||||||
if w.Package == "" { w.Package = "ns" }
|
if w.Package == "" { w.Package = "ns" }
|
||||||
err := os.MkdirAll(w.Package,0755)
|
err := os.MkdirAll(w.Package,0755)
|
||||||
|
@ -582,6 +699,9 @@ func (w *Wrapper) Wrap(toproc []string) {
|
||||||
}
|
}
|
||||||
//FIXME: sort pInterfaces
|
//FIXME: sort pInterfaces
|
||||||
for _,i := range pInterfaces {
|
for _,i := range pInterfaces {
|
||||||
|
if i == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
fmt.Printf("Interface %s: %d properties, %d methods\n",
|
fmt.Printf("Interface %s: %d properties, %d methods\n",
|
||||||
i.Name, len(i.Properties), len(i.Methods))
|
i.Name, len(i.Properties), len(i.Methods))
|
||||||
|
|
||||||
|
@ -589,7 +709,7 @@ func (w *Wrapper) Wrap(toproc []string) {
|
||||||
func New%s() *%s {
|
func New%s() *%s {
|
||||||
return (*%s)(unsafe.Pointer(C.New%s()))
|
return (*%s)(unsafe.Pointer(C.New%s()))
|
||||||
}
|
}
|
||||||
`,i.Name,i.Name,i.Name,i.Name))
|
`,i.GoName,i.GoName,i.GoName,i.Name))
|
||||||
|
|
||||||
w.cCode.WriteString(fmt.Sprintf(`
|
w.cCode.WriteString(fmt.Sprintf(`
|
||||||
%s*
|
%s*
|
||||||
|
@ -614,8 +734,16 @@ New%s() {
|
||||||
//fmt.Printf("Processing function %s %s\n",m.Type.CType(),m.Name)
|
//fmt.Printf("Processing function %s %s\n",m.Type.CType(),m.Name)
|
||||||
w.ProcessFunction(m)
|
w.ProcessFunction(m)
|
||||||
}
|
}
|
||||||
|
for _,e := range w.NamedEnums {
|
||||||
|
w.ProcessEnum(e)
|
||||||
|
}
|
||||||
|
for _,e := range w.AnonEnums {
|
||||||
|
w.ProcessEnum(e)
|
||||||
|
}
|
||||||
fmt.Printf("%d functions\n", len(w.Functions))
|
fmt.Printf("%d functions\n", len(w.Functions))
|
||||||
|
fmt.Printf("%d enums\n", len(w.NamedEnums) + len(w.AnonEnums))
|
||||||
of.WriteString("package " + w.Package + "\n\n")
|
of.WriteString("package " + w.Package + "\n\n")
|
||||||
|
of.WriteString(w.cgoFlags.String() + "\n")
|
||||||
of.WriteString(w.cCode.String())
|
of.WriteString(w.cCode.String())
|
||||||
of.WriteString(`
|
of.WriteString(`
|
||||||
*/
|
*/
|
||||||
|
@ -626,6 +754,7 @@ import (
|
||||||
)
|
)
|
||||||
`)
|
`)
|
||||||
of.WriteString(w.goTypes.String())
|
of.WriteString(w.goTypes.String())
|
||||||
|
of.WriteString(w.goConst.String())
|
||||||
of.WriteString(w.goHelpers.String())
|
of.WriteString(w.goHelpers.String())
|
||||||
of.WriteString(w.goCode.String())
|
of.WriteString(w.goCode.String())
|
||||||
of.Close()
|
of.Close()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user