go/internal/gcimporter: update gcimporter.go to incorporate std lib changes
This CL brings over changes from https://golang.org/cl/74354/
which were not brought over.
The code was adjusted slightly such that a filename is still available
for ImportData even if a custom lookup function is provided (adjustments
are on lines 133, 188-193).
Change-Id: I58960e648c9aae1683eb4d7f8d7578f09349eca2
Reviewed-on: https://go-review.googlesource.com/c/143017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/go/internal/gcimporter/gcimporter.go b/go/internal/gcimporter/gcimporter.go
index 47dd461..9cf1866 100644
--- a/go/internal/gcimporter/gcimporter.go
+++ b/go/internal/gcimporter/gcimporter.go
@@ -128,42 +128,69 @@
// the corresponding package object to the packages map, and returns the object.
// The packages map must contain all packages already imported.
//
-func Import(packages map[string]*types.Package, path, srcDir string) (pkg *types.Package, err error) {
- filename, id := FindPkg(path, srcDir)
- if filename == "" {
+func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
+ var rc io.ReadCloser
+ var filename, id string
+ if lookup != nil {
+ // With custom lookup specified, assume that caller has
+ // converted path to a canonical import path for use in the map.
if path == "unsafe" {
return types.Unsafe, nil
}
- err = fmt.Errorf("can't find import: %q", id)
- return
- }
+ id = path
- // no need to re-import if the package was imported completely before
- if pkg = packages[id]; pkg != nil && pkg.Complete() {
- return
- }
-
- // open file
- f, err := os.Open(filename)
- if err != nil {
- return
- }
- defer func() {
- f.Close()
- if err != nil {
- // add file name to error
- err = fmt.Errorf("reading export data: %s: %v", filename, err)
+ // No need to re-import if the package was imported completely before.
+ if pkg = packages[id]; pkg != nil && pkg.Complete() {
+ return
}
- }()
+ f, err := lookup(path)
+ if err != nil {
+ return nil, err
+ }
+ rc = f
+ } else {
+ filename, id = FindPkg(path, srcDir)
+ if filename == "" {
+ if path == "unsafe" {
+ return types.Unsafe, nil
+ }
+ return nil, fmt.Errorf("can't find import: %q", id)
+ }
+
+ // no need to re-import if the package was imported completely before
+ if pkg = packages[id]; pkg != nil && pkg.Complete() {
+ return
+ }
+
+ // open file
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ if err != nil {
+ // add file name to error
+ err = fmt.Errorf("%s: %v", filename, err)
+ }
+ }()
+ rc = f
+ }
+ defer rc.Close()
var hdr string
- buf := bufio.NewReader(f)
+ buf := bufio.NewReader(rc)
if hdr, err = FindExportData(buf); err != nil {
return
}
switch hdr {
case "$$\n":
+ // Work-around if we don't have a filename; happens only if lookup != nil.
+ // Either way, the filename is only needed for importer error messages, so
+ // this is fine.
+ if filename == "" {
+ filename = path
+ }
return ImportData(packages, filename, id, buf)
case "$$B\n":
diff --git a/go/internal/gcimporter/gcimporter11_test.go b/go/internal/gcimporter/gcimporter11_test.go
index 787620d..720eac4 100644
--- a/go/internal/gcimporter/gcimporter11_test.go
+++ b/go/internal/gcimporter/gcimporter11_test.go
@@ -54,7 +54,7 @@
importPath := s[0]
objName := s[1]
- pkg, err := Import(make(map[string]*types.Package), importPath, ".")
+ pkg, err := Import(make(map[string]*types.Package), importPath, ".", nil)
if err != nil {
t.Error(err)
continue
diff --git a/go/internal/gcimporter/gcimporter_test.go b/go/internal/gcimporter/gcimporter_test.go
index bfcb738..ef75f4e 100644
--- a/go/internal/gcimporter/gcimporter_test.go
+++ b/go/internal/gcimporter/gcimporter_test.go
@@ -88,7 +88,7 @@
func testPath(t *testing.T, path, srcDir string) *types.Package {
t0 := time.Now()
- pkg, err := Import(make(map[string]*types.Package), path, srcDir)
+ pkg, err := Import(make(map[string]*types.Package), path, srcDir, nil)
if err != nil {
t.Errorf("testPath(%s): %s", path, err)
return nil
@@ -190,7 +190,7 @@
}
// test that export data can be imported
- _, err := Import(make(map[string]*types.Package), pkgpath, dir)
+ _, err := Import(make(map[string]*types.Package), pkgpath, dir, nil)
if err != nil {
// ok to fail if it fails with a newer version error for select files
if strings.Contains(err.Error(), "newer version") {
@@ -227,7 +227,7 @@
defer os.Remove(filename)
// test that importing the corrupted file results in an error
- _, err = Import(make(map[string]*types.Package), pkgpath, dir)
+ _, err = Import(make(map[string]*types.Package), pkgpath, dir, nil)
if err == nil {
t.Errorf("import corrupted %q succeeded", pkgpath)
} else if msg := err.Error(); !strings.Contains(msg, "version skew") {
@@ -290,7 +290,7 @@
}
imports := make(map[string]*types.Package)
- _, err := Import(imports, "net/http", ".")
+ _, err := Import(imports, "net/http", ".", nil)
if err != nil {
t.Fatal(err)
}
@@ -346,7 +346,7 @@
// import go/internal/gcimporter which imports go/types partially
imports := make(map[string]*types.Package)
- _, err := Import(imports, "go/internal/gcimporter", ".")
+ _, err := Import(imports, "go/internal/gcimporter", ".", nil)
if err != nil {
t.Fatal(err)
}
@@ -414,7 +414,7 @@
// The same issue occurs with vendoring.)
imports := make(map[string]*types.Package)
for i := 0; i < 3; i++ {
- if _, err := Import(imports, "./././testdata/p", "."); err != nil {
+ if _, err := Import(imports, "./././testdata/p", ".", nil); err != nil {
t.Fatal(err)
}
}
@@ -468,7 +468,7 @@
}
func importPkg(t *testing.T, path string) *types.Package {
- pkg, err := Import(make(map[string]*types.Package), path, ".")
+ pkg, err := Import(make(map[string]*types.Package), path, ".", nil)
if err != nil {
t.Fatal(err)
}