1
0
mirror of https://github.com/golang/go synced 2024-11-18 16:14:46 -07:00

go.tools/go/types: better error messages

- for unused packages where base(package path) != package name
- for conflicts between imported packages or dot-imported objects
  and local declarations

Per suggestions from adonovan, inspired by the gc error messages.

LGTM=adonovan
R=adonovan, bradfitz
CC=golang-codereviews
https://golang.org/cl/135550043
This commit is contained in:
Robert Griesemer 2014-09-08 10:29:00 -07:00
parent 9872f0d268
commit 476d41c67b
2 changed files with 29 additions and 4 deletions

View File

@ -9,6 +9,7 @@ import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/token" "go/token"
pathLib "path"
"strconv" "strconv"
"strings" "strings"
"unicode" "unicode"
@ -207,6 +208,14 @@ func (check *Checker) collectObjects() {
// A package scope may contain non-exported objects, // A package scope may contain non-exported objects,
// do not import them! // do not import them!
if obj.Exported() { if obj.Exported() {
// TODO(gri) When we import a package, we create
// a new local package object. We should do the
// same for each dot-imported object. That way
// they can have correct position information.
// (We must not modify their existing position
// information because the same package - found
// via Config.Packages - may be dot-imported in
// another package!)
check.declare(fileScope, nil, obj) check.declare(fileScope, nil, obj)
check.recordImplicit(s, obj) check.recordImplicit(s, obj)
} }
@ -343,7 +352,14 @@ func (check *Checker) collectObjects() {
for _, scope := range check.fileScopes { for _, scope := range check.fileScopes {
for _, obj := range scope.elems { for _, obj := range scope.elems {
if alt := pkg.scope.Lookup(obj.Name()); alt != nil { if alt := pkg.scope.Lookup(obj.Name()); alt != nil {
check.errorf(alt.Pos(), "%s already declared in this file through import of package %s", obj.Name(), obj.Pkg().Name()) if pkg, ok := obj.(*PkgName); ok {
check.errorf(alt.Pos(), "%s already declared through import of %s", alt.Name(), pkg.Imported())
check.reportAltDecl(pkg)
} else {
check.errorf(alt.Pos(), "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
// TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything
check.reportAltDecl(obj)
}
} }
} }
} }
@ -397,7 +413,13 @@ func (check *Checker) unusedImports() {
// Unused "blank imports" are automatically ignored // Unused "blank imports" are automatically ignored
// since _ identifiers are not entered into scopes. // since _ identifiers are not entered into scopes.
if !obj.used { if !obj.used {
check.softErrorf(obj.pos, "%q imported but not used", obj.imported.path) path := obj.imported.path
base := pathLib.Base(path)
if obj.name == base {
check.softErrorf(obj.pos, "%q imported but not used", path)
} else {
check.softErrorf(obj.pos, "%q imported but not used as %s", path, obj.name)
}
} }
default: default:
// All other objects in the file scope must be dot- // All other objects in the file scope must be dot-

View File

@ -17,7 +17,7 @@ import (
) )
import "math" /* ERROR "imported but not used" */ import "math" /* ERROR "imported but not used" */
import m /* ERROR "imported but not used" */ "math" import m /* ERROR "imported but not used as m" */ "math"
import _ "math" import _ "math"
import ( import (
@ -34,8 +34,11 @@ import f2 "fmt"
type flag int type flag int
type _ reflect /* ERROR "not exported" */ .flag type _ reflect /* ERROR "not exported" */ .flag
// imported package name may conflict with local objects
type reflect /* ERROR "reflect already declared" */ int
// dot-imported exported objects may conflict with local objects // dot-imported exported objects may conflict with local objects
type Value /* ERROR "already declared in this file" */ struct{} type Value /* ERROR "Value already declared through dot-import of package reflect" */ struct{}
var _ = fmt.Println // use "fmt" var _ = fmt.Println // use "fmt"