aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Donovan <adonovan@google.com>2015-02-20 11:23:27 -0500
committerAlan Donovan <adonovan@google.com>2015-02-20 17:56:13 +0000
commit51931f86bff673e8a6255ee0d5960fc7f78c609e (patch)
tree426822876568843412b444ae3154c09f96fc3673
parentf96426939ca581c13e94e15b8365e1957968bf40 (diff)
downloadtools-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.go24
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
}