internal/lsp: create types for package paths and IDs
This change replaces the strings that were previously used for both the
ID and package path fields. This is a precursor to the change that will
replace the uses of package path with package ID.
Change-Id: I353e98aedede9b85c7a183fdd49048ff43b1e26d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/181757
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/internal/lsp/cache/check.go b/internal/lsp/cache/check.go
index 5c8cdf1..c31d3d1 100644
--- a/internal/lsp/cache/check.go
+++ b/internal/lsp/cache/check.go
@@ -22,24 +22,24 @@
// seen maintains the set of previously imported packages.
// If we have seen a package that is already in this map, we have a circular import.
- seen map[string]struct{}
+ seen map[packagePath]struct{}
// topLevelPkgID is the ID of the package from which type-checking began.
- topLevelPkgID string
+ topLevelPkgID packageID
ctx context.Context
fset *token.FileSet
}
func (imp *importer) Import(pkgPath string) (*types.Package, error) {
- pkg, err := imp.getPkg(pkgPath)
+ pkg, err := imp.getPkg(packagePath(pkgPath))
if err != nil {
return nil, err
}
return pkg.types, nil
}
-func (imp *importer) getPkg(pkgPath string) (*pkg, error) {
+func (imp *importer) getPkg(pkgPath packagePath) (*pkg, error) {
if _, ok := imp.seen[pkgPath]; ok {
return nil, fmt.Errorf("circular import detected")
}
@@ -80,7 +80,7 @@
return e.pkg, nil
}
-func (imp *importer) typeCheck(pkgPath string) (*pkg, error) {
+func (imp *importer) typeCheck(pkgPath packagePath) (*pkg, error) {
meta, ok := imp.view.mcache.packages[pkgPath]
if !ok {
return nil, fmt.Errorf("no metadata for %v", pkgPath)
@@ -89,7 +89,7 @@
id: meta.id,
pkgPath: meta.pkgPath,
files: meta.files,
- imports: make(map[string]*pkg),
+ imports: make(map[packagePath]*pkg),
typesSizes: meta.typesSizes,
typesInfo: &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
@@ -117,13 +117,13 @@
} else if len(files) == 0 { // not the unsafe package, no parsed files
return nil, fmt.Errorf("no parsed files for package %s", pkg.pkgPath)
} else {
- pkg.types = types.NewPackage(meta.pkgPath, meta.name)
+ pkg.types = types.NewPackage(string(meta.pkgPath), meta.name)
}
pkg.syntax = files
// Handle circular imports by copying previously seen imports.
- seen := make(map[string]struct{})
+ seen := make(map[packagePath]struct{})
for k, v := range imp.seen {
seen[k] = v
}
diff --git a/internal/lsp/cache/gofile.go b/internal/lsp/cache/gofile.go
index a3e1249..a9dd25f 100644
--- a/internal/lsp/cache/gofile.go
+++ b/internal/lsp/cache/gofile.go
@@ -131,9 +131,9 @@
f.view.mcache.mu.Lock()
defer f.view.mcache.mu.Unlock()
- seen := make(map[string]struct{}) // visited packages
+ seen := make(map[packagePath]struct{}) // visited packages
results := make(map[*goFile]struct{})
- f.view.reverseDeps(ctx, seen, results, pkg.PkgPath())
+ f.view.reverseDeps(ctx, seen, results, packagePath(pkg.PkgPath()))
var files []source.GoFile
for rd := range results {
@@ -149,7 +149,7 @@
return files
}
-func (v *view) reverseDeps(ctx context.Context, seen map[string]struct{}, results map[*goFile]struct{}, pkgPath string) {
+func (v *view) reverseDeps(ctx context.Context, seen map[packagePath]struct{}, results map[*goFile]struct{}, pkgPath packagePath) {
if _, ok := seen[pkgPath]; ok {
return
}
diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go
index a8cc7a0..ea7f7bc 100644
--- a/internal/lsp/cache/load.go
+++ b/internal/lsp/cache/load.go
@@ -20,7 +20,7 @@
}
// Save the metadata's current missing imports, if any.
- var originalMissingImports map[string]struct{}
+ var originalMissingImports map[packagePath]struct{}
if f.meta != nil {
originalMissingImports = f.meta.missingImports
}
@@ -40,7 +40,7 @@
imp := &importer{
view: v,
- seen: make(map[string]struct{}),
+ seen: make(map[packagePath]struct{}),
ctx: ctx,
fset: f.FileSet(),
topLevelPkgID: f.meta.id,
@@ -48,7 +48,7 @@
// Start prefetching direct imports.
for importPath := range f.meta.children {
- go imp.Import(importPath)
+ go imp.Import(string(importPath))
}
// Type-check package.
pkg, err := imp.getPkg(f.meta.pkgPath)
@@ -65,7 +65,7 @@
return nil, nil
}
-func sameSet(x, y map[string]struct{}) bool {
+func sameSet(x, y map[packagePath]struct{}) bool {
if len(x) != len(y) {
return false
}
@@ -103,7 +103,7 @@
return pkg.Errors, fmt.Errorf("package %s has errors, skipping type-checking", pkg.PkgPath)
}
// Build the import graph for this package.
- v.link(ctx, pkg.PkgPath, pkg, nil)
+ v.link(ctx, packagePath(pkg.PkgPath), pkg, nil)
}
return nil, nil
}
@@ -136,16 +136,16 @@
return false
}
-func (v *view) link(ctx context.Context, pkgPath string, pkg *packages.Package, parent *metadata) *metadata {
+func (v *view) link(ctx context.Context, pkgPath packagePath, pkg *packages.Package, parent *metadata) *metadata {
m, ok := v.mcache.packages[pkgPath]
if !ok {
m = &metadata{
pkgPath: pkgPath,
- id: pkg.ID,
+ id: packageID(pkg.ID),
typesSizes: pkg.TypesSizes,
- parents: make(map[string]bool),
- children: make(map[string]bool),
- missingImports: make(map[string]struct{}),
+ parents: make(map[packagePath]bool),
+ children: make(map[packagePath]bool),
+ missingImports: make(map[packagePath]struct{}),
}
v.mcache.packages[pkgPath] = m
}
@@ -168,15 +168,16 @@
}
for importPath, importPkg := range pkg.Imports {
if len(importPkg.Errors) > 0 {
- m.missingImports[pkg.PkgPath] = struct{}{}
+ m.missingImports[pkgPath] = struct{}{}
}
- if _, ok := m.children[importPath]; !ok {
- v.link(ctx, importPath, importPkg, m)
+ importPkgPath := packagePath(importPath)
+ if _, ok := m.children[importPkgPath]; !ok {
+ v.link(ctx, importPkgPath, importPkg, m)
}
}
// Clear out any imports that have been removed.
for importPath := range m.children {
- if _, ok := pkg.Imports[importPath]; !ok {
+ if _, ok := pkg.Imports[string(importPath)]; !ok {
delete(m.children, importPath)
if child, ok := v.mcache.packages[importPath]; ok {
delete(child.parents, pkgPath)
diff --git a/internal/lsp/cache/pkg.go b/internal/lsp/cache/pkg.go
index caf1ee5..9c3b71d 100644
--- a/internal/lsp/cache/pkg.go
+++ b/internal/lsp/cache/pkg.go
@@ -18,14 +18,17 @@
// pkg contains the type information needed by the source package.
type pkg struct {
- id, pkgPath string
- files []string
- syntax []*astFile
- errors []packages.Error
- imports map[string]*pkg
- types *types.Package
- typesInfo *types.Info
- typesSizes types.Sizes
+ // ID and package path have their own types to avoid being used interchangeably.
+ id packageID
+ pkgPath packagePath
+
+ files []string
+ syntax []*astFile
+ errors []packages.Error
+ imports map[packagePath]*pkg
+ types *types.Package
+ typesInfo *types.Info
+ typesSizes types.Sizes
// The analysis cache holds analysis information for all the packages in a view.
// Each graph node (action) is one unit of analysis.
@@ -35,6 +38,12 @@
analyses map[*analysis.Analyzer]*analysisEntry
}
+// packageID is a type that abstracts a package ID.
+type packageID string
+
+// packagePath is a type that abstracts a package path.
+type packagePath string
+
type analysisEntry struct {
done chan struct{}
succeeded bool
@@ -108,11 +117,11 @@
if len(a.FactTypes) > 0 {
importPaths := make([]string, 0, len(pkg.imports))
for importPath := range pkg.imports {
- importPaths = append(importPaths, importPath)
+ importPaths = append(importPaths, string(importPath))
}
sort.Strings(importPaths) // for determinism
for _, importPath := range importPaths {
- dep, ok := pkg.imports[importPath]
+ dep, ok := pkg.imports[packagePath(importPath)]
if !ok {
continue
}
@@ -129,7 +138,7 @@
}
func (pkg *pkg) PkgPath() string {
- return pkg.pkgPath
+ return string(pkg.pkgPath)
}
func (pkg *pkg) GetFilenames() []string {
@@ -165,7 +174,7 @@
}
func (pkg *pkg) GetImport(pkgPath string) source.Package {
- if imp := pkg.imports[pkgPath]; imp != nil {
+ if imp := pkg.imports[packagePath(pkgPath)]; imp != nil {
return imp
}
// Don't return a nil pointer because that still satisfies the interface.
diff --git a/internal/lsp/cache/session.go b/internal/lsp/cache/session.go
index 64bd142..5fc4031 100644
--- a/internal/lsp/cache/session.go
+++ b/internal/lsp/cache/session.go
@@ -81,10 +81,10 @@
filesByURI: make(map[span.URI]viewFile),
filesByBase: make(map[string][]viewFile),
mcache: &metadataCache{
- packages: make(map[string]*metadata),
+ packages: make(map[packagePath]*metadata),
},
pcache: &packageCache{
- packages: make(map[string]*entry),
+ packages: make(map[packagePath]*entry),
},
ignoredURIs: make(map[span.URI]struct{}),
}
diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go
index a15dd33..2fb70ac 100644
--- a/internal/lsp/cache/view.go
+++ b/internal/lsp/cache/view.go
@@ -71,23 +71,25 @@
type metadataCache struct {
mu sync.Mutex
- packages map[string]*metadata
+ packages map[packagePath]*metadata
}
type metadata struct {
- id, pkgPath, name string
+ id packageID
+ pkgPath packagePath
+ name string
files []string
typesSizes types.Sizes
- parents, children map[string]bool
+ parents, children map[packagePath]bool
// missingImports is the set of unresolved imports for this package.
// It contains any packages with `go list` errors.
- missingImports map[string]struct{}
+ missingImports map[packagePath]struct{}
}
type packageCache struct {
mu sync.Mutex
- packages map[string]*entry
+ packages map[packagePath]*entry
}
type entry struct {
@@ -227,20 +229,10 @@
// invalidateContent invalidates the content of a Go file,
// including any position and type information that depends on it.
func (f *goFile) invalidateContent() {
- f.view.pcache.mu.Lock()
f.handleMu.Lock()
- defer func() {
- f.handleMu.Unlock()
- f.view.pcache.mu.Unlock()
- }()
+ defer f.handleMu.Unlock()
- f.ast = nil
- f.token = nil
-
- // Remove the package and all of its reverse dependencies from the cache.
- if f.pkg != nil {
- f.view.remove(f.pkg.pkgPath, map[string]struct{}{})
- }
+ f.invalidateAST()
f.handle = nil
}
@@ -255,14 +247,14 @@
// Remove the package and all of its reverse dependencies from the cache.
if f.pkg != nil {
- f.view.remove(f.pkg.pkgPath, map[string]struct{}{})
+ f.view.remove(f.pkg.pkgPath, map[packagePath]struct{}{})
}
}
// remove invalidates a package and its reverse dependencies in the view's
// package cache. It is assumed that the caller has locked both the mutexes
// of both the mcache and the pcache.
-func (v *view) remove(pkgPath string, seen map[string]struct{}) {
+func (v *view) remove(pkgPath packagePath, seen map[packagePath]struct{}) {
if _, ok := seen[pkgPath]; ok {
return
}