diff options
author | Alan Donovan <adonovan@google.com> | 2015-02-20 11:23:27 -0500 |
---|---|---|
committer | Alan Donovan <adonovan@google.com> | 2015-02-20 17:56:13 +0000 |
commit | 51931f86bff673e8a6255ee0d5960fc7f78c609e (patch) | |
tree | 426822876568843412b444ae3154c09f96fc3673 | |
parent | f96426939ca581c13e94e15b8365e1957968bf40 (diff) | |
download | tools-51931f86bff673e8a6255ee0d5960fc7f78c609e.tar.gz |
go/loader: define a FindPackage hook for build systems not compatible with "go build".
Google's proprietary build system, for example, does not use the
_test.go suffix to distinguish test from non-test files; this
information is stated explicitly in another form.
Change-Id: I3a8e919dbc556b6d5cfea1d2123da2616bd934d4
Reviewed-on: https://go-review.googlesource.com/5450
Reviewed-by: David Crawshaw <crawshaw@golang.org>
-rw-r--r-- | go/loader/loader.go | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/go/loader/loader.go b/go/loader/loader.go index 0fdda05..209b49a 100644 --- a/go/loader/loader.go +++ b/go/loader/loader.go @@ -290,6 +290,15 @@ type Config struct { // to Program.Created. ImportPkgs map[string]bool + // FindPackage is called during Load to create the build.Package + // for a given import path. If nil, a default implementation + // based on ctxt.Import is used. A client may use this hook to + // adapt to a proprietary build system that does not follow the + // "go build" layout conventions, for example. + // + // It must be safe to call concurrently from multiple goroutines. + FindPackage func(ctxt *build.Context, importPath string) (*build.Package, error) + // PackageCreated is a hook called when a types.Package // is created but before it has been populated. // @@ -625,6 +634,10 @@ func (conf *Config) Load() (*Program, error) { conf.TypeChecker.Error = func(e error) { fmt.Fprintln(os.Stderr, e) } } + if conf.FindPackage == nil { + conf.FindPackage = defaultFindPackage + } + prog := &Program{ Fset: conf.fset(), Imported: make(map[string]*PackageInfo), @@ -663,7 +676,7 @@ func (conf *Config) Load() (*Program, error) { continue } - bp, err := conf.findSourcePackage(path) + bp, err := conf.FindPackage(conf.build(), path) if err != nil { // Package not found, or can't even parse package declaration. // Already reported by previous loop; ignore it. @@ -820,12 +833,11 @@ func (conf *Config) build() *build.Context { return &build.Default } -// findSourcePackage locates the specified (possibly empty) package +// defaultFindPackage locates the specified (possibly empty) package // using go/build logic. It returns an error if not found. -// -func (conf *Config) findSourcePackage(path string) (*build.Package, error) { +func defaultFindPackage(ctxt *build.Context, path string) (*build.Package, error) { // Import(srcDir="") disables local imports, e.g. import "./foo". - bp, err := conf.build().Import(path, "", 0) + bp, err := ctxt.Import(path, "", 0) if _, ok := err.(*build.NoGoError); ok { return bp, nil // empty directory is not an error } @@ -1058,7 +1070,7 @@ func (imp *importer) importFromBinary(path string) (*PackageInfo, error) { // The returned PackageInfo's typeCheck function must be called. // func (imp *importer) loadFromSource(path string) (*PackageInfo, error) { - bp, err := imp.conf.findSourcePackage(path) + bp, err := imp.conf.FindPackage(imp.conf.build(), path) if err != nil { return nil, err // package not found } |