func (g *goGen) genStruct(obj *types.TypeName, typ *types.Struct) { //fmt.Printf("obj: %#v\ntyp: %#v\n", obj, typ) pkgname := obj.Pkg().Name() g.Printf("//export GoPy_%[1]s\n", obj.Name()) g.Printf("type GoPy_%[1]s unsafe.Pointer\n\n", obj.Name()) for i := 0; i < typ.NumFields(); i++ { f := typ.Field(i) if !f.Exported() { continue } ft := f.Type() ftname := g.qualifiedType(ft) if needWrapType(ft) { ftname = fmt.Sprintf("GoPy_%[1]s_field_%d", obj.Name(), i+1) g.Printf("//export %s\n", ftname) g.Printf("type %s unsafe.Pointer\n\n", ftname) } g.Printf("//export GoPy_%[1]s_getter_%[2]d\n", obj.Name(), i+1) g.Printf("func GoPy_%[1]s_getter_%[2]d(self GoPy_%[1]s) %[3]s {\n", obj.Name(), i+1, ftname, ) g.Indent() g.Printf( "ret := (*%[1]s)(unsafe.Pointer(self))\n", pkgname+"."+obj.Name(), ) if needWrapType(f.Type()) { dt := getTypedesc(f.Type()) g.Printf("%s(unsafe.Pointer(&ret.%s))\n", dt.cgotype, f.Name()) } else { g.Printf("return ret.%s\n", f.Name()) } g.Outdent() g.Printf("}\n\n") } g.Printf("//export GoPy_%[1]s_new\n", obj.Name()) g.Printf("func GoPy_%[1]s_new() GoPy_%[1]s {\n", obj.Name()) g.Indent() g.Printf("return (GoPy_%[1]s)(unsafe.Pointer(&%[2]s.%[1]s{}))\n", obj.Name(), pkgname, ) g.Outdent() g.Printf("}\n\n") }
func makeIOutput(strukt *types.Struct, typename *types.TypeName) IObj { iobj := dump(typename.Name(), strukt, reflect.StructTag("")).(IStruct) for i := range iobj.items { if item, ok := iobj.items[i].(IBasic); ok { switch item.name { case "kind": item.options = typename.Name() iobj.items[i] = item case "apiVersion": item.options = typename.Pkg().Name() iobj.items[i] = item } } } return iobj }
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) } }