| // Copyright 2011 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // This file implements the Import function for tests to use gc-generated object files. |
| |
| package importer |
| |
| import ( |
| "bufio" |
| "fmt" |
| "internal/exportdata" |
| "internal/pkgbits" |
| "io" |
| "os" |
| |
| "cmd/compile/internal/types2" |
| ) |
| |
| // Import imports a gc-generated package given its import path and srcDir, adds |
| // the corresponding package object to the packages map, and returns the object. |
| // The packages map must contain all packages already imported. |
| // |
| // This function should only be used in tests. |
| func Import(packages map[string]*types2.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types2.Package, err error) { |
| var rc io.ReadCloser |
| var 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 types2.Unsafe, nil |
| } |
| id = path |
| |
| // 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 { |
| var filename string |
| filename, id, err = exportdata.FindPkg(path, srcDir) |
| if filename == "" { |
| if path == "unsafe" { |
| return types2.Unsafe, nil |
| } |
| return nil, err |
| } |
| |
| // 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() |
| |
| buf := bufio.NewReader(rc) |
| data, err := exportdata.ReadUnified(buf) |
| if err != nil { |
| err = fmt.Errorf("import %q: %v", path, err) |
| return |
| } |
| s := string(data) |
| |
| input := pkgbits.NewPkgDecoder(id, s) |
| pkg = ReadPackage(nil, packages, input) |
| |
| return |
| } |