func (p *exporter) paramList(params *types.Tuple, variadic bool) { // use negative length to indicate unnamed parameters // (look at the first parameter only since either all // names are present or all are absent) n := params.Len() if n > 0 && params.At(0).Name() == "" { n = -n } p.int(n) for i := 0; i < params.Len(); i++ { q := params.At(i) t := q.Type() if variadic && i == params.Len()-1 { t = &dddSlice{t.(*types.Slice).Elem()} } p.typ(t) if n > 0 { name := q.Name() p.string(name) if name != "_" { p.pkg(q.Pkg(), false) } } p.string("") // no compiler-specific info } }
// paramName replaces incompatible name with a p0-pN name. // Missing names, or existing names of the form p[0-9] are incompatible. // TODO(crawshaw): Replace invalid unicode names. func paramName(params *types.Tuple, pos int) string { name := params.At(pos).Name() if name == "" || name[0] == '_' || paramRE.MatchString(name) { name = fmt.Sprintf("p%d", pos) } return name }
func (p *exporter) tuple(t *types.Tuple) { n := t.Len() p.int(n) for i := 0; i < n; i++ { p.param(t.At(i)) } }
func tuplesCompatibleExtra(p1, p2 *types.Tuple, typeDirection cmp) []*types.Var { len1 := p1.Len() len2 := p2.Len() if len1 > len2 { return nil } vars := make([]*types.Var, len2-len1) for i := 0; i < len2; i++ { if i >= len1 { v2 := p2.At(i) vars[i-len1] = v2 continue } v1 := p1.At(i) v2 := p2.At(i) c := cmpTypes(v1.Type(), v2.Type()) if c == cmpEqual || c == typeDirection { continue } return nil } return vars }
func toList(t *types.Tuple) []*types.Var { var r []*types.Var for i := 0; i < t.Len(); i++ { r = append(r, t.At(i)) } return r }
func tupleToSlice(tu *types.Tuple) []Type { ts := []Type{} for i := 0; i < tu.Len(); i++ { v := tu.At(i) ts = append(ts, encodeType(v.Type())) } return ts }
func (m Method) listTypes(t *types.Tuple) []string { num := t.Len() list := make([]string, num) for i := 0; i < num; i++ { list[i] = types.TypeString(t.At(i).Type(), m.gen.qf) } return list }
func tupleContains(tuple *types.Tuple, v *types.Var) bool { for i := 0; i < tuple.Len(); i++ { if tuple.At(i) == v { return true } } return false }
func (h Hasher) hashTuple(tuple *types.Tuple) uint32 { // See go/types.identicalTypes for rationale. n := tuple.Len() var hash uint32 = 9137 + 2*uint32(n) for i := 0; i < n; i++ { hash += 3 * h.Hash(tuple.At(i).Type()) } return hash }
func (sym *symtab) processTuple(tuple *types.Tuple) { if tuple == nil { return } for i := 0; i < tuple.Len(); i++ { ivar := tuple.At(i) ityp := ivar.Type() isym := sym.symtype(ityp) if isym == nil { sym.addType(ivar, ityp) } } }
func (w *Walker) writeParams(buf *bytes.Buffer, t *types.Tuple, variadic bool) { buf.WriteByte('(') for i, n := 0, t.Len(); i < n; i++ { if i > 0 { buf.WriteString(", ") } typ := t.At(i).Type() if variadic && i+1 == n { buf.WriteString("...") typ = typ.(*types.Slice).Elem() } w.writeType(buf, typ) } buf.WriteByte(')') }
func (p *printer) writeTuple(this *types.Package, tup *types.Tuple, variadic bool, visited []types.Type) { p.print("(") for i, n := 0, tup.Len(); i < n; i++ { if i > 0 { p.print(", ") } v := tup.At(i) if name := v.Name(); name != "" { p.print(name) p.print(" ") } typ := v.Type() if variadic && i == n-1 { p.print("...") typ = typ.(*types.Slice).Elem() } p.writeTypeInternal(this, typ, visited) } p.print(")") }
func newVarsFrom(p *Package, tuple *types.Tuple) []*Var { vars := make([]*Var, 0, tuple.Len()) for i := 0; i < tuple.Len(); i++ { vars = append(vars, newVarFrom(p, tuple.At(i))) } return vars }
func (c *converter) convertTuple(v *gotypes.Tuple, conv func(*gotypes.Var) *types.Var) *types.Tuple { if v == nil { return nil } if v, ok := c.converted[v]; ok { return v.(*types.Tuple) } vars := make([]*types.Var, 0, v.Len()) for i := 0; i < v.Len(); i++ { vars = append(vars, conv(v.At(i))) } ret := types.NewTuple(vars...) c.converted[v] = ret return ret }
// t is a tuple for representing parameters or return values of function. func (g *generator) parse(name string, t *types.Tuple) *args { ps := toList(t) var fields []*types.Var var tags []string imports := map[types.Object]*ast.SelectorExpr{} un := uniqueNames{} m := &args{} for _, p := range ps { n := p.Name() if n == "" { n = p.Type().String() if !validIdentifier(n) { n = "p" } } n = un.get(capitalize(n)) t := types.NewField(0, g.pkg, n, p.Type(), false) // Filter out context and error. switch p.Type().String() { case "golang.org/x/net/context.Context": ctxName := un.get("ctx") m.Args = append(m.Args, func(string) string { return ctxName }) m.CtxName = ctxName m.HasCtx = true m.Args2 = append(m.Args2, struct{ Name, Type string }{ctxName, types.TypeString(t.Type(), relativeTo(g.pkg))}) continue case "error": errName := un.get("err") m.Args = append(m.Args, func(string) string { return errName }) m.ErrName = errName m.HasErr = true m.Args2 = append(m.Args2, struct{ Name, Type string }{errName, types.TypeString(t.Type(), relativeTo(g.pkg))}) continue } m.Args2 = append(m.Args2, struct{ Name, Type string }{uncapitalize(n), types.TypeString(t.Type(), relativeTo(g.pkg))}) updateDeps(g.rev[p.Type()], g.info, imports) // Make sure all the names are unique. m.Args = append(m.Args, func(s string) string { return fmt.Sprintf("%s.%s", s, n) }) fields = append(fields, t) tags = append(tags, fmt.Sprintf(`json:"%s"`, toSnake(n))) } if !m.HasCtx { m.CtxName = un.get("ctx") } if !m.HasErr { m.ErrName = un.get("err") } imps := cleanImports(imports) m.StructDef = structDef{ Pkg: g.pkg.Name(), Imports: imps, Name: name, } for i, v := range fields { m.StructDef.Fields = append(m.StructDef.Fields, struct { Name string Tag string Type string }{ Name: v.Name(), Type: types.TypeString(v.Type(), relativeTo(g.pkg)), Tag: tags[i], }) } return m }