const preserveImportGraph … type unit … type typeCheckBatch … // addHandles is called by each goroutine joining the type check batch, to // ensure that the batch has all inputs necessary for type checking. func (b *typeCheckBatch) addHandles(handles map[PackageID]*packageHandle) { … } // getHandle retrieves the packageHandle for the given id. func (b *typeCheckBatch) getHandle(id PackageID) *packageHandle { … } type futurePackage … type pkgOrErr … // TypeCheck parses and type-checks the specified packages, // and returns them in the same order as the ids. // The resulting packages' types may belong to different importers, // so types from different packages are incommensurable. // // The resulting packages slice always contains len(ids) entries, though some // of them may be nil if (and only if) the resulting error is non-nil. // // An error is returned if any of the requested packages fail to type-check. // This is different from having type-checking errors: a failure to type-check // indicates context cancellation or otherwise significant failure to perform // the type-checking operation. // // In general, clients should never need to type-checked syntax for an // intermediate test variant (ITV) package. Callers should apply // RemoveIntermediateTestVariants (or equivalent) before this method, or any // of the potentially type-checking methods below. func (s *Snapshot) TypeCheck(ctx context.Context, ids ...PackageID) ([]*Package, error) { … } type preTypeCheck … type postTypeCheck … // forEachPackage does a pre- and post- order traversal of the packages // specified by ids using the provided pre and post functions. // // The pre func is optional. If set, pre is evaluated after the package // handle has been constructed, but before type-checking. If pre returns false, // type-checking is skipped for this package handle. // // post is called with a syntax package after type-checking completes // successfully. It is only called if pre returned true. // // Both pre and post may be called concurrently. func (s *Snapshot) forEachPackage(ctx context.Context, ids []PackageID, pre preTypeCheck, post postTypeCheck) error { … } // acquireTypeChecking joins or starts a concurrent type checking batch. // // The batch may be queried for package information using [typeCheckBatch.query]. // The second result must be called when the batch is no longer needed, to // release the resource. func (s *Snapshot) acquireTypeChecking() (*typeCheckBatch, func()) { … } // newTypeCheckBatch creates a new type checking batch using the provided // shared parseCache. // // If a non-nil importGraph is provided, imports in this graph will be reused. func newTypeCheckBatch(parseCache *parseCache, gopackagesdriver bool) *typeCheckBatch { … } // query executes a traversal of package information in the given typeCheckBatch. // For each package in importIDs, the package will be loaded "for import" (sans // syntax). // // For each package in syntaxIDs, the package will be handled following the // pre- and post- traversal logic of [Snapshot.forEachPackage]. // // Package handles must be provided for each package in the forward transitive // closure of either importIDs or syntaxIDs. // // TODO(rfindley): simplify this API by clarifying shared import graph and // package handle logic. func (b *typeCheckBatch) query(ctx context.Context, syntaxIDs []PackageID, pre preTypeCheck, post postTypeCheck, handles map[PackageID]*packageHandle) error { … } // getImportPackage returns the *types.Package to use for importing the // package referenced by id. // // This may be the package produced by type-checking syntax (as in the case // where id is in the set of requested IDs), a package loaded from export data, // or a package type-checked for import only. func (b *typeCheckBatch) getImportPackage(ctx context.Context, id PackageID) (pkg *types.Package, err error) { … } // handleSyntaxPackage handles one package from the ids slice. // // If type checking occurred while handling the package, it returns the // resulting types.Package so that it may be used for importing. // // handleSyntaxPackage returns (nil, nil) if pre returned false. func (b *typeCheckBatch) handleSyntaxPackage(ctx context.Context, i int, id PackageID, pre preTypeCheck, post postTypeCheck) error { … } // getPackage type checks one [Package] in the batch. func (b *typeCheckBatch) getPackage(ctx context.Context, ph *packageHandle) (*Package, error) { … } // storePackageResults serializes and writes information derived from p to the // file cache. // The context is used only for logging; cancellation does not affect the operation. func storePackageResults(ctx context.Context, ph *packageHandle, p *Package) { … } // Metadata implements the [metadata.Source] interface. func (b *typeCheckBatch) Metadata(id PackageID) *metadata.Package { … } // importPackage loads the given package from its export data in p.exportData // (which must already be populated). func (b *typeCheckBatch) importPackage(ctx context.Context, mp *metadata.Package, data []byte) (*types.Package, error) { … } // checkPackageForImport type checks, but skips function bodies and does not // record syntax information. func (b *typeCheckBatch) checkPackageForImport(ctx context.Context, ph *packageHandle) (*types.Package, error) { … } // importLookup returns a function that may be used to look up a package ID for // a given package path, based on the forward transitive closure of the initial // package (id). // // The resulting function is not concurrency safe. func importLookup(mp *metadata.Package, source metadata.Source) func(PackagePath) PackageID { … } type packageState … const validMetadata … const validLocalData … const validKey … const validImports … const validPackage … type packageHandle … type packageData … // clone returns a shallow copy of the receiver. func (ph *packageHandle) clone() *packageHandle { … } // getPackageHandles gets package handles for all given ids and their // dependencies, recursively. The resulting [packageHandle] values are fully // evaluated (their state will be at least validKey). func (s *Snapshot) getPackageHandles(ctx context.Context, ids []PackageID) (map[PackageID]*packageHandle, error) { … } type packageHandleBuilder … type handleNode … type partialRefs … // getTransitiveRefs gets or computes the set of transitively reachable // packages for each exported name in the package specified by id. // // The operation may fail if building a predecessor failed. If and only if this // occurs, the result will be nil. func (b *packageHandleBuilder) getTransitiveRefs(pkgID PackageID) map[string]*typerefs.PackageSet { … } // getOneTransitiveRefLocked computes the full set packages transitively // reachable through the given sym reference. // // It may return nil if the reference is invalid (i.e. the referenced name does // not exist). func (b *packageHandleBuilder) getOneTransitiveRefLocked(sym typerefs.Symbol) *typerefs.PackageSet { … } // evaluatePackageHandle recomputes the derived information in the package handle. // On success, the handle's state is validKey. // // evaluatePackageHandle must only be called from getPackageHandles. func (b *packageHandleBuilder) evaluatePackageHandle(ctx context.Context, n *handleNode) (err error) { … } // typerefs returns typerefs for the package described by m and cgfs, after // either computing it or loading it from the file cache. func (s *Snapshot) typerefs(ctx context.Context, mp *metadata.Package, cgfs []file.Handle) (map[string][]typerefs.Symbol, error) { … } // typerefData retrieves encoded typeref data from the filecache, or computes it on // a cache miss. func (s *Snapshot) typerefData(ctx context.Context, id PackageID, imports map[ImportPath]*metadata.Package, cgfs []file.Handle) ([]byte, error) { … } // typerefsKey produces a key for the reference information produced by the // typerefs package. func typerefsKey(id PackageID, imports map[ImportPath]*metadata.Package, compiledGoFiles []file.Handle) file.Hash { … } type typeCheckInputs … func (s *Snapshot) typeCheckInputs(ctx context.Context, mp *metadata.Package) (*typeCheckInputs, error) { … } // readFiles reads the content of each file URL from the source // (e.g. snapshot or cache). func readFiles(ctx context.Context, fs file.Source, uris []protocol.DocumentURI) (_ []file.Handle, err error) { … } // localPackageKey returns a key for local inputs into type-checking, excluding // dependency information: files, metadata, and configuration. func localPackageKey(inputs *typeCheckInputs) file.Hash { … } // checkPackage type checks the parsed source files in compiledGoFiles. // (The resulting pkg also holds the parsed but not type-checked goFiles.) // deps holds the future results of type-checking the direct dependencies. func (b *typeCheckBatch) checkPackage(ctx context.Context, fset *token.FileSet, ph *packageHandle, imports map[PackagePath]*types.Package) (*Package, error) { … } var goVersionRx … func (b *typeCheckBatch) typesConfig(ctx context.Context, inputs *typeCheckInputs, imports map[PackagePath]*types.Package, onError func(e error)) *types.Config { … } // validGoVersion reports whether goVersion is a valid Go version for go/types. // types.NewChecker panics if GoVersion is invalid. // // Note that, prior to go1.21, go/types required exactly two components to the // version number. For example, go types would panic with the Go version // go1.21.1. validGoVersion handles this case when built with go1.20 or earlier. func validGoVersion(goVersion string) bool { … } // releaseVersion reports the Go language version used to compile gopls, or "" // if it cannot be determined. func releaseVersion() string { … } // depsErrors creates diagnostics for each metadata error (e.g. import cycle). // These may be attached to import declarations in the transitive source files // of pkg, or to 'requires' declarations in the package's go.mod file. // // TODO(rfindley): move this to load.go func depsErrors(ctx context.Context, snapshot *Snapshot, mp *metadata.Package) ([]*Diagnostic, error) { … } // missingPkgError returns an error message for a missing package that varies // based on the user's workspace mode. func missingPkgError(from PackageID, pkgPath string, viewType ViewType) error { … } // typeErrorsToDiagnostics translates a slice of types.Errors into a slice of // Diagnostics. // // In addition to simply mapping data such as position information and error // codes, this function interprets related go/types "continuation" errors as // protocol.DiagnosticRelatedInformation. Continuation errors are go/types // errors whose messages starts with "\t". By convention, these errors relate // to the previous error in the errs slice (such as if they were printed in // sequence to a terminal). // // Fields in typeCheckInputs may affect the resulting diagnostics. func typeErrorsToDiagnostics(pkg *syntaxPackage, inputs *typeCheckInputs, errs []types.Error) []*Diagnostic { … } type importerFunc … func (f importerFunc) Import(path string) (*types.Package, error) { … }