func (g *ObjcGen) genInterfaceInterface(obj *types.TypeName, summary ifaceSummary, isProtocol bool) { g.Printf("@interface %[1]s%[2]s : ", g.namePrefix, obj.Name()) if isErrorType(obj.Type()) { g.Printf("NSError") } else { g.Printf("NSObject") } prots := []string{"goSeqRefInterface"} if isProtocol { 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") 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()) continue } s := g.funcSummary(nil, m) g.Printf("- %s;\n", s.asMethod(g)) } g.Printf("@end\n") }
func (g *objcGen) genStructH(obj *types.TypeName, t *types.Struct) { g.Printf("@interface %s%s : NSObject {\n", g.namePrefix, obj.Name()) g.Printf("}\n") g.Printf("@property(strong, readonly) id _ref;\n") g.Printf("\n") g.Printf("- (id)initWithRef:(id)ref;\n") // accessors to exported fields. for _, f := range exportedFields(t) { if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", obj.Name(), f.Name(), t) continue } name, typ := f.Name(), g.objcFieldType(f.Type()) g.Printf("- (%s)%s;\n", typ, lowerFirst(name)) g.Printf("- (void)set%s:(%s)v;\n", name, typ) } // exported methods for _, m := range exportedMethodSet(types.NewPointer(obj.Type())) { 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) g.Printf("- %s;\n", lowerFirst(s.asMethod(g))) } g.Printf("@end\n") }
func (g *objcGen) genInterfaceH(obj *types.TypeName, t *types.Interface) { g.Printf("@protocol %s%s\n", g.namePrefix, obj.Name()) for _, m := range exportedMethodSet(obj.Type()) { s := g.funcSummary(m) g.Printf("- %s;\n", s.asMethod(g)) } g.Printf("@end\n") }
func (g *ObjcGen) genStructM(obj *types.TypeName, t *types.Struct) { fields := exportedFields(t) 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") g.Indent() g.Printf("self = [super init];\n") g.Printf("if (self) { __ref = ref; }\n") 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()) { g.Printf("// skipped unsupported field %s with type %T\n\n", f.Name(), f) continue } g.genGetter(obj.Name(), f) g.genSetter(obj.Name(), f) } for _, m := range methods { 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(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\n") }
func newStruct(p *Package, obj *types.TypeName) (Struct, error) { sym := p.syms.symtype(obj.Type()) if sym == nil { panic(fmt.Errorf("no such object [%s] in symbols table", obj.Id())) } sym.doc = p.getDoc("", obj) s := Struct{ pkg: p, sym: sym, obj: obj, } return s, nil }
func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { fields := exportedFields(T) methods := exportedMethodSet(types.NewPointer(obj.Type())) for _, f := range fields { if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", obj.Name(), f.Name(), t) continue } g.Printf("//export proxy%s_%s_%s_Set\n", g.pkgPrefix, obj.Name(), f.Name()) g.Printf("func proxy%s_%s_%s_Set(refnum C.int32_t, v C.%s) {\n", g.pkgPrefix, obj.Name(), f.Name(), g.cgoType(f.Type())) g.Indent() g.Printf("ref := _seq.FromRefNum(int32(refnum))\n") g.genRead("_v", "v", f.Type(), modeRetained) g.Printf("ref.Get().(*%s%s).%s = _v\n", g.pkgName(g.Pkg), obj.Name(), f.Name()) g.Outdent() g.Printf("}\n\n") g.Printf("//export proxy%s_%s_%s_Get\n", g.pkgPrefix, obj.Name(), f.Name()) g.Printf("func proxy%s_%s_%s_Get(refnum C.int32_t) C.%s {\n", g.pkgPrefix, obj.Name(), f.Name(), g.cgoType(f.Type())) g.Indent() g.Printf("ref := _seq.FromRefNum(int32(refnum))\n") g.Printf("v := ref.Get().(*%s%s).%s\n", g.pkgName(g.Pkg), obj.Name(), f.Name()) g.genWrite("_v", "v", f.Type(), modeRetained) g.Printf("return _v\n") g.Outdent() g.Printf("}\n\n") } for _, m := range methods { if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } g.genFuncSignature(m, obj.Name()) g.Indent() g.Printf("ref := _seq.FromRefNum(int32(refnum))\n") g.Printf("v := ref.Get().(*%s%s)\n", g.pkgName(g.Pkg), obj.Name()) g.genFuncBody(m, "v.") g.Outdent() g.Printf("}\n\n") } // Export constructor for ObjC and Java default no-arg constructors g.Printf("//export new_%s_%s\n", g.Pkg.Name(), obj.Name()) g.Printf("func new_%s_%s() C.int32_t {\n", g.Pkg.Name(), obj.Name()) g.Indent() g.Printf("return C.int32_t(_seq.ToRefNum(new(%s%s)))\n", g.pkgName(g.Pkg), obj.Name()) g.Outdent() g.Printf("}\n") }
func (c *converter) convertTypeName(v *gotypes.TypeName) *types.TypeName { if v == nil { return nil } if v, ok := c.converted[v]; ok { return v.(*types.TypeName) } // This part is a bit tricky. gcimport calls NewTypeName with a nil typ // argument, and then calls NewNamed on the resulting *TypeName, which // sets its typ to a *Named referring to itself. So if we get a *TypeName // whose Type() is a *Named whose Obj() is the same *TypeName, we know it // was constructed this way, so we do the same. Otherwise we get into a // infinite recursion converting the *TypeName's type. var typ types.Type if named, ok := v.Type().(*gotypes.Named); !ok || named.Obj() != v { typ = c.convertType(v.Type()) } ret := types.NewTypeName( token.Pos(v.Pos()), c.convertPackage(v.Pkg()), v.Name(), typ, ) c.converted[v] = ret named := types.NewNamed(ret, c.convertType(v.Type().Underlying()), nil) c.converted[v.Type()] = named return ret }
func (g *ObjcGen) genStructH(obj *types.TypeName, t *types.Struct) { 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 <goSeqRefInterface>") } 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) { if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", obj.Name(), f.Name(), t) continue } name, typ := f.Name(), g.objcFieldType(f.Type()) g.Printf("- (%s)%s;\n", typ, objcNameReplacer(lowerFirst(name))) g.Printf("- (void)set%s:(%s)v;\n", name, typ) } // exported methods for _, m := range exportedMethodSet(types.NewPointer(obj.Type())) { 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(g.ostructs[obj], m) g.Printf("- %s;\n", objcNameReplacer(lowerFirst(s.asMethod(g)))) } g.Printf("@end\n") }
func (g *JavaGen) genFromRefnum(toName, fromName string, t types.Type, o *types.TypeName) { oPkg := o.Pkg() isJava := isJavaType(o.Type()) if !isErrorType(o.Type()) && !g.validPkg(oPkg) && !isJava { g.errorf("type %s is defined in package %s, which is not bound", t, oPkg) return } p := pkgPrefix(oPkg) g.Printf("jobject %s = go_seq_from_refnum(env, %s, ", toName, fromName) if isJava { g.Printf("NULL, NULL") } else { g.Printf("proxy_class_%s_%s, proxy_class_%s_%s_cons", p, o.Name(), p, o.Name()) } g.Printf(");\n") }
// methodsFor returns the named type and corresponding methods if the type // denoted by obj is not an interface and has methods. Otherwise it returns // the zero value. func methodsFor(obj *types.TypeName) (*types.Named, []*types.Selection) { named, _ := obj.Type().(*types.Named) if named == nil { // A type name's type can also be the // exported basic type unsafe.Pointer. return nil, nil } if _, ok := named.Underlying().(*types.Interface); ok { // ignore interfaces return nil, nil } methods := combinedMethodSet(named) if len(methods) == 0 { return nil, nil } return named, methods }
func methodDocComment(prog *loader.Program, tname *types.TypeName, methodName string) (string, error) { t := tname.Type() if !types.IsInterface(t) { // Use the pointer type to get as many methods as possible. t = types.NewPointer(t) } mset := types.NewMethodSet(t) sel := mset.Lookup(nil, methodName) if sel == nil { return "", errgo.Newf("cannot find method %v on %v", methodName, t) } obj := sel.Obj() decl, err := findDecl(prog, obj.Pos()) if err != nil { return "", errgo.Mask(err) } switch decl := decl.(type) { case *ast.GenDecl: if decl.Tok != token.TYPE { return "", errgo.Newf("found non-type decl %#v", decl) } for _, spec := range decl.Specs { tspec := spec.(*ast.TypeSpec) it := tspec.Type.(*ast.InterfaceType) for _, m := range it.Methods.List { for _, id := range m.Names { if id.Pos() == obj.Pos() { return m.Doc.Text(), nil } } } } return "", errgo.Newf("method definition not found in type") case *ast.FuncDecl: if decl.Name.Pos() != obj.Pos() { return "", errgo.Newf("method definition not found (at %#v)", prog.Fset.Position(obj.Pos())) } return decl.Doc.Text(), nil default: return "", errgo.Newf("unexpected declaration %T found", decl) } }
func (g *objcGen) genStructH(obj *types.TypeName, t *types.Struct) { g.Printf("@interface %s%s : NSObject {\n", g.namePrefix, obj.Name()) g.Printf("}\n") g.Printf("@property(strong, readonly) id _ref;\n") g.Printf("\n") g.Printf("- (id)initWithRef:(id)ref;\n") // accessors to exported fields. for _, f := range exportedFields(t) { name, typ := f.Name(), g.objcFieldType(f.Type()) g.Printf("- (%s)%s;\n", typ, lowerFirst(name)) g.Printf("- (void)set%s:(%s)v;\n", name, typ) } // exported methods for _, m := range exportedMethodSet(types.NewPointer(obj.Type())) { s := g.funcSummary(m) g.Printf("- %s;\n", lowerFirst(s.asMethod(g))) } g.Printf("@end\n") }
func (g *ObjcGen) genInterfaceM(obj *types.TypeName, t *types.Interface) bool { summary := makeIfaceSummary(t) // @implementation Interface -- similar to what genStructM does. g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name()) g.Printf("}\n") g.Printf("\n") g.Printf("- (instancetype)initWithRef:(id)ref {\n") g.Indent() 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") g.Printf("\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()) continue } s := g.funcSummary(nil, 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("\n") return summary.implementable }
func (g *objcGen) genStructM(obj *types.TypeName, t *types.Struct) { fields := exportedFields(t) methods := exportedMethodSet(types.NewPointer(obj.Type())) desc := fmt.Sprintf("_GO_%s_%s", g.pkgName, obj.Name()) g.Printf("#define %s_DESCRIPTOR_ \"go.%s.%s\"\n", desc, g.pkgName, obj.Name()) for i, f := range fields { g.Printf("#define %s_FIELD_%s_GET_ (0x%x0f)\n", desc, f.Name(), i) g.Printf("#define %s_FIELD_%s_SET_ (0x%x1f)\n", desc, f.Name(), i) } for i, m := range methods { g.Printf("#define %s_%s_ (0x%x0c)\n", desc, m.Name(), i) } g.Printf("\n") g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name()) g.Printf("}\n\n") g.Printf("- (id)initWithRef:(id)ref {\n") g.Indent() g.Printf("self = [super init];\n") g.Printf("if (self) { __ref = ref; }\n") g.Printf("return self;\n") g.Outdent() g.Printf("}\n\n") for _, f := range fields { g.genGetter(desc, f) g.genSetter(desc, f) } for _, m := range methods { s := g.funcSummary(m) g.Printf("- %s {\n", s.asMethod(g)) g.Indent() g.genFunc(desc+"_DESCRIPTOR_", desc+"_"+m.Name()+"_", s, true) g.Outdent() g.Printf("}\n\n") } g.Printf("@end\n") }
func (g *javaGen) genInterface(o *types.TypeName) { iface := o.Type().(*types.Named).Underlying().(*types.Interface) summary := makeIfaceSummary(iface) g.Printf("public interface %s extends go.Seq.Object {\n", o.Name()) g.Indent() methodSigErr := false for _, m := range summary.callable { if err := g.funcSignature(m, false); err != nil { methodSigErr = true g.errorf("%v", err) } g.Printf(";\n\n") } if methodSigErr { return // skip stub generation, more of the same errors } if summary.implementable { g.genInterfaceStub(o, iface) } g.Printf(javaProxyPreamble, o.Name()) g.Indent() for _, m := range summary.callable { g.genFunc(m, true) } for i, m := range summary.callable { g.Printf("static final int CALL_%s = 0x%x0a;\n", m.Name(), i+1) } g.Outdent() g.Printf("}\n") g.Outdent() g.Printf("}\n\n") }
func (w *Walker) emitType(obj *types.TypeName) { name := obj.Name() typ := obj.Type() switch typ := typ.Underlying().(type) { case *types.Struct: w.emitStructType(name, typ) case *types.Interface: w.emitIfaceType(name, typ) return // methods are handled by emitIfaceType default: w.emitf("type %s %s", name, w.typeString(typ.Underlying())) } // emit methods with value receiver var methodNames map[string]bool vset := types.NewMethodSet(typ) for i, n := 0, vset.Len(); i < n; i++ { m := vset.At(i) if m.Obj().Exported() { w.emitMethod(m) if methodNames == nil { methodNames = make(map[string]bool) } methodNames[m.Obj().Name()] = true } } // emit methods with pointer receiver; exclude // methods that we have emitted already // (the method set of *T includes the methods of T) pset := types.NewMethodSet(types.NewPointer(typ)) for i, n := 0, pset.Len(); i < n; i++ { m := pset.At(i) if m.Obj().Exported() && !methodNames[m.Obj().Name()] { w.emitMethod(m) } } }
func (g *javaGen) genInterface(o *types.TypeName) { iface := o.Type().(*types.Named).Underlying().(*types.Interface) g.Printf("public interface %s extends go.Seq.Object {\n", o.Name()) g.Indent() methodSigErr := false for i := 0; i < iface.NumMethods(); i++ { if err := g.funcSignature(iface.Method(i), false); err != nil { methodSigErr = true g.errorf("%v", err) } g.Printf(";\n\n") } if methodSigErr { return // skip stub generation, more of the same errors } g.genInterfaceStub(o, iface) g.Printf(javaProxyPreamble, o.Name()) g.Indent() for i := 0; i < iface.NumMethods(); i++ { g.genFunc(iface.Method(i), true) } for i := 0; i < iface.NumMethods(); i++ { g.Printf("static final int CALL_%s = 0x%x0a;\n", iface.Method(i).Name(), i+1) } g.Outdent() g.Printf("}\n") g.Outdent() g.Printf("}\n\n") }
func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { fields := exportedFields(T) methods := exportedMethodSet(types.NewPointer(obj.Type())) g.Printf("const (\n") g.Indent() g.Printf("proxy%s_Descriptor = \"go.%s.%s\"\n", obj.Name(), g.pkg.Name(), obj.Name()) for i, f := range fields { g.Printf("proxy%s_%s_Get_Code = 0x%x0f\n", obj.Name(), f.Name(), i) g.Printf("proxy%s_%s_Set_Code = 0x%x1f\n", obj.Name(), f.Name(), i) } for i, m := range methods { g.Printf("proxy%s_%s_Code = 0x%x0c\n", obj.Name(), m.Name(), i) } g.Outdent() g.Printf(")\n\n") g.Printf("type proxy%s seq.Ref\n\n", obj.Name()) for _, f := range fields { seqTyp := seqType(f.Type()) g.Printf("func proxy%s_%s_Set(out, in *seq.Buffer) {\n", obj.Name(), f.Name()) g.Indent() g.Printf("ref := in.ReadRef()\n") g.Printf("v := in.Read%s()\n", seqTyp) if seqTyp == "Ref" { g.Printf("ref.Get().(*%s.%s).%s = v.Get().(%s)\n", g.pkg.Name(), obj.Name(), f.Name(), g.typeString(f.Type())) } else { // TODO(crawshaw): other kinds of non-ptr types. g.Printf("ref.Get().(*%s.%s).%s = v\n", g.pkg.Name(), obj.Name(), f.Name()) } g.Outdent() g.Printf("}\n\n") g.Printf("func proxy%s_%s_Get(out, in *seq.Buffer) {\n", obj.Name(), f.Name()) g.Indent() g.Printf("ref := in.ReadRef()\n") g.Printf("v := ref.Get().(*%s.%s).%s\n", g.pkg.Name(), obj.Name(), f.Name()) if seqTyp == "Ref" { g.Printf("out.WriteGoRef(v)\n") } else { g.Printf("out.Write%s(v)\n", seqTyp) } g.Outdent() g.Printf("}\n\n") } for _, m := range methods { g.Printf("func proxy%s_%s(out, in *seq.Buffer) {\n", obj.Name(), m.Name()) g.Indent() g.Printf("ref := in.ReadRef()\n") g.Printf("v := ref.Get().(*%s.%s)\n", g.pkg.Name(), obj.Name()) g.genFuncBody(m, "v") g.Outdent() g.Printf("}\n\n") } g.Printf("func init() {\n") g.Indent() for _, f := range fields { n := f.Name() g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Set_Code, proxy%s_%s_Set)\n", obj.Name(), obj.Name(), n, obj.Name(), n) g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Get_Code, proxy%s_%s_Get)\n", obj.Name(), obj.Name(), n, obj.Name(), n) } for _, m := range methods { n := m.Name() g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Code, proxy%s_%s)\n", obj.Name(), obj.Name(), n, obj.Name(), n) } g.Outdent() g.Printf("}\n\n") }
func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { fields := exportedFields(T) methods := exportedMethodSet(types.NewPointer(obj.Type())) g.Printf("public static final class %s implements go.Seq.Object {\n", obj.Name()) g.Indent() g.Printf("private static final String DESCRIPTOR = \"go.%s.%s\";\n", g.pkg.Name(), obj.Name()) for i, f := range fields { g.Printf("private static final int FIELD_%s_GET = 0x%x0f;\n", f.Name(), i) g.Printf("private static final int FIELD_%s_SET = 0x%x1f;\n", f.Name(), i) } for i, m := range methods { g.Printf("private static final int CALL_%s = 0x%x0c;\n", m.Name(), i) } g.Printf("\n") g.Printf("private go.Seq.Ref ref;\n\n") n := obj.Name() g.Printf("private %s(go.Seq.Ref ref) { this.ref = ref; }\n\n", n) g.Printf(`public go.Seq.Ref ref() { return ref; } public void call(int code, go.Seq in, go.Seq out) { throw new RuntimeException("internal error: cycle: cannot call concrete proxy"); } `) for _, f := range fields { g.Printf("public %s get%s() {\n", g.javaType(f.Type()), f.Name()) g.Indent() g.Printf("Seq in = new Seq();\n") g.Printf("Seq out = new Seq();\n") g.Printf("in.writeRef(ref);\n") g.Printf("Seq.send(DESCRIPTOR, FIELD_%s_GET, in, out);\n", f.Name()) if seqType(f.Type()) == "Ref" { g.Printf("return new %s(out.read%s);\n", g.javaType(f.Type()), seqRead(f.Type())) } else { g.Printf("return out.read%s;\n", seqRead(f.Type())) } g.Outdent() g.Printf("}\n\n") g.Printf("public void set%s(%s v) {\n", f.Name(), g.javaType(f.Type())) g.Indent() g.Printf("Seq in = new Seq();\n") g.Printf("Seq out = new Seq();\n") g.Printf("in.writeRef(ref);\n") g.Printf("in.write%s;\n", seqWrite(f.Type(), "v")) g.Printf("Seq.send(DESCRIPTOR, FIELD_%s_SET, in, out);\n", f.Name()) g.Outdent() g.Printf("}\n\n") } for _, m := range methods { g.genFunc(m, true) } g.Printf("@Override public boolean equals(Object o) {\n") g.Indent() g.Printf("if (o == null || !(o instanceof %s)) {\n return false;\n}\n", n) g.Printf("%s that = (%s)o;\n", n, n) for _, f := range fields { nf := f.Name() g.Printf("%s this%s = get%s();\n", g.javaType(f.Type()), nf, nf) g.Printf("%s that%s = that.get%s();\n", g.javaType(f.Type()), nf, nf) if isJavaPrimitive(f.Type()) { g.Printf("if (this%s != that%s) {\n return false;\n}\n", nf, nf) } else { g.Printf("if (this%s == null) {\n", nf) g.Indent() g.Printf("if (that%s != null) {\n return false;\n}\n", nf) g.Outdent() g.Printf("} else if (!this%s.equals(that%s)) {\n return false;\n}\n", nf, nf) } } g.Printf("return true;\n") g.Outdent() g.Printf("}\n\n") g.Printf("@Override public int hashCode() {\n") g.Printf(" return java.util.Arrays.hashCode(new Object[] {") for i, f := range fields { if i > 0 { g.Printf(", ") } g.Printf("get%s()", f.Name()) } g.Printf("});\n") g.Printf("}\n\n") // TODO(crawshaw): use String() string if it is defined. g.Printf("@Override public String toString() {\n") g.Indent() g.Printf("StringBuilder b = new StringBuilder();\n") g.Printf(`b.append("%s").append("{");`, obj.Name()) g.Printf("\n") for _, f := range fields { n := f.Name() g.Printf(`b.append("%s:").append(get%s()).append(",");`, n, n) g.Printf("\n") } g.Printf(`return b.append("}").toString();`) g.Printf("\n") g.Outdent() g.Printf("}\n\n") g.Outdent() g.Printf("}\n\n") }
func (g *goGen) genInterface(obj *types.TypeName) { iface := obj.Type().(*types.Named).Underlying().(*types.Interface) ifaceDesc := fmt.Sprintf("go.%s.%s", g.pkg.Name(), obj.Name()) summary := makeIfaceSummary(iface) // Descriptor and code for interface methods. g.Printf("const (\n") g.Indent() g.Printf("proxy%s_Descriptor = %q\n", obj.Name(), ifaceDesc) for i, m := range summary.callable { g.Printf("proxy%s_%s_Code = 0x%x0a\n", obj.Name(), m.Name(), i+1) } g.Outdent() g.Printf(")\n\n") // Define the entry points. for _, m := range summary.callable { g.Printf("func proxy%s_%s(out, in *seq.Buffer) {\n", obj.Name(), m.Name()) g.Indent() g.Printf("ref := in.ReadRef()\n") g.Printf("v := ref.Get().(%s.%s)\n", g.pkg.Name(), obj.Name()) g.genFuncBody(m, "v") g.Outdent() g.Printf("}\n\n") } // Register the method entry points. if len(summary.callable) > 0 { g.Printf("func init() {\n") g.Indent() for _, m := range summary.callable { g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Code, proxy%s_%s)\n", obj.Name(), obj.Name(), m.Name(), obj.Name(), m.Name()) } g.Outdent() g.Printf("}\n\n") } // Define a proxy interface. if !summary.implementable { // The interface defines an unexported method or a method that // uses an unexported type. We cannot generate a proxy object // for such a type. return } g.Printf("type proxy%s seq.Ref\n\n", obj.Name()) for i := 0; i < iface.NumMethods(); i++ { m := iface.Method(i) sig := m.Type().(*types.Signature) params := sig.Params() res := sig.Results() if res.Len() > 2 || (res.Len() == 2 && !isErrorType(res.At(1).Type())) { g.errorf("functions and methods must return either zero or one value, and optionally an error: %s.%s", obj.Name(), m.Name()) continue } g.Printf("func (p *proxy%s) %s(", obj.Name(), m.Name()) for i := 0; i < params.Len(); i++ { if i > 0 { g.Printf(", ") } g.Printf("%s %s", paramName(params, i), g.typeString(params.At(i).Type())) } g.Printf(") ") if res.Len() == 1 { g.Printf(g.typeString(res.At(0).Type())) } else if res.Len() == 2 { g.Printf("(%s, error)", g.typeString(res.At(0).Type())) } g.Printf(" {\n") g.Indent() g.Printf("in := new(seq.Buffer)\n") for i := 0; i < params.Len(); i++ { g.genWrite(paramName(params, i), "in", params.At(i).Type()) } if res.Len() == 0 { g.Printf("seq.Transact((*seq.Ref)(p), %q, proxy%s_%s_Code, in)\n", ifaceDesc, obj.Name(), m.Name()) } else { g.Printf("out := seq.Transact((*seq.Ref)(p), %q, proxy%s_%s_Code, in)\n", ifaceDesc, obj.Name(), m.Name()) var rvs []string for i := 0; i < res.Len(); i++ { rv := fmt.Sprintf("res_%d", i) g.genRead(rv, "out", res.At(i).Type()) rvs = append(rvs, rv) } g.Printf("return %s\n", strings.Join(rvs, ",")) } g.Outdent() g.Printf("}\n\n") } }
func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) { fields := exportedFields(T) methods := exportedMethodSet(types.NewPointer(obj.Type())) g.Printf("const (\n") g.Indent() g.Printf("proxy%s_Descriptor = \"go.%s.%s\"\n", obj.Name(), g.pkg.Name(), obj.Name()) for i, f := range fields { g.Printf("proxy%s_%s_Get_Code = 0x%x0f\n", obj.Name(), f.Name(), i) g.Printf("proxy%s_%s_Set_Code = 0x%x1f\n", obj.Name(), f.Name(), i) } for i, m := range methods { g.Printf("proxy%s_%s_Code = 0x%x0c\n", obj.Name(), m.Name(), i) } g.Outdent() g.Printf(")\n\n") g.Printf("type proxy%s seq.Ref\n\n", obj.Name()) for _, f := range fields { g.Printf("func proxy%s_%s_Set(out, in *seq.Buffer) {\n", obj.Name(), f.Name()) g.Indent() g.Printf("ref := in.ReadRef()\n") g.genRead("v", "in", f.Type()) g.Printf("ref.Get().(*%s.%s).%s = v\n", g.pkg.Name(), obj.Name(), f.Name()) g.Outdent() g.Printf("}\n\n") g.Printf("func proxy%s_%s_Get(out, in *seq.Buffer) {\n", obj.Name(), f.Name()) g.Indent() g.Printf("ref := in.ReadRef()\n") g.Printf("v := ref.Get().(*%s.%s).%s\n", g.pkg.Name(), obj.Name(), f.Name()) g.genWrite("v", "out", f.Type()) g.Outdent() g.Printf("}\n\n") } for _, m := range methods { g.Printf("func proxy%s_%s(out, in *seq.Buffer) {\n", obj.Name(), m.Name()) g.Indent() g.Printf("ref := in.ReadRef()\n") g.Printf("v := ref.Get().(*%s.%s)\n", g.pkg.Name(), obj.Name()) g.genFuncBody(m, "v") g.Outdent() g.Printf("}\n\n") } g.Printf("func init() {\n") g.Indent() for _, f := range fields { n := f.Name() g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Set_Code, proxy%s_%s_Set)\n", obj.Name(), obj.Name(), n, obj.Name(), n) g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Get_Code, proxy%s_%s_Get)\n", obj.Name(), obj.Name(), n, obj.Name(), n) } for _, m := range methods { n := m.Name() g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Code, proxy%s_%s)\n", obj.Name(), obj.Name(), n, obj.Name(), n) } g.Outdent() g.Printf("}\n\n") }
func (g *goGen) genInterface(obj *types.TypeName) { iface := obj.Type().(*types.Named).Underlying().(*types.Interface) summary := makeIfaceSummary(iface) // Define the entry points. 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()) continue } g.genFuncSignature(m, obj.Name()) g.Indent() g.Printf("ref := _seq.FromRefNum(int32(refnum))\n") g.Printf("v := ref.Get().(%s%s)\n", g.pkgName(g.Pkg), obj.Name()) g.genFuncBody(m, "v.") g.Outdent() g.Printf("}\n\n") } // Define a proxy interface. if !summary.implementable { // The interface defines an unexported method or a method that // uses an unexported type. We cannot generate a proxy object // for such a type. return } g.Printf("type proxy%s_%s _seq.Ref\n\n", g.pkgPrefix, obj.Name()) g.Printf("func (p *proxy%s_%s) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }\n\n", g.pkgPrefix, obj.Name()) for _, m := range summary.callable { if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or result types\n", obj.Name(), m.Name()) continue } sig := m.Type().(*types.Signature) params := sig.Params() res := sig.Results() if res.Len() > 2 || (res.Len() == 2 && !isErrorType(res.At(1).Type())) { g.errorf("functions and methods must return either zero or one value, and optionally an error: %s.%s", obj.Name(), m.Name()) continue } g.Printf("func (p *proxy%s_%s) %s(", g.pkgPrefix, obj.Name(), m.Name()) for i := 0; i < params.Len(); i++ { if i > 0 { g.Printf(", ") } g.Printf("param_%s %s", g.paramName(params, i), g.typeString(params.At(i).Type())) } g.Printf(") ") if res.Len() == 1 { g.Printf(g.typeString(res.At(0).Type())) } else if res.Len() == 2 { g.Printf("(%s, error)", g.typeString(res.At(0).Type())) } g.Printf(" {\n") g.Indent() for i := 0; i < params.Len(); i++ { pn := "param_" + g.paramName(params, i) g.genWrite("_"+pn, pn, params.At(i).Type(), modeTransient) } if res.Len() > 0 { g.Printf("res := ") } g.Printf("C.cproxy%s_%s_%s(C.int32_t(p.Bind_proxy_refnum__())", g.pkgPrefix, obj.Name(), m.Name()) for i := 0; i < params.Len(); i++ { g.Printf(", _param_%s", g.paramName(params, i)) } g.Printf(")\n") var retName string if res.Len() > 0 { if res.Len() == 1 { T := res.At(0).Type() g.genRead("_res", "res", T, modeRetained) retName = "_res" } else { var rvs []string for i := 0; i < res.Len(); i++ { rv := fmt.Sprintf("res_%d", i) g.genRead(rv, fmt.Sprintf("res.r%d", i), res.At(i).Type(), modeRetained) rvs = append(rvs, rv) } retName = strings.Join(rvs, ", ") } g.Printf("return %s\n", retName) } g.Outdent() g.Printf("}\n\n") } }
func (g *objcGen) genInterfaceMethodProxy(obj *types.TypeName, m *types.Func) { oName := obj.Name() s := g.funcSummary(m) g.genInterfaceMethodSignature(m, oName, false) g.Indent() g.Printf("@autoreleasepool {\n") g.Indent() g.Printf("%s o = go_seq_objc_from_refnum(refnum);\n", g.objcType(obj.Type())) for _, p := range s.params { g.genRead("_"+p.name, p.name, p.typ, modeTransient) } // call method if !s.returnsVal() { for _, p := range s.retParams { if isErrorType(p.typ) { g.Printf("NSError* %s = nil;\n", p.name) } else { g.Printf("%s %s;\n", g.objcType(p.typ), p.name) } } } 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 { if s.returnsVal() { // len(s.retParams) == 1 && s.retParams[0] != error p := s.retParams[0] g.genWrite("returnVal", p.typ, modeRetained) g.Printf("return _returnVal;\n") } else { var rets []string for i, p := range s.retParams { if isErrorType(p.typ) { g.Printf("NSString *%s_str = nil;\n", p.name) if i == len(s.retParams)-1 { // last param. g.Printf("if (!returnVal) {\n") } else { g.Printf("if (%s != nil) {\n", p.name) } g.Indent() g.Printf("%[1]s_str = [%[1]s localizedDescription];\n", p.name) g.Printf("if (%[1]s_str == nil || %[1]s_str.length == 0) {\n", p.name) g.Indent() g.Printf("%[1]s_str = @\"gobind: unknown error\";\n", p.name) g.Outdent() g.Printf("}\n") g.Outdent() g.Printf("}\n") g.genWrite(p.name+"_str", p.typ, modeRetained) rets = append(rets, fmt.Sprintf("_%s_str", p.name)) } else { g.genWrite(p.name, p.typ, modeRetained) rets = append(rets, "_"+p.name) } } if len(rets) > 1 { g.Printf("cproxy%s_%s_%s_return _sres = {\n", g.pkgPrefix, oName, m.Name()) g.Printf(" %s\n", strings.Join(rets, ", ")) g.Printf("};\n") g.Printf("return _sres;\n") } else { g.Printf("return %s;\n", rets[0]) } } } g.Outdent() g.Printf("}\n") g.Outdent() g.Printf("}\n\n") }
func (a *analysis) namedType(obj *types.TypeName, implements map[*types.Named]implementsFacts) { qualifier := types.RelativeTo(obj.Pkg()) T := obj.Type().(*types.Named) v := &TypeInfoJSON{ Name: obj.Name(), Size: sizes.Sizeof(T), Align: sizes.Alignof(T), Methods: []anchorJSON{}, // (JS wants non-nil) } // addFact adds the fact "is implemented by T" (by) or // "implements T" (!by) to group. addFact := func(group *implGroupJSON, T types.Type, by bool) { Tobj := deref(T).(*types.Named).Obj() var byKind string if by { // Show underlying kind of implementing type, // e.g. "slice", "array", "struct". s := reflect.TypeOf(T.Underlying()).String() byKind = strings.ToLower(strings.TrimPrefix(s, "*types.")) } group.Facts = append(group.Facts, implFactJSON{ ByKind: byKind, Other: anchorJSON{ Href: a.posURL(Tobj.Pos(), len(Tobj.Name())), Text: types.TypeString(T, qualifier), }, }) } // IMPLEMENTS if r, ok := implements[T]; ok { if isInterface(T) { // "T is implemented by <conc>" ... // "T is implemented by <iface>"... // "T implements <iface>"... group := implGroupJSON{ Descr: types.TypeString(T, qualifier), } // Show concrete types first; use two passes. for _, sub := range r.to { if !isInterface(sub) { addFact(&group, sub, true) } } for _, sub := range r.to { if isInterface(sub) { addFact(&group, sub, true) } } for _, super := range r.from { addFact(&group, super, false) } v.ImplGroups = append(v.ImplGroups, group) } else { // T is concrete. if r.from != nil { // "T implements <iface>"... group := implGroupJSON{ Descr: types.TypeString(T, qualifier), } for _, super := range r.from { addFact(&group, super, false) } v.ImplGroups = append(v.ImplGroups, group) } if r.fromPtr != nil { // "*C implements <iface>"... group := implGroupJSON{ Descr: "*" + types.TypeString(T, qualifier), } for _, psuper := range r.fromPtr { addFact(&group, psuper, false) } v.ImplGroups = append(v.ImplGroups, group) } } } // METHOD SETS for _, sel := range typeutil.IntuitiveMethodSet(T, &a.prog.MethodSets) { meth := sel.Obj().(*types.Func) pos := meth.Pos() // may be 0 for error.Error v.Methods = append(v.Methods, anchorJSON{ Href: a.posURL(pos, len(meth.Name())), Text: types.SelectionString(sel, qualifier), }) } // Since there can be many specs per decl, we // can't attach the link to the keyword 'type' // (as we do with 'func'); we use the Ident. fi, offset := a.fileAndOffset(obj.Pos()) fi.addLink(aLink{ start: offset, end: offset + len(obj.Name()), title: fmt.Sprintf("type info for %s", obj.Name()), onclick: fmt.Sprintf("onClickTypeInfo(%d)", fi.addData(v)), }) // Add info for exported package-level types to the package info. if obj.Exported() && isPackageLevel(obj) { // TODO(adonovan): Path is not unique! // It is possible to declare a non-test package called x_test. a.result.pkgInfo(obj.Pkg().Path()).addType(v) } }
func (g *objcGen) genStructM(obj *types.TypeName, t *types.Struct) { fields := exportedFields(t) methods := exportedMethodSet(types.NewPointer(obj.Type())) desc := fmt.Sprintf("_GO_%s_%s", g.pkgName, obj.Name()) g.Printf("#define %s_DESCRIPTOR_ \"go.%s.%s\"\n", desc, g.pkgName, obj.Name()) for i, f := range fields { g.Printf("#define %s_FIELD_%s_GET_ (0x%x0f)\n", desc, f.Name(), i) g.Printf("#define %s_FIELD_%s_SET_ (0x%x1f)\n", desc, f.Name(), i) } for i, m := range methods { g.Printf("#define %s_%s_ (0x%x0c)\n", desc, m.Name(), i) } g.Printf("\n") g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name()) g.Printf("}\n\n") g.Printf("- (id)initWithRef:(id)ref {\n") g.Indent() g.Printf("self = [super init];\n") g.Printf("if (self) { _ref = ref; }\n") g.Printf("return self;\n") g.Outdent() g.Printf("}\n\n") for _, f := range fields { // getter // TODO(hyangah): support error type fields? s := &funcSummary{ name: f.Name(), ret: g.objcType(f.Type()), } s.retParams = append(s.retParams, paramInfo{typ: f.Type(), name: "ret_"}) g.Printf("- %s {\n", s.asMethod(g)) g.Indent() g.genFunc(desc+"_DESCRIPTOR_", desc+"_FIELD_"+f.Name()+"_GET_", s, true) g.Outdent() g.Printf("}\n\n") // setter s = &funcSummary{ name: "set" + f.Name(), ret: "void", } s.params = append(s.params, paramInfo{typ: f.Type(), name: "v"}) g.Printf("- %s {\n", s.asMethod(g)) g.Indent() g.genFunc(desc+"_DESCRIPTOR_", desc+"_FIELD_"+f.Name()+"_SET_", s, true) g.Outdent() g.Printf("}\n\n") } for _, m := range methods { s := g.funcSummary(m) g.Printf("- %s {\n", s.asMethod(g)) g.Indent() g.genFunc(desc+"_DESCRIPTOR_", desc+"_"+m.Name()+"_", s, true) g.Outdent() g.Printf("}\n\n") } g.Printf("@end\n") }
func (g *objcGen) genInterfaceM(obj *types.TypeName, t *types.Interface) { methods := exportedMethodSet(obj.Type()) desc := fmt.Sprintf("_GO_%s_%s", g.pkgName, obj.Name()) g.Printf("#define %s_DESCRIPTOR_ \"go.%s.%s\"\n", desc, g.pkgName, obj.Name()) for i, m := range methods { g.Printf("#define %s_%s_ (0x%x0a)\n", desc, m.Name(), i+1) } g.Printf("\n") // @interface Interface -- similar to what genStructH does. g.Printf("@interface %[1]s%[2]s : NSObject <%[1]s%[2]s> {\n", g.namePrefix, obj.Name()) g.Printf("}\n") g.Printf("@property(strong, readonly) id ref;\n") g.Printf("\n") g.Printf("- (id)initWithRef:(id)ref;\n") for _, m := range methods { s := g.funcSummary(m) g.Printf("- %s;\n", s.asMethod(g)) } g.Printf("@end\n") g.Printf("\n") // @implementation Interface -- similar to what genStructM does. g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name()) g.Printf("}\n") g.Printf("\n") g.Printf("- (id)initWithRef:(id)ref {\n") g.Indent() g.Printf("self = [super init];\n") g.Printf("if (self) { _ref = ref; }\n") g.Printf("return self;\n") g.Outdent() g.Printf("}\n") g.Printf("\n") for _, m := range methods { s := g.funcSummary(m) g.Printf("- %s {\n", s.asMethod(g)) g.Indent() g.genFunc(desc+"_DESCRIPTOR_", desc+"_"+m.Name()+"_", s, true) g.Outdent() g.Printf("}\n\n") } g.Printf("@end\n") g.Printf("\n") // proxy function. g.Printf("static void proxy%s%s(id obj, int code, GoSeq* in, GoSeq* out) {\n", g.namePrefix, obj.Name()) g.Indent() g.Printf("switch (code) {\n") for _, m := range methods { g.Printf("case %s_%s_: {\n", desc, m.Name()) g.Indent() g.genInterfaceMethodProxy(obj, g.funcSummary(m)) g.Outdent() g.Printf("} break;\n") } g.Printf("default:\n") g.Indent() g.Printf("NSLog(@\"unknown code %%x for %s_DESCRIPTOR_\", code);\n", desc) g.Outdent() g.Printf("}\n") g.Outdent() g.Printf("}\n") }
func (g *ObjcGen) genInterfaceMethodProxy(obj *types.TypeName, m *types.Func) { oName := obj.Name() s := g.funcSummary(nil, m) g.genInterfaceMethodSignature(m, oName, false, g.paramName) g.Indent() g.Printf("@autoreleasepool {\n") g.Indent() g.Printf("%s* o = go_seq_objc_from_refnum(refnum);\n", g.refTypeBase(obj.Type())) for _, p := range s.params { g.genRead("_"+p.name, p.name, p.typ, modeTransient) } // call method if !s.returnsVal() { for _, p := range s.retParams { if isErrorType(p.typ) { g.Printf("NSError* %s = nil;\n", p.name) } else { g.Printf("%s %s;\n", g.objcType(p.typ), p.name) } } } 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 { 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 { if s.returnsVal() { // len(s.retParams) == 1 && s.retParams[0] != error p := s.retParams[0] g.genWrite("returnVal", p.typ, modeRetained) g.Printf("return _returnVal;\n") } else { var rets []string for i, p := range s.retParams { if isErrorType(p.typ) { g.Printf("NSError *_%s = nil;\n", p.name) if i == len(s.retParams)-1 { // last param. g.Printf("if (!returnVal) {\n") } else { g.Printf("if (%s != nil) {\n", p.name) } g.Indent() g.Printf("_%[1]s = %[1]s;\n", p.name) g.Outdent() g.Printf("}\n") g.genWrite("_"+p.name, p.typ, modeRetained) rets = append(rets, "__"+p.name) } else { g.genWrite(p.name, p.typ, modeRetained) rets = append(rets, "_"+p.name) } } if len(rets) > 1 { g.Printf("cproxy%s_%s_%s_return _sres = {\n", g.pkgPrefix, oName, m.Name()) g.Printf(" %s\n", strings.Join(rets, ", ")) g.Printf("};\n") g.Printf("return _sres;\n") } else { g.Printf("return %s;\n", rets[0]) } } } g.Outdent() g.Printf("}\n") g.Outdent() g.Printf("}\n\n") }
func (g *javaGen) genStruct(obj *types.TypeName, T *types.Struct) { fields := exportedFields(T) methods := exportedMethodSet(types.NewPointer(obj.Type())) var impls []string pT := types.NewPointer(obj.Type()) for _, iface := range g.allIntf { if types.AssignableTo(pT, iface.obj.Type()) { n := iface.obj.Name() if p := iface.obj.Pkg(); p != g.pkg { n = fmt.Sprintf("%s.%s.%s", g.javaPkgName(p), className(p), n) } impls = append(impls, n) } } g.Printf("public static final class %s extends Seq.Proxy", obj.Name()) if len(impls) > 0 { g.Printf(" implements %s", strings.Join(impls, ", ")) } g.Printf(" {\n") g.Indent() n := obj.Name() g.Printf("private %s(go.Seq.Ref ref) { super(ref); }\n\n", n) for _, f := range fields { if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", n, f.Name(), t) continue } g.Printf("public final native %s get%s();\n", g.javaType(f.Type()), f.Name()) g.Printf("public final native void set%s(%s v);\n\n", f.Name(), g.javaType(f.Type())) } var isStringer bool for _, m := range methods { if !g.isSigSupported(m.Type()) { g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name()) continue } g.genFuncSignature(m, false, false) t := m.Type().(*types.Signature) isStringer = isStringer || (m.Name() == "String" && t.Params().Len() == 0 && t.Results().Len() == 1 && types.Identical(t.Results().At(0).Type(), types.Typ[types.String])) } g.Printf("@Override public boolean equals(Object o) {\n") g.Indent() g.Printf("if (o == null || !(o instanceof %s)) {\n return false;\n}\n", n) g.Printf("%s that = (%s)o;\n", n, n) for _, f := range fields { if t := f.Type(); !g.isSupported(t) { g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", n, f.Name(), t) continue } nf := f.Name() g.Printf("%s this%s = get%s();\n", g.javaType(f.Type()), nf, nf) g.Printf("%s that%s = that.get%s();\n", g.javaType(f.Type()), nf, nf) if isJavaPrimitive(f.Type()) { g.Printf("if (this%s != that%s) {\n return false;\n}\n", nf, nf) } else { g.Printf("if (this%s == null) {\n", nf) g.Indent() g.Printf("if (that%s != null) {\n return false;\n}\n", nf) g.Outdent() g.Printf("} else if (!this%s.equals(that%s)) {\n return false;\n}\n", nf, nf) } } g.Printf("return true;\n") g.Outdent() g.Printf("}\n\n") g.Printf("@Override public int hashCode() {\n") g.Printf(" return java.util.Arrays.hashCode(new Object[] {") idx := 0 for _, f := range fields { if t := f.Type(); !g.isSupported(t) { continue } if idx > 0 { g.Printf(", ") } idx++ g.Printf("get%s()", f.Name()) } g.Printf("});\n") g.Printf("}\n\n") g.Printf("@Override public String toString() {\n") g.Indent() if isStringer { g.Printf("return String();\n") } else { g.Printf("StringBuilder b = new StringBuilder();\n") g.Printf(`b.append("%s").append("{");`, obj.Name()) g.Printf("\n") for _, f := range fields { if t := f.Type(); !g.isSupported(t) { continue } n := f.Name() g.Printf(`b.append("%s:").append(get%s()).append(",");`, n, n) g.Printf("\n") } g.Printf(`return b.append("}").toString();`) g.Printf("\n") } g.Outdent() g.Printf("}\n") g.Outdent() g.Printf("}\n\n") }