go/packages: add ErrorKind field to differentiate error sources

Some applications (for example, diagnostics shown to a user in an
editor) may want to distinguish between errors generated by
the driver, parser, and type-checker. The Error struct did not have any
mechanism for doing this, so add an ErrorKind field and set it in
appendError.

Change-Id: If347163225d1e3a567e98610e9ba8a0930e4659c
Reviewed-on: https://go-review.googlesource.com/139317
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
Rebecca Stambler 2018-10-03 12:52:17 -04:00
parent c930a8531d
commit 9599141856
2 changed files with 37 additions and 14 deletions

View File

@ -194,15 +194,21 @@ func golistDriverFallback(cfg *Config, words ...string) (*driverResponse, error)
response.Packages = append(response.Packages, testmainPkg)
outdir, err := getOutdir()
if err != nil {
testmainPkg.Errors = append(testmainPkg.Errors,
Error{"-", fmt.Sprintf("failed to generate testmain: %v", err)})
testmainPkg.Errors = append(testmainPkg.Errors, Error{
Pos: "-",
Msg: fmt.Sprintf("failed to generate testmain: %v", err),
Kind: ListError,
})
return
}
testmain := filepath.Join(outdir, "testmain.go")
extraimports, extradeps, err := generateTestmain(testmain, testPkg, xtestPkg)
if err != nil {
testmainPkg.Errors = append(testmainPkg.Errors,
Error{"-", fmt.Sprintf("failed to generate testmain: %v", err)})
testmainPkg.Errors = append(testmainPkg.Errors, Error{
Pos: "-",
Msg: fmt.Sprintf("failed to generate testmain: %v", err),
Kind: ListError,
})
}
deps = append(deps, extradeps...)
for _, imp := range extraimports { // testing, testing/internal/testdeps, and maybe os

View File

@ -238,10 +238,23 @@ type Package struct {
// An Error describes a problem with a package's metadata, syntax, or types.
type Error struct {
Pos string // "file:line:col" or "file:line" or "" or "-"
Msg string
Pos string // "file:line:col" or "file:line" or "" or "-"
Msg string
Kind ErrorKind
}
// ErrorKind describes the source of the error, allowing the user to
// differentiate between errors generated by the driver, the parser, or the
// type-checker.
type ErrorKind int
const (
UnknownError ErrorKind = iota
ListError
ParserError
TypeError
)
func (err Error) Error() string {
pos := err.Pos
if pos == "" {
@ -572,31 +585,35 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
case *os.PathError:
// from parser
errs = append(errs, Error{
Pos: err.Path + ":1",
Msg: err.Err.Error(),
Pos: err.Path + ":1",
Msg: err.Err.Error(),
Kind: ParserError,
})
case scanner.ErrorList:
// from parser
for _, err := range err {
errs = append(errs, Error{
Pos: err.Pos.String(),
Msg: err.Msg,
Pos: err.Pos.String(),
Msg: err.Msg,
Kind: ParserError,
})
}
case types.Error:
// from type checker
errs = append(errs, Error{
Pos: err.Fset.Position(err.Pos).String(),
Msg: err.Msg,
Pos: err.Fset.Position(err.Pos).String(),
Msg: err.Msg,
Kind: TypeError,
})
default:
// unexpected impoverished error from parser?
errs = append(errs, Error{
Pos: "-",
Msg: err.Error(),
Pos: "-",
Msg: err.Error(),
Kind: UnknownError,
})
// If you see this error message, please file a bug.