package imports
import "golang.org/x/tools/internal/imports"
Package imports implements a Go pretty-printer (like package "go/format") that also adds or removes import statements as necessary.
Index ¶
- Constants
- func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, extraMode parser.Mode) (formatted []byte, err error)
- func CanUse(filename, dir string) bool
- func GetAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error
- func GetImportPaths(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error
- func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchPkg, filename, filePkg string, env *ProcessEnv) error
- func ImportPathToAssumedName(importPath string) string
- func PrimeCache(ctx context.Context, resolver Resolver) error
- func Process(filename string, src []byte, opt *Options) (formatted []byte, err error)
- func ScanModuleCache(dir string, cache *DirInfoCache, logf func(string, ...any))
- func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map[string]float64, error)
- func VendorlessPath(ipath string) string
- type DirInfoCache
- func NewDirInfoCache() *DirInfoCache
- func (d *DirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []stdlib.Symbol, error)
- func (d *DirInfoCache) CachePackageName(info directoryPackageInfo) (string, error)
- func (d *DirInfoCache) Keys() (keys []string)
- func (d *DirInfoCache) Load(dir string) (directoryPackageInfo, bool)
- func (d *DirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func()
- func (d *DirInfoCache) Store(dir string, info directoryPackageInfo)
- type ImportFix
- type ImportFixType
- type ImportInfo
- type ImportPath
- type IndexSource
- func NewIndexSource(cachedir string) *IndexSource
- func (s *IndexSource) LoadPackageNames(ctx context.Context, srcDir string, paths []ImportPath) (map[ImportPath]PackageName, error)
- func (s *IndexSource) ResolveReferences(ctx context.Context, filename string, missing References) ([]*Result, error)
- type ModuleResolver
- type Options
- type PackageExport
- type PackageInfo
- type PackageName
- type ProcessEnv
- func (e *ProcessEnv) ClearModuleInfo()
- func (e *ProcessEnv) CopyConfig() *ProcessEnv
- func (e *ProcessEnv) GetResolver() (Resolver, error)
- func (e *ProcessEnv) UpdateResolver(r Resolver)
- type ProcessEnvSource
- func NewProcessEnvSource(env *ProcessEnv, filename, pkgName string) (*ProcessEnvSource, error)
- func (s *ProcessEnvSource) LoadPackageNames(ctx context.Context, srcDir string, unknown []string) (map[string]string, error)
- func (s *ProcessEnvSource) ResolveReferences(ctx context.Context, filename string, refs map[string]map[string]bool) ([]*Result, error)
- type References
- type Resolver
- type Result
- type Source
- type Symbol
Constants ¶
const MaxRelevance = 7.0
MaxRelevance is the highest relevance, used for the standard library. Chosen arbitrarily to match pre-existing gopls code.
Functions ¶
func ApplyFixes ¶
func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, extraMode parser.Mode) (formatted []byte, err error)
ApplyFixes applies all of the fixes to the file and formats it. extraMode is added in when parsing the file. src and opts must be specified, but no env is needed.
func CanUse ¶
CanUse reports whether the package in dir is usable from filename, respecting the Go "internal" and "vendor" visibility rules.
func GetAllCandidates ¶
func GetAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error
GetAllCandidates calls wrapped for each package whose name starts with searchPrefix, and can be imported from filename with the package name filePkg.
Beware that the wrapped function may be called multiple times concurrently. TODO(adonovan): encapsulate the concurrency.
func GetImportPaths ¶
func GetImportPaths(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error
GetImportPaths calls wrapped for each package whose import path starts with searchPrefix, and can be imported from filename with the package name filePkg.
func GetPackageExports ¶
func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchPkg, filename, filePkg string, env *ProcessEnv) error
GetPackageExports returns all known packages with name pkg and their exports.
func ImportPathToAssumedName ¶
ImportPathToAssumedName returns the assumed package name of an import path. It does this using only string parsing of the import path. It picks the last element of the path that does not look like a major version, and then picks the valid identifier off the start of that element. It is used to determine if a local rename should be added to an import for clarity. This function could be moved to a standard package and exported if we want for use in other tools.
func PrimeCache ¶
func Process ¶
Process implements golang.org/x/tools/imports.Process with explicit context in opt.Env.
func ScanModuleCache ¶
func ScanModuleCache(dir string, cache *DirInfoCache, logf func(string, ...any))
ScanModuleCache walks the given directory, which must be a GOMODCACHE value, for directory package information, storing the results in cache.
func ScoreImportPaths ¶
func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map[string]float64, error)
func VendorlessPath ¶
VendorlessPath returns the devendorized version of the import path ipath. For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b".
Types ¶
type DirInfoCache ¶
type DirInfoCache struct {
// contains filtered or unexported fields
}
DirInfoCache is a concurrency-safe map for storing information about directories that may contain packages.
The information in this cache is built incrementally. Entries are initialized in scan. No new keys should be added in any other functions, as all directories containing packages are identified in scan.
Other functions, including loadExports and findPackage, may update entries in this cache as they discover new things about the directory.
The information in the cache is not expected to change for the cache's lifetime, so there is no protection against competing writes. Users should take care not to hold the cache across changes to the underlying files.
func NewDirInfoCache ¶
func NewDirInfoCache() *DirInfoCache
func (*DirInfoCache) CacheExports ¶
func (d *DirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []stdlib.Symbol, error)
func (*DirInfoCache) CachePackageName ¶
func (d *DirInfoCache) CachePackageName(info directoryPackageInfo) (string, error)
func (*DirInfoCache) Keys ¶
func (d *DirInfoCache) Keys() (keys []string)
Keys returns the keys currently present in d.
func (*DirInfoCache) Load ¶
func (d *DirInfoCache) Load(dir string) (directoryPackageInfo, bool)
Load returns a copy of the directoryPackageInfo for absolute directory dir.
func (*DirInfoCache) ScanAndListen ¶
func (d *DirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func()
ScanAndListen calls listener on all the items in the cache, and on anything newly added. The returned stop function waits for all in-flight callbacks to finish and blocks new ones.
func (*DirInfoCache) Store ¶
func (d *DirInfoCache) Store(dir string, info directoryPackageInfo)
Store stores the package info for dir.
type ImportFix ¶
type ImportFix struct { // StmtInfo represents the import statement this fix will add, remove, or change. StmtInfo ImportInfo // IdentName is the identifier that this fix will add or remove. IdentName string // FixType is the type of fix this is (AddImport, DeleteImport, SetImportName). FixType ImportFixType Relevance float64 // see pkg }
func FixImports ¶
func FixImports(ctx context.Context, filename string, src []byte, goroot string, logf func(string, ...any), source Source) (fixes []*ImportFix, err error)
FixImports returns a list of fixes to the imports that, when applied, will leave the imports in the same state as Process. src and opt must be specified.
Note that filename's directory influences which imports can be chosen, so it is important that filename be accurate.
type ImportFixType ¶
type ImportFixType int
const ( AddImport ImportFixType = iota DeleteImport SetImportName )
type ImportInfo ¶
type ImportInfo struct { ImportPath string // import path, e.g. "crypto/rand". Name string // import name, e.g. "crand", or "" if none. }
An ImportInfo represents a single import statement.
type ImportPath ¶
type ImportPath = string
These types document the APIs below.
TODO(rfindley): consider making these defined types rather than aliases.
type IndexSource ¶
type IndexSource struct {
// contains filtered or unexported fields
}
implements Source using modindex, so only for module cache.
this is perhaps over-engineered. A new Index is read at first use. And then Update is called after every 15 minutes, and a new Index is read if the index changed. It is not clear the Mutex is needed.
func NewIndexSource ¶
func NewIndexSource(cachedir string) *IndexSource
create a new Source. Called from NewView in cache/session.go.
func (*IndexSource) LoadPackageNames ¶
func (s *IndexSource) LoadPackageNames(ctx context.Context, srcDir string, paths []ImportPath) (map[ImportPath]PackageName, error)
func (*IndexSource) ResolveReferences ¶
func (s *IndexSource) ResolveReferences(ctx context.Context, filename string, missing References) ([]*Result, error)
type ModuleResolver ¶
type ModuleResolver struct {
// contains filtered or unexported fields
}
ModuleResolver implements the Resolver interface for a workspace using modules.
A goal of the ModuleResolver is to invoke the Go command as little as possible. To this end, it runs the Go command only for listing module information (i.e. `go list -m -e -json ...`). Package scanning, the process of loading package information for the modules, is implemented internally via the scan method.
It has two types of state: the state derived from the go command, which is populated by init, and the state derived from scans, which is populated via scan. A root is considered scanned if it has been walked to discover directories. However, if the scan did not require additional information from the directory (such as package name or exports), the directory information itself may be partially populated. It will be lazily filled in as needed by scans, using the scanCallback.
func (*ModuleResolver) ClearForNewScan ¶
func (r *ModuleResolver) ClearForNewScan() Resolver
ClearForNewScan invalidates the last scan.
It preserves the set of roots, but forgets about the set of directories. Though it forgets the set of module cache directories, it remembers their contents, since they are assumed to be immutable.
type Options ¶
type Options struct { Env *ProcessEnv // The environment to use. Note: this contains the cached module and filesystem state. // LocalPrefix is a comma-separated string of import path prefixes, which, if // set, instructs Process to sort the import paths with the given prefixes // into another group after 3rd-party packages. LocalPrefix string Fragment bool // Accept fragment of a source file (no package statement) AllErrors bool // Report all errors (not just the first 10 on different lines) Comments bool // Print comments (true if nil *Options provided) TabIndent bool // Use tabs for indent (true if nil *Options provided) TabWidth int // Tab width (8 if nil *Options provided) FormatOnly bool // Disable the insertion and deletion of imports }
Options is golang.org/x/tools/imports.Options with extra internal-only options.
type PackageExport ¶
A PackageExport is a package and its exports.
type PackageInfo ¶
type PackageInfo struct { Name string // package name in the package declaration, if known Exports map[string]bool // set of names of known package level sortSymbols }
A PackageInfo represents what's known about a package.
type PackageName ¶
type PackageName = string
These types document the APIs below.
TODO(rfindley): consider making these defined types rather than aliases.
type ProcessEnv ¶
type ProcessEnv struct { GocmdRunner *gocommand.Runner BuildFlags []string ModFlag string // SkipPathInScan returns true if the path should be skipped from scans of // the RootCurrentModule root type. The function argument is a clean, // absolute path. SkipPathInScan func(string) bool // Env overrides the OS environment, and can be used to specify // GOPROXY, GO111MODULE, etc. PATH cannot be set here, because // exec.Command will not honor it. // Specifying all of requiredGoEnvVars avoids a call to `go env`. Env map[string]string WorkingDir string // If Logf is non-nil, debug logging is enabled through this function. Logf func(format string, args ...any) // If set, ModCache holds a shared cache of directory info to use across // multiple ProcessEnvs. ModCache *DirInfoCache // contains filtered or unexported fields }
ProcessEnv contains environment variables and settings that affect the use of the go command, the go/build package, etc.
...a ProcessEnv *also* overwrites its Env along with derived state in the form of the resolver. And because it is lazily initialized, an env may just be broken and unusable, but there is no way for the caller to detect that: all queries will just fail.
TODO(rfindley): refactor this package so that this type (perhaps renamed to just Env or Config) is an immutable configuration struct, to be exchanged for an initialized object via a constructor that returns an error. Perhaps the signature should be `func NewResolver(*Env) (*Resolver, error)`, where resolver is a concrete type used for resolving imports. Via this refactoring, we can avoid the need to call ProcessEnv.init and ProcessEnv.GoEnv everywhere, and implicitly fix all the places where this these are misused. Also, we'd delegate the caller the decision of how to handle a broken environment.
func (*ProcessEnv) ClearModuleInfo ¶
func (e *ProcessEnv) ClearModuleInfo()
ClearModuleInfo invalidates resolver state that depends on go.mod file contents (essentially, the output of go list -m -json ...).
Notably, it does not forget directory contents, which are reset asynchronously via ClearForNewScan.
If the ProcessEnv is a GOPATH environment, ClearModuleInfo is a no op.
TODO(rfindley): move this to a new env.go, consolidating ProcessEnv methods.
func (*ProcessEnv) CopyConfig ¶
func (e *ProcessEnv) CopyConfig() *ProcessEnv
CopyConfig copies the env's configuration into a new env.
func (*ProcessEnv) GetResolver ¶
func (e *ProcessEnv) GetResolver() (Resolver, error)
func (*ProcessEnv) UpdateResolver ¶
func (e *ProcessEnv) UpdateResolver(r Resolver)
UpdateResolver sets the resolver for the ProcessEnv to use in imports operations. Only for use with the result of [Resolver.ClearForNewScan].
TODO(rfindley): this awkward API is a result of the (arguably) inverted relationship between configuration and state described in the doc comment for ProcessEnv.
type ProcessEnvSource ¶
type ProcessEnvSource struct {
// contains filtered or unexported fields
}
ProcessEnvSource implements the Source interface using the legacy ProcessEnv abstraction.
func NewProcessEnvSource ¶
func NewProcessEnvSource(env *ProcessEnv, filename, pkgName string) (*ProcessEnvSource, error)
NewProcessEnvSource returns a ProcessEnvSource wrapping the given env, to be used for fixing imports in the file with name filename in package named pkgName.
func (*ProcessEnvSource) LoadPackageNames ¶
func (s *ProcessEnvSource) LoadPackageNames(ctx context.Context, srcDir string, unknown []string) (map[string]string, error)
func (*ProcessEnvSource) ResolveReferences ¶
func (s *ProcessEnvSource) ResolveReferences(ctx context.Context, filename string, refs map[string]map[string]bool) ([]*Result, error)
type References ¶
type References = map[PackageName]map[Symbol]bool
References is set of References found in a Go file. The first map key is the left hand side of a selector expression, the second key is the right hand side, and the value should always be true.
type Resolver ¶
type Resolver interface { // ClearForNewScan returns a new Resolver based on the receiver that has // cleared its internal caches of directory contents. // // The new resolver should be primed and then set via // [ProcessEnv.UpdateResolver]. ClearForNewScan() Resolver // contains filtered or unexported methods }
A Resolver does the build-system-specific parts of goimports.
type Result ¶
type Result struct { Import *ImportInfo Package *PackageInfo }
A Result satisfies a missing import.
The Import field describes the missing import spec, and the Package field summarizes the package exports.
type Source ¶
type Source interface { // LoadPackageNames queries PackageName information for the requested import // paths, when operating from the provided srcDir. // // TODO(rfindley): try to refactor to remove this operation. LoadPackageNames(ctx context.Context, srcDir string, paths []ImportPath) (map[ImportPath]PackageName, error) // ResolveReferences asks the Source for the best package name to satisfy // each of the missing references, in the context of fixing the given // filename. // // Returns a map from package name to a [Result] for that package name that // provides the required symbols. Keys may be omitted in the map if no // candidates satisfy all missing references for that package name. It is up // to each data source to select the best result for each entry in the // missing map. ResolveReferences(ctx context.Context, filename string, missing References) ([]*Result, error) }
A Source provides imports to satisfy unresolved references in the file being fixed.
type Symbol ¶
type Symbol = string
These types document the APIs below.
TODO(rfindley): consider making these defined types rather than aliases.
Source Files ¶
fix.go imports.go mod.go mod_cache.go sortimports.go source.go source_env.go source_modindex.go
- Version
- v0.30.0 (latest)
- Published
- Feb 10, 2025
- Platform
- linux/amd64
- Imports
- 36 packages
- Last checked
- 8 hours ago –
Tools for package owners.