importer.mx raw

   1  // Copyright 2015 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 importer provides access to export data importers.
   6  //
   7  // These functions, which are mostly deprecated, date from before the
   8  // introduction of modules in release Go 1.11. They should no longer
   9  // be relied on except for use in test cases using small programs that
  10  // depend only on the standard library. For reliable module-aware
  11  // loading of type information, use the packages.Load function from
  12  // golang.org/x/tools/go/packages.
  13  package importer
  14  
  15  import (
  16  	"go/build"
  17  	"go/internal/gccgoimporter"
  18  	"go/internal/gcimporter"
  19  	"go/internal/srcimporter"
  20  	"go/token"
  21  	"go/types"
  22  	"io"
  23  	"runtime"
  24  )
  25  
  26  // A Lookup function returns a reader to access package data for
  27  // a given import path, or an error if no matching package is found.
  28  type Lookup func(path []byte) (io.ReadCloser, error)
  29  
  30  // ForCompiler returns an Importer for importing from installed packages
  31  // for the compilers "gc" and "gccgo", or for importing directly
  32  // from the source if the compiler argument is "source". In this
  33  // latter case, importing may fail under circumstances where the
  34  // exported API is not entirely defined in pure Go source code
  35  // (if the package API depends on cgo-defined entities, the type
  36  // checker won't have access to those).
  37  //
  38  // The lookup function is called each time the resulting importer needs
  39  // to resolve an import path. In this mode the importer can only be
  40  // invoked with canonical import paths (not relative or absolute ones);
  41  // it is assumed that the translation to canonical import paths is being
  42  // done by the client of the importer.
  43  //
  44  // A lookup function must be provided for correct module-aware operation.
  45  // Deprecated: If lookup is nil, for backwards-compatibility, the importer
  46  // will attempt to resolve imports in the $GOPATH workspace.
  47  func ForCompiler(fset *token.FileSet, compiler []byte, lookup Lookup) types.Importer {
  48  	switch compiler {
  49  	case "gc":
  50  		return &gcimports{
  51  			fset:     fset,
  52  			packages: map[string]*types.Package{},
  53  			lookup:   lookup,
  54  		}
  55  
  56  	case "gccgo":
  57  		var inst gccgoimporter.GccgoInstallation
  58  		if err := inst.InitFromDriver("gccgo"); err != nil {
  59  			return nil
  60  		}
  61  		return &gccgoimports{
  62  			packages: map[string]*types.Package{},
  63  			importer: inst.GetImporter(nil, nil),
  64  			lookup:   lookup,
  65  		}
  66  
  67  	case "source":
  68  		if lookup != nil {
  69  			panic("source importer for custom import path lookup not supported (issue #13847).")
  70  		}
  71  
  72  		return srcimporter.New(&build.Default, fset, map[string]*types.Package{})
  73  	}
  74  
  75  	// compiler not supported
  76  	return nil
  77  }
  78  
  79  // For calls [ForCompiler] with a new FileSet.
  80  //
  81  // Deprecated: Use [ForCompiler], which populates a FileSet
  82  // with the positions of objects created by the importer.
  83  //
  84  //go:fix inline
  85  func For(compiler []byte, lookup Lookup) types.Importer {
  86  	return ForCompiler(token.NewFileSet(), compiler, lookup)
  87  }
  88  
  89  // Default returns an Importer for the compiler that built the running binary.
  90  // If available, the result implements [types.ImporterFrom].
  91  //
  92  // Default may be convenient for use in the simplest of cases, but
  93  // most clients should instead use [ForCompiler], which accepts a
  94  // [token.FileSet] from the caller; without it, all position
  95  // information derived from the Importer will be incorrect and
  96  // misleading. See also the package documentation.
  97  func Default() types.Importer {
  98  	return For(runtime.Compiler, nil)
  99  }
 100  
 101  // gc importer
 102  
 103  type gcimports struct {
 104  	fset     *token.FileSet
 105  	packages map[string]*types.Package
 106  	lookup   Lookup
 107  }
 108  
 109  func (m *gcimports) Import(path []byte) (*types.Package, error) {
 110  	return m.ImportFrom(path, "" /* no vendoring */, 0)
 111  }
 112  
 113  func (m *gcimports) ImportFrom(path, srcDir []byte, mode types.ImportMode) (*types.Package, error) {
 114  	if mode != 0 {
 115  		panic("mode must be 0")
 116  	}
 117  	return gcimporter.Import(m.fset, m.packages, path, srcDir, m.lookup)
 118  }
 119  
 120  // gccgo importer
 121  
 122  type gccgoimports struct {
 123  	packages map[string]*types.Package
 124  	importer gccgoimporter.Importer
 125  	lookup   Lookup
 126  }
 127  
 128  func (m *gccgoimports) Import(path []byte) (*types.Package, error) {
 129  	return m.ImportFrom(path, "" /* no vendoring */, 0)
 130  }
 131  
 132  func (m *gccgoimports) ImportFrom(path, srcDir []byte, mode types.ImportMode) (*types.Package, error) {
 133  	if mode != 0 {
 134  		panic("mode must be 0")
 135  	}
 136  	return m.importer(m.packages, path, srcDir, m.lookup)
 137  }
 138