From 95bd0c4fdf163d875765b42c6c707221d49fe137 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Tue, 2 Sep 2014 18:12:08 -0400 Subject: [PATCH] go.tools/go/types: add (*PkgName).ImportedPackage method. It returns the value formerly returned by Pkg(), i.e. the imported package. Pkg() now returns the package enclosing the import statement, which is consistent with all other Objects. Fixes golang/go#8628. LGTM=gri R=gri CC=golang-codereviews https://golang.org/cl/136090043 --- go/types/call.go | 4 ++-- go/types/object.go | 11 ++++++++--- go/types/resolver.go | 4 ++-- godoc/analysis/typeinfo.go | 4 ++-- oracle/describe.go | 6 +++--- oracle/referrers.go | 8 ++++---- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/go/types/call.go b/go/types/call.go index 093a2c57..d92c0699 100644 --- a/go/types/call.go +++ b/go/types/call.go @@ -256,9 +256,9 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { if pkg, _ := check.scope.LookupParent(ident.Name).(*PkgName); pkg != nil { check.recordUse(ident, pkg) pkg.used = true - exp := pkg.pkg.scope.Lookup(sel) + exp := pkg.imported.scope.Lookup(sel) if exp == nil { - if !pkg.pkg.fake { + if !pkg.imported.fake { check.errorf(e.Pos(), "%s not declared by package %s", sel, ident) } goto Error diff --git a/go/types/object.go b/go/types/object.go index a495f85c..0bd59f16 100644 --- a/go/types/object.go +++ b/go/types/object.go @@ -114,12 +114,17 @@ func (obj *object) sameId(pkg *Package, name string) bool { // A PkgName represents an imported Go package. type PkgName struct { object + imported *Package } -func NewPkgName(pos token.Pos, pkg *Package, name string) *PkgName { - return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], false}} +func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName { + return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], false}, imported} } +// Imported returns the package that was imported. +// It is distinct from Pkg(), which is the package containing the import statement. +func (obj *PkgName) Imported() *Package { return obj.imported } + // A Const represents a declared constant. type Const struct { object @@ -227,7 +232,7 @@ func writeObject(buf *bytes.Buffer, this *Package, obj Object) { switch obj := obj.(type) { case *PkgName: fmt.Fprintf(buf, "package %s", obj.Name()) - if path := obj.Pkg().path; path != "" && path != obj.Name() { + if path := obj.imported.path; path != "" && path != obj.name { fmt.Fprintf(buf, " (%q)", path) } return diff --git a/go/types/resolver.go b/go/types/resolver.go index 33333537..dce877bc 100644 --- a/go/types/resolver.go +++ b/go/types/resolver.go @@ -192,7 +192,7 @@ func (check *Checker) collectObjects() { } } - obj := NewPkgName(s.Pos(), imp, name) + obj := NewPkgName(s.Pos(), pkg, name, imp) if s.Name != nil { // in a dot-import, the dot represents the package check.recordDef(s.Name, obj) @@ -397,7 +397,7 @@ func (check *Checker) unusedImports() { // Unused "blank imports" are automatically ignored // since _ identifiers are not entered into scopes. if !obj.used { - check.softErrorf(obj.pos, "%q imported but not used", obj.pkg.path) + check.softErrorf(obj.pos, "%q imported but not used", obj.imported.path) } default: // All other objects in the file scope must be dot- diff --git a/godoc/analysis/typeinfo.go b/godoc/analysis/typeinfo.go index 88b987d3..3dbb2f5d 100644 --- a/godoc/analysis/typeinfo.go +++ b/godoc/analysis/typeinfo.go @@ -77,11 +77,11 @@ func (a *analysis) doTypeInfo(info *loader.PackageInfo, implements map[*types.Na // Correct the position for non-renaming import specs. // import "sync/atomic" // ^^^^^^^^^^^ - if obj, ok := obj.(*types.PkgName); ok && id.Name == obj.Pkg().Name() { + if obj, ok := obj.(*types.PkgName); ok && id.Name == obj.Imported().Name() { // Assume this is a non-renaming import. // NB: not true for degenerate renamings: `import foo "foo"`. pos++ - Len = len(obj.Pkg().Path()) + Len = len(obj.Imported().Path()) } if obj.Pkg() == nil { diff --git a/oracle/describe.go b/oracle/describe.go index 26a81b9b..8e43407b 100644 --- a/oracle/describe.go +++ b/oracle/describe.go @@ -505,8 +505,8 @@ func describePackage(o *Oracle, qpos *QueryPos, path []ast.Node) (*describePacka } else if p := qpos.info.Implicits[n]; p != nil { pkgname = p.(*types.PkgName) } - description = fmt.Sprintf("import of package %q", pkgname.Pkg().Path()) - pkg = pkgname.Pkg() + pkg = pkgname.Imported() + description = fmt.Sprintf("import of package %q", pkg.Path()) case *ast.Ident: if _, isDef := path[1].(*ast.File); isDef { @@ -516,7 +516,7 @@ func describePackage(o *Oracle, qpos *QueryPos, path []ast.Node) (*describePacka } else { // e.g. import id "..." // or id.F() - pkg = qpos.info.ObjectOf(n).Pkg() + pkg = qpos.info.ObjectOf(n).(*types.PkgName).Imported() description = fmt.Sprintf("reference to package %q", pkg.Path()) } diff --git a/oracle/referrers.go b/oracle/referrers.go index ae62db3d..91af9cdb 100644 --- a/oracle/referrers.go +++ b/oracle/referrers.go @@ -48,15 +48,15 @@ func referrers(o *Oracle, qpos *QueryPos) (queryResult, error) { } // same reports whether x and y are identical, or both are PkgNames -// referring to the same Package. +// that import the same Package. // func sameObj(x, y types.Object) bool { if x == y { return true } - if _, ok := x.(*types.PkgName); ok { - if _, ok := y.(*types.PkgName); ok { - return x.Pkg() == y.Pkg() + if x, ok := x.(*types.PkgName); ok { + if y, ok := y.(*types.PkgName); ok { + return x.Imported() == y.Imported() } } return false