-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
[Status: WORK IN PROGRESS. Do not review yet.]
Background: The package golang.org/x/tools/go/gcexportdata provides two functions, Write and Read. As described in #68898, they serve two purposes:
- a serialization mechanism for types.Package values. They assume that writer and reader are compiled from the same source code; there is no protocol stability.
- a mechanism to read export data written by last "tip + 2" releases of the Go compiler.
These two purposes are quite independent, and the actual protocols they use are unrelated. (The first uses "indexed" form, the second "unified".) Much of the challenge of maintaining go/types and x/tools/go/gcexportdata comes from version skew between std and x/tools: witness the number of delicate changes to both made recently to support materialized Alias types, and then the addition of type parameters to aliases. In this instance, the skew is unnecessary as the codec can be tightly coupled go/types and needn't support any other versions.
Proposal: We propose to add the read and write functions to go/types itself:
package types // "go/types"
// Export returns a serialized form of pkg that can be read by the same version of [Import].
// The encoding is not specified and may change at any time.
func Export(fset *token.FileSet, pkg *Package, opts ExportOptions) ([]byte, error)
type ExportOptions struct {
Deep bool // encode information about dependencies too
}
// Import returns the package described by data,
// which must have been produced by the same version of [Export].
// It calls importDeps at most once to obtain all needed direct dependencies (perhaps in parallel).
func Import(fset *token.FileSet, data []byte, importDeps importDepsFunc, path string, opts ImportOptions) (*Package, error)
type ImportOptions struct { /* for future use */ }
type importDepsFunc = func(packagePaths []string) ([]*types.Package, error)This API is a synthesis of gcexportdata and internal/gcimporter.{Im,Ex}portShallow, which are used by gopls for "shallow" encodings.
Open questions:
- The implementation of Export and Import depend on objectpath. How would this work in go/types?
- Assuming the legacy uses of Read for files produced by Write (not cmd/compile) would be supported by (eventually) delegating to types.Import, that would break the implicit promise that newer versions of Read can consume files produced by older versions of Write, which is not something that
types.Import,Exportwould guarantee. How disruptive is that likely to be? I suspect that no existing tools rely on this implicit promise because we often temporarily break it during the course of normal development (e.g. adding generics, type aliases) over many CLs.
@griesemer @findleyr @timothy-king
@znkr (for shallow export data)
Metadata
Metadata
Assignees
Labels
Type
Projects
Status