Beispiel #1
0
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")
}
Beispiel #2
0
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")
}
Beispiel #3
0
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")
}
Beispiel #4
0
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")
}
Beispiel #5
0
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
}
Beispiel #6
0
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")
}
Beispiel #7
0
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
}
Beispiel #8
0
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")
}
Beispiel #9
0
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")
}
Beispiel #10
0
// 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
}
Beispiel #11
0
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)
	}
}
Beispiel #12
0
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")
}
Beispiel #13
0
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
}
Beispiel #14
0
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")
}
Beispiel #15
0
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")
}
Beispiel #16
0
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)
		}
	}
}
Beispiel #17
0
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")
}
Beispiel #18
0
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")
}
Beispiel #19
0
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")
}
Beispiel #20
0
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")
	}
}
Beispiel #21
0
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")
}
Beispiel #22
0
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")
	}
}
Beispiel #23
0
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")
}
Beispiel #24
0
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)
	}
}
Beispiel #25
0
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")
}
Beispiel #26
0
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")
}
Beispiel #27
0
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")
}
Beispiel #28
0
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")
}