Commit e8185365 authored by Rémy Oudompheng's avatar Rémy Oudompheng

go: record location of failed imports for error reporting.

Fixes #2664.

R=rsc
CC=golang-dev, remy
https://golang.org/cl/5593047
parent 33f3afa7
...@@ -119,7 +119,7 @@ func download(arg string, stk *importStack) { ...@@ -119,7 +119,7 @@ func download(arg string, stk *importStack) {
stk.push(p.ImportPath) stk.push(p.ImportPath)
defer stk.pop() defer stk.pop()
if err := downloadPackage(p); err != nil { if err := downloadPackage(p); err != nil {
errorf("%s", &PackageError{stk.copy(), err.Error()}) errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
return return
} }
......
...@@ -59,10 +59,14 @@ type Package struct { ...@@ -59,10 +59,14 @@ type Package struct {
// A PackageError describes an error loading information about a package. // A PackageError describes an error loading information about a package.
type PackageError struct { type PackageError struct {
ImportStack []string // shortest path from package named on command line to this one ImportStack []string // shortest path from package named on command line to this one
Pos string // position of error
Err string // the error itself Err string // the error itself
} }
func (p *PackageError) Error() string { func (p *PackageError) Error() string {
if p.Pos != "" {
return strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Pos + ": " + p.Err
}
return strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err return strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err
} }
...@@ -360,6 +364,12 @@ Stale: ...@@ -360,6 +364,12 @@ Stale:
} }
deps[path] = true deps[path] = true
p1 := loadPackage(path, stk) p1 := loadPackage(path, stk)
if p1.Error != nil {
if info.ImportPos != nil && len(info.ImportPos[path]) > 0 {
pos := info.ImportPos[path][0]
p1.Error.Pos = pos.String()
}
}
imports = append(imports, p1) imports = append(imports, p1)
for _, dep := range p1.Deps { for _, dep := range p1.Deps {
deps[dep] = true deps[dep] = true
......
...@@ -71,6 +71,8 @@ func TestBuild(t *testing.T) { ...@@ -71,6 +71,8 @@ func TestBuild(t *testing.T) {
t.Errorf("ScanDir(%#q): %v", tt.dir, err) t.Errorf("ScanDir(%#q): %v", tt.dir, err)
continue continue
} }
// Don't bother testing import positions.
tt.info.ImportPos, tt.info.TestImportPos = info.ImportPos, info.TestImportPos
if !reflect.DeepEqual(info, tt.info) { if !reflect.DeepEqual(info, tt.info) {
t.Errorf("ScanDir(%#q) = %#v, want %#v\n", tt.dir, info, tt.info) t.Errorf("ScanDir(%#q) = %#v, want %#v\n", tt.dir, info, tt.info)
continue continue
......
...@@ -116,10 +116,11 @@ func envOr(name, def string) string { ...@@ -116,10 +116,11 @@ func envOr(name, def string) string {
} }
type DirInfo struct { type DirInfo struct {
Package string // Name of package in dir Package string // Name of package in dir
PackageComment *ast.CommentGroup // Package comments from GoFiles PackageComment *ast.CommentGroup // Package comments from GoFiles
ImportPath string // Import path of package in dir ImportPath string // Import path of package in dir
Imports []string // All packages imported by GoFiles Imports []string // All packages imported by GoFiles
ImportPos map[string][]token.Position // Source code location of imports
// Source files // Source files
GoFiles []string // .go files in dir (excluding CgoFiles, TestGoFiles, XTestGoFiles) GoFiles []string // .go files in dir (excluding CgoFiles, TestGoFiles, XTestGoFiles)
...@@ -134,9 +135,10 @@ type DirInfo struct { ...@@ -134,9 +135,10 @@ type DirInfo struct {
CgoLDFLAGS []string // Cgo LDFLAGS directives CgoLDFLAGS []string // Cgo LDFLAGS directives
// Test information // Test information
TestGoFiles []string // _test.go files in package TestGoFiles []string // _test.go files in package
XTestGoFiles []string // _test.go files outside package XTestGoFiles []string // _test.go files outside package
TestImports []string // All packages imported by (X)TestGoFiles TestImports []string // All packages imported by (X)TestGoFiles
TestImportPos map[string][]token.Position
} }
func (d *DirInfo) IsCommand() bool { func (d *DirInfo) IsCommand() bool {
...@@ -223,8 +225,8 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) { ...@@ -223,8 +225,8 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
var Sfiles []string // files with ".S" (capital S) var Sfiles []string // files with ".S" (capital S)
var di DirInfo var di DirInfo
imported := make(map[string]bool) imported := make(map[string][]token.Position)
testImported := make(map[string]bool) testImported := make(map[string][]token.Position)
fset := token.NewFileSet() fset := token.NewFileSet()
for _, d := range dirs { for _, d := range dirs {
if d.IsDir() { if d.IsDir() {
...@@ -327,9 +329,9 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) { ...@@ -327,9 +329,9 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted) log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
} }
if isTest { if isTest {
testImported[path] = true testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
} else { } else {
imported[path] = true imported[path] = append(imported[path], fset.Position(spec.Pos()))
} }
if path == "C" { if path == "C" {
if isTest { if isTest {
...@@ -366,12 +368,14 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) { ...@@ -366,12 +368,14 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
return nil, fmt.Errorf("%s: no Go source files", dir) return nil, fmt.Errorf("%s: no Go source files", dir)
} }
di.Imports = make([]string, len(imported)) di.Imports = make([]string, len(imported))
di.ImportPos = imported
i := 0 i := 0
for p := range imported { for p := range imported {
di.Imports[i] = p di.Imports[i] = p
i++ i++
} }
di.TestImports = make([]string, len(testImported)) di.TestImports = make([]string, len(testImported))
di.TestImportPos = testImported
i = 0 i = 0
for p := range testImported { for p := range testImported {
di.TestImports[i] = p di.TestImports[i] = p
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment