Make a Go Interface instead of a struct for top level objects.
Use a new struct Id as a concrete version of that type.
This commit is contained in:
parent
c0c17e88d1
commit
c03e37bd54
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,4 +5,4 @@ program
|
|||
examples/foundation/foundation
|
||||
examples/foundation/ns
|
||||
examples/simple/simple
|
||||
examples/simple/simple/ClassOne
|
||||
examples/simple/ClassOne
|
||||
|
|
16
examples/foundation/main.go
Normal file
16
examples/foundation/main.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitlab.wow.st/gmp/nswrap/examples/foundation/ns"
|
||||
)
|
||||
|
||||
func main() {
|
||||
n1 := ns.StringWithUTF8String(ns.CharFromString("hi there"))
|
||||
c1 := n1.CapitalizedString()
|
||||
gs := c1.UTF8String().String()
|
||||
fmt.Println(gs)
|
||||
a := ns.ArrayWithObjects(n1)
|
||||
_ = a
|
||||
}
|
|
@ -18,5 +18,11 @@ struct stru {int a,b;};
|
|||
- (int) hi2:(struct stru*)in;
|
||||
- (struct stru) nstru1;
|
||||
- (struct stru*) nstru2;
|
||||
- (void) hi:(id)in;
|
||||
- (void) hi3:(id)in;
|
||||
@end
|
||||
|
||||
@interface ClassTwo : ClassOne
|
||||
{ }
|
||||
- (ClassTwo*) init;
|
||||
@end
|
||||
|
|
|
@ -54,6 +54,19 @@
|
|||
ret->b = 10;
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (void) hi:(id)in
|
||||
{
|
||||
NSLog(@"hi");
|
||||
}
|
||||
- (void) hi3:(id)in
|
||||
{
|
||||
NSLog(@"hi");
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ClassTwo
|
||||
- (ClassTwo*) init
|
||||
{
|
||||
return [super init];
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Package = "ClassOne"
|
||||
InputFiles = [ "ClassOne/simple.h" ]
|
||||
Classes = [ "ClassOne" ]
|
||||
Classes = [ "ClassOne","ClassTwo" ]
|
||||
Imports = [ "simple.h" ]
|
||||
|
|
4
main.go
4
main.go
|
@ -153,9 +153,9 @@ func Start() (err error) {
|
|||
if err != nil {
|
||||
// If clang fails it still prints out the AST, so we have to run it
|
||||
// again to get the real error.
|
||||
errBody, _ := exec.Command("clang", cargs...).CombinedOutput()
|
||||
// errBody, _ := exec.Command("clang", cargs...).CombinedOutput()
|
||||
|
||||
panic("clang failed: " + err.Error() + ":\n\n" + string(errBody))
|
||||
panic("clang failed: " + err.Error() + ":\n\n")
|
||||
}
|
||||
|
||||
lines := readAST(astPP)
|
||||
|
|
|
@ -12,6 +12,26 @@ var super map[string]string
|
|||
//go struct.
|
||||
var wrapped map[string]bool
|
||||
|
||||
func shouldWrap(gt string) bool {
|
||||
if wrapped == nil {
|
||||
wrapped = make(map[string]bool)
|
||||
return false
|
||||
}
|
||||
return gt != "" && gt[0] == '*' && wrapped[gt[1:]]
|
||||
}
|
||||
|
||||
//goInterfaces records the names of top level Go interfaces. Pointers to these
|
||||
//are dereferenced to bare interface names.
|
||||
var goInterfaces map[string]bool
|
||||
|
||||
func isGoInterface(gt string) bool {
|
||||
if goInterfaces == nil {
|
||||
goInterfaces = make(map[string]bool)
|
||||
return false
|
||||
}
|
||||
return goInterfaces[gt]
|
||||
}
|
||||
|
||||
//TypeParameters maps, for each class, a TypedefName to a type, representing
|
||||
//the Objective-C type parameters for that class
|
||||
var TypeParameters map[string]map[string]string
|
||||
|
@ -109,9 +129,6 @@ func (t *Type) BaseType() *Type {
|
|||
t.Node.BaseType(),
|
||||
t.Class,
|
||||
)
|
||||
// if ret.CType() == ret.Class + " *" { // "instancename"
|
||||
// ret.ctype = ret.Class
|
||||
// }
|
||||
return ret
|
||||
}
|
||||
|
||||
|
@ -141,6 +158,9 @@ func _goType(ct string) string {
|
|||
ct = strings.Title(ct)
|
||||
ct = strings.ReplaceAll(ct," ","")
|
||||
ct = strings.ReplaceAll(ct,"Struct","")
|
||||
if len(ct) > 0 && ct[0] == '*' && isGoInterface(ct[1:]) {
|
||||
return ct[1:]
|
||||
}
|
||||
return ct
|
||||
}
|
||||
|
||||
|
@ -208,13 +228,26 @@ func (t *Type) GoInterfaceDecl() string {
|
|||
gt = gt[1:] // dereference wrapped types
|
||||
}
|
||||
super := Super(gt)
|
||||
if goInterfaces == nil {
|
||||
goInterfaces = make(map[string]bool)
|
||||
}
|
||||
if super == "" {
|
||||
super = "ptr unsafe.Pointer"
|
||||
goInterfaces[gt] = true
|
||||
return fmt.Sprintf(`
|
||||
//%s (%s)
|
||||
type %s interface {
|
||||
Ptr() unsafe.Pointer
|
||||
}
|
||||
`,t.Node.Ctype(),t.BaseType().GoType(),gt)
|
||||
}
|
||||
if isGoInterface(super) {
|
||||
super = "Id"
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
//%s (%s)
|
||||
type %s struct { %s }
|
||||
`,t.Node.Ctype(),t.BaseType().GoType(),gt,super)
|
||||
func (o *%s) Ptr() unsafe.Pointer { return o.ptr }
|
||||
`,t.Node.Ctype(),t.BaseType().GoType(),gt,super,gt)
|
||||
}
|
||||
|
||||
func (t *Type) IsFunction() bool {
|
||||
|
@ -242,12 +275,15 @@ func (t *Type) CToGo(cval string) string { // cast C value to CGo
|
|||
func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
||||
var ret strings.Builder
|
||||
rt := rtype.CType()
|
||||
wrap := func(gt string) bool {
|
||||
return gt != "" && gt[0] == '*' && wrapped[gt[1:]]
|
||||
}
|
||||
if rt != "void" {
|
||||
if wrap(rtype.GoType()) {
|
||||
ret.WriteString(" ret := &" + rtype.GoType()[1:] + "{}\n")
|
||||
rtgt := rtype.GoType()
|
||||
if shouldWrap(rtgt) || isGoInterface(rtgt) {
|
||||
if isGoInterface(rtgt) {
|
||||
rtgt = "Id"
|
||||
} else {
|
||||
rtgt = rtgt[1:]
|
||||
}
|
||||
ret.WriteString(" ret := &" + rtgt + "{}\n")
|
||||
ret.WriteString(" ret.ptr = unsafe.Pointer(")
|
||||
} else {
|
||||
ret.WriteString(" return (" + rtype.GoType() + ")(")
|
||||
|
@ -261,8 +297,8 @@ 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 wrap(pt.GoType()) {
|
||||
p = pn + ".ptr"
|
||||
if shouldWrap(pt.GoType()) || isGoInterface(pt.GoType()) {
|
||||
p = pn + ".Ptr()"
|
||||
} else {
|
||||
if pt.Node.IsPointer() {
|
||||
p = "unsafe.Pointer(" + pn + ")"
|
||||
|
@ -275,7 +311,7 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
|||
ret.WriteString(strings.Join(parms,", "))
|
||||
ret.WriteString(")")
|
||||
if rt != "void" {
|
||||
if wrap(rtype.GoType()) {
|
||||
if shouldWrap(rtype.GoType()) || isGoInterface(rtype.GoType()) {
|
||||
ret.WriteString(`)
|
||||
return ret
|
||||
`)
|
||||
|
|
|
@ -35,6 +35,10 @@ func NewWrapper(debug bool) *Wrapper {
|
|||
ret.cCode.WriteString(`/*
|
||||
#cgo CFLAGS: -x objective-c
|
||||
#cgo LDFLAGS: -framework Foundation
|
||||
`)
|
||||
ret.goTypes.WriteString(`
|
||||
type Id struct { ptr unsafe.Pointer }
|
||||
func (o *Id) Ptr() unsafe.Pointer { return o.ptr }
|
||||
`)
|
||||
return ret
|
||||
}
|
||||
|
@ -331,12 +335,12 @@ func (w *Wrapper) processType(tp *types.Type) {
|
|||
if bt.IsFunction() {
|
||||
return
|
||||
}
|
||||
w.goTypes.WriteString(bt.GoTypeDecl())
|
||||
super := types.Super(gt)
|
||||
if super != "" {
|
||||
types.Wrap(super)
|
||||
w.processType(types.NewTypeFromString(super,""))
|
||||
}
|
||||
w.goTypes.WriteString(bt.GoTypeDecl())
|
||||
}
|
||||
|
||||
func (w *Wrapper) CharHelpers() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user