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
This commit is contained in:
Alan Donovan 2014-09-02 18:12:08 -04:00
parent 297fd8229c
commit 95bd0c4fdf
6 changed files with 21 additions and 16 deletions

View File

@ -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

View File

@ -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

View File

@ -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-

View File

@ -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 {

View File

@ -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())
}

View File

@ -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