From 5efdaf2100b5f305e331cb3651282d7105af2235 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 17 Oct 2018 16:03:08 -0700 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Alan Donovan --- go/internal/gcimporter/gcimporter.go | 73 ++++++++++++++------- go/internal/gcimporter/gcimporter11_test.go | 2 +- go/internal/gcimporter/gcimporter_test.go | 14 ++-- 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/go/internal/gcimporter/gcimporter.go b/go/internal/gcimporter/gcimporter.go index 47dd4613..9cf18660 100644 --- a/go/internal/gcimporter/gcimporter.go +++ b/go/internal/gcimporter/gcimporter.go @@ -128,42 +128,69 @@ func ImportData(packages map[string]*types.Package, filename, id string, data io // 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 787620d6..720eac44 100644 --- a/go/internal/gcimporter/gcimporter11_test.go +++ b/go/internal/gcimporter/gcimporter11_test.go @@ -54,7 +54,7 @@ func TestImportedTypes(t *testing.T) { 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 bfcb7389..ef75f4e1 100644 --- a/go/internal/gcimporter/gcimporter_test.go +++ b/go/internal/gcimporter/gcimporter_test.go @@ -88,7 +88,7 @@ func compile(t *testing.T, dirname, filename string) string { 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 @@ func TestVersionHandling(t *testing.T) { } // 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 @@ func TestVersionHandling(t *testing.T) { 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 @@ func TestCorrectMethodPackage(t *testing.T) { } 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 @@ func TestIssue13898(t *testing.T) { // 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 @@ func TestIssue15517(t *testing.T) { // 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 TestIssue20046(t *testing.T) { } 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) }