From 0879aa9afa947b7fb230b003f5de5c7c3ab8cce8 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 13 Jan 2018 13:16:51 +0100 Subject: [PATCH] bind: support types with the same title name as their packages If a Go struct or interface has the same name as its package class, append an underscore to the generated Java class name. Fixes golang/go#23327. Change-Id: Ib680af35c956801073a0effb510a3ed9bbb8b9d1 Reviewed-on: https://go-review.googlesource.com/87656 Reviewed-by: Hyang-Ah Hana Kim --- bind/genjava.go | 70 ++++++++++++++++------- bind/java/SeqTest.java | 9 +++ bind/testdata/interfaces.go | 5 ++ bind/testdata/interfaces.go.golden | 15 +++++ bind/testdata/interfaces.java.c.golden | 22 +++++++ bind/testdata/interfaces.java.golden | 29 ++++++++++ bind/testdata/interfaces.java.h.golden | 5 ++ bind/testdata/interfaces.objc.go.h.golden | 2 + bind/testdata/interfaces.objc.h.golden | 19 ++++++ bind/testdata/interfaces.objc.m.golden | 24 ++++++++ bind/testdata/structs.go | 6 ++ bind/testdata/structs.go.golden | 12 ++++ bind/testdata/structs.java.c.golden | 17 ++++++ bind/testdata/structs.java.golden | 45 +++++++++++++++ bind/testdata/structs.java.h.golden | 2 + bind/testdata/structs.objc.h.golden | 13 +++++ bind/testdata/structs.objc.m.golden | 26 +++++++++ bind/testpkg/secondpkg/secondpkg.go | 11 ++++ bind/testpkg/testpkg.go | 5 ++ 19 files changed, 315 insertions(+), 22 deletions(-) diff --git a/bind/genjava.go b/bind/genjava.go index dd3cf18..8991466 100644 --- a/bind/genjava.go +++ b/bind/genjava.go @@ -205,10 +205,10 @@ loop: func (g *JavaGen) ClassNames() []string { var names []string for _, s := range g.structs { - names = append(names, s.obj.Name()) + names = append(names, g.javaTypeName(s.obj.Name())) } for _, iface := range g.interfaces { - names = append(names, iface.obj.Name()) + names = append(names, g.javaTypeName(iface.obj.Name())) } return names } @@ -242,7 +242,7 @@ func (g *JavaGen) genStruct(s structInfo) { if g.Pkg != nil { pkgPath = g.Pkg.Path() } - n := s.obj.Name() + n := g.javaTypeName(s.obj.Name()) g.Printf(javaPreamble, g.javaPkgName(g.Pkg), n, g.gobindOpts(), pkgPath) fields := exportedFields(s.t) @@ -254,7 +254,7 @@ func (g *JavaGen) genStruct(s structInfo) { impls = append(impls, "Seq.GoObject") for _, cls := range jinf.supers { if cls.Interface { - impls = append(impls, cls.Name) + impls = append(impls, g.javaTypeName(cls.Name)) } } } else { @@ -266,7 +266,12 @@ func (g *JavaGen) genStruct(s structInfo) { if types.AssignableTo(pT, iface.obj.Type()) { n := iface.obj.Name() if p := iface.obj.Pkg(); p != g.Pkg { + if n == JavaClassName(p) { + n = n + "_" + } n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n) + } else { + n = g.javaTypeName(n) } impls = append(impls, n) } @@ -277,7 +282,7 @@ func (g *JavaGen) genStruct(s structInfo) { g.Printf("public final class %s", n) if jinf != nil { if jinf.extends != nil { - g.Printf(" extends %s", jinf.extends.Name) + g.Printf(" extends %s", g.javaTypeName(jinf.extends.Name)) } } if len(impls) > 0 { @@ -350,6 +355,16 @@ func (g *JavaGen) genStruct(s structInfo) { g.Printf("}\n\n") } +// javaTypeName returns the class name of a given Go type name. If +// the type name clashes with the package class name, an underscore is +// appended. +func (g *JavaGen) javaTypeName(n string) string { + if n == JavaClassName(g.Pkg) { + return n + "_" + } + return n +} + func (g *JavaGen) javadoc(doc string) { if doc == "" { return @@ -514,7 +529,7 @@ func (g *JavaGen) genInterface(iface interfaceInfo) { if g.Pkg != nil { pkgPath = g.Pkg.Path() } - g.Printf(javaPreamble, g.javaPkgName(g.Pkg), iface.obj.Name(), g.gobindOpts(), pkgPath) + g.Printf(javaPreamble, g.javaPkgName(g.Pkg), g.javaTypeName(iface.obj.Name()), g.gobindOpts(), pkgPath) var exts []string numM := iface.t.NumMethods() @@ -523,14 +538,19 @@ func (g *JavaGen) genInterface(iface interfaceInfo) { if other.t.NumMethods() < numM && types.AssignableTo(iface.t, other.t) { n := other.obj.Name() if p := other.obj.Pkg(); p != g.Pkg { + if n == JavaClassName(p) { + n = n + "_" + } n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n) + } else { + n = g.javaTypeName(n) } exts = append(exts, n) } } doc := g.docs[iface.obj.Name()] g.javadoc(doc.Doc()) - g.Printf("public interface %s", iface.obj.Name()) + g.Printf("public interface %s", g.javaTypeName(iface.obj.Name())) if len(exts) > 0 { g.Printf(" extends %s", strings.Join(exts, ", ")) } @@ -675,10 +695,14 @@ func (g *JavaGen) javaType(T types.Type) string { break } // TODO(crawshaw): more checking here + clsName := n.Name() if nPkg != g.Pkg { - return fmt.Sprintf("%s.%s", g.javaPkgName(nPkg), n.Name()) + if clsName == JavaClassName(nPkg) { + clsName += "_" + } + return fmt.Sprintf("%s.%s", g.javaPkgName(nPkg), clsName) } else { - return n.Name() + return g.javaTypeName(clsName) } default: g.errorf("unsupported javaType: %#+v, %s\n", T, T) @@ -713,10 +737,10 @@ func (g *JavaGen) genJNIFuncSignature(o *types.Func, sName string, jm *java.Func if proxy { g.Printf(g.className()) // 0024 is the mangled form of $, for naming inner classes. - g.Printf("_00024") - g.Printf("proxy") + g.Printf("_00024proxy%s", sName) + } else { + g.Printf(java.JNIMangle(g.javaTypeName(sName))) } - g.Printf("%s", sName) } else { g.Printf(g.className()) } @@ -1037,9 +1061,10 @@ func (g *JavaGen) genJNIField(o *types.TypeName, f *types.Var) { g.Printf("// skipped field %s with unsupported type: %T\n\n", o.Name(), t) return } + n := java.JNIMangle(g.javaTypeName(o.Name())) // setter g.Printf("JNIEXPORT void JNICALL\n") - g.Printf("Java_%s_%s_set%s(JNIEnv *env, jobject this, %s v) {\n", g.jniPkgName(), o.Name(), f.Name(), g.jniType(f.Type())) + g.Printf("Java_%s_%s_set%s(JNIEnv *env, jobject this, %s v) {\n", g.jniPkgName(), n, f.Name(), g.jniType(f.Type())) g.Indent() g.Printf("int32_t o = go_seq_to_refnum_go(env, this);\n") g.genJavaToC("v", f.Type(), modeRetained) @@ -1050,7 +1075,7 @@ func (g *JavaGen) genJNIField(o *types.TypeName, f *types.Var) { // getter g.Printf("JNIEXPORT %s JNICALL\n", g.jniType(f.Type())) - g.Printf("Java_%s_%s_get%s(JNIEnv *env, jobject this) {\n", g.jniPkgName(), o.Name(), f.Name()) + g.Printf("Java_%s_%s_get%s(JNIEnv *env, jobject this) {\n", g.jniPkgName(), n, f.Name()) g.Indent() g.Printf("int32_t o = go_seq_to_refnum_go(env, this);\n") g.Printf("%s r0 = ", g.cgoType(f.Type())) @@ -1066,9 +1091,10 @@ func (g *JavaGen) genJNIVar(o *types.Var) { g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t) return } + n := java.JNIMangle(g.javaTypeName(o.Name())) // setter g.Printf("JNIEXPORT void JNICALL\n") - g.Printf("Java_%s_%s_set%s(JNIEnv *env, jclass clazz, %s v) {\n", g.jniPkgName(), g.className(), o.Name(), g.jniType(o.Type())) + g.Printf("Java_%s_%s_set%s(JNIEnv *env, jclass clazz, %s v) {\n", g.jniPkgName(), g.className(), n, g.jniType(o.Type())) g.Indent() g.genJavaToC("v", o.Type(), modeRetained) g.Printf("var_set%s_%s(_v);\n", g.pkgPrefix, o.Name()) @@ -1078,7 +1104,7 @@ func (g *JavaGen) genJNIVar(o *types.Var) { // getter g.Printf("JNIEXPORT %s JNICALL\n", g.jniType(o.Type())) - g.Printf("Java_%s_%s_get%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), g.className(), o.Name()) + g.Printf("Java_%s_%s_get%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), g.className(), n) g.Indent() g.Printf("%s r0 = ", g.cgoType(o.Type())) g.Printf("var_get%s_%s();\n", g.pkgPrefix, o.Name()) @@ -1096,7 +1122,7 @@ func (g *JavaGen) genJNIConstructor(f *types.Func, sName string) { res := sig.Results() g.Printf("JNIEXPORT jobject JNICALL\n") - g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz", g.jniPkgName(), sName, java.JNIMangle("__"+f.Name())) + g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz", g.jniPkgName(), java.JNIMangle(g.javaTypeName(sName)), java.JNIMangle("__"+f.Name())) params := sig.Params() for i := 0; i < params.Len(); i++ { v := params.At(i) @@ -1402,7 +1428,7 @@ func (g *JavaGen) jniSigType(T types.Type) string { } g.errorf("unsupported pointer to type: %s", T) case *types.Named: - return "L" + g.jniClassSigPrefix(T.Obj().Pkg()) + T.Obj().Name() + ";" + return "L" + g.jniClassSigPrefix(T.Obj().Pkg()) + g.javaTypeName(T.Obj().Name()) + ";" default: g.errorf("unsupported jniType: %#+v, %s\n", T, T) } @@ -1456,7 +1482,7 @@ func (g *JavaGen) GenC() error { continue } } - g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(s.obj.Pkg())+s.obj.Name()) + g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(s.obj.Pkg())+g.javaTypeName(s.obj.Name())) g.Printf("proxy_class_%s_%s = (*env)->NewGlobalRef(env, clazz);\n", g.pkgPrefix, s.obj.Name()) g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"\", \"(Lgo/Seq$Ref;)V\");\n", g.pkgPrefix, s.obj.Name()) } @@ -1472,7 +1498,7 @@ func (g *JavaGen) GenC() error { g.Printf("mid_error_Error = (*env)->GetMethodID(env, clazz, \"getMessage\", \"()Ljava/lang/String;\");\n") continue } - g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+iface.obj.Name()) + g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+g.javaTypeName(iface.obj.Name())) for _, m := range iface.summary.callable { if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name()) @@ -1510,7 +1536,7 @@ func (g *JavaGen) GenC() error { } if len(cons) == 0 && (jinf == nil || jinf.genNoargCon) { g.Printf("JNIEXPORT jobject JNICALL\n") - g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), sName, java.JNIMangle("__New")) + g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), java.JNIMangle(g.javaTypeName(sName)), java.JNIMangle("__New")) g.Indent() g.Printf("int32_t refnum = new_%s_%s();\n", g.pkgPrefix, sName) // Pass no proxy class so that the Seq.Ref is returned instead. @@ -1578,7 +1604,7 @@ func (g *JavaGen) GenJava() error { if isErrorType(iface.obj.Type()) { g.Printf(" extends Exception") } - g.Printf(" implements Seq.Proxy, %s {\n", n) + g.Printf(" implements Seq.Proxy, %s {\n", g.javaTypeName(n)) g.Indent() g.genProxyImpl("proxy" + n) g.Printf("proxy%s(Seq.Ref ref) { this.ref = ref; }\n\n", n) diff --git a/bind/java/SeqTest.java b/bind/java/SeqTest.java index 36f3169..ccaa813 100644 --- a/bind/java/SeqTest.java +++ b/bind/java/SeqTest.java @@ -588,4 +588,13 @@ public class SeqTest extends InstrumentationTestCase { public void testTags() { assertEquals("Constant from a tagged file", 42, Testpkg.TaggedConst); } + + public void testClassNameWithPackageName() { + testpkg.Testpkg_ o = new secondpkg.Secondpkg_(); + secondpkg.Secondpkg_ o2 = Secondpkg.newSecondpkg(); + o2.m(); + o2.setV("hi"); + assertEquals(o2.getV(), "hi"); + Testpkg.clashingParameterFromOtherPackage(o2); + } } diff --git a/bind/testdata/interfaces.go b/bind/testdata/interfaces.go index 0eaa99a..9e2da3a 100644 --- a/bind/testdata/interfaces.go +++ b/bind/testdata/interfaces.go @@ -62,3 +62,8 @@ type I3 interface { // not bound func F() seven { return seven{} } func G(u seven) {} + +// Interfaces is an interface with the same name as its package. +type Interfaces interface { + SomeMethod() +} diff --git a/bind/testdata/interfaces.go.golden b/bind/testdata/interfaces.go.golden index 16baa81..a4700d6 100644 --- a/bind/testdata/interfaces.go.golden +++ b/bind/testdata/interfaces.go.golden @@ -112,6 +112,21 @@ func (p *proxyinterfaces_I3) F() interfaces.I1 { return _res } +//export proxyinterfaces_Interfaces_SomeMethod +func proxyinterfaces_Interfaces_SomeMethod(refnum C.int32_t) { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(interfaces.Interfaces) + v.SomeMethod() +} + +type proxyinterfaces_Interfaces _seq.Ref + +func (p *proxyinterfaces_Interfaces) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() } + +func (p *proxyinterfaces_Interfaces) SomeMethod() { + C.cproxyinterfaces_Interfaces_SomeMethod(C.int32_t(p.Bind_proxy_refnum__())) +} + //export proxyinterfaces_LargerI_AnotherFunc func proxyinterfaces_LargerI_AnotherFunc(refnum C.int32_t) { ref := _seq.FromRefNum(int32(refnum)) diff --git a/bind/testdata/interfaces.java.c.golden b/bind/testdata/interfaces.java.c.golden index 7c31204..0f11d5d 100644 --- a/bind/testdata/interfaces.java.c.golden +++ b/bind/testdata/interfaces.java.c.golden @@ -24,6 +24,9 @@ static jmethodID mid_I2_G; jclass proxy_class_interfaces_I3; jmethodID proxy_class_interfaces_I3_cons; static jmethodID mid_I3_F; +jclass proxy_class_interfaces_Interfaces; +jmethodID proxy_class_interfaces_Interfaces_cons; +static jmethodID mid_Interfaces_SomeMethod; jclass proxy_class_interfaces_LargerI; jmethodID proxy_class_interfaces_LargerI_cons; static jmethodID mid_LargerI_AnotherFunc; @@ -68,6 +71,12 @@ Java_interfaces_Interfaces__1init(JNIEnv *env, jclass _unused) { clazz = (*env)->FindClass(env, "interfaces/I3"); mid_I3_F = (*env)->GetMethodID(env, clazz, "f", "()Linterfaces/I1;"); + clazz = (*env)->FindClass(env, "interfaces/Interfaces$proxyInterfaces"); + proxy_class_interfaces_Interfaces = (*env)->NewGlobalRef(env, clazz); + proxy_class_interfaces_Interfaces_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); + clazz = (*env)->FindClass(env, "interfaces/Interfaces_"); + mid_Interfaces_SomeMethod = (*env)->GetMethodID(env, clazz, "someMethod", "()V"); + clazz = (*env)->FindClass(env, "interfaces/Interfaces$proxyLargerI"); proxy_class_interfaces_LargerI = (*env)->NewGlobalRef(env, clazz); proxy_class_interfaces_LargerI_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); @@ -190,6 +199,19 @@ int32_t cproxyinterfaces_I3_F(int32_t refnum) { return _res; } +JNIEXPORT void JNICALL +Java_interfaces_Interfaces_00024proxyInterfaces_someMethod(JNIEnv* env, jobject __this__) { + int32_t o = go_seq_to_refnum_go(env, __this__); + proxyinterfaces_Interfaces_SomeMethod(o); +} + +void cproxyinterfaces_Interfaces_SomeMethod(int32_t refnum) { + JNIEnv *env = go_seq_push_local_frame(0); + jobject o = go_seq_from_refnum(env, refnum, proxy_class_interfaces_Interfaces, proxy_class_interfaces_Interfaces_cons); + (*env)->CallVoidMethod(env, o, mid_Interfaces_SomeMethod); + go_seq_pop_local_frame(env); +} + JNIEXPORT void JNICALL Java_interfaces_Interfaces_00024proxyLargerI_anotherFunc(JNIEnv* env, jobject __this__) { int32_t o = go_seq_to_refnum_go(env, __this__); diff --git a/bind/testdata/interfaces.java.golden b/bind/testdata/interfaces.java.golden index 6b95947..87402b7 100644 --- a/bind/testdata/interfaces.java.golden +++ b/bind/testdata/interfaces.java.golden @@ -73,6 +73,22 @@ public interface I3 { } +// Java class interfaces.Interfaces_ is a proxy for talking to a Go program. +// gobind -lang=java interfaces +// +// File is generated by gobind. Do not edit. +package interfaces; + +import go.Seq; + +/** + * Interfaces is an interface with the same name as its package. + */ +public interface Interfaces_ { + public void someMethod(); + +} + // Java class interfaces.LargerI is a proxy for talking to a Go program. // gobind -lang=java interfaces // @@ -199,6 +215,19 @@ public abstract class Interfaces { public native I1 f(); } + private static final class proxyInterfaces implements Seq.Proxy, Interfaces_ { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyInterfaces(Seq.Ref ref) { this.ref = ref; } + + public native void someMethod(); + } private static final class proxyLargerI implements Seq.Proxy, LargerI { private final Seq.Ref ref; diff --git a/bind/testdata/interfaces.java.h.golden b/bind/testdata/interfaces.java.h.golden index 05840e8..5d5f3f1 100644 --- a/bind/testdata/interfaces.java.h.golden +++ b/bind/testdata/interfaces.java.h.golden @@ -33,6 +33,11 @@ extern jmethodID proxy_class_interfaces_I3_cons; int32_t cproxyinterfaces_I3_F(int32_t refnum); +extern jclass proxy_class_interfaces_Interfaces; +extern jmethodID proxy_class_interfaces_Interfaces_cons; + +void cproxyinterfaces_Interfaces_SomeMethod(int32_t refnum); + extern jclass proxy_class_interfaces_LargerI; extern jmethodID proxy_class_interfaces_LargerI_cons; diff --git a/bind/testdata/interfaces.objc.go.h.golden b/bind/testdata/interfaces.objc.go.h.golden index 8452626..983de54 100644 --- a/bind/testdata/interfaces.objc.go.h.golden +++ b/bind/testdata/interfaces.objc.go.h.golden @@ -14,6 +14,8 @@ int32_t cproxyinterfaces_I_Rand(int32_t refnum); int32_t cproxyinterfaces_I3_F(int32_t refnum); +void cproxyinterfaces_Interfaces_SomeMethod(int32_t refnum); + void cproxyinterfaces_LargerI_AnotherFunc(int32_t refnum); int32_t cproxyinterfaces_LargerI_Rand(int32_t refnum); diff --git a/bind/testdata/interfaces.objc.h.golden b/bind/testdata/interfaces.objc.h.golden index ca5c7a4..c54288e 100644 --- a/bind/testdata/interfaces.objc.h.golden +++ b/bind/testdata/interfaces.objc.h.golden @@ -18,6 +18,8 @@ @protocol InterfacesI2; @protocol InterfacesI3; @class InterfacesI3; +@protocol InterfacesInterfaces; +@class InterfacesInterfaces; @protocol InterfacesLargerI; @class InterfacesLargerI; @protocol InterfacesSameI; @@ -59,6 +61,10 @@ - (InterfacesI1*)f; @end +@protocol InterfacesInterfaces +- (void)someMethod; +@end + @protocol InterfacesLargerI - (void)anotherFunc; - (int32_t)rand; @@ -84,6 +90,8 @@ FOUNDATION_EXPORT id InterfacesSeven(void); @class InterfacesI3; +@class InterfacesInterfaces; + @class InterfacesLargerI; @class InterfacesSameI; @@ -118,6 +126,17 @@ FOUNDATION_EXPORT id InterfacesSeven(void); - (InterfacesI1*)f; @end +/** + * Interfaces is an interface with the same name as its package. + */ +@interface InterfacesInterfaces : NSObject { +} +@property(strong, readonly) id _ref; + +- (instancetype)initWithRef:(id)ref; +- (void)someMethod; +@end + @interface InterfacesLargerI : NSObject { } @property(strong, readonly) id _ref; diff --git a/bind/testdata/interfaces.objc.m.golden b/bind/testdata/interfaces.objc.m.golden index 7b5e1d9..54383df 100644 --- a/bind/testdata/interfaces.objc.m.golden +++ b/bind/testdata/interfaces.objc.m.golden @@ -116,6 +116,23 @@ @end +@implementation InterfacesInterfaces { +} + +- (instancetype)initWithRef:(id)ref { + self = [super init]; + if (self) { __ref = ref; } + return self; +} + +- (void)someMethod { + int32_t refnum = go_seq_go_to_refnum(self._ref); + proxyinterfaces_Interfaces_SomeMethod(refnum); +} + +@end + + @implementation InterfacesLargerI { } @@ -287,6 +304,13 @@ int32_t cproxyinterfaces_I3_F(int32_t refnum) { } } +void cproxyinterfaces_Interfaces_SomeMethod(int32_t refnum) { + @autoreleasepool { + InterfacesInterfaces* o = go_seq_objc_from_refnum(refnum); + [o someMethod]; + } +} + void cproxyinterfaces_LargerI_AnotherFunc(int32_t refnum) { @autoreleasepool { InterfacesLargerI* o = go_seq_objc_from_refnum(refnum); diff --git a/bind/testdata/structs.go b/bind/testdata/structs.go index 2505062..5974bdc 100644 --- a/bind/testdata/structs.go +++ b/bind/testdata/structs.go @@ -38,3 +38,9 @@ func (s *S2) M() { func (_ *S2) String() string { return "" } + +// Structs is a struct with the same name as its package. +type Structs struct{} + +func (_ *Structs) M() { +} diff --git a/bind/testdata/structs.go.golden b/bind/testdata/structs.go.golden index 49e366f..817ec5d 100644 --- a/bind/testdata/structs.go.golden +++ b/bind/testdata/structs.go.golden @@ -102,6 +102,18 @@ func new_structs_S2() C.int32_t { return C.int32_t(_seq.ToRefNum(new(structs.S2))) } +//export proxystructs_Structs_M +func proxystructs_Structs_M(refnum C.int32_t) { + ref := _seq.FromRefNum(int32(refnum)) + v := ref.Get().(*structs.Structs) + v.M() +} + +//export new_structs_Structs +func new_structs_Structs() C.int32_t { + return C.int32_t(_seq.ToRefNum(new(structs.Structs))) +} + //export proxystructs_I_M func proxystructs_I_M(refnum C.int32_t) { ref := _seq.FromRefNum(int32(refnum)) diff --git a/bind/testdata/structs.java.c.golden b/bind/testdata/structs.java.c.golden index 52ca312..0934a11 100644 --- a/bind/testdata/structs.java.c.golden +++ b/bind/testdata/structs.java.c.golden @@ -16,6 +16,8 @@ jclass proxy_class_structs_S; jmethodID proxy_class_structs_S_cons; jclass proxy_class_structs_S2; jmethodID proxy_class_structs_S2_cons; +jclass proxy_class_structs_Structs; +jmethodID proxy_class_structs_Structs_cons; JNIEXPORT void JNICALL Java_structs_Structs__1init(JNIEnv *env, jclass _unused) { @@ -26,6 +28,9 @@ Java_structs_Structs__1init(JNIEnv *env, jclass _unused) { clazz = (*env)->FindClass(env, "structs/S2"); proxy_class_structs_S2 = (*env)->NewGlobalRef(env, clazz); proxy_class_structs_S2_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); + clazz = (*env)->FindClass(env, "structs/Structs_"); + proxy_class_structs_Structs = (*env)->NewGlobalRef(env, clazz); + proxy_class_structs_Structs_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); clazz = (*env)->FindClass(env, "structs/Structs$proxyI"); proxy_class_structs_I = (*env)->NewGlobalRef(env, clazz); proxy_class_structs_I_cons = (*env)->GetMethodID(env, clazz, "", "(Lgo/Seq$Ref;)V"); @@ -126,6 +131,18 @@ Java_structs_S2_string(JNIEnv* env, jobject __this__) { return _r0; } +JNIEXPORT jobject JNICALL +Java_structs_Structs_1__1_1New(JNIEnv *env, jclass clazz) { + int32_t refnum = new_structs_Structs(); + return go_seq_from_refnum(env, refnum, NULL, NULL); +} + +JNIEXPORT void JNICALL +Java_structs_Structs_1_m(JNIEnv* env, jobject __this__) { + int32_t o = go_seq_to_refnum_go(env, __this__); + proxystructs_Structs_M(o); +} + JNIEXPORT void JNICALL Java_structs_Structs_00024proxyI_m(JNIEnv* env, jobject __this__) { int32_t o = go_seq_to_refnum_go(env, __this__); diff --git a/bind/testdata/structs.java.golden b/bind/testdata/structs.java.golden index 9f5009e..e1aed3f 100644 --- a/bind/testdata/structs.java.golden +++ b/bind/testdata/structs.java.golden @@ -106,6 +106,51 @@ public final class S2 implements Seq.Proxy, I { } } +// Java class structs.Structs_ is a proxy for talking to a Go program. +// gobind -lang=java structs +// +// File is generated by gobind. Do not edit. +package structs; + +import go.Seq; + +public final class Structs_ implements Seq.Proxy, I { + static { Structs.touch(); } + + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + Structs_(Seq.Ref ref) { this.ref = ref; } + + public Structs_() { this.ref = __New(); } + + private static native Seq.Ref __New(); + + public native void m(); + @Override public boolean equals(Object o) { + if (o == null || !(o instanceof Structs_)) { + return false; + } + Structs_ that = (Structs_)o; + return true; + } + + @Override public int hashCode() { + return java.util.Arrays.hashCode(new Object[] {}); + } + + @Override public String toString() { + StringBuilder b = new StringBuilder(); + b.append("Structs_").append("{"); + return b.append("}").toString(); + } +} + // Java class structs.I is a proxy for talking to a Go program. // gobind -lang=java structs // diff --git a/bind/testdata/structs.java.h.golden b/bind/testdata/structs.java.h.golden index b80a847..4c84d34 100644 --- a/bind/testdata/structs.java.h.golden +++ b/bind/testdata/structs.java.h.golden @@ -17,4 +17,6 @@ extern jclass proxy_class_structs_S; extern jmethodID proxy_class_structs_S_cons; extern jclass proxy_class_structs_S2; extern jmethodID proxy_class_structs_S2_cons; +extern jclass proxy_class_structs_Structs; +extern jmethodID proxy_class_structs_Structs_cons; #endif diff --git a/bind/testdata/structs.objc.h.golden b/bind/testdata/structs.objc.h.golden index 0ba8eab..3522f1e 100644 --- a/bind/testdata/structs.objc.h.golden +++ b/bind/testdata/structs.objc.h.golden @@ -12,6 +12,7 @@ @class StructsS; @class StructsS2; +@class StructsStructs; @protocol StructsI; @class StructsI; @@ -43,6 +44,18 @@ - (NSString*)string; @end +/** + * Structs is a struct with the same name as its package. + */ +@interface StructsStructs : NSObject { +} +@property(strong, readonly) id _ref; + +- (instancetype)initWithRef:(id)ref; +- (instancetype)init; +- (void)m; +@end + FOUNDATION_EXPORT StructsS* StructsIdentity(StructsS* s); FOUNDATION_EXPORT StructsS* StructsIdentityWithError(StructsS* s, NSError** error); diff --git a/bind/testdata/structs.objc.m.golden b/bind/testdata/structs.objc.m.golden index 3d28302..87b1da8 100644 --- a/bind/testdata/structs.objc.m.golden +++ b/bind/testdata/structs.objc.m.golden @@ -123,6 +123,32 @@ @end + +@implementation StructsStructs { +} + +- (instancetype)initWithRef:(id)ref { + self = [super init]; + if (self) { __ref = ref; } + return self; +} + +- (instancetype)init { + self = [super init]; + if (self) { + __ref = go_seq_from_refnum(new_structs_Structs()); + } + return self; +} + +- (void)m { + int32_t refnum = go_seq_go_to_refnum(self._ref); + proxystructs_Structs_M(refnum); +} + +@end + + @implementation StructsI { } diff --git a/bind/testpkg/secondpkg/secondpkg.go b/bind/testpkg/secondpkg/secondpkg.go index 94f3e31..b7e7cd5 100644 --- a/bind/testpkg/secondpkg/secondpkg.go +++ b/bind/testpkg/secondpkg/secondpkg.go @@ -31,3 +31,14 @@ const HelloString = "secondpkg string" func Hello() string { return HelloString } + +type Secondpkg struct { + V string +} + +func (_ *Secondpkg) M() { +} + +func NewSecondpkg() *Secondpkg { + return new(Secondpkg) +} diff --git a/bind/testpkg/testpkg.go b/bind/testpkg/testpkg.go index f0cda07..8ebbcd3 100644 --- a/bind/testpkg/testpkg.go +++ b/bind/testpkg/testpkg.go @@ -606,3 +606,8 @@ func TestSIGPIPE() { panic(fmt.Errorf("got %v, expected EPIPE", err)) } } + +// Testpkg is an empty interface with the same name as its package. +type Testpkg interface{} + +func ClashingParameterFromOtherPackage(_ *secondpkg.Secondpkg) {}