Source file src/go/importer/importer.go
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 string) (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 45 // operation. Providing a nil value for lookup is deprecated but, for 46 // backwards-compatibility, the importer will in this case attempt to 47 // resolve imports in the $GOPATH workspace. 48 func ForCompiler(fset *token.FileSet, compiler string, lookup Lookup) types.Importer { 49 switch compiler { 50 case "gc": 51 return &gcimports{ 52 fset: fset, 53 packages: make(map[string]*types.Package), 54 lookup: lookup, 55 } 56 57 case "gccgo": 58 var inst gccgoimporter.GccgoInstallation 59 if err := inst.InitFromDriver("gccgo"); err != nil { 60 return nil 61 } 62 return &gccgoimports{ 63 packages: make(map[string]*types.Package), 64 importer: inst.GetImporter(nil, nil), 65 lookup: lookup, 66 } 67 68 case "source": 69 if lookup != nil { 70 panic("source importer for custom import path lookup not supported (issue #13847).") 71 } 72 73 return srcimporter.New(&build.Default, fset, make(map[string]*types.Package)) 74 } 75 76 // compiler not supported 77 return nil 78 } 79 80 // For calls [ForCompiler] with a new FileSet. 81 // 82 // Deprecated: Use [ForCompiler], which populates a FileSet 83 // with the positions of objects created by the importer. 84 // 85 //go:fix inline 86 func For(compiler string, lookup Lookup) types.Importer { 87 return ForCompiler(token.NewFileSet(), compiler, lookup) 88 } 89 90 // Default returns an Importer for the compiler that built the running binary. 91 // If available, the result implements [types.ImporterFrom]. 92 // 93 // Default may be convenient for use in the simplest of cases, but 94 // most clients should instead use [ForCompiler], which accepts a 95 // [token.FileSet] from the caller; without it, all position 96 // information derived from the Importer will be incorrect and 97 // misleading. See also the package documentation. 98 func Default() types.Importer { 99 return For(runtime.Compiler, nil) 100 } 101 102 // gc importer 103 104 type gcimports struct { 105 fset *token.FileSet 106 packages map[string]*types.Package 107 lookup Lookup 108 } 109 110 func (m *gcimports) Import(path string) (*types.Package, error) { 111 return m.ImportFrom(path, "" /* no vendoring */, 0) 112 } 113 114 func (m *gcimports) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) { 115 if mode != 0 { 116 panic("mode must be 0") 117 } 118 return gcimporter.Import(m.fset, m.packages, path, srcDir, m.lookup) 119 } 120 121 // gccgo importer 122 123 type gccgoimports struct { 124 packages map[string]*types.Package 125 importer gccgoimporter.Importer 126 lookup Lookup 127 } 128 129 func (m *gccgoimports) Import(path string) (*types.Package, error) { 130 return m.ImportFrom(path, "" /* no vendoring */, 0) 131 } 132 133 func (m *gccgoimports) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) { 134 if mode != 0 { 135 panic("mode must be 0") 136 } 137 return m.importer(m.packages, path, srcDir, m.lookup) 138 } 139