Skip to content

Commit a0ef9b6

Browse files
committed
internal/lsp: prepare for deletion of view.modURI
Splitting this CL out of CL 257417 to minimize the number of changes. A few of the view's methods are moved to the snapshot, as they will soon rely on the snapshot's modules field. Some dead code is also deleted. We now populate the snapshot's modules field even when ExperimentalWorkspaceModule is not true, but we stop looking for modules after searching the view's root. Change-Id: Id0068ec10fafcfa6f7694dfcb8aaee8cb025078f Reviewed-on: https://go-review.googlesource.com/c/tools/+/257961 Trust: Rebecca Stambler <[email protected]> Run-TryBot: Rebecca Stambler <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]>
1 parent 19e0367 commit a0ef9b6

15 files changed

+87
-91
lines changed

internal/lsp/cache/load.go

+1-11
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,6 @@ func (s *snapshot) load(ctx context.Context, scopes ...interface{}) error {
5858
query = append(query, string(scope))
5959
case fileURI:
6060
query = append(query, fmt.Sprintf("file=%s", span.URI(scope).Filename()))
61-
case directoryURI:
62-
filename := span.URI(scope).Filename()
63-
q := fmt.Sprintf("%s/...", filename)
64-
// Simplify the query if it will be run in the requested directory.
65-
// This ensures compatibility with Go 1.12 that doesn't allow
66-
// <directory>/... in GOPATH mode.
67-
if s.view.rootURI.Filename() == filename {
68-
q = "./..."
69-
}
70-
query = append(query, q)
7161
case moduleLoadScope:
7262
query = append(query, fmt.Sprintf("%s/...", scope))
7363
case viewLoadScope:
@@ -82,7 +72,7 @@ func (s *snapshot) load(ctx context.Context, scopes ...interface{}) error {
8272
panic(fmt.Sprintf("unknown scope type %T", scope))
8373
}
8474
switch scope.(type) {
85-
case directoryURI, viewLoadScope:
75+
case viewLoadScope:
8676
containsDir = true
8777
}
8878
}

