Skip to content

Commit f801f12

Browse files
committed
gopls/internal/work: fix crash during go.work completion
Completing a use directive for a nonexistent directory crashed gopls. Fix this, and switch the operation to use the more performant filepath.WalkDir. Fixes golang/go#64225 Change-Id: I11c463d2a19bfeefce552b6efdcc9c5892a722f9 Reviewed-on: https://go-review.googlesource.com/c/tools/+/550376 Reviewed-by: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent b85cfba commit f801f12

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

gopls/internal/test/integration/completion/completion_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,7 @@ use ./a/ba
829829
use ./a/b/
830830
use ./dir/foo
831831
use ./dir/foobar/
832+
use ./missing/
832833
-- a/go.mod --
833834
-- go.mod --
834835
-- a/bar/go.mod --
@@ -853,6 +854,7 @@ use ./dir/foobar/
853854
{`use ./a/ba()`, []string{"r"}},
854855
{`use ./dir/foo()`, []string{"bar"}},
855856
{`use ./dir/foobar/()`, []string{}},
857+
{`use ./missing/()`, []string{}},
856858
}
857859
for _, tt := range tests {
858860
completions := env.Completion(env.RegexpSearch("go.work", tt.re))

gopls/internal/work/completion.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"context"
99
"errors"
1010
"fmt"
11+
"io/fs"
1112
"os"
1213
"path/filepath"
1314
"sort"
@@ -74,7 +75,12 @@ func Completion(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, p
7475
const numSeenBound = 10000
7576
var numSeen int
7677
stopWalking := errors.New("hit numSeenBound")
77-
err = filepath.Walk(pathPrefixDir, func(wpath string, info os.FileInfo, err error) error {
78+
err = filepath.WalkDir(pathPrefixDir, func(wpath string, entry fs.DirEntry, err error) error {
79+
if err != nil {
80+
// golang/go#64225: an error reading a dir is expected, as the user may
81+
// be typing out a use directive for a directory that doesn't exist.
82+
return nil
83+
}
7884
if numSeen > numSeenBound {
7985
// Stop traversing if we hit bound.
8086
return stopWalking
@@ -86,7 +92,7 @@ func Completion(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, p
8692
// otherwise it won't match the beginning of the
8793
// base component of the path the user typed in.
8894
rel := strings.TrimPrefix(wpath[len(pathPrefixDir):], string(filepath.Separator))
89-
if info.IsDir() && wpath != pathPrefixDir && !strings.HasPrefix(rel, pathPrefixBase) {
95+
if entry.IsDir() && wpath != pathPrefixDir && !strings.HasPrefix(rel, pathPrefixBase) {
9096
return filepath.SkipDir
9197
}
9298

0 commit comments

Comments
 (0)