From d7fb1ce75784330950eb1403a64e092a448ebc5d Mon Sep 17 00:00:00 2001 From: "Hyang-Ah (Hana) Kim" Date: Tue, 9 Jun 2015 17:36:16 -0700 Subject: [PATCH] bind: fix a bug in handling func returning a struct. Change-Id: I63963c20c283638cfdc86b037f6aff70a115a78c Reviewed-on: https://go-review.googlesource.com/10893 Reviewed-by: David Crawshaw --- bind/genobjc.go | 19 ++++++++++++++++--- bind/testdata/structs.go | 4 ++++ bind/testdata/structs.go.golden | 14 ++++++++++++++ bind/testdata/structs.java.golden | 15 +++++++++++++++ bind/testdata/structs.objc.h.golden | 2 ++ bind/testdata/structs.objc.m.golden | 24 ++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/bind/genobjc.go b/bind/genobjc.go index 1cd2669..cff4d4a 100644 --- a/bind/genobjc.go +++ b/bind/genobjc.go @@ -302,7 +302,7 @@ func (g *objcGen) genFunc(pkgDesc, callDesc string, s *funcSummary, isMethod boo } g.Printf("go_seq_send(%s, %s, &in_, &out_);\n", pkgDesc, callDesc) - for _, p := range s.retParams { + for i, p := range s.retParams { if isErrorType(p.typ) { g.Printf("NSString* _%s = go_seq_readUTF8(&out_);\n", p.name) g.Printf("if ([_%s length] != 0 && %s != nil) {\n", p.name, p.name) @@ -312,9 +312,9 @@ func (g *objcGen) genFunc(pkgDesc, callDesc string, s *funcSummary, isMethod boo g.Printf("*%s = [NSError errorWithDomain:errDomain code:1 userInfo:details];\n", p.name) g.Outdent() g.Printf("}\n") - } else if s := g.seqType(p.typ); s != "Ref" { + } else if seqTyp := g.seqType(p.typ); seqTyp != "Ref" { g.Printf("%s %s = go_seq_read%s(&out_);\n", g.objcType(p.typ), p.name, g.seqType(p.typ)) - } else { + } else if i == len(s.retParams)-1 { // last, non-error type param. ptype := g.objcType(p.typ) g.Printf("GoSeqRef* %s_ref = go_seq_readRef(&out_);\n", p.name) g.Printf("%s %s = %s_ref.obj;\n", ptype, p.name, p.name) @@ -323,6 +323,19 @@ func (g *objcGen) genFunc(pkgDesc, callDesc string, s *funcSummary, isMethod boo g.Printf("%s = [[%s alloc] initWithRef:%s_ref];\n", p.name, ptype[:len(ptype)-1], p.name) g.Outdent() g.Printf("}\n") + } else { + ptype := g.objcType(p.typ) + g.Printf("GoSeqRef* %s_ref = go_seq_readRef(&out_);\n", p.name) + g.Printf("if (%s != NULL) {\n", p.name) + g.Indent() + g.Printf("*%s = %s_ref.obj;\n", p.name, p.name) + g.Printf("if (*%s == NULL) {\n", p.name) + g.Indent() + g.Printf("*%s = [[%s alloc] initWithRef:%s_ref];\n", p.name, ptype[:len(ptype)-1], p.name) + g.Outdent() + g.Printf("}\n") + g.Outdent() + g.Printf("}\n") } } diff --git a/bind/testdata/structs.go b/bind/testdata/structs.go index 3f1a4e3..7218ce0 100644 --- a/bind/testdata/structs.go +++ b/bind/testdata/structs.go @@ -16,3 +16,7 @@ func (s *S) Sum() float64 { func Identity(s *S) *S { return s } + +func IdentityWithError(s *S) (*S, error) { + return s, nil +} diff --git a/bind/testdata/structs.go.golden b/bind/testdata/structs.go.golden index ecf1dea..f55b3e1 100644 --- a/bind/testdata/structs.go.golden +++ b/bind/testdata/structs.go.golden @@ -17,6 +17,19 @@ func proxy_Identity(out, in *seq.Buffer) { out.WriteGoRef(res) } +func proxy_IdentityWithError(out, in *seq.Buffer) { + // Must be a Go object + param_s_ref := in.ReadRef() + param_s := param_s_ref.Get().(*structs.S) + res, err := structs.IdentityWithError(param_s) + out.WriteGoRef(res) + if err == nil { + out.WriteString("") + } else { + out.WriteString(err.Error()) + } +} + const ( proxyS_Descriptor = "go.structs.S" proxyS_X_Get_Code = 0x00f @@ -69,4 +82,5 @@ func init() { func init() { seq.Register("structs", 1, proxy_Identity) + seq.Register("structs", 2, proxy_IdentityWithError) } diff --git a/bind/testdata/structs.java.golden b/bind/testdata/structs.java.golden index 1805ef1..f1f8a1e 100644 --- a/bind/testdata/structs.java.golden +++ b/bind/testdata/structs.java.golden @@ -19,6 +19,20 @@ public abstract class Structs { return _result; } + public static S IdentityWithError(S s) throws Exception { + go.Seq _in = new go.Seq(); + go.Seq _out = new go.Seq(); + S _result; + _in.writeRef(s.ref()); + Seq.send(DESCRIPTOR, CALL_IdentityWithError, _in, _out); + _result = new S(_out.readRef()); + String _err = _out.readString(); + if (_err != null) { + throw new Exception(_err); + } + return _result; + } + public static final class S implements go.Seq.Object { private static final String DESCRIPTOR = "go.structs.S"; private static final int FIELD_X_GET = 0x00f; @@ -112,5 +126,6 @@ public abstract class Structs { } private static final int CALL_Identity = 1; + private static final int CALL_IdentityWithError = 2; private static final String DESCRIPTOR = "structs"; } diff --git a/bind/testdata/structs.objc.h.golden b/bind/testdata/structs.objc.h.golden index b5b0ca1..1a5b4bb 100644 --- a/bind/testdata/structs.objc.h.golden +++ b/bind/testdata/structs.objc.h.golden @@ -24,4 +24,6 @@ FOUNDATION_EXPORT GoStructs_S* GoStructs_Identity(GoStructs_S* s); +FOUNDATION_EXPORT BOOL GoStructs_IdentityWithError(GoStructs_S* s, GoStructs_S** ret0_, NSError** error); + #endif diff --git a/bind/testdata/structs.objc.m.golden b/bind/testdata/structs.objc.m.golden index 435f4c1..91e329a 100644 --- a/bind/testdata/structs.objc.m.golden +++ b/bind/testdata/structs.objc.m.golden @@ -12,6 +12,7 @@ static NSString *errDomain = @"go.structs"; #define _DESCRIPTOR_ "structs" #define _CALL_Identity_ 1 +#define _CALL_IdentityWithError_ 2 #define _GO_structs_S_DESCRIPTOR_ "go.structs.S" #define _GO_structs_S_FIELD_X_GET_ (0x00f) @@ -99,3 +100,26 @@ GoStructs_S* GoStructs_Identity(GoStructs_S* s) { return ret0_; } +BOOL GoStructs_IdentityWithError(GoStructs_S* s, GoStructs_S** ret0_, NSError** error) { + GoSeq in_ = {}; + GoSeq out_ = {}; + go_seq_writeRef(&in_, s.ref); + go_seq_send(_DESCRIPTOR_, _CALL_IdentityWithError_, &in_, &out_); + GoSeqRef* ret0__ref = go_seq_readRef(&out_); + if (ret0_ != NULL) { + *ret0_ = ret0__ref.obj; + if (*ret0_ == NULL) { + *ret0_ = [[GoStructs_S alloc] initWithRef:ret0__ref]; + } + } + NSString* _error = go_seq_readUTF8(&out_); + if ([_error length] != 0 && error != nil) { + NSMutableDictionary *details = [NSMutableDictionary dictionary]; + [details setValue:_error forKey:NSLocalizedDescriptionKey]; + *error = [NSError errorWithDomain:errDomain code:1 userInfo:details]; + } + go_seq_free(&in_); + go_seq_free(&out_); + return ([_error length] == 0); +} +