internal/lsp/cache/pkg.go

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ type (
4242
// Declare explicit types for files and directories to distinguish between the two.
4343
type (
4444
fileURI span.URI
45-
directoryURI span.URI
4645
moduleLoadScope string
4746
viewLoadScope span.URI
4847
)

internal/lsp/cache/session.go

+10-15
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,9 @@ func (s *Session) createView(ctx context.Context, name string, folder span.URI,
169169
// If workspace module mode is enabled, find all of the modules in the
170170
// workspace.
171171
var modules map[span.URI]*moduleRoot
172-
if options.ExperimentalWorkspaceModule {
173-
modules, err = findWorkspaceModules(ctx, ws.rootURI, options)
174-
if err != nil {
175-
return nil, nil, func() {}, err
176-
}
172+
modules, err = findWorkspaceModules(ctx, ws.rootURI, options)
173+
if err != nil {
174+
return nil, nil, func() {}, err
177175
}
178176

179177
// Now that we have set all required fields,
@@ -276,17 +274,14 @@ func findWorkspaceModules(ctx context.Context, root span.URI, options *source.Op
276274
}
277275
}
278276
// We're only interested in go.mod files.
279-
if filepath.Base(path) != "go.mod" {
280-
return nil
277+
if filepath.Base(path) == "go.mod" {
278+
m := newModule(ctx, span.URIFromPath(path))
279+
modules[m.rootURI] = m
281280
}
282-
// At this point, we definitely have a go.mod file in the workspace,
283-
// so add it to the view.
284-
modURI := span.URIFromPath(path)
285-
rootURI := span.URIFromPath(filepath.Dir(path))
286-
modules[rootURI] = &moduleRoot{
287-
rootURI: rootURI,
288-
modURI: modURI,
289-
sumURI: span.URIFromPath(sumFilename(modURI)),
281+
// If we are not using experimental workspace modules, don't continue
282+
// the search past the view's root.
283+
if !options.ExperimentalWorkspaceModule {
284+
return filepath.SkipDir
290285
}
291286
return nil
292287
})

internal/lsp/cache/snapshot.go

+9-11
Original file line numberDiff line numberDiff line change
@@ -597,28 +597,25 @@ func (s *snapshot) CachedImportPaths(ctx context.Context) (map[string]source.Pac
597597
return results, nil
598598
}
599599

600-
func (s *snapshot) GoModForFile(ctx context.Context, fh source.FileHandle) (source.VersionedFileHandle, error) {
601-
if fh.Kind() != source.Go {
602-
return nil, fmt.Errorf("expected Go file, got %s", fh.Kind())
603-
}
600+
func (s *snapshot) GoModForFile(ctx context.Context, uri span.URI) (span.URI, error) {
604601
if len(s.modules) == 0 {
605602
if s.view.modURI == "" {
606-
return nil, errors.New("no modules in this view")
603+
return "", errors.New("no modules in this view")
607604
}
608-
return s.GetFile(ctx, s.view.modURI)
605+
return s.view.modURI, nil
609606
}
610607
var match span.URI
611608
for _, m := range s.modules {
612609
// Add an os.PathSeparator to the end of each directory to make sure
613610
// that foo/apple/banana does not match foo/a.
614-
if !strings.HasPrefix(fh.URI().Filename()+string(os.PathSeparator), m.rootURI.Filename()+string(os.PathSeparator)) {
611+
if !strings.HasPrefix(uri.Filename()+string(os.PathSeparator), m.rootURI.Filename()+string(os.PathSeparator)) {
615612
continue
616613
}
617614
if len(m.modURI) > len(match) {
618615
match = m.modURI
619616
}
620617
}
621-
return s.GetFile(ctx, match)
618+
return match, nil
622619
}
623620

624621
func (s *snapshot) getPackage(id packageID, mode source.ParseMode) *packageHandle {
@@ -1065,7 +1062,8 @@ func (s *snapshot) clone(ctx context.Context, withoutURIs map[span.URI]source.Ve
10651062
rootURI := span.URIFromPath(filepath.Dir(withoutURI.Filename()))
10661063
if currentMod {
10671064
if _, ok := result.modules[rootURI]; !ok {
1068-
result.addModule(ctx, currentFH.URI())
1065+
m := newModule(ctx, currentFH.URI())
1066+
result.modules[m.rootURI] = m
10691067
result.view.definitelyReinitialize()
10701068
}
10711069
} else if originalMod {
@@ -1542,13 +1540,13 @@ func (s *snapshot) BuildWorkspaceModFile(ctx context.Context) (*modfile.File, er
15421540
return file, nil
15431541
}
15441542

1545-
func (s *snapshot) addModule(ctx context.Context, modURI span.URI) {
1543+
func newModule(ctx context.Context, modURI span.URI) *moduleRoot {
15461544
rootURI := span.URIFromPath(filepath.Dir(modURI.Filename()))
15471545
sumURI := span.URIFromPath(sumFilename(modURI))
15481546
if info, _ := os.Stat(sumURI.Filename()); info == nil {
15491547
sumURI = ""
15501548
}
1551-
s.modules[rootURI] = &moduleRoot{
1549+
return &moduleRoot{
15521550
rootURI: rootURI,
15531551
modURI: modURI,
15541552
sumURI: sumURI,

internal/lsp/cache/view.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -209,15 +209,15 @@ func (f *fileBase) addURI(uri span.URI) int {
209209

210210
func (v *View) ID() string { return v.id }
211211

212-
func (v *View) ValidBuildConfiguration() bool {
213-
return v.hasValidBuildConfiguration
212+
func (s *snapshot) ValidBuildConfiguration() bool {
213+
return s.view.hasValidBuildConfiguration
214214
}
215215

216-
func (v *View) ModFiles() []span.URI {
217-
if v.modURI == "" {
216+
func (s *snapshot) ModFiles() []span.URI {
217+
if s.view.modURI == "" {
218218
return nil
219219
}
220-
return []span.URI{v.modURI}
220+
return []span.URI{s.view.modURI}
221221
}
222222

223223
// tempModFile creates a temporary go.mod file based on the contents of the
@@ -340,13 +340,13 @@ func (v *View) Rebuild(ctx context.Context) (source.Snapshot, func(), error) {
340340
return snapshot, release, nil
341341
}
342342

343-
func (v *View) WriteEnv(ctx context.Context, w io.Writer) error {
344-
v.optionsMu.Lock()
345-
env, buildFlags := v.envLocked()
346-
v.optionsMu.Unlock()
343+
func (s *snapshot) WriteEnv(ctx context.Context, w io.Writer) error {
344+
s.view.optionsMu.Lock()
345+
env, buildFlags := s.view.envLocked()
346+
s.view.optionsMu.Unlock()
347347

348348
fullEnv := make(map[string]string)
349-
for k, v := range v.goEnv {
349+
for k, v := range s.view.goEnv {
350350
fullEnv[k] = v
351351
}
352352
for _, v := range env {
@@ -360,7 +360,7 @@ func (v *View) WriteEnv(ctx context.Context, w io.Writer) error {
360360

361361
}
362362
fmt.Fprintf(w, "go env for %v\n(root %s)\n(valid build configuration = %v)\n(build flags: %v)\n",
363-
v.folder.Filename(), v.rootURI.Filename(), v.hasValidBuildConfiguration, buildFlags)
363+
s.view.folder.Filename(), s.view.rootURI.Filename(), s.view.hasValidBuildConfiguration, buildFlags)
364364
for k, v := range fullEnv {
365365
fmt.Fprintf(w, "%s=%s\n", k, v)
366366
}
@@ -646,18 +646,18 @@ func (v *View) BackgroundContext() context.Context {
646646
return v.backgroundCtx
647647
}
648648

649-
func (v *View) IgnoredFile(uri span.URI) bool {
649+
func (s *snapshot) IgnoredFile(uri span.URI) bool {
650650
filename := uri.Filename()
651651
var prefixes []string
652-
if v.modURI == "" {
653-
for _, entry := range filepath.SplitList(v.gopath) {
652+
if len(s.modules) == 0 {
653+
for _, entry := range filepath.SplitList(s.view.gopath) {
654654
prefixes = append(prefixes, filepath.Join(entry, "src"))
655655
}
656656
} else {
657-
mainMod := filepath.Dir(v.modURI.Filename())
658-
prefixes = []string{mainMod, v.gomodcache}
657+
for _, m := range s.modules {
658+
prefixes = []string{m.rootURI.Filename(), s.view.gomodcache}
659+
}
659660
}
660-
661661
for _, prefix := range prefixes {
662662
if strings.HasPrefix(filename, prefix) {
663663
return checkIgnored(filename[len(prefix):])

internal/lsp/code_action.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -459,11 +459,11 @@ func moduleQuickFixes(ctx context.Context, snapshot source.Snapshot, fh source.V
459459
case source.Mod:
460460
modFH = fh
461461
case source.Go:
462-
var err error
463-
modFH, err = snapshot.GoModForFile(ctx, fh)
462+
modURI, err := snapshot.GoModForFile(ctx, fh.URI())
464463
if err != nil {
465464
return nil, err
466465
}
466+
modFH, err = snapshot.GetFile(ctx, modURI)
467467
}
468468
tidied, err := snapshot.ModTidy(ctx, modFH)
469469
if err == source.ErrTmpModfileUnsupported {

internal/lsp/command.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ func (s *Server) runTests(ctx context.Context, snapshot source.Snapshot, uri pro
339339
})
340340
}
341341

342-
func (s *Server) runGoGenerate(ctx context.Context, snapshot source.Snapshot, uri span.URI, recursive bool, work *workDone) error {
342+
func (s *Server) runGoGenerate(ctx context.Context, snapshot source.Snapshot, dir span.URI, recursive bool, work *workDone) error {
343343
ctx, cancel := context.WithCancel(ctx)
344344
defer cancel()
345345

@@ -353,7 +353,7 @@ func (s *Server) runGoGenerate(ctx context.Context, snapshot source.Snapshot, ur
353353

354354
stderr := io.MultiWriter(er, workDoneWriter{work})
355355

356-
if err := snapshot.RunGoCommandPiped(ctx, uri.Filename(), "generate", args, er, stderr); err != nil {
356+
if err := snapshot.RunGoCommandPiped(ctx, dir.Filename(), "generate", args, er, stderr); err != nil {
357357
return err
358358
}
359359
return nil

internal/lsp/diagnostics.go

+20-7
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,11 @@ If you believe this is a mistake, please file an issue: https://github.com/golan
130130
return nil, nil
131131
}
132132
var (
133-
showMsg *protocol.ShowMessageParams
134-
wg sync.WaitGroup
133+
showMsg *protocol.ShowMessageParams
134+
wg sync.WaitGroup
135+
seenFilesMu sync.Mutex
135136
)
137+
seenFiles := make(map[span.URI]struct{})
136138
for _, pkg := range wsPkgs {
137139
wg.Add(1)
138140
go func(pkg source.Package) {
@@ -141,6 +143,10 @@ If you believe this is a mistake, please file an issue: https://github.com/golan
141143
withAnalysis := alwaysAnalyze // only run analyses for packages with open files
142144
var gcDetailsDir span.URI // find the package's optimization details, if available
143145
for _, pgf := range pkg.CompiledGoFiles() {
146+
seenFilesMu.Lock()
147+
seenFiles[pgf.URI] = struct{}{}
148+
seenFilesMu.Unlock()
149+
144150
if snapshot.IsOpen(pgf.URI) {
145151
withAnalysis = true
146152
}
@@ -159,7 +165,7 @@ If you believe this is a mistake, please file an issue: https://github.com/golan
159165

160166
// Check if might want to warn the user about their build configuration.
161167
// Our caller decides whether to send the message.
162-
if warn && !snapshot.View().ValidBuildConfiguration() {
168+
if warn && !snapshot.ValidBuildConfiguration() {
163169
showMsg = &protocol.ShowMessageParams{
164170
Type: protocol.Warning,
165171
Message: `You are neither in a module nor in your GOPATH. If you are using modules, please open your editor to a directory in your module. If you believe this warning is incorrect, please file an issue: https://github.com/golang/go/issues/new.`,
@@ -187,10 +193,18 @@ If you believe this is a mistake, please file an issue: https://github.com/golan
187193
}
188194
}(pkg)
189195
}
196+
wg.Wait()
190197
// Confirm that every opened file belongs to a package (if any exist in
191198
// the workspace). Otherwise, add a diagnostic to the file.
192199
if len(wsPkgs) > 0 {
193200
for _, o := range s.session.Overlays() {
201+
seenFilesMu.Lock()
202+
_, ok := seenFiles[o.URI()]
203+
seenFilesMu.Unlock()
204+
if ok {
205+
continue
206+
}
207+
194208
diagnostic := s.checkForOrphanedFile(ctx, snapshot, o.URI())
195209
if diagnostic == nil {
196210
continue
@@ -200,7 +214,6 @@ If you believe this is a mistake, please file an issue: https://github.com/golan
200214
addReport(o.VersionedFileIdentity(), true, []*source.Diagnostic{diagnostic})
201215
}
202216
}
203-
wg.Wait()
204217
return reports, showMsg
205218
}
206219

@@ -405,7 +418,7 @@ func (s *Server) handleFatalErrors(ctx context.Context, snapshot source.Snapshot
405418
}
406419

407420
// All other workarounds are for errors associated with modules.
408-
if len(snapshot.View().ModFiles()) == 0 {
421+
if len(snapshot.ModFiles()) == 0 {
409422
return false
410423
}
411424

@@ -431,7 +444,7 @@ See https://github.com/golang/go/issues/39164 for more detail on this issue.`,
431444
// to a specific module, so this will re-run `go mod vendor` in every
432445
// known module with a vendor directory.
433446
// TODO(rstambler): Only re-run `go mod vendor` in the relevant module.
434-
for _, uri := range snapshot.View().ModFiles() {
447+
for _, uri := range snapshot.ModFiles() {
435448
// Check that there is a vendor directory in the module before
436449
// running `go mod vendor`.
437450
if info, _ := os.Stat(filepath.Join(filepath.Dir(uri.Filename()), "vendor")); info == nil {
@@ -459,7 +472,7 @@ See https://github.com/golang/go/issues/39164 for more detail on this issue.`,
459472
if errors.Is(loadErr, source.PackagesLoadError) {
460473
// TODO(rstambler): Construct the diagnostics in internal/lsp/cache
461474
// so that we can avoid this here.
462-
for _, uri := range snapshot.View().ModFiles() {
475+
for _, uri := range snapshot.ModFiles() {
463476
fh, err := snapshot.GetFile(ctx, uri)
464477
if err != nil {
465478
return false

internal/lsp/general.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func (s *Server) addFolders(ctx context.Context, folders []protocol.WorkspaceFol
219219

220220
// Print each view's environment.
221221
buf := &bytes.Buffer{}
222-
if err := view.WriteEnv(ctx, buf); err != nil {
222+
if err := snapshot.WriteEnv(ctx, buf); err != nil {
223223
event.Error(ctx, "failed to write environment", err, tag.Directory.Of(view.Folder().Filename()))
224224
continue
225225
}

internal/lsp/lsp_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ func testLSP(t *testing.T, datum *tests.Data) {
4949
tests.DefaultOptions(options)
5050
session.SetOptions(options)
5151
options.Env = datum.Config.Env
52-
view, _, release, err := session.NewView(ctx, datum.Config.Dir, span.URIFromPath(datum.Config.Dir), options)
53-
release()
52+
view, snapshot, release, err := session.NewView(ctx, datum.Config.Dir, span.URIFromPath(datum.Config.Dir), options)
5453
if err != nil {
5554
t.Fatal(err)
5655
}
@@ -63,7 +62,8 @@ func testLSP(t *testing.T, datum *tests.Data) {
6362
view.SetOptions(ctx, options)
6463

6564
// Only run the -modfile specific tests in module mode with Go 1.14 or above.
66-
datum.ModfileFlagAvailable = len(view.ModFiles()) > 0 && testenv.Go1Point() >= 14
65+
datum.ModfileFlagAvailable = len(snapshot.ModFiles()) > 0 && testenv.Go1Point() >= 14
66+
release()
6767

6868
var modifications []source.FileModification
6969
for filename, content := range datum.Config.Overlay {

internal/lsp/mod/diagnostics.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[source.Vers
2727
defer done()
2828

2929
reports := map[source.VersionedFileIdentity][]*source.Diagnostic{}
30-
for _, uri := range snapshot.View().ModFiles() {
30+
for _, uri := range snapshot.ModFiles() {
3131
fh, err := snapshot.GetFile(ctx, uri)
3232
if err != nil {
3333
return nil, err

internal/lsp/mod/hover.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717

1818
func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) {
1919
var found bool
20-
for _, uri := range snapshot.View().ModFiles() {
20+
for _, uri := range snapshot.ModFiles() {
2121
if fh.URI() == uri {
2222
found = true
2323
break

internal/lsp/source/diagnostics.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type RelatedInformation struct {
4141
func Diagnostics(ctx context.Context, snapshot Snapshot, pkg Package, withAnalysis bool) (map[VersionedFileIdentity][]*Diagnostic, bool, error) {
4242
onlyIgnoredFiles := true
4343
for _, pgf := range pkg.CompiledGoFiles() {
44-
onlyIgnoredFiles = onlyIgnoredFiles && snapshot.View().IgnoredFile(pgf.URI)
44+
onlyIgnoredFiles = onlyIgnoredFiles && snapshot.IgnoredFile(pgf.URI)
4545
}
4646
if onlyIgnoredFiles {
4747
return nil, false, nil

0 commit comments

Comments
 (0)