github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/gcexportdata/importer.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gcexportdata 6 7 import ( 8 "fmt" 9 "go/token" 10 "go/types" 11 "os" 12 ) 13 14 // NewImporter returns a new instance of the types.Importer interface 15 // that reads type information from export data files written by gc. 16 // The Importer also satisfies types.ImporterFrom. 17 // 18 // Export data files are located using "go build" workspace conventions 19 // and the build.Default context. 20 // 21 // Use this importer instead of go/importer.For("gc", ...) to avoid the 22 // version-skew problems described in the documentation of this package, 23 // or to control the FileSet or access the imports map populated during 24 // package loading. 25 // 26 func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { 27 return importer{fset, imports} 28 } 29 30 type importer struct { 31 fset *token.FileSet 32 imports map[string]*types.Package 33 } 34 35 func (imp importer) Import(importPath string) (*types.Package, error) { 36 return imp.ImportFrom(importPath, "", 0) 37 } 38 39 func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { 40 filename, path := Find(importPath, srcDir) 41 if filename == "" { 42 if importPath == "unsafe" { 43 // Even for unsafe, call Find first in case 44 // the package was vendored. 45 return types.Unsafe, nil 46 } 47 return nil, fmt.Errorf("can't find import: %s", importPath) 48 } 49 50 if pkg, ok := imp.imports[path]; ok && pkg.Complete() { 51 return pkg, nil // cache hit 52 } 53 54 // open file 55 f, err := os.Open(filename) 56 if err != nil { 57 return nil, err 58 } 59 defer func() { 60 f.Close() 61 if err != nil { 62 // add file name to error 63 err = fmt.Errorf("reading export data: %s: %v", filename, err) 64 } 65 }() 66 67 r, err := NewReader(f) 68 if err != nil { 69 return nil, err 70 } 71 72 return Read(r, imp.fset, imp.imports, path) 73 }