Skip to content

Commit b6dbcf8

Browse files
committed
internal/gcimporter: have IImportShallow accept an import func
In preparation for skipping imports that aren't reached, change the gcimporter.IImportShallow API to accept an func rather than an explicit map. Update call sites to use a trivial wrapper around the new API. Subsequent CLs will avoid building packages that aren't needed. Updates golang/go#57987 Change-Id: Iee88e5f42fa353cde3e87447031c3e7485f04ca4 Reviewed-on: https://go-review.googlesource.com/c/tools/+/476436 Reviewed-by: Alan Donovan <[email protected]> gopls-CI: kokoro <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 35ef64e commit b6dbcf8

File tree

6 files changed

+37
-12
lines changed

6 files changed

+37
-12
lines changed

gopls/internal/lsp/cache/analysis.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ func typeCheckForAnalysis(fset *token.FileSet, parsed []*source.ParsedGoFile, m
743743
return nil, bug.Errorf("missing export data for %q", pkgPath)
744744
}
745745
hashExport(pkgPath, export)
746-
imported, err := gcimporter.IImportShallow(fset, importMap, export, string(pkgPath), insert)
746+
imported, err := gcimporter.IImportShallow(fset, gcimporter.GetPackageFromMap(importMap), export, string(pkgPath), insert)
747747
if err != nil {
748748
return nil, bug.Errorf("invalid export data for %q: %v", pkgPath, err)
749749
}

gopls/internal/lsp/cache/check.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ func (b *typeCheckBatch) importPackage(ctx context.Context, m *source.Metadata,
354354

355355
// TODO(rfindley): collect "deep" hashes here using the provided
356356
// callback, for precise pruning.
357-
imported, err := gcimporter.IImportShallow(b.fset, impMap, data, string(m.PkgPath), func(*types.Package, string) {})
357+
imported, err := gcimporter.IImportShallow(b.fset, gcimporter.GetPackageFromMap(impMap), data, string(m.PkgPath), func(*types.Package, string) {})
358358
if err != nil {
359359
return nil, bug.Errorf("invalid export data for %q: %v", m.ID, err)
360360
}

internal/gcimporter/gcimporter_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ func TestIssue57729(t *testing.T) {
833833
// Re-import it.
834834
imports := make(map[string]*types.Package)
835835
insert := func(pkg1 *types.Package, name string) { panic("unexpected insert") }
836-
pkg2, err := IImportShallow(fset, imports, data, "p", insert)
836+
pkg2, err := IImportShallow(fset, GetPackageFromMap(imports), data, "p", insert)
837837
if err != nil {
838838
t.Fatalf("import: %v", err) // any failure of IExport+IImport is a bug.
839839
}

internal/gcimporter/iexport.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ func IExportShallow(fset *token.FileSet, pkg *types.Package) ([]byte, error) {
4747
// IImportShallow decodes "shallow" types.Package data encoded by IExportShallow
4848
// in the same executable. This function cannot import data from
4949
// cmd/compile or gcexportdata.Write.
50-
func IImportShallow(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string, insert InsertType) (*types.Package, error) {
50+
func IImportShallow(fset *token.FileSet, importFunc func(path, name string) *types.Package, data []byte, path string, insert InsertType) (*types.Package, error) {
5151
const bundle = false
52-
pkgs, err := iimportCommon(fset, imports, data, bundle, path, insert)
52+
pkgs, err := iimportCommon(fset, importFunc, data, bundle, path, insert)
5353
if err != nil {
5454
return nil, err
5555
}

internal/gcimporter/iimport.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const (
8585
// If the export data version is not recognized or the format is otherwise
8686
// compromised, an error is returned.
8787
func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
88-
pkgs, err := iimportCommon(fset, imports, data, false, path, nil)
88+
pkgs, err := iimportCommon(fset, GetPackageFromMap(imports), data, false, path, nil)
8989
if err != nil {
9090
return 0, nil, err
9191
}
@@ -94,10 +94,36 @@ func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []
9494

9595
// IImportBundle imports a set of packages from the serialized package bundle.
9696
func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
97-
return iimportCommon(fset, imports, data, true, "", nil)
97+
return iimportCommon(fset, GetPackageFromMap(imports), data, true, "", nil)
9898
}
9999

100-
func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string, insert InsertType) (pkgs []*types.Package, err error) {
100+
// A GetPackageFunc is a function that gets the package with
101+
// the given path from the importer state, creating it
102+
// (with the specified name) if necessary.
103+
// It is an abstraction of the map historically used to memoize package creation.
104+
//
105+
// Two calls with the same path must return the same package.
106+
type GetPackageFunc = func(path, name string) *types.Package
107+
108+
// GetPackageFromMap returns a GetPackageFunc that retrieves packages from the
109+
// given map of package path -> package.
110+
//
111+
// The resulting func may mutate m: if a requested package is not found, a new
112+
// package will be inserted into m.
113+
func GetPackageFromMap(m map[string]*types.Package) GetPackageFunc {
114+
return func(path, name string) *types.Package {
115+
if _, ok := m[path]; !ok {
116+
m[path] = types.NewPackage(path, name)
117+
}
118+
return m[path]
119+
}
120+
}
121+
122+
// iimportCommon implements the core of the import algorithm.
123+
//
124+
// The given getPackage func must always return a non-nil package
125+
// (see ImportFromMap for an example).
126+
func iimportCommon(fset *token.FileSet, getPackage GetPackageFunc, data []byte, bundle bool, path string, insert InsertType) (pkgs []*types.Package, err error) {
101127
const currentVersion = iexportVersionCurrent
102128
version := int64(-1)
103129
if !debug {
@@ -195,10 +221,9 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
195221
if pkgPath == "" {
196222
pkgPath = path
197223
}
198-
pkg := imports[pkgPath]
224+
pkg := getPackage(pkgPath, pkgName)
199225
if pkg == nil {
200-
pkg = types.NewPackage(pkgPath, pkgName)
201-
imports[pkgPath] = pkg
226+
errorf("internal error: getPackage returned nil package for %s", pkgPath)
202227
} else if pkg.Name() != pkgName {
203228
errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
204229
}

internal/gcimporter/shallow_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func typecheck(t *testing.T, ppkg *packages.Package) {
118118
)
119119
loadFromExportData := func(imp *packages.Package) (*types.Package, error) {
120120
data := []byte(imp.ExportFile)
121-
return gcimporter.IImportShallow(fset, importMap, data, imp.PkgPath, insert)
121+
return gcimporter.IImportShallow(fset, gcimporter.GetPackageFromMap(importMap), data, imp.PkgPath, insert)
122122
}
123123
insert = func(p *types.Package, name string) {
124124
imp, ok := depsByPkgPath[p.Path()]

0 commit comments

Comments
 (0)