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 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 string, lookup Lookup) types.Importer { 48 switch compiler { 49 case "gc": 50 return &gcimports{ 51 fset: fset, 52 packages: make(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: make(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, make(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 func For(compiler string, lookup Lookup) types.Importer { 84 return ForCompiler(token.NewFileSet(), compiler, lookup) 85 } 86 87 // Default returns an Importer for the compiler that built the running binary. 88 // If available, the result implements [types.ImporterFrom]. 89 // 90 // Default may be convenient for use in the simplest of cases, but 91 // most clients should instead use [ForCompiler], which accepts a 92 // [token.FileSet] from the caller; without it, all position 93 // information derived from the Importer will be incorrect and 94 // misleading. See also the package documentation. 95 func Default() types.Importer { 96 return For(runtime.Compiler, nil) 97 } 98 99 // gc importer 100 101 type gcimports struct { 102 fset *token.FileSet 103 packages map[string]*types.Package 104 lookup Lookup 105 } 106 107 func (m *gcimports) Import(path string) (*types.Package, error) { 108 return m.ImportFrom(path, "" /* no vendoring */, 0) 109 } 110 111 func (m *gcimports) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) { 112 if mode != 0 { 113 panic("mode must be 0") 114 } 115 return gcimporter.Import(m.fset, m.packages, path, srcDir, m.lookup) 116 } 117 118 // gccgo importer 119 120 type gccgoimports struct { 121 packages map[string]*types.Package 122 importer gccgoimporter.Importer 123 lookup Lookup 124 } 125 126 func (m *gccgoimports) Import(path string) (*types.Package, error) { 127 return m.ImportFrom(path, "" /* no vendoring */, 0) 128 } 129 130 func (m *gccgoimports) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) { 131 if mode != 0 { 132 panic("mode must be 0") 133 } 134 return m.importer(m.packages, path, srcDir, m.lookup) 135 } 136