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>
This commit is contained in:
Robert Griesemer 2018-10-17 16:03:08 -07:00
parent a53bc13a63
commit 5efdaf2100
3 changed files with 58 additions and 31 deletions

View File

@ -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":

View File

@ -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

View File

@ -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)
}