From 89b83602188ee84018a2658a8f9f800b4bd80894 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 19 Sep 2016 12:44:13 +0200 Subject: [PATCH] bind: remove error wrappers to preserve error instance identity CL 24800 changed the error representation from strings to objects. However, since native errors types are not immediately compatible across languages, wrapper types were introduced to bridge the gap. This CL remove those wrappers and instead special case the error proxy types to conform to their language error protocol. Specifically: - The ObjC proxy for Go errors now extends NSError and calls initWithDomain to store the error message. - The Go proxy for ObjC NSError return the localizedDescription property for calls to Error. - The Java proxy for Go errors ow extends Exception and overrides getMessage() to return the error message. - The Go proxy for Java Exceptions returns getMessage whenever Error is called. The end result is that error values behave more like normal objects across the language boundary. In particular, instance identity is now preserved: an error passed across the boundary and back will result in the same instance. There are two semantic changes that followed this change: - The domain for wrapped Go errors is now always "go". The domain wasn't useful before this CL: the domains were set to the package name of function or method where the error happened to cross the language boundary. - If a Go method that returns an error is implemented in ObjC, the implementation must now both return NO _and_ set the error result for the calling Go code to receive a non-nil error. Before this CL, because errors were always wrapped, a nil ObjC could be represented with a non-nil wrapper. Change-Id: Idb415b6b13ecf79ccceb60f675059942bfc48fec Reviewed-on: https://go-review.googlesource.com/29298 Reviewed-by: David Crawshaw --- bind/genclasses.go | 4 +- bind/genjava.go | 49 ++++++---- bind/genobjc.go | 44 +++++---- bind/java/Seq.java | 28 +----- bind/java/SeqTest.java | 14 ++- bind/java/seq.h | 5 +- bind/java/seq_android.c.support | 30 +----- bind/objc/SeqTest.m | 19 +++- bind/objc/seq.h | 9 -- bind/objc/seq_darwin.m.support | 23 ----- bind/testdata/basictypes.objc.m.golden | 6 +- bind/testdata/classes.java.c.golden | 10 +- bind/testdata/classes.java.golden | 48 +++++----- bind/testdata/customprefix.objc.m.golden | 2 - bind/testdata/ignore.java.golden | 26 +++++- bind/testdata/ignore.objc.h.golden | 2 +- bind/testdata/ignore.objc.m.golden | 4 +- bind/testdata/interfaces.java.c.golden | 2 +- bind/testdata/interfaces.java.golden | 112 ++++++++++++++++++----- bind/testdata/interfaces.objc.h.golden | 16 ++-- bind/testdata/interfaces.objc.m.golden | 24 +++-- bind/testdata/issue10788.java.golden | 26 +++++- bind/testdata/issue10788.objc.h.golden | 2 +- bind/testdata/issue10788.objc.m.golden | 4 +- bind/testdata/issue12328.java.golden | 12 ++- bind/testdata/issue12328.objc.m.golden | 2 - bind/testdata/issue12403.java.c.golden | 2 +- bind/testdata/issue12403.java.golden | 14 ++- bind/testdata/issue12403.objc.h.golden | 2 +- bind/testdata/issue12403.objc.m.golden | 8 +- bind/testdata/java.java.golden | 56 +++++++++--- bind/testdata/keywords.java.golden | 14 ++- bind/testdata/keywords.objc.h.golden | 2 +- bind/testdata/keywords.objc.m.golden | 4 +- bind/testdata/structs.java.golden | 38 ++++++-- bind/testdata/structs.objc.h.golden | 2 +- bind/testdata/structs.objc.m.golden | 8 +- bind/testdata/try.objc.m.golden | 2 - bind/testdata/vars.java.golden | 26 +++++- bind/testdata/vars.objc.h.golden | 2 +- bind/testdata/vars.objc.m.golden | 4 +- bind/testpkg/testpkg.go | 10 ++ 42 files changed, 433 insertions(+), 284 deletions(-) diff --git a/bind/genclasses.go b/bind/genclasses.go index 30f375d..465a0c8 100644 --- a/bind/genclasses.go +++ b/bind/genclasses.go @@ -302,7 +302,7 @@ func (g *ClassGen) genCMethodBody(cls *java.Class, f *java.Func, virtual bool) { g.Printf(", _a%d", i) } g.Printf(");\n") - g.Printf("jobject _exc = go_seq_wrap_exception(env);\n") + g.Printf("jobject _exc = go_seq_get_exception(env);\n") g.Printf("int32_t _exc_ref = go_seq_to_refnum(env, _exc);\n") if f.Ret != nil { g.genJavaToC("res", f.Ret) @@ -370,7 +370,7 @@ func (g *ClassGen) genC(cls *java.Class) { g.Printf(", _a%d", i) } g.Printf(");\n") - g.Printf("jobject _exc = go_seq_wrap_exception(env);\n") + g.Printf("jobject _exc = go_seq_get_exception(env);\n") g.Printf("int32_t _exc_ref = go_seq_to_refnum(env, _exc);\n") if f.Ret != nil { g.genJavaToC("res", f.Ret) diff --git a/bind/genjava.go b/bind/genjava.go index 589af2f..ee5d65a 100644 --- a/bind/genjava.go +++ b/bind/genjava.go @@ -120,6 +120,15 @@ func (g *JavaGen) GenClass(idx int) error { return nil } +func (g *JavaGen) genProxyImpl(name string) { + g.Printf("private final Seq.Ref ref;\n\n") + g.Printf("@Override public final int incRefnum() {\n") + g.Printf(" int refnum = ref.refnum;\n") + g.Printf(" Seq.incGoRef(refnum);\n") + g.Printf(" return refnum;\n") + g.Printf("}\n\n") +} + func (g *JavaGen) genStruct(s structInfo) { pkgPath := "" if g.Pkg != nil { @@ -140,6 +149,8 @@ func (g *JavaGen) genStruct(s structInfo) { impls = append(impls, cls.Name) } } + } else { + impls = append(impls, "Seq.Proxy") } pT := types.NewPointer(s.obj.Type()) @@ -158,8 +169,6 @@ func (g *JavaGen) genStruct(s structInfo) { if jinf.extends != nil { g.Printf(" extends %s", jinf.extends.Name) } - } else { - g.Printf(" extends Seq.Proxy") } if len(impls) > 0 { g.Printf(" implements %s", strings.Join(impls, ", ")) @@ -168,8 +177,8 @@ func (g *JavaGen) genStruct(s structInfo) { g.Indent() g.Printf("static { %s.touch(); }\n\n", g.className()) + g.genProxyImpl(n) if jinf != nil { - g.Printf("private final Seq.Ref ref;\n\n") for _, f := range jinf.cons { if !g.isSigSupported(f.Type()) { g.Printf("// skipped constructor %s.%s with unsupported parameter or return types\n\n", n, f.Name()) @@ -184,13 +193,8 @@ func (g *JavaGen) genStruct(s structInfo) { g.Printf("public %s() { this.ref = __New(); }\n\n", n) g.Printf("private static native Seq.Ref __New();\n\n") } - g.Printf("@Override public final int incRefnum() {\n") - g.Printf(" int refnum = ref.refnum;\n") - g.Printf(" Seq.incGoRef(refnum);\n") - g.Printf(" return refnum;\n") - g.Printf("}\n\n") } else { - g.Printf("%s(Seq.Ref ref) { super(ref); }\n\n", n) + g.Printf("%s(Seq.Ref ref) { this.ref = ref; }\n\n", n) } for _, f := range fields { @@ -1090,7 +1094,7 @@ func (g *JavaGen) genMethodInterfaceProxy(oName string, m *types.Func) { rets = append(rets, retName) } if res.Len() == 2 || isErrorType(t) { - g.Printf("jobject exc = go_seq_wrap_exception(env);\n") + g.Printf("jobject exc = go_seq_get_exception(env);\n") errType := types.Universe.Lookup("error").Type() g.genJavaToC("exc", errType, modeRetained) retName = "_exc" @@ -1288,6 +1292,13 @@ func (g *JavaGen) GenC() error { g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+className(pkg)+"$proxy"+iface.obj.Name()) g.Printf("proxy_class_%s_%s = (*env)->NewGlobalRef(env, clazz);\n", g.pkgPrefix, iface.obj.Name()) g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"\", \"(Lgo/Seq$Ref;)V\");\n", g.pkgPrefix, iface.obj.Name()) + if isErrorType(iface.obj.Type()) { + // As a special case, Java Exceptions are passed to Go pretending to implement the Go error interface. + // To complete the illusion, use the Throwable.getMessage method for proxied calls to the error.Error method. + g.Printf("clazz = (*env)->FindClass(env, \"java/lang/Throwable\");\n") + 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()) for _, m := range iface.summary.callable { if !g.isSigSupported(m.Type()) { @@ -1390,12 +1401,22 @@ func (g *JavaGen) GenJava() error { g.Printf("private static native void _init();\n\n") for _, iface := range g.interfaces { - g.Printf(javaProxyPreamble, iface.obj.Name()) + n := iface.obj.Name() + g.Printf("private static final class proxy%s", n) + if isErrorType(iface.obj.Type()) { + g.Printf(" extends Exception") + } + g.Printf(" implements Seq.Proxy, %s {\n", n) g.Indent() + g.genProxyImpl("proxy" + n) + g.Printf("proxy%s(Seq.Ref ref) { this.ref = ref; }\n\n", n) + if isErrorType(iface.obj.Type()) { + g.Printf("@Override public String getMessage() { return error(); }\n\n") + } 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()) + g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", n, m.Name()) continue } g.Printf("public native ") @@ -1461,10 +1482,6 @@ func classNameFor(t types.Type) string { } const ( - javaProxyPreamble = `private static final class proxy%[1]s extends Seq.Proxy implements %[1]s { - proxy%[1]s(Seq.Ref ref) { super(ref); } - -` 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 49467f0..b1ab0ff 100644 --- a/bind/genobjc.go +++ b/bind/genobjc.go @@ -193,12 +193,8 @@ func (g *objcGen) gobindOpts() string { func (g *objcGen) genM() error { var pkgPath string - var errDomain string if g.Pkg != nil { pkgPath = g.Pkg.Path() - errDomain = "go." + pkgPath - } else { - errDomain = "go" } g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath) g.Printf("#include \n") @@ -206,8 +202,6 @@ func (g *objcGen) genM() error { g.Printf("#include \"_cgo_export.h\"\n") g.Printf("#include %q\n", g.namePrefix+".h") g.Printf("\n") - g.Printf("static NSString* errDomain = @%q;\n", errDomain) - g.Printf("\n") // struct for _, s := range g.structs { @@ -676,7 +670,7 @@ func (g *objcGen) genFunc(s *funcSummary, objName string) { if isErrorType(p.typ) { g.Printf("if (_%s != nil && %s != nil) {\n", p.name, p.name) g.Indent() - g.Printf("*%s = go_seq_to_nserror(_%s, errDomain);\n", p.name, p.name) + g.Printf("*%s = _%s;\n", p.name, p.name) g.Outdent() g.Printf("}\n") } else { @@ -696,14 +690,19 @@ func (g *objcGen) genFunc(s *funcSummary, objName string) { } func (g *objcGen) genInterfaceInterface(obj *types.TypeName, summary ifaceSummary, isProtocol bool) { - g.Printf("@interface %[1]s%[2]s : NSObject", g.namePrefix, obj.Name()) + g.Printf("@interface %[1]s%[2]s : ", g.namePrefix, obj.Name()) + if isErrorType(obj.Type()) { + g.Printf("NSError") + } else { + g.Printf("NSObject") + } if isProtocol { g.Printf(" <%[1]s%[2]s>", g.namePrefix, obj.Name()) } g.Printf(" {\n}\n") g.Printf("@property(strong, readonly) id _ref;\n") g.Printf("\n") - g.Printf("- (id)initWithRef:(id)ref;\n") + g.Printf("- (instancetype)initWithRef:(id)ref;\n") for _, m := range summary.callable { if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) @@ -740,10 +739,17 @@ func (g *objcGen) genInterfaceM(obj *types.TypeName, t *types.Interface) bool { g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name()) g.Printf("}\n") g.Printf("\n") - g.Printf("- (id)initWithRef:(id)ref {\n") + g.Printf("- (instancetype)initWithRef:(id)ref {\n") g.Indent() - g.Printf("self = [super init];\n") - g.Printf("if (self) { __ref = ref; }\n") + if isErrorType(obj.Type()) { + g.Printf("if (self) {\n") + g.Printf(" __ref = ref;\n") + g.Printf(" self = [super initWithDomain:@\"go\" code:1 userInfo:@{NSLocalizedDescriptionKey: [self error]}];\n") + g.Printf("}\n") + } else { + g.Printf("self = [super init];\n") + g.Printf("if (self) { __ref = ref; }\n") + } g.Printf("return self;\n") g.Outdent() g.Printf("}\n") @@ -790,10 +796,16 @@ func (g *objcGen) genInterfaceMethodProxy(obj *types.TypeName, m *types.Func) { } } - if s.ret == "void" { - g.Printf("[o %s];\n", s.callMethod(g)) + if isErrorType(obj.Type()) && m.Name() == "Error" { + // As a special case, ObjC NSErrors are passed to Go pretending to implement the Go error interface. + // They don't actually have an Error method, so calls to to it needs to be rerouted. + g.Printf("NSString *returnVal = [o localizedDescription];\n") } else { - g.Printf("%s returnVal = [o %s];\n", s.ret, s.callMethod(g)) + if s.ret == "void" { + g.Printf("[o %s];\n", s.callMethod(g)) + } else { + g.Printf("%s returnVal = [o %s];\n", s.ret, s.callMethod(g)) + } } if len(s.retParams) > 0 { @@ -812,7 +824,7 @@ func (g *objcGen) genInterfaceMethodProxy(obj *types.TypeName, m *types.Func) { g.Printf("if (%s != nil) {\n", p.name) } g.Indent() - g.Printf("_%[1]s = [[goSeqErrorWrapper alloc] initWithError:%[1]s];\n", p.name) + g.Printf("_%[1]s = %[1]s;\n", p.name) g.Outdent() g.Printf("}\n") g.genWrite("_"+p.name, p.typ, modeRetained) diff --git a/bind/java/Seq.java b/bind/java/Seq.java index 2d636a9..b421a93 100644 --- a/bind/java/Seq.java +++ b/bind/java/Seq.java @@ -9,7 +9,6 @@ import java.util.IdentityHashMap; import java.util.logging.Logger; import go.Universe; -import go.error; // Seq is a sequence of machine-dependent encoded values. // Used by automatically generated language bindings to talk to Go. @@ -48,18 +47,6 @@ public class Seq { private Seq() { } - private static void throwException(error err) throws Exception { - throw new Exception(err.error()); - } - - private static error wrapThrowable(final Throwable t) { - return new error() { - @Override public String error() { - return t.getMessage(); - } - }; - } - // ctx is an android.context.Context. static native void setContext(java.lang.Object ctx); @@ -105,23 +92,10 @@ public class Seq { // invalidating it before being translated on the Go side. int incRefnum(); } - // A Proxy is a Java object that proxies a Go object. Proxies, unlike // GoObjects, are unwrapped to their Go counterpart when deserialized // in Go. - public static abstract class Proxy implements GoObject { - private final Ref ref; - - protected Proxy(Ref ref) { - this.ref = ref; - } - - @Override public final int incRefnum() { - int refnum = ref.refnum; - Seq.incGoRef(refnum); - return refnum; - } - } + public interface Proxy extends GoObject {} // A Ref is an object tagged with an integer for passing back and // forth across the language boundary. diff --git a/bind/java/SeqTest.java b/bind/java/SeqTest.java index 6348e01..5e6af55 100644 --- a/bind/java/SeqTest.java +++ b/bind/java/SeqTest.java @@ -416,11 +416,19 @@ public class SeqTest extends InstrumentationTestCase { } public void testErrorField() { - final String want = "an error message"; Node n = Testpkg.newNode("ErrTest"); - n.setErr(new Exception(want)); + Exception want = new Exception("an error message"); + n.setErr(want); Exception got = n.getErr(); - assertEquals("want back the error message we set", want, got.getMessage()); + assertTrue("want back the error we set", want == got); + String msg = Testpkg.errorMessage(want); + assertEquals("the error message must match", want.getMessage(), msg); + } + + public void testErrorDup() { + Exception err = Testpkg.getGlobalErr(); + assertTrue("the Go error instance must preserve its identity", Testpkg.isGlobalErr(err)); + assertEquals("the Go error message must be preserved", "global err", err.getMessage()); } //test if we have JNI local reference table overflow error diff --git a/bind/java/seq.h b/bind/java/seq.h index 6c0ae58..363056d 100644 --- a/bind/java/seq.h +++ b/bind/java/seq.h @@ -39,9 +39,8 @@ extern int32_t go_seq_to_refnum_go(JNIEnv *env, jobject o); extern jobject go_seq_from_refnum(JNIEnv *env, int32_t refnum, jclass proxy_class, jmethodID proxy_cons); extern void go_seq_maybe_throw_exception(JNIEnv *env, jobject msg); -// go_seq_wrap_exception wraps a pending exception in a Java object implementing the -// golang/x/mobile/bind/errors.Error interface. If there is no pending exception, it returns NULL. -extern jobject go_seq_wrap_exception(JNIEnv *env); +// go_seq_get_exception returns any pending exception and clears the exception status. +extern jobject go_seq_get_exception(JNIEnv *env); extern jbyteArray go_seq_to_java_bytearray(JNIEnv *env, nbyteslice s, int copy); extern nbyteslice go_seq_from_java_bytearray(JNIEnv *env, jbyteArray s, int copy); diff --git a/bind/java/seq_android.c.support b/bind/java/seq_android.c.support index 19a57d3..495b9e2 100644 --- a/bind/java/seq_android.c.support +++ b/bind/java/seq_android.c.support @@ -25,13 +25,11 @@ static JavaVM *jvm; static pthread_key_t jnienvs; static jclass seq_class; -static jmethodID seq_throw_exc; static jmethodID seq_getRef; static jmethodID seq_decRef; static jmethodID seq_incRef; static jmethodID seq_incGoObjectRef; static jmethodID seq_incRefnum; -static jmethodID seq_wrapThrowable; static jfieldID ref_objField; @@ -60,23 +58,19 @@ static JNIEnv *go_seq_get_thread_env(void) { return env; } -void go_seq_maybe_throw_exception(JNIEnv *env, jobject msg) { - if (msg != NULL) { - if ((*env)->IsInstanceOf(env, msg, throwable_class)) { - (*env)->Throw(env, msg); - } else { - (*env)->CallStaticVoidMethod(env, seq_class, seq_throw_exc, msg); - } +void go_seq_maybe_throw_exception(JNIEnv *env, jobject exc) { + if (exc != NULL) { + (*env)->Throw(env, exc); } } -jobject go_seq_wrap_exception(JNIEnv *env) { +jobject go_seq_get_exception(JNIEnv *env) { jthrowable exc = (*env)->ExceptionOccurred(env); if (!exc) { return NULL; } (*env)->ExceptionClear(env); - return (*env)->CallStaticObjectMethod(env, seq_class, seq_wrapThrowable, exc); + return exc; } jbyteArray go_seq_to_java_bytearray(JNIEnv *env, nbyteslice s, int copy) { @@ -310,11 +304,6 @@ Java_go_Seq_init(JNIEnv *env, jclass clazz) { } seq_class = (*env)->NewGlobalRef(env, clazz); - seq_throw_exc = (*env)->GetStaticMethodID(env, seq_class, "throwException", "(Lgo/error;)V"); - if (seq_throw_exc == NULL) { - LOG_FATAL("failed to find method Seq.throwException"); - } - seq_getRef = (*env)->GetStaticMethodID(env, seq_class, "getRef", "(I)Lgo/Seq$Ref;"); if (seq_getRef == NULL) { LOG_FATAL("failed to find method Seq.getRef"); @@ -335,15 +324,6 @@ Java_go_Seq_init(JNIEnv *env, jclass clazz) { if (seq_incGoObjectRef == NULL) { LOG_FATAL("failed to find method Seq.incGoObjectRef"); } - seq_wrapThrowable = (*env)->GetStaticMethodID(env, seq_class, "wrapThrowable", "(Ljava/lang/Throwable;)Lgo/error;"); - if (seq_wrapThrowable == NULL) { - LOG_FATAL("failed to find method Seq.wrapThrowable"); - } - throwable_class = (*env)->FindClass(env, "java/lang/Throwable"); - if (throwable_class == NULL) { - LOG_FATAL("failed to find Throwable class"); - } - throwable_class = (*env)->NewGlobalRef(env, throwable_class); jclass ref_class = (*env)->FindClass(env, "go/Seq$Ref"); if (ref_class == NULL) { LOG_FATAL("failed to find the Seq.Ref class"); diff --git a/bind/objc/SeqTest.m b/bind/objc/SeqTest.m index 7709131..8fd15cf 100644 --- a/bind/objc/SeqTest.m +++ b/bind/objc/SeqTest.m @@ -35,6 +35,7 @@ static int numI = 0; } return true; } + *error = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:@{NSLocalizedDescriptionKey: @"NumberError"}]; return false; } @@ -295,12 +296,20 @@ static int numI = 0; } - (void)testErrorField { - NSString *want = @"an error message"; + NSString *wantMsg = @"an error message"; + NSError *want = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:@{NSLocalizedDescriptionKey: wantMsg}]; GoTestpkgNode *n = GoTestpkgNewNode(@"ErrTest"); - n.err = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:@{NSLocalizedDescriptionKey: want}]; + n.err = want; NSError *got = n.err; - NSString *gotMsg = [got.userInfo valueForKey:NSLocalizedDescriptionKey]; - XCTAssertEqualObjects(gotMsg, want, @"err = %@, want %@", gotMsg, want); + XCTAssertEqual(got, want, @"got different objects efter roundtrip"); + NSString *gotMsg = GoTestpkgErrorMessage(want); + XCTAssertEqualObjects(gotMsg, wantMsg, @"err = %@, want %@", gotMsg, wantMsg); +} + +- (void)testErrorDup { + NSError *err = GoTestpkg.globalErr; + XCTAssertTrue(GoTestpkgIsGlobalErr(err), @"A Go error must preserve its identity across the boundary"); + XCTAssertEqualObjects([err localizedDescription], @"global err", "A Go error message must be preserved"); } - (void)testVar { @@ -343,6 +352,8 @@ static int numI = 0; NSString *ret; NSError *error; XCTAssertFalse(GoTestpkgCallIStringError(num, @"alphabet", &ret, &error), @"GoTestpkgCallIStringError(Number, 'alphabet') succeeded; want error"); + NSString *desc = [error localizedDescription]; + XCTAssertEqualObjects(desc, @"NumberError", @"GoTestpkgCallIStringError(Number, 'alphabet') returned unexpected error message %@", desc); NSError *error2; XCTAssertTrue(GoTestpkgCallIStringError(num, @"number", &ret, &error2), @"GoTestpkgCallIStringError(Number, 'number') failed(%@); want success", error2); XCTAssertEqualObjects(ret, @"OK", @"GoTestpkgCallIStringError(Number, 'number') returned unexpected results %@", ret); diff --git a/bind/objc/seq.h b/bind/objc/seq.h index 8941760..f1f2e95 100644 --- a/bind/objc/seq.h +++ b/bind/objc/seq.h @@ -24,14 +24,6 @@ userInfo:NULL]; \ } -// goErrorWrapper is a adapter between an NSError * and the bind Error interface -@interface goSeqErrorWrapper : NSObject { -} -@property NSError *err; - -- (id)initWithError:(NSError *)err; -@end - // 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. @@ -92,6 +84,5 @@ extern nstring go_seq_from_objc_string(NSString *s); extern NSData *go_seq_to_objc_bytearray(nbyteslice, int copy); extern NSString *go_seq_to_objc_string(nstring str); -extern NSError *go_seq_to_nserror(id err, NSString *errDomain); #endif // __GO_SEQ_HDR__ diff --git a/bind/objc/seq_darwin.m.support b/bind/objc/seq_darwin.m.support index 933a35f..917a4ef 100644 --- a/bind/objc/seq_darwin.m.support +++ b/bind/objc/seq_darwin.m.support @@ -49,22 +49,6 @@ // Note that this file is copied into and compiled with the generated // bindings. -@implementation goSeqErrorWrapper { -} -@synthesize err; - -- (id)initWithError:(NSError *)e { - if (!(self = [super init])) - return nil; - self.err = e; - return self; -} - -- (NSString *)error { - return [self.err localizedDescription]; -} -@end - // A simple thread-safe mutable dictionary. @interface goSeqDictionary : NSObject { } @@ -250,13 +234,6 @@ nstring go_seq_from_objc_string(NSString *s) { return res; } -NSError *go_seq_to_nserror(id err, NSString *errDomain) { - NSString *errStr = [err error]; - NSMutableDictionary* details = [NSMutableDictionary dictionary]; - [details setValue:errStr forKey:NSLocalizedDescriptionKey]; - return [NSError errorWithDomain:errDomain code:1 userInfo:details]; -} - @implementation GoSeqRef { } diff --git a/bind/testdata/basictypes.objc.m.golden b/bind/testdata/basictypes.objc.m.golden index 2f8bff7..3dbe443 100644 --- a/bind/testdata/basictypes.objc.m.golden +++ b/bind/testdata/basictypes.objc.m.golden @@ -8,8 +8,6 @@ #include "_cgo_export.h" #include "GoBasictypes.h" -static NSString* errDomain = @"go.basictypes"; - const BOOL GoBasictypesABool = YES; const double GoBasictypesAFloat = 0.2015; NSString* const GoBasictypesALongString = @"LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString,LongString"; @@ -47,7 +45,7 @@ BOOL GoBasictypesError(NSError** error) { } } if (_error != nil && error != nil) { - *error = go_seq_to_nserror(_error, errDomain); + *error = _error; } return (_error == nil); } @@ -65,7 +63,7 @@ BOOL GoBasictypesErrorPair(long* ret0_, NSError** error) { } *ret0_ = _ret0_; if (_error != nil && error != nil) { - *error = go_seq_to_nserror(_error, errDomain); + *error = _error; } return (_error == nil); } diff --git a/bind/testdata/classes.java.c.golden b/bind/testdata/classes.java.c.golden index 41942e1..c8c6a73 100644 --- a/bind/testdata/classes.java.c.golden +++ b/bind/testdata/classes.java.c.golden @@ -39,7 +39,7 @@ jint cproxy_java_lang_Runnable_run(jint this) { // Must be a Java object jobject _this = go_seq_from_refnum(env, this, NULL, NULL); (*env)->CallVoidMethod(env, _this, m_java_lang_Runnable_run); - jobject _exc = go_seq_wrap_exception(env); + jobject _exc = go_seq_get_exception(env); int32_t _exc_ref = go_seq_to_refnum(env, _exc); go_seq_pop_local_frame(env); return _exc_ref; @@ -50,7 +50,7 @@ ret_jint cproxy_java_io_InputStream_read__(jint this) { // Must be a Java object jobject _this = go_seq_from_refnum(env, this, NULL, NULL); jint res = (*env)->CallIntMethod(env, _this, m_java_io_InputStream_read__); - jobject _exc = go_seq_wrap_exception(env); + jobject _exc = go_seq_get_exception(env); int32_t _exc_ref = go_seq_to_refnum(env, _exc); jint _res = res; go_seq_pop_local_frame(env); @@ -63,7 +63,7 @@ ret_jint csuper_java_io_InputStream_read__(jint this) { // Must be a Java object jobject _this = go_seq_from_refnum(env, this, NULL, NULL); jint res = (*env)->CallNonvirtualIntMethod(env, _this, class_java_io_InputStream, m_java_io_InputStream_read__); - jobject _exc = go_seq_wrap_exception(env); + jobject _exc = go_seq_get_exception(env); int32_t _exc_ref = go_seq_to_refnum(env, _exc); jint _res = res; go_seq_pop_local_frame(env); @@ -76,7 +76,7 @@ ret_jint cproxy_java_util_concurrent_Future_get__(jint this) { // Must be a Java object jobject _this = go_seq_from_refnum(env, this, NULL, NULL); jobject res = (*env)->CallObjectMethod(env, _this, m_java_util_concurrent_Future_get__); - jobject _exc = go_seq_wrap_exception(env); + jobject _exc = go_seq_get_exception(env); int32_t _exc_ref = go_seq_to_refnum(env, _exc); jint _res = go_seq_to_refnum(env, res); go_seq_pop_local_frame(env); @@ -91,7 +91,7 @@ ret_jint cproxy_java_util_concurrent_Future_get__JLjava_util_concurrent_TimeUnit jlong _a0 = a0; jobject _a1 = go_seq_from_refnum(env, a1, NULL, NULL); jobject res = (*env)->CallObjectMethod(env, _this, m_java_util_concurrent_Future_get__JLjava_util_concurrent_TimeUnit_2, _a0, _a1); - jobject _exc = go_seq_wrap_exception(env); + jobject _exc = go_seq_get_exception(env); int32_t _exc_ref = go_seq_to_refnum(env, _exc); jint _res = go_seq_to_refnum(env, res); go_seq_pop_local_frame(env); diff --git a/bind/testdata/classes.java.golden b/bind/testdata/classes.java.golden index 2716ec9..40d4999 100644 --- a/bind/testdata/classes.java.golden +++ b/bind/testdata/classes.java.golden @@ -11,18 +11,18 @@ public final class Future implements Seq.GoObject, java.util.concurrent.Future { private final Seq.Ref ref; + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + Future(Seq.Ref ref) { this.ref = ref; } public Future() { this.ref = __New(); } private static native Seq.Ref __New(); - @Override public final int incRefnum() { - int refnum = ref.refnum; - Seq.incGoRef(refnum); - return refnum; - } - public final native java.util.concurrent.Future getFuture(); public final native void setFuture(java.util.concurrent.Future v); @@ -43,6 +43,12 @@ public final class InputStream extends java.io.InputStream implements Seq.GoObje private final Seq.Ref ref; + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + public InputStream() { super(); this.ref = __NewInputStream(); @@ -50,12 +56,6 @@ public final class InputStream extends java.io.InputStream implements Seq.GoObje private static native Seq.Ref __NewInputStream(); - @Override public final int incRefnum() { - int refnum = ref.refnum; - Seq.incGoRef(refnum); - return refnum; - } - public final native java.io.InputStream getInputStream(); public final native void setInputStream(java.io.InputStream v); @@ -75,18 +75,18 @@ public final class Object extends java.lang.Object implements Seq.GoObject { private final Seq.Ref ref; + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + Object(Seq.Ref ref) { this.ref = ref; } public Object() { this.ref = __New(); } private static native Seq.Ref __New(); - @Override public final int incRefnum() { - int refnum = ref.refnum; - Seq.incGoRef(refnum); - return refnum; - } - public final native java.lang.Object getObject(); public final native void setObject(java.lang.Object v); @@ -105,18 +105,18 @@ public final class Runnable implements Seq.GoObject, java.lang.Runnable { private final Seq.Ref ref; + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + Runnable(Seq.Ref ref) { this.ref = ref; } public Runnable() { this.ref = __New(); } private static native Seq.Ref __New(); - @Override public final int incRefnum() { - int refnum = ref.refnum; - Seq.incGoRef(refnum); - return refnum; - } - public final native java.lang.Runnable getRunnable(); public final native void setRunnable(java.lang.Runnable v); diff --git a/bind/testdata/customprefix.objc.m.golden b/bind/testdata/customprefix.objc.m.golden index f8f7425..5eae706 100644 --- a/bind/testdata/customprefix.objc.m.golden +++ b/bind/testdata/customprefix.objc.m.golden @@ -8,8 +8,6 @@ #include "_cgo_export.h" #include "EXCustomprefix.h" -static NSString* errDomain = @"go.customprefix"; - void EXCustomprefixF() { proxycustomprefix__F(); diff --git a/bind/testdata/ignore.java.golden b/bind/testdata/ignore.java.golden index b273056..7a90fde 100644 --- a/bind/testdata/ignore.java.golden +++ b/bind/testdata/ignore.java.golden @@ -6,10 +6,18 @@ package go.ignore; import go.Seq; -public final class S extends Seq.Proxy implements I { +public final class S implements Seq.Proxy, I { static { Ignore.touch(); } - S(Seq.Ref ref) { super(ref); } + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + S(Seq.Ref ref) { this.ref = ref; } // skipped field S.F with unsupported type: *types.Interface @@ -75,9 +83,17 @@ public abstract class Ignore { private static native void _init(); - private static final class proxyI extends Seq.Proxy implements I { - proxyI(Seq.Ref ref) { super(ref); } - + private static final class proxyI implements Seq.Proxy, I { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyI(Seq.Ref ref) { this.ref = ref; } + // skipped method I.Argument with unsupported parameter or return types // skipped method I.Result with unsupported parameter or return types diff --git a/bind/testdata/ignore.objc.h.golden b/bind/testdata/ignore.objc.h.golden index 3515ac5..a47b512 100644 --- a/bind/testdata/ignore.objc.h.golden +++ b/bind/testdata/ignore.objc.h.golden @@ -55,7 +55,7 @@ } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; // skipped method I.Argument with unsupported parameter or return types // skipped method I.Result with unsupported parameter or return types diff --git a/bind/testdata/ignore.objc.m.golden b/bind/testdata/ignore.objc.m.golden index 57f1ba2..ed46739 100644 --- a/bind/testdata/ignore.objc.m.golden +++ b/bind/testdata/ignore.objc.m.golden @@ -8,8 +8,6 @@ #include "_cgo_export.h" #include "GoIgnore.h" -static NSString* errDomain = @"go.ignore"; - @implementation GoIgnoreS { } @@ -31,7 +29,7 @@ static NSString* errDomain = @"go.ignore"; @implementation GoIgnoreI { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; diff --git a/bind/testdata/interfaces.java.c.golden b/bind/testdata/interfaces.java.c.golden index 71b12b5..1295730 100644 --- a/bind/testdata/interfaces.java.c.golden +++ b/bind/testdata/interfaces.java.c.golden @@ -124,7 +124,7 @@ int32_t cproxyinterfaces_Error_Err(int32_t refnum) { JNIEnv *env = go_seq_push_local_frame(0); jobject o = go_seq_from_refnum(env, refnum, proxy_class_interfaces_Error, proxy_class_interfaces_Error_cons); (*env)->CallVoidMethod(env, o, mid_Error_Err); - jobject exc = go_seq_wrap_exception(env); + jobject exc = go_seq_get_exception(env); int32_t _exc = go_seq_to_refnum(env, exc); go_seq_pop_local_frame(env); return _exc; diff --git a/bind/testdata/interfaces.java.golden b/bind/testdata/interfaces.java.golden index 5c49ed0..8164d15 100644 --- a/bind/testdata/interfaces.java.golden +++ b/bind/testdata/interfaces.java.golden @@ -124,45 +124,109 @@ public abstract class Interfaces { private static native void _init(); - private static final class proxyError extends Seq.Proxy implements Error { - proxyError(Seq.Ref ref) { super(ref); } - + private static final class proxyError implements Seq.Proxy, Error { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyError(Seq.Ref ref) { this.ref = ref; } + public native void err() throws Exception; } - private static final class proxyI extends Seq.Proxy implements I { - proxyI(Seq.Ref ref) { super(ref); } - + private static final class proxyI implements Seq.Proxy, I { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyI(Seq.Ref ref) { this.ref = ref; } + public native int rand(); } - private static final class proxyI1 extends Seq.Proxy implements I1 { - proxyI1(Seq.Ref ref) { super(ref); } - + private static final class proxyI1 implements Seq.Proxy, I1 { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyI1(Seq.Ref ref) { this.ref = ref; } + public native void j(); } - private static final class proxyI2 extends Seq.Proxy implements I2 { - proxyI2(Seq.Ref ref) { super(ref); } - + private static final class proxyI2 implements Seq.Proxy, I2 { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyI2(Seq.Ref ref) { this.ref = ref; } + public native void g(); } - private static final class proxyI3 extends Seq.Proxy implements I3 { - proxyI3(Seq.Ref ref) { super(ref); } - + private static final class proxyI3 implements Seq.Proxy, I3 { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyI3(Seq.Ref ref) { this.ref = ref; } + public native I1 f(); } - private static final class proxyLargerI extends Seq.Proxy implements LargerI { - proxyLargerI(Seq.Ref ref) { super(ref); } - + private static final class proxyLargerI implements Seq.Proxy, LargerI { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyLargerI(Seq.Ref ref) { this.ref = ref; } + public native void anotherFunc(); public native int rand(); } - private static final class proxySameI extends Seq.Proxy implements SameI { - proxySameI(Seq.Ref ref) { super(ref); } - + private static final class proxySameI implements Seq.Proxy, SameI { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxySameI(Seq.Ref ref) { this.ref = ref; } + public native int rand(); } - private static final class proxyWithParam extends Seq.Proxy implements WithParam { - proxyWithParam(Seq.Ref ref) { super(ref); } - + private static final class proxyWithParam implements Seq.Proxy, WithParam { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyWithParam(Seq.Ref ref) { this.ref = ref; } + public native void hasParam(boolean p0); } diff --git a/bind/testdata/interfaces.objc.h.golden b/bind/testdata/interfaces.objc.h.golden index 4464d81..171c519 100644 --- a/bind/testdata/interfaces.objc.h.golden +++ b/bind/testdata/interfaces.objc.h.golden @@ -36,7 +36,7 @@ } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (void)j; @end @@ -44,7 +44,7 @@ } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (void)g; @end @@ -87,7 +87,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (BOOL)err:(NSError**)error; @end @@ -95,7 +95,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (int32_t)rand; @end @@ -103,7 +103,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (GoInterfacesI1*)f; @end @@ -111,7 +111,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (void)anotherFunc; - (int32_t)rand; @end @@ -120,7 +120,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (int32_t)rand; @end @@ -128,7 +128,7 @@ FOUNDATION_EXPORT id GoInterfacesSeven(); } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (void)hasParam:(BOOL)p0; @end diff --git a/bind/testdata/interfaces.objc.m.golden b/bind/testdata/interfaces.objc.m.golden index 47ccc23..4b7d5d4 100644 --- a/bind/testdata/interfaces.objc.m.golden +++ b/bind/testdata/interfaces.objc.m.golden @@ -8,12 +8,10 @@ #include "_cgo_export.h" #include "GoInterfaces.h" -static NSString* errDomain = @"go.interfaces"; - @implementation GoInterfacesError { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -31,7 +29,7 @@ static NSString* errDomain = @"go.interfaces"; } } if (_error != nil && error != nil) { - *error = go_seq_to_nserror(_error, errDomain); + *error = _error; } return (_error == nil); } @@ -42,7 +40,7 @@ static NSString* errDomain = @"go.interfaces"; @implementation GoInterfacesI { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -61,7 +59,7 @@ static NSString* errDomain = @"go.interfaces"; @implementation GoInterfacesI1 { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -78,7 +76,7 @@ static NSString* errDomain = @"go.interfaces"; @implementation GoInterfacesI2 { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -95,7 +93,7 @@ static NSString* errDomain = @"go.interfaces"; @implementation GoInterfacesI3 { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -121,7 +119,7 @@ static NSString* errDomain = @"go.interfaces"; @implementation GoInterfacesLargerI { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -145,7 +143,7 @@ static NSString* errDomain = @"go.interfaces"; @implementation GoInterfacesSameI { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -164,7 +162,7 @@ static NSString* errDomain = @"go.interfaces"; @implementation GoInterfacesWithParam { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -211,7 +209,7 @@ BOOL GoInterfacesCallErr(id e, NSError** error) { } } if (_error != nil && error != nil) { - *error = go_seq_to_nserror(_error, errDomain); + *error = _error; } return (_error == nil); } @@ -236,7 +234,7 @@ int32_t cproxyinterfaces_Error_Err(int32_t refnum) { BOOL returnVal = [o err:&error]; id _error = nil; if (!returnVal) { - _error = [[goSeqErrorWrapper alloc] initWithError:error]; + _error = error; } int32_t __error; if ([(id)(_error) isKindOfClass:[GoUniverseerror class]]) { diff --git a/bind/testdata/issue10788.java.golden b/bind/testdata/issue10788.java.golden index 4f23190..08d15f6 100644 --- a/bind/testdata/issue10788.java.golden +++ b/bind/testdata/issue10788.java.golden @@ -6,10 +6,18 @@ package go.issue10788; import go.Seq; -public final class TestStruct extends Seq.Proxy { +public final class TestStruct implements Seq.Proxy { static { Issue10788.touch(); } - TestStruct(Seq.Ref ref) { super(ref); } + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + TestStruct(Seq.Ref ref) { this.ref = ref; } public final native String getValue(); public final native void setValue(String v); @@ -78,9 +86,17 @@ public abstract class Issue10788 { private static native void _init(); - private static final class proxyTestInterface extends Seq.Proxy implements TestInterface { - proxyTestInterface(Seq.Ref ref) { super(ref); } - + private static final class proxyTestInterface implements Seq.Proxy, TestInterface { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyTestInterface(Seq.Ref ref) { this.ref = ref; } + public native void doSomeWork(TestStruct s); public native void multipleUnnamedParams(long p0, String p1, long p2); } diff --git a/bind/testdata/issue10788.objc.h.golden b/bind/testdata/issue10788.objc.h.golden index 7ef26c0..25c2e7d 100644 --- a/bind/testdata/issue10788.objc.h.golden +++ b/bind/testdata/issue10788.objc.h.golden @@ -33,7 +33,7 @@ } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (void)doSomeWork:(GoIssue10788TestStruct*)s; - (void)multipleUnnamedParams:(long)p0 p1:(NSString*)p1 p2:(int64_t)p2; @end diff --git a/bind/testdata/issue10788.objc.m.golden b/bind/testdata/issue10788.objc.m.golden index dfdf093..80fc8a5 100644 --- a/bind/testdata/issue10788.objc.m.golden +++ b/bind/testdata/issue10788.objc.m.golden @@ -8,8 +8,6 @@ #include "_cgo_export.h" #include "GoIssue10788.h" -static NSString* errDomain = @"go.issue10788"; - @implementation GoIssue10788TestStruct { } @@ -38,7 +36,7 @@ static NSString* errDomain = @"go.issue10788"; @implementation GoIssue10788TestInterface { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; diff --git a/bind/testdata/issue12328.java.golden b/bind/testdata/issue12328.java.golden index 1afcc1d..3dd20f9 100644 --- a/bind/testdata/issue12328.java.golden +++ b/bind/testdata/issue12328.java.golden @@ -6,10 +6,18 @@ package go.issue12328; import go.Seq; -public final class T extends Seq.Proxy { +public final class T implements Seq.Proxy { static { Issue12328.touch(); } - T(Seq.Ref ref) { super(ref); } + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + T(Seq.Ref ref) { this.ref = ref; } public final native java.lang.Exception getErr(); public final native void setErr(java.lang.Exception v); diff --git a/bind/testdata/issue12328.objc.m.golden b/bind/testdata/issue12328.objc.m.golden index 66969f4..7c5b8c0 100644 --- a/bind/testdata/issue12328.objc.m.golden +++ b/bind/testdata/issue12328.objc.m.golden @@ -8,8 +8,6 @@ #include "_cgo_export.h" #include "GoIssue12328.h" -static NSString* errDomain = @"go.issue12328"; - @implementation GoIssue12328T { } diff --git a/bind/testdata/issue12403.java.c.golden b/bind/testdata/issue12403.java.c.golden index cbb99ff..b641ba9 100644 --- a/bind/testdata/issue12403.java.c.golden +++ b/bind/testdata/issue12403.java.c.golden @@ -60,7 +60,7 @@ struct cproxyissue12403_Parsable_ToJSON_return cproxyissue12403_Parsable_ToJSON( jobject o = go_seq_from_refnum(env, refnum, proxy_class_issue12403_Parsable, proxy_class_issue12403_Parsable_cons); jstring res = (*env)->CallObjectMethod(env, o, mid_Parsable_ToJSON); nstring _res = go_seq_from_java_string(env, res); - jobject exc = go_seq_wrap_exception(env); + jobject exc = go_seq_get_exception(env); int32_t _exc = go_seq_to_refnum(env, exc); cproxyissue12403_Parsable_ToJSON_return sres = { _res, _exc diff --git a/bind/testdata/issue12403.java.golden b/bind/testdata/issue12403.java.golden index 30976be..50c81af 100644 --- a/bind/testdata/issue12403.java.golden +++ b/bind/testdata/issue12403.java.golden @@ -33,9 +33,17 @@ public abstract class Issue12403 { private static native void _init(); - private static final class proxyParsable extends Seq.Proxy implements Parsable { - proxyParsable(Seq.Ref ref) { super(ref); } - + private static final class proxyParsable implements Seq.Proxy, Parsable { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyParsable(Seq.Ref ref) { this.ref = ref; } + public native String fromJSON(String jstr); public native String toJSON() throws Exception; } diff --git a/bind/testdata/issue12403.objc.h.golden b/bind/testdata/issue12403.objc.h.golden index 5b9f310..14c7dad 100644 --- a/bind/testdata/issue12403.objc.h.golden +++ b/bind/testdata/issue12403.objc.h.golden @@ -23,7 +23,7 @@ } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (NSString*)fromJSON:(NSString*)jstr; - (BOOL)toJSON:(NSString**)ret0_ error:(NSError**)error; @end diff --git a/bind/testdata/issue12403.objc.m.golden b/bind/testdata/issue12403.objc.m.golden index 4a06e15..c453a52 100644 --- a/bind/testdata/issue12403.objc.m.golden +++ b/bind/testdata/issue12403.objc.m.golden @@ -8,12 +8,10 @@ #include "_cgo_export.h" #include "GoIssue12403.h" -static NSString* errDomain = @"go.issue12403"; - @implementation GoIssue12403Parsable { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -41,7 +39,7 @@ static NSString* errDomain = @"go.issue12403"; } *ret0_ = _ret0_; if (_error != nil && error != nil) { - *error = go_seq_to_nserror(_error, errDomain); + *error = _error; } return (_error == nil); } @@ -69,7 +67,7 @@ struct cproxyissue12403_Parsable_ToJSON_return cproxyissue12403_Parsable_ToJSON( nstring _ret0_ = go_seq_from_objc_string(ret0_); id _error = nil; if (!returnVal) { - _error = [[goSeqErrorWrapper alloc] initWithError:error]; + _error = error; } int32_t __error; if ([(id)(_error) isKindOfClass:[GoUniverseerror class]]) { diff --git a/bind/testdata/java.java.golden b/bind/testdata/java.java.golden index 3948a2b..74d9694 100644 --- a/bind/testdata/java.java.golden +++ b/bind/testdata/java.java.golden @@ -71,23 +71,55 @@ public abstract class Java { private static native void _init(); - private static final class proxyF extends Seq.Proxy implements F { - proxyF(Seq.Ref ref) { super(ref); } - + private static final class proxyF implements Seq.Proxy, F { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyF(Seq.Ref ref) { this.ref = ref; } + } - private static final class proxyO extends Seq.Proxy implements O { - proxyO(Seq.Ref ref) { super(ref); } - + private static final class proxyO implements Seq.Proxy, O { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyO(Seq.Ref ref) { this.ref = ref; } + // skipped method O.Super with unsupported parameter or return types } - private static final class proxyR extends Seq.Proxy implements R { - proxyR(Seq.Ref ref) { super(ref); } - + private static final class proxyR implements Seq.Proxy, R { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyR(Seq.Ref ref) { this.ref = ref; } + } - private static final class proxyS extends Seq.Proxy implements S { - proxyS(Seq.Ref ref) { super(ref); } - + private static final class proxyS implements Seq.Proxy, S { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyS(Seq.Ref ref) { this.ref = ref; } + // skipped method S.Super with unsupported parameter or return types } diff --git a/bind/testdata/keywords.java.golden b/bind/testdata/keywords.java.golden index b7f5ea1..04e7cb4 100644 --- a/bind/testdata/keywords.java.golden +++ b/bind/testdata/keywords.java.golden @@ -84,9 +84,17 @@ public abstract class Keywords { private static native void _init(); - private static final class proxyKeywordCaller extends Seq.Proxy implements KeywordCaller { - proxyKeywordCaller(Seq.Ref ref) { super(ref); } - + private static final class proxyKeywordCaller implements Seq.Proxy, KeywordCaller { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyKeywordCaller(Seq.Ref ref) { this.ref = ref; } + public native void abstract_(); public native void assert_(); public native void boolean_(); diff --git a/bind/testdata/keywords.objc.h.golden b/bind/testdata/keywords.objc.h.golden index df4c914..1cbdf7d 100644 --- a/bind/testdata/keywords.objc.h.golden +++ b/bind/testdata/keywords.objc.h.golden @@ -74,7 +74,7 @@ } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (void)abstract; - (void)assert; - (void)boolean; diff --git a/bind/testdata/keywords.objc.m.golden b/bind/testdata/keywords.objc.m.golden index d4f9d73..837ce6d 100644 --- a/bind/testdata/keywords.objc.m.golden +++ b/bind/testdata/keywords.objc.m.golden @@ -8,12 +8,10 @@ #include "_cgo_export.h" #include "GoKeywords.h" -static NSString* errDomain = @"go.keywords"; - @implementation GoKeywordsKeywordCaller { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; diff --git a/bind/testdata/structs.java.golden b/bind/testdata/structs.java.golden index 61402a3..306f597 100644 --- a/bind/testdata/structs.java.golden +++ b/bind/testdata/structs.java.golden @@ -6,10 +6,18 @@ package go.structs; import go.Seq; -public final class S extends Seq.Proxy { +public final class S implements Seq.Proxy { static { Structs.touch(); } - S(Seq.Ref ref) { super(ref); } + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + S(Seq.Ref ref) { this.ref = ref; } public final native double getX(); public final native void setX(double v); @@ -58,10 +66,18 @@ package go.structs; import go.Seq; -public final class S2 extends Seq.Proxy implements I { +public final class S2 implements Seq.Proxy, I { static { Structs.touch(); } - S2(Seq.Ref ref) { super(ref); } + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + S2(Seq.Ref ref) { this.ref = ref; } public native void m(); public native String string(); @@ -116,9 +132,17 @@ public abstract class Structs { private static native void _init(); - private static final class proxyI extends Seq.Proxy implements I { - proxyI(Seq.Ref ref) { super(ref); } - + private static final class proxyI implements Seq.Proxy, I { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyI(Seq.Ref ref) { this.ref = ref; } + public native void m(); } diff --git a/bind/testdata/structs.objc.h.golden b/bind/testdata/structs.objc.h.golden index 1512cf7..8a911bc 100644 --- a/bind/testdata/structs.objc.h.golden +++ b/bind/testdata/structs.objc.h.golden @@ -50,7 +50,7 @@ FOUNDATION_EXPORT BOOL GoStructsIdentityWithError(GoStructsS* s, GoStructsS** re } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; - (void)m; @end diff --git a/bind/testdata/structs.objc.m.golden b/bind/testdata/structs.objc.m.golden index e48173e..b66a3e3 100644 --- a/bind/testdata/structs.objc.m.golden +++ b/bind/testdata/structs.objc.m.golden @@ -8,8 +8,6 @@ #include "_cgo_export.h" #include "GoStructs.h" -static NSString* errDomain = @"go.structs"; - @implementation GoStructsS { } @@ -67,7 +65,7 @@ static NSString* errDomain = @"go.structs"; } *ret0_ = _ret0_; if (_error != nil && error != nil) { - *error = go_seq_to_nserror(_error, errDomain); + *error = _error; } return (_error == nil); } @@ -108,7 +106,7 @@ static NSString* errDomain = @"go.structs"; @implementation GoStructsI { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; @@ -170,7 +168,7 @@ BOOL GoStructsIdentityWithError(GoStructsS* s, GoStructsS** ret0_, NSError** err } *ret0_ = _ret0_; if (_error != nil && error != nil) { - *error = go_seq_to_nserror(_error, errDomain); + *error = _error; } return (_error == nil); } diff --git a/bind/testdata/try.objc.m.golden b/bind/testdata/try.objc.m.golden index 9750654..0a0c03c 100644 --- a/bind/testdata/try.objc.m.golden +++ b/bind/testdata/try.objc.m.golden @@ -8,8 +8,6 @@ #include "_cgo_export.h" #include "GoTry.h" -static NSString* errDomain = @"go.try"; - NSString* GoTryThis() { nstring r0 = proxytry__This(); diff --git a/bind/testdata/vars.java.golden b/bind/testdata/vars.java.golden index 665910c..c66da14 100644 --- a/bind/testdata/vars.java.golden +++ b/bind/testdata/vars.java.golden @@ -6,10 +6,18 @@ package go.vars; import go.Seq; -public final class S extends Seq.Proxy implements I { +public final class S implements Seq.Proxy, I { static { Vars.touch(); } - S(Seq.Ref ref) { super(ref); } + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + S(Seq.Ref ref) { this.ref = ref; } @Override public boolean equals(Object o) { if (o == null || !(o instanceof S)) { @@ -63,9 +71,17 @@ public abstract class Vars { private static native void _init(); - private static final class proxyI extends Seq.Proxy implements I { - proxyI(Seq.Ref ref) { super(ref); } - + private static final class proxyI implements Seq.Proxy, I { + private final Seq.Ref ref; + + @Override public final int incRefnum() { + int refnum = ref.refnum; + Seq.incGoRef(refnum); + return refnum; + } + + proxyI(Seq.Ref ref) { this.ref = ref; } + } diff --git a/bind/testdata/vars.objc.h.golden b/bind/testdata/vars.objc.h.golden index e1f45b8..4f15bc7 100644 --- a/bind/testdata/vars.objc.h.golden +++ b/bind/testdata/vars.objc.h.golden @@ -68,7 +68,7 @@ } @property(strong, readonly) id _ref; -- (id)initWithRef:(id)ref; +- (instancetype)initWithRef:(id)ref; @end #endif diff --git a/bind/testdata/vars.objc.m.golden b/bind/testdata/vars.objc.m.golden index 7331d71..8a69fb3 100644 --- a/bind/testdata/vars.objc.m.golden +++ b/bind/testdata/vars.objc.m.golden @@ -8,8 +8,6 @@ #include "_cgo_export.h" #include "GoVars.h" -static NSString* errDomain = @"go.vars"; - @implementation GoVarsS { } @@ -25,7 +23,7 @@ static NSString* errDomain = @"go.vars"; @implementation GoVarsI { } -- (id)initWithRef:(id)ref { +- (instancetype)initWithRef:(id)ref { self = [super init]; if (self) { __ref = ref; } return self; diff --git a/bind/testpkg/testpkg.go b/bind/testpkg/testpkg.go index a812e9e..091b640 100644 --- a/bind/testpkg/testpkg.go +++ b/bind/testpkg/testpkg.go @@ -537,3 +537,13 @@ func (ic *InitCaller) Init() {} type Issue17073 interface { OnError(err error) } + +func ErrorMessage(err error) string { + return err.Error() +} + +var GlobalErr error = errors.New("global err") + +func IsGlobalErr(err error) bool { + return GlobalErr == err +}