From 69c1d802e13155c016657de9b29849eae00d3153 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 31 Dec 2019 17:44:34 +0100 Subject: [PATCH] loader: improve error messages for failed imports Add location information (whenever possible) to failed imports. This helps in debugging where an incorrect import came from. For example, show the following error message: /home/ayke/src/github.com/tinygo-org/tinygo/src/machine/machine.go:5:8: cannot find package "foobar" in any of: /usr/local/go/src/foobar (from $GOROOT) /home/ayke/src/foobar (from $GOPATH) Instead of the following: error: cannot find package "foobar" in any of: /usr/local/go/src/foobar (from $GOROOT) /home/ayke/src/foobar (from $GOPATH) --- compiler/compiler.go | 8 ++++++-- loader/loader.go | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/compiler/compiler.go b/compiler/compiler.go index e95a0f90..194e9844 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -251,13 +251,17 @@ func (c *Compiler) Compile(mainPath string) []error { return []error{err} } } else { - _, err = lprogram.Import(mainPath, wd) + _, err = lprogram.Import(mainPath, wd, token.Position{ + Filename: "build command-line-arguments", + }) if err != nil { return []error{err} } } - _, err = lprogram.Import("runtime", "") + _, err = lprogram.Import("runtime", "", token.Position{ + Filename: "build default import", + }) if err != nil { return []error{err} } diff --git a/loader/loader.go b/loader/loader.go index 430e73d9..8c13cb81 100644 --- a/loader/loader.go +++ b/loader/loader.go @@ -6,6 +6,7 @@ import ( "go/ast" "go/build" "go/parser" + "go/scanner" "go/token" "go/types" "os" @@ -46,7 +47,7 @@ type Package struct { // Import loads the given package relative to srcDir (for the vendor directory). // It only loads the current package without recursion. -func (p *Program) Import(path, srcDir string) (*Package, error) { +func (p *Program) Import(path, srcDir string, pos token.Position) (*Package, error) { if p.Packages == nil { p.Packages = make(map[string]*Package) } @@ -59,7 +60,10 @@ func (p *Program) Import(path, srcDir string) (*Package, error) { } buildPkg, err := ctx.Import(path, srcDir, build.ImportComment) if err != nil { - return nil, err + return nil, scanner.Error{ + Pos: pos, + Msg: err.Error(), // TODO: define a new error type that will wrap the inner error + } } if existingPkg, ok := p.Packages[buildPkg.ImportPath]; ok { // Already imported, or at least started the import. @@ -467,7 +471,14 @@ func (p *Package) importRecursively(includeTests bool) error { if _, ok := p.Imports[to]; ok { continue } - importedPkg, err := p.Program.Import(to, p.Package.Dir) + // Find error location. + var pos token.Position + if len(p.Package.ImportPos[to]) > 0 { + pos = p.Package.ImportPos[to][0] + } else { + pos = token.Position{Filename: p.Package.ImportPath} + } + importedPkg, err := p.Program.Import(to, p.Package.Dir, pos) if err != nil { if err, ok := err.(*ImportCycleError); ok { err.Packages = append([]string{p.ImportPath}, err.Packages...)