Fixed type wrapping, further conversion to new type system. The
Go side looks pretty good at this point.
This commit is contained in:
parent
fb21881a8b
commit
e143dbb6a7
|
@ -5,8 +5,13 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
//super is a map recording which class is the parent of each other class
|
||||
var super map[string]string
|
||||
|
||||
//wrapped is a map recording whether a given GoType is to be "wrapped" in a
|
||||
//go struct.
|
||||
var wrapped map[string]bool
|
||||
|
||||
func Super(c string) string {
|
||||
if super == nil {
|
||||
super = make(map[string]string)
|
||||
|
@ -25,7 +30,6 @@ type Type struct {
|
|||
Node *Node
|
||||
Class string
|
||||
ctype string
|
||||
wrapped bool
|
||||
}
|
||||
|
||||
func NewType(n *Node, c string) *Type {
|
||||
|
@ -52,9 +56,12 @@ func (t *Type) String() string {
|
|||
return t.Node.String()
|
||||
}
|
||||
|
||||
func (t *Type) Wrap() *Type {
|
||||
t.wrapped = true
|
||||
return t
|
||||
func (t *Type) Wrap() {
|
||||
if wrapped == nil {
|
||||
wrapped = make(map[string]bool)
|
||||
}
|
||||
// it is the pointers to this type that get wrapped
|
||||
wrapped["*" + t.GoType()] = true
|
||||
}
|
||||
|
||||
func (t *Type) BaseType() *Type {
|
||||
|
@ -108,7 +115,8 @@ func (t *Type) CType() string {
|
|||
}
|
||||
|
||||
func (t *Type) GoTypeDecl() string {
|
||||
if t.wrapped {
|
||||
if wrapped[t.GoType()] {
|
||||
fmt.Printf("%s -> %s: %s is wrapped\n",t.GoType(),t.CGoType(),t.Class)
|
||||
return t.GoInterfaceDecl()
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
|
@ -138,7 +146,7 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
|||
var ret strings.Builder
|
||||
rt := rtype.CType()
|
||||
if rt != "void" {
|
||||
if rtype.wrapped {
|
||||
if wrapped[rtype.GoType()] {
|
||||
ret.WriteString(" ret := &" + rtype.GoType()[1:] + "{}\n")
|
||||
ret.WriteString(" ret.ptr = unsafe.Pointer(")
|
||||
} else {
|
||||
|
@ -153,7 +161,7 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
|||
for i := 0; i < len(pnames); i++ {
|
||||
pn,pt := pnames[i],ptypes[i]
|
||||
p := pn
|
||||
if pt.wrapped {
|
||||
if wrapped[pt.GoType()] {
|
||||
p = pn + ".ptr"
|
||||
} else {
|
||||
p = "(" + pt.CGoType() + ")(" + pn + ")"
|
||||
|
@ -163,7 +171,7 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
|||
ret.WriteString(strings.Join(parms,", "))
|
||||
ret.WriteString(")")
|
||||
if rt != "void" {
|
||||
if rtype.wrapped {
|
||||
if wrapped[rtype.GoType()] {
|
||||
ret.WriteString(`)
|
||||
return ret
|
||||
`)
|
||||
|
@ -172,6 +180,7 @@ return ret
|
|||
if rtype.Node.IsPointer() {
|
||||
ret.WriteString(")")
|
||||
}
|
||||
ret.WriteString("\n")
|
||||
}
|
||||
}
|
||||
return ret.String()
|
||||
|
|
|
@ -119,6 +119,13 @@ func (n *Node) IsStruct() bool {
|
|||
return n.Children[0].Kind == "Struct"
|
||||
}
|
||||
|
||||
func (n *Node) IsFunction() bool {
|
||||
if n == nil || len(n.Children) < 1 {
|
||||
return false
|
||||
}
|
||||
return n.Children[len(n.Children)-1].Kind == "Function"
|
||||
}
|
||||
|
||||
//BaseType strips off all layers of pointer indirection
|
||||
func (n *Node) BaseType() *Node {
|
||||
if n == nil {
|
||||
|
|
111
wrap/main.go
111
wrap/main.go
|
@ -30,6 +30,7 @@ type Wrapper struct {
|
|||
goTypes strings.Builder // put Go type declarations here
|
||||
goCode strings.Builder // put Go code here
|
||||
Processed map[string]bool
|
||||
Processed2 map[string]bool
|
||||
}
|
||||
|
||||
var gobuiltinTypes map[string]bool = map[string]bool{
|
||||
|
@ -155,23 +156,6 @@ func (w *Wrapper) goType(t,class string) string {
|
|||
return ct
|
||||
}
|
||||
|
||||
//FIXME: to be deleted
|
||||
func cType(t, class string) string {
|
||||
n, err := types.Parse(t)
|
||||
if err != nil {
|
||||
//fmt.Printf("Cannot parse type %s\n",t)
|
||||
return "NOT IMPLEMENTED"
|
||||
}
|
||||
nt := n.CtypeSimplified()
|
||||
if nt == "id" {
|
||||
return "NSObject"
|
||||
}
|
||||
if nt == "instancetype" {
|
||||
return class + " *"
|
||||
}
|
||||
return nt
|
||||
}
|
||||
|
||||
func NewWrapper(debug bool) *Wrapper {
|
||||
Debug = debug
|
||||
if Debug { fmt.Println("// Debug mode") }
|
||||
|
@ -182,6 +166,7 @@ func NewWrapper(debug bool) *Wrapper {
|
|||
ctMap: map[string]*types.Node{},
|
||||
goStructTypes: map[string]cStruct{},
|
||||
Processed: map[string]bool{},
|
||||
Processed2: map[string]bool{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,6 +352,8 @@ func (w *Wrapper) add(name string, ns []ast.Node) {
|
|||
}
|
||||
w.AddType(name,name) // need this?
|
||||
}
|
||||
tp := types.NewTypeFromString(name,name)
|
||||
tp.Wrap()
|
||||
var avail bool
|
||||
for _,c := range ns {
|
||||
switch x := c.(type) {
|
||||
|
@ -433,7 +420,7 @@ func (w *Wrapper) GetParms(n *ast.ObjCMethodDecl,class string) ([]Parameter,bool
|
|||
Pname: n.Parameters[j],
|
||||
Vname: x.Name,
|
||||
Type: x.Type,
|
||||
Tp: types.NewTypeFromString(x.Name,class),
|
||||
Tp: types.NewTypeFromString(x.Type,class),
|
||||
}
|
||||
ret = append(ret,p)
|
||||
j++
|
||||
|
@ -474,6 +461,30 @@ func (w *Wrapper) GetParms(n *ast.ObjCMethodDecl,class string) ([]Parameter,bool
|
|||
return ret, true
|
||||
}
|
||||
|
||||
// new version of ProcessType
|
||||
func (w *Wrapper) pt2(tps ...*types.Type) {
|
||||
switch len(tps) {
|
||||
case 0:
|
||||
return
|
||||
case 1:
|
||||
break
|
||||
default:
|
||||
for _,tp := range tps {
|
||||
w.pt2(tp)
|
||||
}
|
||||
return
|
||||
}
|
||||
tp := tps[0].BaseType()
|
||||
if w.Processed2[tp.GoType()] {
|
||||
return
|
||||
}
|
||||
w.Processed2[tp.GoType()] = true
|
||||
if tp.Node.IsFunction() {
|
||||
return
|
||||
}
|
||||
w.goTypes.WriteString(tp.GoTypeDecl())
|
||||
}
|
||||
|
||||
func (w *Wrapper) ProcessType(gotype string) {
|
||||
if gotype == "" {
|
||||
return
|
||||
|
@ -574,62 +585,24 @@ New%s() {
|
|||
if Debug {
|
||||
fmt.Printf(" method: %s (%s)\n", m.Name, m.Type)
|
||||
}
|
||||
if m.Tp.Node.IsFunction() {
|
||||
continue
|
||||
}
|
||||
gname := strings.Title(m.Name)
|
||||
cname := i.Name + "_" + m.Name
|
||||
|
||||
grtype := ""
|
||||
grptr := ""
|
||||
_ = grptr
|
||||
w.AddType(m.Type,i.Name)
|
||||
//cmtype := cType(m.Type,i.Name)
|
||||
cmtype := w.ctMap[w.goType(m.Type,i.Name)].CtypeSimplified()
|
||||
if !m.isVoid() {
|
||||
grtype = w.goType(cmtype,i.Name)
|
||||
if grtype == "" {
|
||||
grtype = fmt.Sprintf("// goType(%s): NOT IMPLEMENTED\n",cmtype)
|
||||
continue
|
||||
}
|
||||
}
|
||||
gcast := ""
|
||||
gcast2 := ""
|
||||
_ = gcast
|
||||
_ = gcast2
|
||||
if grtype != "" {
|
||||
if grtype[0] == '*' { // pointer return type
|
||||
if _,ok := w.Interfaces[grtype[1:]]; ok {
|
||||
//grptr = "*"
|
||||
gcast = "ret := &" + grtype[1:] + "{}\n ret.ptr = unsafe.Pointer("
|
||||
gcast2 = ")\n return ret"
|
||||
} else {
|
||||
gcast = "return (" + grtype + ")(unsafe.Pointer("
|
||||
gcast2 = "))"
|
||||
}
|
||||
} else {
|
||||
gcast = fmt.Sprintf("return (%s)(",grtype)
|
||||
gcast2 = ")"
|
||||
}
|
||||
}
|
||||
if grtype == "id" { // can't return id
|
||||
continue
|
||||
}
|
||||
w.ProcessType(grtype)
|
||||
gplist, gptypes, ok := w.goparamlist(m)
|
||||
_ = gplist
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
w.ProcessTypes(gptypes)
|
||||
//cmtype := w.ctMap[w.goType(m.Type,i.Name)].CtypeSimplified()
|
||||
gplist,_,_ := w.goparamlist(m)
|
||||
cmtype := m.Tp.CType()
|
||||
ns,tps := gpntp(m)
|
||||
w.pt2(tps...)
|
||||
w.pt2(m.Tp)
|
||||
w.goCode.WriteString(fmt.Sprintf(`
|
||||
func (o *%s) %s(%s) %s {
|
||||
`,i.Name,gname,gplist,m.Tp.GoType()))
|
||||
w.goCode.WriteString(types.GoToC(gname,ns,m.Tp,tps))
|
||||
w.goCode.WriteString(`
|
||||
}
|
||||
`)
|
||||
|
||||
/*w.goCode.WriteString(fmt.Sprintf(`
|
||||
%sC.%s_%s(%s)%s
|
||||
}`,i.Name, gname, gplist, grptr, grtype, gcast, i.Name, m.Name, w.goparamnames(m),gcast2))*/
|
||||
w.goCode.WriteString(
|
||||
types.GoToC(cname,ns,m.Tp,tps) + "}\n")
|
||||
|
||||
cret := ""
|
||||
if !m.isVoid() {
|
||||
|
@ -643,9 +616,9 @@ func (o *%s) %s(%s) %s {
|
|||
}
|
||||
w.cCode.WriteString(fmt.Sprintf(`
|
||||
%s
|
||||
%s_%s(%s) {
|
||||
%s(%s) {
|
||||
%s[%s %s];
|
||||
}`, cmtype, i.Name, m.Name, w.cparamlist(m), cret, cobj, w.objcparamlist(m)))
|
||||
}`, cmtype, cname, w.cparamlist(m), cret, cobj, w.objcparamlist(m)))
|
||||
}
|
||||
}
|
||||
fmt.Println(`package main
|
||||
|
|
Loading…
Reference in New Issue
Block a user