diff --git a/go/types/api.go b/go/types/api.go index 2e19d5ef..eb90ad9c 100644 --- a/go/types/api.go +++ b/go/types/api.go @@ -138,6 +138,8 @@ type Importer func(imports map[string]*Package, path string) (pkg *Package, err // entire package is checked. If there are errors, the package may be // only partially type-checked, and the resulting package may be incomplete // (missing objects, imports, etc.). +// The provided package path must not resolve to ".", otherwise Check +// returns immediately with a corresponding error message. func (ctxt *Context) Check(path string, fset *token.FileSet, files ...*ast.File) (*Package, error) { return check(ctxt, path, fset, files...) } diff --git a/go/types/check.go b/go/types/check.go index 472efe2d..f4c80a3a 100644 --- a/go/types/check.go +++ b/go/types/check.go @@ -10,6 +10,7 @@ import ( "fmt" "go/ast" "go/token" + "path" "code.google.com/p/go.tools/go/exact" ) @@ -83,9 +84,9 @@ func (check *checker) later(f *Func, sig *Signature, body *ast.BlockStmt) { // A bailout panic is raised to indicate early termination. type bailout struct{} -func check(ctxt *Context, path string, fset *token.FileSet, files ...*ast.File) (pkg *Package, err error) { +func check(ctxt *Context, pkgPath string, fset *token.FileSet, files ...*ast.File) (pkg *Package, err error) { pkg = &Package{ - path: path, + path: pkgPath, scope: NewScope(Universe), imports: make(map[string]*Package), } @@ -117,6 +118,12 @@ func check(ctxt *Context, path string, fset *token.FileSet, files ...*ast.File) } }() + // we need a reasonable path to continue + if path.Clean(pkgPath) == "." { + check.errorf(token.NoPos, "Check invoked with invalid package path: %q", pkgPath) + return + } + // determine package name and files i := 0 for _, file := range files { diff --git a/go/types/errors.go b/go/types/errors.go index d4392efa..f354a2ef 100644 --- a/go/types/errors.go +++ b/go/types/errors.go @@ -320,9 +320,13 @@ func writeType(buf *bytes.Buffer, typ Type) { case *Named: s := "" if obj := t.obj; obj != nil { - if obj.pkg != nil && obj.pkg.path != "" { - buf.WriteString(obj.pkg.path) - buf.WriteString(".") + if obj.pkg != nil { + // TODO(gri) Ideally we only want the qualification + // if we are referring to a type that was imported; + // but not when we are at the "top". We don't have + // this information easily available here. + buf.WriteString(obj.pkg.name) + buf.WriteByte('.') } s = t.obj.name } diff --git a/go/types/types_test.go b/go/types/types_test.go index 54fbb871..d9a948c5 100644 --- a/go/types/types_test.go +++ b/go/types/types_test.go @@ -20,7 +20,8 @@ func makePkg(t *testing.T, src string) (*Package, error) { if err != nil { return nil, err } - pkg, err := Check("", fset, file) + // use the package name as package path + pkg, err := Check(file.Name.Name, fset, file) return pkg, err } @@ -56,7 +57,7 @@ var testTypes = []testEntry{ {`struct { string elems []T - }`, `struct{string; elems []T}`}, + }`, `struct{string; elems []p.T}`}, // pointers dup("*int"),