func (p *exporter) field(f *types.Var) { // anonymous fields have "" name name := "" if !f.Anonymous() { name = f.Name() } // qualifiedName will always emit the field package for // anonymous fields because "" is not an exported name. p.qualifiedName(f.Pkg(), name) p.typ(f.Type()) }
func (tr *Transformer) matchWildcard(xobj *types.Var, y ast.Expr) bool { name := xobj.Name() if tr.verbose { fmt.Fprintf(os.Stderr, "%s: wildcard %s -> %s?: ", tr.fset.Position(y.Pos()), name, astString(tr.fset, y)) } // Check that y is assignable to the declared type of the param. if yt := tr.info.TypeOf(y); !types.AssignableTo(yt, xobj.Type()) { if tr.verbose { fmt.Fprintf(os.Stderr, "%s not assignable to %s\n", yt, xobj.Type()) } return false } // A wildcard matches any expression. // If it appears multiple times in the pattern, it must match // the same expression each time. if old, ok := tr.env[name]; ok { // found existing binding tr.allowWildcards = false r := tr.matchExpr(old, y) if tr.verbose { fmt.Fprintf(os.Stderr, "%t secondary match, primary was %s\n", r, astString(tr.fset, old)) } tr.allowWildcards = true return r } if tr.verbose { fmt.Fprintf(os.Stderr, "primary match\n") } tr.env[name] = y // record binding return true }
// checkStructField checks that the field renaming will not cause // conflicts at its declaration, or ambiguity or changes to any selection. func (r *renamer) checkStructField(from *types.Var) { // Check that the struct declaration is free of field conflicts, // and field/method conflicts. // go/types offers no easy way to get from a field (or interface // method) to its declaring struct (or interface), so we must // ascend the AST. info, path, _ := r.iprog.PathEnclosingInterval(from.Pos(), from.Pos()) // path is [Ident Field FieldList StructType ... File]. Can't fail. // Ascend past parens (unlikely). i := 4 for { _, ok := path[i].(*ast.ParenExpr) if !ok { break } i++ } if spec, ok := path[i].(*ast.TypeSpec); ok { // This struct is also a named type. // We must check for direct (non-promoted) field/field // and method/field conflicts. named := info.Defs[spec.Name].Type() prev, indices, _ := types.LookupFieldOrMethod(named, true, info.Pkg, r.to) if len(indices) == 1 { r.errorf(from.Pos(), "renaming this field %q to %q", from.Name(), r.to) r.errorf(prev.Pos(), "\twould conflict with this %s", objectKind(prev)) return // skip checkSelections to avoid redundant errors } } else { // This struct is not a named type. // We need only check for direct (non-promoted) field/field conflicts. T := info.Types[path[3].(*ast.StructType)].Type.Underlying().(*types.Struct) for i := 0; i < T.NumFields(); i++ { if prev := T.Field(i); prev.Name() == r.to { r.errorf(from.Pos(), "renaming this field %q to %q", from.Name(), r.to) r.errorf(prev.Pos(), "\twould conflict with this field") return // skip checkSelections to avoid redundant errors } } } // Renaming an anonymous field requires renaming the type too. e.g. // print(s.T) // if we rename T to U, // type T int // this and // var s struct {T} // this must change too. if from.Anonymous() { if named, ok := from.Type().(*types.Named); ok { r.check(named.Obj()) } else if named, ok := deref(from.Type()).(*types.Named); ok { r.check(named.Obj()) } } // Check integrity of existing (field and method) selections. r.checkSelections(from) }
func (g *Go) pkg_var(v *types.Var) (ret content.Variable) { ret.Name.Relative = dotre.ReplaceAllString(v.Name(), "") ret.Type = g.pkg_type(v.Type()) return }
func (p *exporter) param(v *types.Var) { p.string(v.Name()) p.typ(v.Type()) }