diff --git a/bind/bind_test.go b/bind/bind_test.go index f83cb9c..ad9f4d3 100644 --- a/bind/bind_test.go +++ b/bind/bind_test.go @@ -50,6 +50,7 @@ var javaTests = []string{ var objcTests = []string{ "testdata/objc.go", + "testdata/objcw.go", } var fset = token.NewFileSet() @@ -136,7 +137,7 @@ func TestGenObjc(t *testing.T) { Pkg: pkg, }, } - g.Init() + g.Init(nil) testcases := []struct { suffix string @@ -463,7 +464,7 @@ func TestCustomPrefix(t *testing.T) { Pkg: pkg, }, } - og.Init() + og.Init(nil) testCases := []struct { golden string gen func(w io.Writer) error diff --git a/bind/gen.go b/bind/gen.go index 1878142..ac8bca5 100644 --- a/bind/gen.go +++ b/bind/gen.go @@ -333,7 +333,7 @@ func (g *Generator) isSigSupported(t types.Type) bool { // isSupported returns whether the generators can handle the type. func (g *Generator) isSupported(t types.Type) bool { - if isErrorType(t) || isJavaType(t) { + if isErrorType(t) || isWrapperType(t) { return true } switch t := t.(type) { diff --git a/bind/gengo.go b/bind/gengo.go index 9bbba4d..f86f6c6 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -410,10 +410,11 @@ func (g *goGen) genRead(toVar, fromVar string, typ types.Type, mode varMode) { if iface, ok := t.Underlying().(*types.Interface); ok { hasProxy = makeIfaceSummary(iface).implementable } - isJava := isJavaType(t) + pkgFirst := typePkgFirstElem(t) + isWrapper := pkgFirst == "Java" || pkgFirst == "ObjC" o := t.Obj() oPkg := o.Pkg() - if !isErrorType(t) && !g.validPkg(oPkg) && !isJava { + if !isErrorType(t) && !g.validPkg(oPkg) && !isWrapper { g.errorf("type %s is defined in %s, which is not bound", t, oPkg) return } @@ -424,8 +425,14 @@ func (g *goGen) genRead(toVar, fromVar string, typ types.Type, mode varMode) { g.Printf(" %s = %s_ref.Get().(%s%s)\n", toVar, toVar, g.pkgName(oPkg), o.Name()) if hasProxy { g.Printf(" } else { // foreign object \n") - if isJava { - clsName := flattenName(classNameFor(t)) + if isWrapper { + var clsName string + switch pkgFirst { + case "Java": + clsName = flattenName(classNameFor(t)) + case "ObjC": + clsName = t.Obj().Name() + } g.Printf(" %s = (*proxy_class_%s)(%s_ref)\n", toVar, clsName, toVar) } else { g.Printf(" %s = (*proxy%s_%s)(%s_ref)\n", toVar, pkgPrefix(oPkg), o.Name(), toVar) @@ -451,7 +458,7 @@ func (g *goGen) typeString(typ types.Type) string { return types.TypeString(typ, types.RelativeTo(pkg)) } oPkg := obj.Pkg() - if !g.validPkg(oPkg) && !isJavaType(t) { + if !g.validPkg(oPkg) && !isWrapperType(t) { g.errorf("type %s is defined in %s, which is not bound", t, oPkg) return "TODO" } diff --git a/bind/genjava.go b/bind/genjava.go index 59d2f88..f2a82fa 100644 --- a/bind/genjava.go +++ b/bind/genjava.go @@ -1490,6 +1490,10 @@ func classNameFor(t types.Type) string { return strings.Replace(pkg.Path()[len("Java/"):], "/", ".", -1) + "." + obj.Name() } +func isJavaType(t types.Type) bool { + return typePkgFirstElem(t) == "Java" +} + const ( javaPreamble = `// Java class %[1]s.%[2]s is a proxy for talking to a Go program. // gobind %[3]s %[4]s diff --git a/bind/genobjc.go b/bind/genobjc.go index 1ae7003..b629550 100644 --- a/bind/genobjc.go +++ b/bind/genobjc.go @@ -10,6 +10,8 @@ import ( "go/types" "math" "strings" + + "golang.org/x/mobile/internal/importers/objc" ) // TODO(hyangah): handle method name conflicts. @@ -22,15 +24,64 @@ import ( type ObjcGen struct { Prefix string // prefix arg passed by flag. + *Generator + // fields set by init. namePrefix string - - *Generator + // Map of all wrapped Objc types + wrapMap map[string]*objc.Named + // Structs that embeds Objc wrapper types. + ostructs map[*types.TypeName]*objcClassInfo + modules []string } -func (g *ObjcGen) Init() { +type objcClassInfo struct { + // The Objc class this class extends. + extends *objc.Named + // All classes and protocols this class extends and conforms to. + supers []*objc.Named + methods map[string]*objc.Func +} + +func (g *ObjcGen) Init(wrappers []*objc.Named) { g.Generator.Init() g.namePrefix = g.namePrefixOf(g.Pkg) + g.wrapMap = make(map[string]*objc.Named) + modMap := make(map[string]struct{}) + for _, w := range wrappers { + g.wrapMap[w.GoName] = w + if _, exists := modMap[w.Module]; !exists { + g.modules = append(g.modules, w.Module) + modMap[w.Module] = struct{}{} + } + } + if _, exists := modMap["Foundation"]; !exists { + g.modules = append(g.modules, "Foundation") + } + g.ostructs = make(map[*types.TypeName]*objcClassInfo) + for _, s := range g.structs { + embds := embeddedObjcTypes(s.t) + if len(embds) == 0 { + continue + } + inf := &objcClassInfo{ + methods: make(map[string]*objc.Func), + } + for _, n := range embds { + t := g.wrapMap[n] + for _, f := range t.AllMethods { + inf.methods[f.GoName] = f + } + inf.supers = append(inf.supers, t) + if !t.Protocol { + if inf.extends != nil { + g.errorf("%s embeds more than one ObjC class; only one is allowed.", s.obj) + } + inf.extends = t + } + } + g.ostructs[s.obj] = inf + } } func (g *ObjcGen) namePrefixOf(pkg *types.Package) string { @@ -86,8 +137,11 @@ func (g *ObjcGen) GenH() error { g.Printf("#ifndef __%s_H__\n", g.namePrefix) g.Printf("#define __%s_H__\n", g.namePrefix) g.Printf("\n") - g.Printf("#include \n") - g.Printf("#include \"GoUniverse.h\"\n") + for _, m := range g.modules { + g.Printf("@import %s;\n", m) + } + g.Printf("#include \"GoUniverse.h\"\n\n") + if g.Pkg != nil { for _, pkg := range g.Pkg.Imports() { if g.validPkg(pkg) { @@ -347,9 +401,11 @@ func (g *ObjcGen) genConstM(o *types.Const) { type funcSummary struct { name string + goname string ret string sig *types.Signature params, retParams []paramInfo + hasthis bool } type paramInfo struct { @@ -357,20 +413,63 @@ type paramInfo struct { name string } -func (g *ObjcGen) funcSummary(obj *types.Func) *funcSummary { +func (g *ObjcGen) funcSummary(oinf *objcClassInfo, obj *types.Func) *funcSummary { sig := obj.Type().(*types.Signature) - s := &funcSummary{name: obj.Name(), sig: sig} - + s := &funcSummary{goname: obj.Name(), sig: sig} + var om *objc.Func + var sigElems []string + if oinf != nil { + om = oinf.methods[obj.Name()] + } + if om != nil { + sigElems = strings.Split(om.Sig, ":") + s.name = sigElems[0] + } else { + s.name = obj.Name() + } params := sig.Params() - for i := 0; i < params.Len(); i++ { + first := 0 + if om != nil { + // Check the implicit this argument and the argument count of the overridden method + excess := params.Len() - len(om.Params) + if excess < 0 { + g.errorf("method %s has fewer arguments than the method it overrides", obj.Name()) + } else if excess > 1 { + g.errorf("overriding method %s has more arguments than the method it overrides", obj.Name()) + } else if excess == 1 { + s.hasthis = true + first = 1 + t := params.At(0).Type() + if !isObjcType(t) { + g.errorf("the `this` argument to method %s is not a ObjC type", obj.Name()) + return s + } else { + ot := g.wrapMap[t.(*types.Named).Obj().Name()] + found := false + for _, sup := range oinf.supers { + if ot == sup { + found = true + break + } + } + if !found { + g.errorf("the type %s of the `this` argument to method %s is not a super class of the enclosing struct", ot.Name, obj.Name()) + } + } + } + } + for i := first; i < params.Len(); i++ { p := params.At(i) v := paramInfo{ - typ: p.Type(), - name: g.paramName(params, i), + typ: p.Type(), + } + if om != nil { + v.name = sigElems[i-first] + } else { + v.name = g.paramName(params, i) } s.params = append(s.params, v) } - res := sig.Results() switch res.Len() { case 0: @@ -488,13 +587,13 @@ func (g *ObjcGen) genFuncH(obj *types.Func) { g.Printf("// skipped function %s with unsupported parameter or return types\n\n", obj.Name()) return } - if s := g.funcSummary(obj); s != nil { + if s := g.funcSummary(nil, obj); s != nil { g.Printf("FOUNDATION_EXPORT %s;\n", s.asFunc(g)) } } func (g *ObjcGen) genFuncM(obj *types.Func) { - s := g.funcSummary(obj) + s := g.funcSummary(nil, obj) if s == nil { return } @@ -555,20 +654,20 @@ func (g *ObjcGen) genWrite(varName string, t types.Type, mode varMode) { case *types.Named: switch u := t.Underlying().(type) { case *types.Interface: - g.genRefWrite(varName, t) + g.genRefWrite(varName) default: g.errorf("unsupported named type: %s / %T", u, u) } case *types.Pointer: - g.genRefWrite(varName, t) + g.genRefWrite(varName) default: g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName) } } -func (g *ObjcGen) genRefWrite(varName string, t types.Type) { +func (g *ObjcGen) genRefWrite(varName string) { g.Printf("int32_t _%s;\n", varName) - g.Printf("if ([(id)(%s) isKindOfClass:[%s class]]) {\n", varName, g.refTypeBase(t)) + g.Printf("if ([%s conformsToProtocol:@protocol(goSeqRefInterface)]) {\n", varName) g.Indent() g.Printf("id %[1]s_proxy = (id)(%[1]s);\n", varName) g.Printf("_%s = go_seq_go_to_refnum(%s_proxy._ref);\n", varName, varName) @@ -587,7 +686,11 @@ func (g *ObjcGen) genRefRead(toName, fromName string, t types.Type) { g.Printf("if (%s_ref != NULL) {\n", toName) g.Printf(" %s = %s_ref.obj;\n", toName, toName) g.Printf(" if (%s == nil) {\n", toName) - g.Printf(" %s = [[%s alloc] initWithRef:%s_ref];\n", toName, ptype, toName) + if isObjcType(t) { + g.Printf(" LOG_FATAL(@\"unexpected NULL reference\");\n") + } else { + g.Printf(" %s = [[%s alloc] initWithRef:%s_ref];\n", toName, ptype, toName) + } g.Printf(" }\n") g.Printf("}\n") } @@ -637,6 +740,9 @@ func (g *ObjcGen) genRead(toName, fromName string, t types.Type, mode varMode) { func (g *ObjcGen) genFunc(s *funcSummary, objName string) { if objName != "" { g.Printf("int32_t refnum = go_seq_go_to_refnum(self._ref);\n") + if s.hasthis { + g.genRefWrite("self") + } } for _, p := range s.params { g.genWrite(p.name, p.typ, modeTransient) @@ -647,12 +753,15 @@ func (g *ObjcGen) genFunc(s *funcSummary, objName string) { g.Printf("%s r0 = ", g.cgoType(s.retParams[0].typ)) } else { resPrefix = "res." - g.Printf("struct proxy%s_%s_%s_return res = ", g.pkgPrefix, objName, s.name) + g.Printf("struct proxy%s_%s_%s_return res = ", g.pkgPrefix, objName, s.goname) } } - g.Printf("proxy%s_%s_%s(", g.pkgPrefix, objName, s.name) + g.Printf("proxy%s_%s_%s(", g.pkgPrefix, objName, s.goname) if objName != "" { g.Printf("refnum") + if s.hasthis { + g.Printf(", _self") + } } for i, p := range s.params { if i > 0 || objName != "" { @@ -700,9 +809,11 @@ func (g *ObjcGen) genInterfaceInterface(obj *types.TypeName, summary ifaceSummar } else { g.Printf("NSObject") } + prots := []string{"goSeqRefInterface"} if isProtocol { - g.Printf(" <%[1]s%[2]s>", g.namePrefix, obj.Name()) + prots = append(prots, fmt.Sprintf("%[1]s%[2]s", g.namePrefix, obj.Name())) } + g.Printf(" <%s>", strings.Join(prots, ", ")) g.Printf(" {\n}\n") g.Printf("@property(strong, readonly) id _ref;\n") g.Printf("\n") @@ -712,7 +823,7 @@ func (g *ObjcGen) genInterfaceInterface(obj *types.TypeName, summary ifaceSummar g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } - s := g.funcSummary(m) + s := g.funcSummary(nil, m) g.Printf("- %s;\n", s.asMethod(g)) } g.Printf("@end\n") @@ -724,13 +835,13 @@ func (g *ObjcGen) genInterfaceH(obj *types.TypeName, t *types.Interface) { g.genInterfaceInterface(obj, summary, false) return } - g.Printf("@protocol %s%s\n", g.namePrefix, obj.Name()) + g.Printf("@protocol %s%s \n", g.namePrefix, obj.Name()) for _, m := range makeIfaceSummary(t).callable { if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } - s := g.funcSummary(m) + s := g.funcSummary(nil, m) g.Printf("- %s;\n", s.asMethod(g)) } g.Printf("@end\n") @@ -764,7 +875,7 @@ func (g *ObjcGen) genInterfaceM(obj *types.TypeName, t *types.Interface) bool { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } - s := g.funcSummary(m) + s := g.funcSummary(nil, m) g.Printf("- %s {\n", s.asMethod(g)) g.Indent() g.genFunc(s, obj.Name()) @@ -779,7 +890,7 @@ func (g *ObjcGen) genInterfaceM(obj *types.TypeName, t *types.Interface) bool { func (g *ObjcGen) genInterfaceMethodProxy(obj *types.TypeName, m *types.Func) { oName := obj.Name() - s := g.funcSummary(m) + s := g.funcSummary(nil, m) g.genInterfaceMethodSignature(m, oName, false, g.paramName) g.Indent() g.Printf("@autoreleasepool {\n") @@ -875,11 +986,31 @@ func (g *ObjcGen) genRelease(varName string, t types.Type, mode varMode) { } func (g *ObjcGen) genStructH(obj *types.TypeName, t *types.Struct) { - g.Printf("@interface %s%s : NSObject {\n", g.namePrefix, obj.Name()) + g.Printf("@interface %s%s : ", g.namePrefix, obj.Name()) + oinf := g.ostructs[obj] + if oinf != nil { + var prots []string + for _, sup := range oinf.supers { + if !sup.Protocol { + g.Printf(sup.Name) + } else { + prots = append(prots, sup.Name) + } + } + if len(prots) > 0 { + g.Printf(" <%s>", strings.Join(prots, ", ")) + } + } else { + g.Printf("NSObject ") + } + g.Printf(" {\n") g.Printf("}\n") g.Printf("@property(strong, readonly) id _ref;\n") g.Printf("\n") g.Printf("- (id)initWithRef:(id)ref;\n") + if oinf != nil { + g.Printf("- (id)init;\n") + } // accessors to exported fields. for _, f := range exportedFields(t) { @@ -898,7 +1029,7 @@ func (g *ObjcGen) genStructH(obj *types.TypeName, t *types.Struct) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } - s := g.funcSummary(m) + s := g.funcSummary(g.ostructs[obj], m) g.Printf("- %s;\n", objcNameReplacer(lowerFirst(s.asMethod(g)))) } g.Printf("@end\n") @@ -909,6 +1040,7 @@ func (g *ObjcGen) genStructM(obj *types.TypeName, t *types.Struct) { methods := exportedMethodSet(types.NewPointer(obj.Type())) g.Printf("\n") + oinf := g.ostructs[obj] g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name()) g.Printf("}\n\n") g.Printf("- (id)initWithRef:(id)ref {\n") @@ -918,6 +1050,19 @@ func (g *ObjcGen) genStructM(obj *types.TypeName, t *types.Struct) { g.Printf("return self;\n") g.Outdent() g.Printf("}\n\n") + if oinf != nil { + g.Printf("- (id)init {\n") + g.Indent() + g.Printf("self = [super init];\n") + g.Printf("if (self) {\n") + g.Indent() + g.Printf("__ref = go_seq_from_refnum(new_%s_%s());\n", g.pkgPrefix, obj.Name()) + g.Outdent() + g.Printf("}\n") + g.Printf("return self;\n") + g.Outdent() + g.Printf("}\n\n") + } for _, f := range fields { if !g.isSupported(f.Type()) { @@ -933,14 +1078,14 @@ func (g *ObjcGen) genStructM(obj *types.TypeName, t *types.Struct) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } - s := g.funcSummary(m) + s := g.funcSummary(g.ostructs[obj], m) g.Printf("- %s {\n", s.asMethod(g)) g.Indent() g.genFunc(s, obj.Name()) g.Outdent() g.Printf("}\n\n") } - g.Printf("@end\n") + g.Printf("@end\n\n") } func (g *ObjcGen) errorf(format string, args ...interface{}) { @@ -955,6 +1100,9 @@ func (g *ObjcGen) refTypeBase(typ types.Type) string { } case *types.Named: n := typ.Obj() + if isObjcType(typ) { + return g.wrapMap[n.Name()].Name + } if isErrorType(typ) || g.validPkg(n.Pkg()) { switch typ.Underlying().(type) { case *types.Interface, *types.Struct: @@ -1031,6 +1179,10 @@ func (g *ObjcGen) objcType(typ types.Type) string { return "TODO" case *types.Named: n := typ.Obj() + if isObjcType(typ) { + w := g.wrapMap[n.Name()] + return w.ObjcType() + } if !isErrorType(typ) && !g.validPkg(n.Pkg()) { g.errorf("type %s is in package %s, which is not bound", n.Name(), n.Pkg().Name()) return "TODO" @@ -1053,6 +1205,31 @@ func (g *ObjcGen) objcType(typ types.Type) string { } } +// embeddedObjcTypes returns the possible empty list of Objc types embedded +// in the given struct type. +func embeddedObjcTypes(t *types.Struct) []string { + typeSet := make(map[string]struct{}) + var typs []string + for i := 0; i < t.NumFields(); i++ { + f := t.Field(i) + if !f.Exported() { + continue + } + if ft := f.Type(); isObjcType(ft) { + name := ft.(*types.Named).Obj().Name() + if _, exists := typeSet[name]; !exists { + typeSet[name] = struct{}{} + typs = append(typs, name) + } + } + } + return typs +} + +func isObjcType(t types.Type) bool { + return typePkgFirstElem(t) == "ObjC" +} + var objcNameReplacer = newNameSanitizer([]string{ "void", "char", "short", "int", "long", "float", "double", "signed", "unsigned", "id", "const", "volatile", "in", "out", "inout", "bycopy", diff --git a/bind/objc/SeqWrappers.m b/bind/objc/SeqWrappers.m index 90be888..8594c07 100644 --- a/bind/objc/SeqWrappers.m +++ b/bind/objc/SeqWrappers.m @@ -35,13 +35,13 @@ @implementation wrappers - (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. } - (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; } - (void)testFunction { @@ -59,4 +59,39 @@ - (void)testError { GoObjcpkgError(); } + +- (void)testClass { + GoObjcpkgGoNSDate *d = [[GoObjcpkgGoNSDate alloc] init]; + NSString *desc = [d description]; // Also stores this + XCTAssertEqual(d, [d this], "GoNSDate this not identical"); + XCTAssertEqual(GoObjcpkgHash, [d hash], "GoNSDate this not identical"); + XCTAssertTrue([desc isEqualToString:GoObjcpkgDescriptionStr], "GoNSDate description mismatch: %@", desc); + GoObjcpkgGoUIResponder *resp = [[GoObjcpkgGoUIResponder alloc] init]; + [resp pressesBegan:nil withEvent:nil]; + XCTAssertTrue([resp called], "GoUIResponder.pressesBegan not called"); +} + +- (void)testSuper { + GoObjcpkgGoNSObject *o = [[GoObjcpkgGoNSObject alloc] init]; + struct objc_super _super = { + .receiver = o, + .super_class = [NSObject class], + }; + NSString *superDesc = ((NSString *(*)(struct objc_super*, SEL))objc_msgSendSuper)(&_super, @selector(description)); + XCTAssertTrue([superDesc isEqualToString:[o description]], "GoNSObject description mismatch"); + [o setUseThis:TRUE]; + XCTAssertTrue([GoObjcpkgDescriptionStr isEqualToString:[o description]], "GoNSObject description mismatch"); +} + +- (void)testIdentity { + NSDate *d = [[NSDate alloc] init]; + NSDate *d2 = GoObjcpkgDupNSDate(d); + XCTAssertEqual(d, d2, @"GoObjcpkgDupNSDate failed to duplicate ObjC instance"); + GoObjcpkgGoNSDate *gd = [[GoObjcpkgGoNSDate alloc] init]; + NSDate *gd2 = GoObjcpkgDupNSDate(gd); + XCTAssertEqual(gd, gd2, @"GoObjcpkgDupNSDate failed to duplicate Go instance"); + NSDate *gd3 = GoObjcpkgNewGoNSDate(); + NSDate *gd4 = GoObjcpkgDupNSDate(gd3); + XCTAssertEqual(gd4, gd3, @"GoObjcpkgDupNSDate failed to duplicate instance created in Go"); +} @end diff --git a/bind/objc/seq.h b/bind/objc/seq.h index f1f2e95..6dfc334 100644 --- a/bind/objc/seq.h +++ b/bind/objc/seq.h @@ -6,6 +6,7 @@ #define __GO_SEQ_HDR__ #include +#include "ref.h" #include "GoUniverse.h" #ifdef DEBUG @@ -24,32 +25,6 @@ userInfo:NULL]; \ } -// GoSeqRef is an object tagged with an integer for passing back and -// forth across the language boundary. A GoSeqRef may represent either -// an instance of a Go object, or an Objective-C object passed to Go. -// The explicit allocation of a GoSeqRef is used to pin a Go object -// when it is passed to Objective-C. The Go seq package maintains a -// reference to the Go object in a map keyed by the refnum. When the -// GoSeqRef is deallocated, the Go seq package will clear the -// corresponding entry in the map. -// TODO(hyangah): update the doc as golang.org/issue/10933 is fixed. -@interface GoSeqRef : NSObject { -} -@property(readonly) int32_t refnum; -@property(strong) id obj; // NULL when representing a Go object. - -// new GoSeqRef object to proxy a Go object. The refnum must be -// provided from Go side. -- (instancetype)initWithRefnum:(int32_t)refnum obj:(id)obj; - -- (int32_t)incNum; - -@end - -@protocol goSeqRefInterface --(GoSeqRef*) _ref; -@end - // Platform specific types typedef struct nstring { void *ptr; diff --git a/bind/testdata/basictypes.objc.h.golden b/bind/testdata/basictypes.objc.h.golden index 58b18e4..fc13cb1 100644 --- a/bind/testdata/basictypes.objc.h.golden +++ b/bind/testdata/basictypes.objc.h.golden @@ -6,9 +6,10 @@ #ifndef __GoBasictypes_H__ #define __GoBasictypes_H__ -#include +@import Foundation; #include "GoUniverse.h" + FOUNDATION_EXPORT const BOOL GoBasictypesABool; FOUNDATION_EXPORT const double GoBasictypesAFloat; FOUNDATION_EXPORT NSString* const GoBasictypesALongString; diff --git a/bind/testdata/customprefix.objc.h.golden b/bind/testdata/customprefix.objc.h.golden index 6dc2598..127d55e 100644 --- a/bind/testdata/customprefix.objc.h.golden +++ b/bind/testdata/customprefix.objc.h.golden @@ -6,9 +6,10 @@ #ifndef __EXCustomprefix_H__ #define __EXCustomprefix_H__ -#include +@import Foundation; #include "GoUniverse.h" + FOUNDATION_EXPORT void EXCustomprefixF(); #endif diff --git a/bind/testdata/ignore.objc.h.golden b/bind/testdata/ignore.objc.h.golden index a47b512..8c680ab 100644 --- a/bind/testdata/ignore.objc.h.golden +++ b/bind/testdata/ignore.objc.h.golden @@ -6,14 +6,15 @@ #ifndef __GoIgnore_H__ #define __GoIgnore_H__ -#include +@import Foundation; #include "GoUniverse.h" + @class GoIgnoreS; @protocol GoIgnoreI; @class GoIgnoreI; -@interface GoIgnoreS : NSObject { +@interface GoIgnoreS : NSObject { } @property(strong, readonly) id _ref; @@ -26,7 +27,7 @@ @end -@protocol GoIgnoreI +@protocol GoIgnoreI // skipped method I.Argument with unsupported parameter or return types // skipped method I.Result with unsupported parameter or return types @@ -51,7 +52,7 @@ @class GoIgnoreI; -@interface GoIgnoreI : NSObject { +@interface GoIgnoreI : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/ignore.objc.m.golden b/bind/testdata/ignore.objc.m.golden index ed46739..01eb28b 100644 --- a/bind/testdata/ignore.objc.m.golden +++ b/bind/testdata/ignore.objc.m.golden @@ -26,6 +26,7 @@ @end + @implementation GoIgnoreI { } diff --git a/bind/testdata/interfaces.objc.h.golden b/bind/testdata/interfaces.objc.h.golden index 171c519..e876cee 100644 --- a/bind/testdata/interfaces.objc.h.golden +++ b/bind/testdata/interfaces.objc.h.golden @@ -6,9 +6,10 @@ #ifndef __GoInterfaces_H__ #define __GoInterfaces_H__ -#include +@import Foundation; #include "GoUniverse.h" + @protocol GoInterfacesError; @class GoInterfacesError; @protocol GoInterfacesI; @@ -24,15 +25,15 @@ @protocol GoInterfacesWithParam; @class GoInterfacesWithParam; -@protocol GoInterfacesError +@protocol GoInterfacesError - (BOOL)err:(NSError**)error; @end -@protocol GoInterfacesI +@protocol GoInterfacesI - (int32_t)rand; @end -@interface GoInterfacesI1 : NSObject { +@interface GoInterfacesI1 : NSObject { } @property(strong, readonly) id _ref; @@ -40,7 +41,7 @@ - (void)j; @end -@interface GoInterfacesI2 : NSObject { +@interface GoInterfacesI2 : NSObject { } @property(strong, readonly) id _ref; @@ -48,20 +49,20 @@ - (void)g; @end -@protocol GoInterfacesI3 +@protocol GoInterfacesI3 - (GoInterfacesI1*)f; @end -@protocol GoInterfacesLargerI +@protocol GoInterfacesLargerI - (void)anotherFunc; - (int32_t)rand; @end -@protocol GoInterfacesSameI +@protocol GoInterfacesSameI - (int32_t)rand; @end -@protocol GoInterfacesWithParam +@protocol GoInterfacesWithParam - (void)hasParam:(BOOL)p0; @end @@ -83,7 +84,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); @class GoInterfacesWithParam; -@interface GoInterfacesError : NSObject { +@interface GoInterfacesError : NSObject { } @property(strong, readonly) id _ref; @@ -91,7 +92,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); - (BOOL)err:(NSError**)error; @end -@interface GoInterfacesI : NSObject { +@interface GoInterfacesI : NSObject { } @property(strong, readonly) id _ref; @@ -99,7 +100,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); - (int32_t)rand; @end -@interface GoInterfacesI3 : NSObject { +@interface GoInterfacesI3 : NSObject { } @property(strong, readonly) id _ref; @@ -107,7 +108,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); - (GoInterfacesI1*)f; @end -@interface GoInterfacesLargerI : NSObject { +@interface GoInterfacesLargerI : NSObject { } @property(strong, readonly) id _ref; @@ -116,7 +117,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); - (int32_t)rand; @end -@interface GoInterfacesSameI : NSObject { +@interface GoInterfacesSameI : NSObject { } @property(strong, readonly) id _ref; @@ -124,7 +125,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); - (int32_t)rand; @end -@interface GoInterfacesWithParam : NSObject { +@interface GoInterfacesWithParam : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/interfaces.objc.m.golden b/bind/testdata/interfaces.objc.m.golden index 4b7d5d4..111dd31 100644 --- a/bind/testdata/interfaces.objc.m.golden +++ b/bind/testdata/interfaces.objc.m.golden @@ -180,7 +180,7 @@ int32_t GoInterfacesAdd3(id r) { int32_t _r; - if ([(id)(r) isKindOfClass:[GoInterfacesI class]]) { + if ([r conformsToProtocol:@protocol(goSeqRefInterface)]) { id r_proxy = (id)(r); _r = go_seq_go_to_refnum(r_proxy._ref); } else { @@ -193,7 +193,7 @@ int32_t GoInterfacesAdd3(id r) { BOOL GoInterfacesCallErr(id e, NSError** error) { int32_t _e; - if ([(id)(e) isKindOfClass:[GoInterfacesError class]]) { + if ([e conformsToProtocol:@protocol(goSeqRefInterface)]) { id e_proxy = (id)(e); _e = go_seq_go_to_refnum(e_proxy._ref); } else { @@ -237,7 +237,7 @@ int32_t cproxyinterfaces_Error_Err(int32_t refnum) { _error = error; } int32_t __error; - if ([(id)(_error) isKindOfClass:[GoUniverseerror class]]) { + if ([_error conformsToProtocol:@protocol(goSeqRefInterface)]) { id _error_proxy = (id)(_error); __error = go_seq_go_to_refnum(_error_proxy._ref); } else { @@ -275,7 +275,7 @@ int32_t cproxyinterfaces_I3_F(int32_t refnum) { GoInterfacesI3* o = go_seq_objc_from_refnum(refnum); GoInterfacesI1* returnVal = [o f]; int32_t _returnVal; - if ([(id)(returnVal) isKindOfClass:[GoInterfacesI1 class]]) { + if ([returnVal conformsToProtocol:@protocol(goSeqRefInterface)]) { id returnVal_proxy = (id)(returnVal); _returnVal = go_seq_go_to_refnum(returnVal_proxy._ref); } else { diff --git a/bind/testdata/issue10788.objc.h.golden b/bind/testdata/issue10788.objc.h.golden index 5bb4a39..9c020ad 100644 --- a/bind/testdata/issue10788.objc.h.golden +++ b/bind/testdata/issue10788.objc.h.golden @@ -6,14 +6,15 @@ #ifndef __GoIssue10788_H__ #define __GoIssue10788_H__ -#include +@import Foundation; #include "GoUniverse.h" + @class GoIssue10788TestStruct; @protocol GoIssue10788TestInterface; @class GoIssue10788TestInterface; -@interface GoIssue10788TestStruct : NSObject { +@interface GoIssue10788TestStruct : NSObject { } @property(strong, readonly) id _ref; @@ -22,14 +23,14 @@ - (void)setValue:(NSString*)v; @end -@protocol GoIssue10788TestInterface +@protocol GoIssue10788TestInterface - (void)doSomeWork:(GoIssue10788TestStruct*)s; - (void)multipleUnnamedParams:(long)p0 p1:(NSString*)p1 日本:(int64_t)日本; @end @class GoIssue10788TestInterface; -@interface GoIssue10788TestInterface : NSObject { +@interface GoIssue10788TestInterface : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/issue10788.objc.m.golden b/bind/testdata/issue10788.objc.m.golden index 5d99e1f..f10240d 100644 --- a/bind/testdata/issue10788.objc.m.golden +++ b/bind/testdata/issue10788.objc.m.golden @@ -33,6 +33,7 @@ @end + @implementation GoIssue10788TestInterface { } @@ -45,7 +46,7 @@ - (void)doSomeWork:(GoIssue10788TestStruct*)s { int32_t refnum = go_seq_go_to_refnum(self._ref); int32_t _s; - if ([(id)(s) isKindOfClass:[GoIssue10788TestStruct class]]) { + if ([s conformsToProtocol:@protocol(goSeqRefInterface)]) { id s_proxy = (id)(s); _s = go_seq_go_to_refnum(s_proxy._ref); } else { diff --git a/bind/testdata/issue12328.objc.h.golden b/bind/testdata/issue12328.objc.h.golden index 5e36fc8..39a8b26 100644 --- a/bind/testdata/issue12328.objc.h.golden +++ b/bind/testdata/issue12328.objc.h.golden @@ -6,12 +6,13 @@ #ifndef __GoIssue12328_H__ #define __GoIssue12328_H__ -#include +@import Foundation; #include "GoUniverse.h" + @class GoIssue12328T; -@interface GoIssue12328T : NSObject { +@interface GoIssue12328T : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/issue12328.objc.m.golden b/bind/testdata/issue12328.objc.m.golden index 7c5b8c0..a617b81 100644 --- a/bind/testdata/issue12328.objc.m.golden +++ b/bind/testdata/issue12328.objc.m.golden @@ -35,7 +35,7 @@ - (void)setErr:(NSError*)v { int32_t refnum = go_seq_go_to_refnum(self._ref); int32_t _v; - if ([(id)(v) isKindOfClass:[GoUniverseerror class]]) { + if ([v conformsToProtocol:@protocol(goSeqRefInterface)]) { id v_proxy = (id)(v); _v = go_seq_go_to_refnum(v_proxy._ref); } else { @@ -47,6 +47,7 @@ @end + __attribute__((constructor)) static void init() { init_seq(); } diff --git a/bind/testdata/issue12403.objc.h.golden b/bind/testdata/issue12403.objc.h.golden index 14c7dad..f77fad2 100644 --- a/bind/testdata/issue12403.objc.h.golden +++ b/bind/testdata/issue12403.objc.h.golden @@ -6,20 +6,21 @@ #ifndef __GoIssue12403_H__ #define __GoIssue12403_H__ -#include +@import Foundation; #include "GoUniverse.h" + @protocol GoIssue12403Parsable; @class GoIssue12403Parsable; -@protocol GoIssue12403Parsable +@protocol GoIssue12403Parsable - (NSString*)fromJSON:(NSString*)jstr; - (BOOL)toJSON:(NSString**)ret0_ error:(NSError**)error; @end @class GoIssue12403Parsable; -@interface GoIssue12403Parsable : NSObject { +@interface GoIssue12403Parsable : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/issue12403.objc.m.golden b/bind/testdata/issue12403.objc.m.golden index c453a52..2761c21 100644 --- a/bind/testdata/issue12403.objc.m.golden +++ b/bind/testdata/issue12403.objc.m.golden @@ -70,7 +70,7 @@ struct cproxyissue12403_Parsable_ToJSON_return cproxyissue12403_Parsable_ToJSON( _error = error; } int32_t __error; - if ([(id)(_error) isKindOfClass:[GoUniverseerror class]]) { + if ([_error conformsToProtocol:@protocol(goSeqRefInterface)]) { id _error_proxy = (id)(_error); __error = go_seq_go_to_refnum(_error_proxy._ref); } else { diff --git a/bind/testdata/keywords.objc.h.golden b/bind/testdata/keywords.objc.h.golden index 1cbdf7d..d8ba6f5 100644 --- a/bind/testdata/keywords.objc.h.golden +++ b/bind/testdata/keywords.objc.h.golden @@ -6,13 +6,14 @@ #ifndef __GoKeywords_H__ #define __GoKeywords_H__ -#include +@import Foundation; #include "GoUniverse.h" + @protocol GoKeywordsKeywordCaller; @class GoKeywordsKeywordCaller; -@protocol GoKeywordsKeywordCaller +@protocol GoKeywordsKeywordCaller - (void)abstract; - (void)assert; - (void)boolean; @@ -70,7 +71,7 @@ @class GoKeywordsKeywordCaller; -@interface GoKeywordsKeywordCaller : NSObject { +@interface GoKeywordsKeywordCaller : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/objcw.go b/bind/testdata/objcw.go new file mode 100644 index 0000000..136c9c9 --- /dev/null +++ b/bind/testdata/objcw.go @@ -0,0 +1,39 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package objc + +import ( + "ObjC/Foundation" + "ObjC/UIKit" +) + +type GoNSDate struct { + Foundation.NSDate + this Foundation.NSDate +} + +func (d *GoNSDate) Hash(this Foundation.NSDate) int { + return 0 +} + +type GoNSObject struct { + C Foundation.NSObjectC // The class + P Foundation.NSObjectP // The protocol +} + +func (o *GoNSObject) Description(this Foundation.NSObjectC) string { + return "" +} + +func DupNSDate(date Foundation.NSDate) Foundation.NSDate { + return date +} + +type GoUIResponder struct { + UIKit.UIResponder +} + +func (r *GoUIResponder) PressesBegan(_ Foundation.NSSet, _ UIKit.UIPressesEvent) { +} diff --git a/bind/testdata/objcw.go.golden b/bind/testdata/objcw.go.golden new file mode 100644 index 0000000..056a784 --- /dev/null +++ b/bind/testdata/objcw.go.golden @@ -0,0 +1,487 @@ +//File is generated by gobind. Do not edit. + +package ObjC + +// Used to silence this package not used errors +const Dummy = 0 + +type Foundation_NSDate interface { + Hash() (uint) + Description() (string) + Super() Foundation_NSDate +} + +type Foundation_NSObjectC interface { + Hash() (uint) + Description() (string) + Super() Foundation_NSObjectC +} + +type Foundation_NSObjectP interface { + Hash() (uint) + Description() (string) +} + +type Foundation_NSSet interface { + Hash() (uint) + Description() (string) + Super() Foundation_NSSet +} + +type UIKit_UIResponder interface { + Hash() (uint) + Description() (string) + Super() UIKit_UIResponder +} + +type UIKit_UIPressesEvent interface { + Hash() (uint) + Description() (string) + Super() UIKit_UIPressesEvent +} + +// File is generated by gobind. Do not edit. + +package gomobile_bind + +// #cgo CFLAGS: -fobjc-arc -fmodules -fblocks +// #include "interfaces.h" +import "C" + +import "ObjC" +import _seq "golang.org/x/mobile/bind/seq" + +type proxy interface { Bind_proxy_refnum__() int32 } + +// Suppress unused package error + +var _ = _seq.FromRefNum +const _ = ObjC.Dummy + +func init() { +} + +type proxy_class_NSDate _seq.Ref + +func (p *proxy_class_NSDate) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() } + +func (p *proxy_class_NSDate) Hash() (uint) { + res := C.cproxy_NSDate_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *proxy_class_NSDate) Description() (string) { + res := C.cproxy_NSDate_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func (p *proxy_class_NSDate) Super() ObjC.Foundation_NSDate { + return &super_NSDate{p} +} + +type super_NSDate struct {*proxy_class_NSDate} + +func (p *super_NSDate) Hash() (uint) { + res := C.csuper_NSDate_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *super_NSDate) Description() (string) { + res := C.csuper_NSDate_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func init() { +} + +type proxy_class_NSObjectC _seq.Ref + +func (p *proxy_class_NSObjectC) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() } + +func (p *proxy_class_NSObjectC) Hash() (uint) { + res := C.cproxy_NSObjectC_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *proxy_class_NSObjectC) Description() (string) { + res := C.cproxy_NSObjectC_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func (p *proxy_class_NSObjectC) Super() ObjC.Foundation_NSObjectC { + return &super_NSObjectC{p} +} + +type super_NSObjectC struct {*proxy_class_NSObjectC} + +func (p *super_NSObjectC) Hash() (uint) { + res := C.csuper_NSObjectC_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *super_NSObjectC) Description() (string) { + res := C.csuper_NSObjectC_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func init() { +} + +type proxy_class_NSObjectP _seq.Ref + +func (p *proxy_class_NSObjectP) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() } + +func (p *proxy_class_NSObjectP) Hash() (uint) { + res := C.cproxy_NSObjectP_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *proxy_class_NSObjectP) Description() (string) { + res := C.cproxy_NSObjectP_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func init() { +} + +type proxy_class_NSSet _seq.Ref + +func (p *proxy_class_NSSet) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() } + +func (p *proxy_class_NSSet) Hash() (uint) { + res := C.cproxy_NSSet_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *proxy_class_NSSet) Description() (string) { + res := C.cproxy_NSSet_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func (p *proxy_class_NSSet) Super() ObjC.Foundation_NSSet { + return &super_NSSet{p} +} + +type super_NSSet struct {*proxy_class_NSSet} + +func (p *super_NSSet) Hash() (uint) { + res := C.csuper_NSSet_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *super_NSSet) Description() (string) { + res := C.csuper_NSSet_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func init() { +} + +type proxy_class_UIResponder _seq.Ref + +func (p *proxy_class_UIResponder) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() } + +func (p *proxy_class_UIResponder) Hash() (uint) { + res := C.cproxy_UIResponder_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *proxy_class_UIResponder) Description() (string) { + res := C.cproxy_UIResponder_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func (p *proxy_class_UIResponder) Super() ObjC.UIKit_UIResponder { + return &super_UIResponder{p} +} + +type super_UIResponder struct {*proxy_class_UIResponder} + +func (p *super_UIResponder) Hash() (uint) { + res := C.csuper_UIResponder_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *super_UIResponder) Description() (string) { + res := C.csuper_UIResponder_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func init() { +} + +type proxy_class_UIPressesEvent _seq.Ref + +func (p *proxy_class_UIPressesEvent) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() } + +func (p *proxy_class_UIPressesEvent) Hash() (uint) { + res := C.cproxy_UIPressesEvent_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *proxy_class_UIPressesEvent) Description() (string) { + res := C.cproxy_UIPressesEvent_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +func (p *proxy_class_UIPressesEvent) Super() ObjC.UIKit_UIPressesEvent { + return &super_UIPressesEvent{p} +} + +type super_UIPressesEvent struct {*proxy_class_UIPressesEvent} + +func (p *super_UIPressesEvent) Hash() (uint) { + res := C.csuper_UIPressesEvent_Hash(C.int(p.Bind_proxy_refnum__())) + _res := uint(res) + return _res +} + +func (p *super_UIPressesEvent) Description() (string) { + res := C.csuper_UIPressesEvent_Description(C.int(p.Bind_proxy_refnum__())) + _res := decodeString(res) + return _res +} + +// Package gomobile_bind is an autogenerated binder stub for package objc. +// gobind -lang=go objcw +// +// File is generated by gobind. Do not edit. +package gomobile_bind + +/* +#include +#include +#include "seq.h" +#include "objc.h" + +*/ +import "C" + +import ( + "ObjC/Foundation" + "ObjC/UIKit" + _seq "golang.org/x/mobile/bind/seq" + "objcw" +) + +// suppress the error if seq ends up unused +var _ = _seq.FromRefNum + +//export proxyobjc_GoNSDate_NSDate_Set +func proxyobjc_GoNSDate_NSDate_Set(refnum C.int32_t, v C.int32_t) { + ref := _seq.FromRefNum(int32(refnum)) + var _v Foundation.NSDate + _v_ref := _seq.FromRefNum(int32(v)) + if _v_ref != nil { + if v < 0 { // go object + _v = _v_ref.Get().(Foundation.NSDate) + } else { // foreign object + _v = (*proxy_class_NSDate)(_v_ref) + } + } + ref.Get().(*objc.GoNSDate).NSDate = _v +} + +//export proxyobjc_GoNSDate_NSDate_Get +func proxyobjc_GoNSDate_NSDate_Get(refnum C.int32_t) C.int32_t { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(*objc.GoNSDate).NSDate + var _v C.int32_t = _seq.NullRefNum + if v != nil { + _v = C.int32_t(_seq.ToRefNum(v)) + } + return _v +} + +//export proxyobjc_GoNSDate_Hash +func proxyobjc_GoNSDate_Hash(refnum C.int32_t, param_this C.int32_t) C.nint { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(*objc.GoNSDate) + var _param_this Foundation.NSDate + _param_this_ref := _seq.FromRefNum(int32(param_this)) + if _param_this_ref != nil { + if param_this < 0 { // go object + _param_this = _param_this_ref.Get().(Foundation.NSDate) + } else { // foreign object + _param_this = (*proxy_class_NSDate)(_param_this_ref) + } + } + res_0 := v.Hash(_param_this) + _res_0 := C.nint(res_0) + return _res_0 +} + +//export new_objc_GoNSDate +func new_objc_GoNSDate() C.int32_t { + return C.int32_t(_seq.ToRefNum(new(objc.GoNSDate))) +} + +//export proxyobjc_GoNSObject_C_Set +func proxyobjc_GoNSObject_C_Set(refnum C.int32_t, v C.int32_t) { + ref := _seq.FromRefNum(int32(refnum)) + var _v Foundation.NSObjectC + _v_ref := _seq.FromRefNum(int32(v)) + if _v_ref != nil { + if v < 0 { // go object + _v = _v_ref.Get().(Foundation.NSObjectC) + } else { // foreign object + _v = (*proxy_class_NSObjectC)(_v_ref) + } + } + ref.Get().(*objc.GoNSObject).C = _v +} + +//export proxyobjc_GoNSObject_C_Get +func proxyobjc_GoNSObject_C_Get(refnum C.int32_t) C.int32_t { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(*objc.GoNSObject).C + var _v C.int32_t = _seq.NullRefNum + if v != nil { + _v = C.int32_t(_seq.ToRefNum(v)) + } + return _v +} + +//export proxyobjc_GoNSObject_P_Set +func proxyobjc_GoNSObject_P_Set(refnum C.int32_t, v C.int32_t) { + ref := _seq.FromRefNum(int32(refnum)) + var _v Foundation.NSObjectP + _v_ref := _seq.FromRefNum(int32(v)) + if _v_ref != nil { + if v < 0 { // go object + _v = _v_ref.Get().(Foundation.NSObjectP) + } else { // foreign object + _v = (*proxy_class_NSObjectP)(_v_ref) + } + } + ref.Get().(*objc.GoNSObject).P = _v +} + +//export proxyobjc_GoNSObject_P_Get +func proxyobjc_GoNSObject_P_Get(refnum C.int32_t) C.int32_t { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(*objc.GoNSObject).P + var _v C.int32_t = _seq.NullRefNum + if v != nil { + _v = C.int32_t(_seq.ToRefNum(v)) + } + return _v +} + +//export proxyobjc_GoNSObject_Description +func proxyobjc_GoNSObject_Description(refnum C.int32_t, param_this C.int32_t) C.nstring { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(*objc.GoNSObject) + var _param_this Foundation.NSObjectC + _param_this_ref := _seq.FromRefNum(int32(param_this)) + if _param_this_ref != nil { + if param_this < 0 { // go object + _param_this = _param_this_ref.Get().(Foundation.NSObjectC) + } else { // foreign object + _param_this = (*proxy_class_NSObjectC)(_param_this_ref) + } + } + res_0 := v.Description(_param_this) + _res_0 := encodeString(res_0) + return _res_0 +} + +//export new_objc_GoNSObject +func new_objc_GoNSObject() C.int32_t { + return C.int32_t(_seq.ToRefNum(new(objc.GoNSObject))) +} + +//export proxyobjc_GoUIResponder_UIResponder_Set +func proxyobjc_GoUIResponder_UIResponder_Set(refnum C.int32_t, v C.int32_t) { + ref := _seq.FromRefNum(int32(refnum)) + var _v UIKit.UIResponder + _v_ref := _seq.FromRefNum(int32(v)) + if _v_ref != nil { + if v < 0 { // go object + _v = _v_ref.Get().(UIKit.UIResponder) + } else { // foreign object + _v = (*proxy_class_UIResponder)(_v_ref) + } + } + ref.Get().(*objc.GoUIResponder).UIResponder = _v +} + +//export proxyobjc_GoUIResponder_UIResponder_Get +func proxyobjc_GoUIResponder_UIResponder_Get(refnum C.int32_t) C.int32_t { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(*objc.GoUIResponder).UIResponder + var _v C.int32_t = _seq.NullRefNum + if v != nil { + _v = C.int32_t(_seq.ToRefNum(v)) + } + return _v +} + +//export proxyobjc_GoUIResponder_PressesBegan +func proxyobjc_GoUIResponder_PressesBegan(refnum C.int32_t, param_p0 C.int32_t, param_p1 C.int32_t) { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(*objc.GoUIResponder) + var _param_p0 Foundation.NSSet + _param_p0_ref := _seq.FromRefNum(int32(param_p0)) + if _param_p0_ref != nil { + if param_p0 < 0 { // go object + _param_p0 = _param_p0_ref.Get().(Foundation.NSSet) + } else { // foreign object + _param_p0 = (*proxy_class_NSSet)(_param_p0_ref) + } + } + var _param_p1 UIKit.UIPressesEvent + _param_p1_ref := _seq.FromRefNum(int32(param_p1)) + if _param_p1_ref != nil { + if param_p1 < 0 { // go object + _param_p1 = _param_p1_ref.Get().(UIKit.UIPressesEvent) + } else { // foreign object + _param_p1 = (*proxy_class_UIPressesEvent)(_param_p1_ref) + } + } + v.PressesBegan(_param_p0, _param_p1) +} + +//export new_objc_GoUIResponder +func new_objc_GoUIResponder() C.int32_t { + return C.int32_t(_seq.ToRefNum(new(objc.GoUIResponder))) +} + +//export proxyobjc__DupNSDate +func proxyobjc__DupNSDate(param_date C.int32_t) C.int32_t { + var _param_date Foundation.NSDate + _param_date_ref := _seq.FromRefNum(int32(param_date)) + if _param_date_ref != nil { + if param_date < 0 { // go object + _param_date = _param_date_ref.Get().(Foundation.NSDate) + } else { // foreign object + _param_date = (*proxy_class_NSDate)(_param_date_ref) + } + } + res_0 := objc.DupNSDate(_param_date) + var _res_0 C.int32_t = _seq.NullRefNum + if res_0 != nil { + _res_0 = C.int32_t(_seq.ToRefNum(res_0)) + } + return _res_0 +} diff --git a/bind/testdata/structs.objc.h.golden b/bind/testdata/structs.objc.h.golden index 8a911bc..fd09096 100644 --- a/bind/testdata/structs.objc.h.golden +++ b/bind/testdata/structs.objc.h.golden @@ -6,15 +6,16 @@ #ifndef __GoStructs_H__ #define __GoStructs_H__ -#include +@import Foundation; #include "GoUniverse.h" + @class GoStructsS; @class GoStructsS2; @protocol GoStructsI; @class GoStructsI; -@interface GoStructsS : NSObject { +@interface GoStructsS : NSObject { } @property(strong, readonly) id _ref; @@ -27,7 +28,7 @@ - (double)sum; @end -@interface GoStructsS2 : NSObject { +@interface GoStructsS2 : NSObject { } @property(strong, readonly) id _ref; @@ -36,7 +37,7 @@ - (NSString*)string; @end -@protocol GoStructsI +@protocol GoStructsI - (void)m; @end @@ -46,7 +47,7 @@ FOUNDATION_EXPORT BOOL GoStructsIdentityWithError(GoStructsS* s, GoStructsS** re @class GoStructsI; -@interface GoStructsI : NSObject { +@interface GoStructsI : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/structs.objc.m.golden b/bind/testdata/structs.objc.m.golden index b66a3e3..04ba279 100644 --- a/bind/testdata/structs.objc.m.golden +++ b/bind/testdata/structs.objc.m.golden @@ -80,6 +80,7 @@ @end + @implementation GoStructsS2 { } @@ -103,6 +104,7 @@ @end + @implementation GoStructsI { } @@ -123,7 +125,7 @@ GoStructsS* GoStructsIdentity(GoStructsS* s) { int32_t _s; - if ([(id)(s) isKindOfClass:[GoStructsS class]]) { + if ([s conformsToProtocol:@protocol(goSeqRefInterface)]) { id s_proxy = (id)(s); _s = go_seq_go_to_refnum(s_proxy._ref); } else { @@ -143,7 +145,7 @@ GoStructsS* GoStructsIdentity(GoStructsS* s) { BOOL GoStructsIdentityWithError(GoStructsS* s, GoStructsS** ret0_, NSError** error) { int32_t _s; - if ([(id)(s) isKindOfClass:[GoStructsS class]]) { + if ([s conformsToProtocol:@protocol(goSeqRefInterface)]) { id s_proxy = (id)(s); _s = go_seq_go_to_refnum(s_proxy._ref); } else { diff --git a/bind/testdata/try.objc.h.golden b/bind/testdata/try.objc.h.golden index 6bbd53c..cfedb08 100644 --- a/bind/testdata/try.objc.h.golden +++ b/bind/testdata/try.objc.h.golden @@ -6,9 +6,10 @@ #ifndef __GoTry_H__ #define __GoTry_H__ -#include +@import Foundation; #include "GoUniverse.h" + FOUNDATION_EXPORT NSString* GoTryThis(); #endif diff --git a/bind/testdata/vars.objc.h.golden b/bind/testdata/vars.objc.h.golden index 4f15bc7..ed10da5 100644 --- a/bind/testdata/vars.objc.h.golden +++ b/bind/testdata/vars.objc.h.golden @@ -6,21 +6,22 @@ #ifndef __GoVars_H__ #define __GoVars_H__ -#include +@import Foundation; #include "GoUniverse.h" + @class GoVarsS; @protocol GoVarsI; @class GoVarsI; -@interface GoVarsS : NSObject { +@interface GoVarsS : NSObject { } @property(strong, readonly) id _ref; - (id)initWithRef:(id)ref; @end -@protocol GoVarsI +@protocol GoVarsI @end @interface GoVars : NSObject @@ -64,7 +65,7 @@ @class GoVarsI; -@interface GoVarsI : NSObject { +@interface GoVarsI : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/vars.objc.m.golden b/bind/testdata/vars.objc.m.golden index 8a69fb3..bf689a7 100644 --- a/bind/testdata/vars.objc.m.golden +++ b/bind/testdata/vars.objc.m.golden @@ -20,6 +20,7 @@ @end + @implementation GoVarsI { } @@ -90,7 +91,7 @@ + (void) setAStructPtr:(GoVarsS*)v { int32_t _v; - if ([(id)(v) isKindOfClass:[GoVarsS class]]) { + if ([v conformsToProtocol:@protocol(goSeqRefInterface)]) { id v_proxy = (id)(v); _v = go_seq_go_to_refnum(v_proxy._ref); } else { @@ -169,7 +170,7 @@ + (void) setAnInterface:(id)v { int32_t _v; - if ([(id)(v) isKindOfClass:[GoVarsI class]]) { + if ([v conformsToProtocol:@protocol(goSeqRefInterface)]) { id v_proxy = (id)(v); _v = go_seq_go_to_refnum(v_proxy._ref); } else { diff --git a/bind/testpkg/objcpkg/classes.go b/bind/testpkg/objcpkg/classes.go new file mode 100644 index 0000000..a3dfe6f --- /dev/null +++ b/bind/testpkg/objcpkg/classes.go @@ -0,0 +1,68 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package objcpkg + +import ( + "ObjC/Foundation" + "ObjC/UIKit" +) + +const ( + DescriptionStr = "Descriptrion from Go" + Hash = 42 +) + +type GoNSDate struct { + Foundation.NSDate + this Foundation.NSDate +} + +func (d *GoNSDate) Hash(this Foundation.NSDate) int { + return Hash +} + +func (d *GoNSDate) Description(this Foundation.NSDate) string { + // Test this call + if h := this.Hash(); h != Hash { + panic("hash mismatch") + } + d.this = this + return DescriptionStr +} + +func (d *GoNSDate) This() Foundation.NSDate { + return d.this +} + +func NewGoNSDate() *GoNSDate { + return new(GoNSDate) +} + +type GoNSObject struct { + C Foundation.NSObjectC // The class + P Foundation.NSObjectP // The protocol + UseThis bool +} + +func (o *GoNSObject) Description(this Foundation.NSObjectC) string { + if o.UseThis { + return DescriptionStr + } else { + return this.Super().Description() + } +} + +func DupNSDate(date Foundation.NSDate) Foundation.NSDate { + return date +} + +type GoUIResponder struct { + UIKit.UIResponder + Called bool +} + +func (r *GoUIResponder) PressesBegan(_ Foundation.NSSet, _ UIKit.UIPressesEvent) { + r.Called = true +} diff --git a/bind/types.go b/bind/types.go index 95167f7..1b8a6f0 100644 --- a/bind/types.go +++ b/bind/types.go @@ -76,9 +76,9 @@ func exportedMethodSet(T types.Type) []*types.Func { if !obj.Exported() { continue } - // Skip methods from the embedded java classes, so that + // Skip methods from the embedded classes, so that // only methods that are implemented in Go are included. - if isJavaPkg(obj.Pkg()) { + if pref := pkgFirstElem(obj.Pkg()); pref == "Java" || pref == "ObjC" { continue } switch obj := obj.(type) { @@ -142,14 +142,27 @@ func isRefType(t types.Type) bool { } } -func isJavaType(t types.Type) bool { +func typePkgFirstElem(t types.Type) string { nt, ok := t.(*types.Named) if !ok { - return false + return "" } - return isJavaPkg(nt.Obj().Pkg()) + return pkgFirstElem(nt.Obj().Pkg()) } -func isJavaPkg(p *types.Package) bool { - return p != nil && strings.HasPrefix(p.Path(), "Java/") +func pkgFirstElem(p *types.Package) string { + if p == nil { + return "" + } + path := p.Path() + idx := strings.Index(path, "/") + if idx == -1 { + return "" + } + return path[:idx] +} + +func isWrapperType(t types.Type) bool { + e := typePkgFirstElem(t) + return e == "Java" || e == "ObjC" } diff --git a/cmd/gobind/gen.go b/cmd/gobind/gen.go index 9b2f0c8..8325b84 100644 --- a/cmd/gobind/gen.go +++ b/cmd/gobind/gen.go @@ -119,7 +119,7 @@ func genPkg(p *types.Package, allPkg []*types.Package, classes []*java.Class) { }, Prefix: *prefix, } - g.Init() + g.Init(nil) w, closer := writer(gohname) processErr(g.GenGoH()) diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go index 6972775..e7284f4 100644 --- a/cmd/gomobile/bind.go +++ b/cmd/gomobile/bind.go @@ -220,7 +220,7 @@ func (b *binder) GenObjc(pkg *types.Package, allPkg []*types.Package, outdir str }, Prefix: bindPrefix, } - g.Init() + g.Init(wrappers) generate := func(w io.Writer) error { if buildX {