src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

importer.go (2026B)


      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 // Deprecated: Use the higher-level API in golang.org/x/tools/go/packages,
     27 // which is more efficient.
     28 func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom {
     29 	return importer{fset, imports}
     30 }
     31 
     32 type importer struct {
     33 	fset    *token.FileSet
     34 	imports map[string]*types.Package
     35 }
     36 
     37 func (imp importer) Import(importPath string) (*types.Package, error) {
     38 	return imp.ImportFrom(importPath, "", 0)
     39 }
     40 
     41 func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) {
     42 	filename, path := Find(importPath, srcDir)
     43 	if filename == "" {
     44 		if importPath == "unsafe" {
     45 			// Even for unsafe, call Find first in case
     46 			// the package was vendored.
     47 			return types.Unsafe, nil
     48 		}
     49 		return nil, fmt.Errorf("can't find import: %s", importPath)
     50 	}
     51 
     52 	if pkg, ok := imp.imports[path]; ok && pkg.Complete() {
     53 		return pkg, nil // cache hit
     54 	}
     55 
     56 	// open file
     57 	f, err := os.Open(filename)
     58 	if err != nil {
     59 		return nil, err
     60 	}
     61 	defer func() {
     62 		f.Close()
     63 		if err != nil {
     64 			// add file name to error
     65 			err = fmt.Errorf("reading export data: %s: %v", filename, err)
     66 		}
     67 	}()
     68 
     69 	r, err := NewReader(f)
     70 	if err != nil {
     71 		return nil, err
     72 	}
     73 
     74 	return Read(r, imp.fset, imp.imports, path)
     75 }