gopls/internal/lsp/source: extract InDir to a new pathutil package Change-Id: Ib977563e100a536c7721a1cf5690f2f639e5f741 Reviewed-on: https://go-review.googlesource.com/c/tools/+/543918 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go index 09892f4..091b46b 100644 --- a/gopls/internal/lsp/cache/load.go +++ b/gopls/internal/lsp/cache/load.go
@@ -20,6 +20,7 @@ "golang.org/x/tools/gopls/internal/file" "golang.org/x/tools/gopls/internal/immutable" "golang.org/x/tools/gopls/internal/lsp/protocol" + "golang.org/x/tools/gopls/internal/pathutil" "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/event/tag" "golang.org/x/tools/internal/gocommand" @@ -759,7 +760,7 @@ if len(pkg.GoFiles) > 1 { return false } - if !InDir(gocache, pkg.GoFiles[0]) { + if !pathutil.InDir(gocache, pkg.GoFiles[0]) { return false } return true
diff --git a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go index 5d85859..b06ddf2 100644 --- a/gopls/internal/lsp/cache/pkg.go +++ b/gopls/internal/lsp/cache/pkg.go
@@ -75,7 +75,6 @@ RemoveIntermediateTestVariants = source.RemoveIntermediateTestVariants IsCommandLineArguments = source.IsCommandLineArguments BundleQuickFixes = source.BundleQuickFixes - InDir = source.InDir SuggestedFixFromCommand = source.SuggestedFixFromCommand ToProtocolEdits = source.ToProtocolEdits NewFilterer = source.NewFilterer
diff --git a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snapshot.go index 91e57ee..cc38931 100644 --- a/gopls/internal/lsp/cache/snapshot.go +++ b/gopls/internal/lsp/cache/snapshot.go
@@ -38,6 +38,7 @@ "golang.org/x/tools/gopls/internal/lsp/source/methodsets" "golang.org/x/tools/gopls/internal/lsp/source/typerefs" "golang.org/x/tools/gopls/internal/lsp/source/xrefs" + "golang.org/x/tools/gopls/internal/pathutil" "golang.org/x/tools/gopls/internal/persistent" "golang.org/x/tools/gopls/internal/settings" "golang.org/x/tools/gopls/internal/vulncheck" @@ -905,7 +906,7 @@ // If GOWORK is outside the folder, ensure we are watching it. gowork, _ := s.view.GOWORK() - if gowork != "" && !InDir(s.view.folder.Dir.Path(), gowork.Path()) { + if gowork != "" && !pathutil.InDir(s.view.folder.Dir.Path(), gowork.Path()) { patterns[gowork.Path()] = struct{}{} } @@ -914,7 +915,7 @@ for _, dir := range dirs { // If the directory is within the view's folder, we're already watching // it with the first pattern above. - if InDir(s.view.folder.Dir.Path(), dir) { + if pathutil.InDir(s.view.folder.Dir.Path(), dir) { continue } // TODO(rstambler): If microsoft/vscode#3025 is resolved before @@ -955,7 +956,7 @@ s.files.Dirs().Range(func(dir string) { for _, wsDir := range wsDirs { - if InDir(wsDir, dir) { + if pathutil.InDir(wsDir, dir) { patterns[dir] = unit{} } } @@ -1029,7 +1030,7 @@ } var files []protocol.DocumentURI s.files.Range(func(uri protocol.DocumentURI, _ file.Handle) { - if InDir(dir, uri.Path()) { + if pathutil.InDir(dir, uri.Path()) { files = append(files, uri) } }) @@ -1139,7 +1140,7 @@ func moduleForURI(modFiles map[protocol.DocumentURI]struct{}, uri protocol.DocumentURI) protocol.DocumentURI { var match protocol.DocumentURI for modURI := range modFiles { - if !InDir(filepath.Dir(modURI.Path()), uri.Path()) { + if !pathutil.InDir(filepath.Dir(modURI.Path()), uri.Path()) { continue } if len(modURI) > len(match) { @@ -1684,7 +1685,7 @@ // When the module is underneath the view dir, we offer // "use all modules" quick-fixes. - inDir := InDir(viewDir, modDir) + inDir := pathutil.InDir(viewDir, modDir) if rel, err := filepath.Rel(viewDir, modDir); err == nil { modDir = rel @@ -2179,7 +2180,7 @@ m.Range(func(modURI protocol.DocumentURI, _ *memoize.Promise) { if len(modURI) > len(mostRelevant) { - if InDir(filepath.Dir(modURI.Path()), changedFile) { + if pathutil.InDir(filepath.Dir(modURI.Path()), changedFile) { mostRelevant = modURI } }
diff --git a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go index 0869624..669b016 100644 --- a/gopls/internal/lsp/cache/view.go +++ b/gopls/internal/lsp/cache/view.go
@@ -25,6 +25,7 @@ "golang.org/x/mod/semver" "golang.org/x/tools/gopls/internal/file" "golang.org/x/tools/gopls/internal/lsp/protocol" + "golang.org/x/tools/gopls/internal/pathutil" "golang.org/x/tools/gopls/internal/settings" "golang.org/x/tools/gopls/internal/vulncheck" "golang.org/x/tools/internal/event" @@ -568,10 +569,10 @@ // user. It would be better to explicitly consider the set of active modules // wherever relevant. inGoDir := false - if InDir(v.goCommandDir.Path(), v.folder.Dir.Path()) { - inGoDir = InDir(v.goCommandDir.Path(), uri.Path()) + if pathutil.InDir(v.goCommandDir.Path(), v.folder.Dir.Path()) { + inGoDir = pathutil.InDir(v.goCommandDir.Path(), uri.Path()) } - inFolder := InDir(v.folder.Dir.Path(), uri.Path()) + inFolder := pathutil.InDir(v.folder.Dir.Path(), uri.Path()) if !inGoDir && !inFolder { return false @@ -587,7 +588,7 @@ filterer := buildFilterer(folderDir, v.gomodcache, v.folder.Options) return func(uri protocol.DocumentURI) bool { // Only filter relative to the configured root directory. - if InDir(folderDir, uri.Path()) { + if pathutil.InDir(folderDir, uri.Path()) { return pathExcludedByFilter(strings.TrimPrefix(uri.Path(), folderDir), filterer) } return false @@ -978,7 +979,7 @@ // Check if the workspace is within any GOPATH directory. for _, gp := range filepath.SplitList(def.gopath) { - if InDir(filepath.Join(gp, "src"), folder.Dir.Path()) { + if pathutil.InDir(filepath.Join(gp, "src"), folder.Dir.Path()) { def.inGOPATH = true break }
diff --git a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.go index 7d05ce0..4fcd745 100644 --- a/gopls/internal/lsp/fake/editor.go +++ b/gopls/internal/lsp/fake/editor.go
@@ -20,7 +20,7 @@ "golang.org/x/tools/gopls/internal/lsp/command" "golang.org/x/tools/gopls/internal/lsp/glob" "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" + "golang.org/x/tools/gopls/internal/pathutil" "golang.org/x/tools/internal/jsonrpc2" "golang.org/x/tools/internal/jsonrpc2/servertest" "golang.org/x/tools/internal/xcontext" @@ -1302,7 +1302,7 @@ for path := range e.buffers { abs := e.sandbox.Workdir.AbsPath(path) - if oldAbs == abs || source.InDir(oldAbs, abs) { + if oldAbs == abs || pathutil.InDir(oldAbs, abs) { rel, err := filepath.Rel(oldAbs, abs) if err != nil { return nil, nil, fmt.Errorf("filepath.Rel(%q, %q): %v", oldAbs, abs, err)
diff --git a/gopls/internal/lsp/source/util.go b/gopls/internal/lsp/source/util.go index 8c8f5f3..ed2adef 100644 --- a/gopls/internal/lsp/source/util.go +++ b/gopls/internal/lsp/source/util.go
@@ -10,7 +10,6 @@ "go/printer" "go/token" "go/types" - "path/filepath" "regexp" "sort" "strconv" @@ -424,45 +423,6 @@ return true } -// InDir checks whether path is in the file tree rooted at dir. -// It checks only the lexical form of the file names. -// It does not consider symbolic links. -// -// Copied from go/src/cmd/go/internal/search/search.go. -func InDir(dir, path string) bool { - pv := strings.ToUpper(filepath.VolumeName(path)) - dv := strings.ToUpper(filepath.VolumeName(dir)) - path = path[len(pv):] - dir = dir[len(dv):] - switch { - default: - return false - case pv != dv: - return false - case len(path) == len(dir): - if path == dir { - return true - } - return false - case dir == "": - return path != "" - case len(path) > len(dir): - if dir[len(dir)-1] == filepath.Separator { - if path[:len(dir)] == dir { - return path[len(dir):] != "" - } - return false - } - if path[len(dir)] == filepath.Separator && path[:len(dir)] == dir { - if len(path) == len(dir)+1 { - return true - } - return path[len(dir)+1:] != "" - } - return false - } -} - // IsValidImport returns whether importPkgPath is importable // by pkgPath func IsValidImport(pkgPath, importPkgPath PackagePath) bool {
diff --git a/gopls/internal/pathutil/util.go b/gopls/internal/pathutil/util.go new file mode 100644 index 0000000..e19863e --- /dev/null +++ b/gopls/internal/pathutil/util.go
@@ -0,0 +1,49 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pathutil + +import ( + "path/filepath" + "strings" +) + +// InDir checks whether path is in the file tree rooted at dir. +// It checks only the lexical form of the file names. +// It does not consider symbolic links. +// +// Copied from go/src/cmd/go/internal/search/search.go. +func InDir(dir, path string) bool { + pv := strings.ToUpper(filepath.VolumeName(path)) + dv := strings.ToUpper(filepath.VolumeName(dir)) + path = path[len(pv):] + dir = dir[len(dv):] + switch { + default: + return false + case pv != dv: + return false + case len(path) == len(dir): + if path == dir { + return true + } + return false + case dir == "": + return path != "" + case len(path) > len(dir): + if dir[len(dir)-1] == filepath.Separator { + if path[:len(dir)] == dir { + return path[len(dir):] != "" + } + return false + } + if path[len(dir)] == filepath.Separator && path[:len(dir)] == dir { + if len(path) == len(dir)+1 { + return true + } + return path[len(dir)+1:] != "" + } + return false + } +}