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 *javaGen) genFromRefnum(toName, fromName string, t types.Type, o *types.TypeName) { oPkg := o.Pkg() if !g.validPkg(oPkg) { 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, proxy_class_%s_%s, proxy_class_%s_%s_cons);\n", toName, fromName, p, o.Name(), p, o.Name()) }
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") }
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) } }