Skip to content

Commit 6467de6

Browse files
committed
internal/lsp: remove Mod handles
Continuing the massacre, remove ParseModHandle, and Mod*Handle, from the source API. Notably, having the snapshot available means we can simplify the go command invocation paths a lot. Change-Id: Ief4ef41e42f93d653f719a230004861e5e1ef70b Reviewed-on: https://go-review.googlesource.com/c/tools/+/244769 Run-TryBot: Heschi Kreinick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]>
1 parent b47602a commit 6467de6

File tree

11 files changed

+208
-342
lines changed

11 files changed

+208
-342
lines changed

internal/lsp/cache/mod.go

Lines changed: 63 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -29,44 +29,31 @@ const (
2929

3030
type parseModHandle struct {
3131
handle *memoize.Handle
32-
33-
mod, sum source.FileHandle
3432
}
3533

3634
type parseModData struct {
3735
memoize.NoCopy
3836

39-
parsed *modfile.File
40-
m *protocol.ColumnMapper
41-
42-
// parseErrors refers to syntax errors found in the go.mod file.
43-
parseErrors []source.Error
37+
parsed *source.ParsedModule
4438

4539
// err is any error encountered while parsing the file.
4640
err error
4741
}
4842

49-
func (mh *parseModHandle) Mod() source.FileHandle {
50-
return mh.mod
51-
}
52-
53-
func (mh *parseModHandle) Sum() source.FileHandle {
54-
return mh.sum
55-
}
56-
57-
func (mh *parseModHandle) Parse(ctx context.Context, s source.Snapshot) (*modfile.File, *protocol.ColumnMapper, []source.Error, error) {
43+
func (mh *parseModHandle) parse(ctx context.Context, s source.Snapshot) (*source.ParsedModule, error) {
5844
v, err := mh.handle.Get(ctx, s.(*snapshot))
5945
if err != nil {
60-
return nil, nil, nil, err
46+
return nil, err
6147
}
6248
data := v.(*parseModData)
63-
return data.parsed, data.m, data.parseErrors, data.err
49+
return data.parsed, data.err
6450
}
6551

66-
func (s *snapshot) ParseModHandle(ctx context.Context, modFH source.FileHandle) (source.ParseModHandle, error) {
52+
func (s *snapshot) ParseMod(ctx context.Context, modFH source.FileHandle) (*source.ParsedModule, error) {
6753
if handle := s.getModHandle(modFH.URI()); handle != nil {
68-
return handle, nil
54+
return handle.parse(ctx, s)
6955
}
56+
7057
h := s.view.session.cache.store.Bind(modFH.Identity().String(), func(ctx context.Context, _ memoize.Arg) interface{} {
7158
_, done := event.Start(ctx, "cache.ParseModHandle", tag.URI.Of(modFH.URI()))
7259
defer done()
@@ -80,55 +67,52 @@ func (s *snapshot) ParseModHandle(ctx context.Context, modFH source.FileHandle)
8067
Converter: span.NewContentConverter(modFH.URI().Filename(), contents),
8168
Content: contents,
8269
}
83-
parsed, err := modfile.Parse(modFH.URI().Filename(), contents, nil)
84-
if err != nil {
85-
parseErr, _ := extractModParseErrors(modFH.URI(), m, err, contents)
86-
var parseErrors []source.Error
87-
if parseErr != nil {
88-
parseErrors = append(parseErrors, *parseErr)
89-
}
90-
return &parseModData{
91-
parseErrors: parseErrors,
92-
err: err,
93-
}
70+
data := &parseModData{
71+
parsed: &source.ParsedModule{
72+
Mapper: m,
73+
},
9474
}
95-
return &parseModData{
96-
parsed: parsed,
97-
m: m,
75+
data.parsed.File, data.err = modfile.Parse(modFH.URI().Filename(), contents, nil)
76+
if data.err != nil {
77+
// Attempt to convert the error to a non-fatal parse error.
78+
if parseErr, extractErr := extractModParseErrors(modFH.URI(), m, data.err, contents); extractErr == nil {
79+
data.err = nil
80+
data.parsed.ParseErrors = []source.Error{*parseErr}
81+
}
9882
}
83+
return data
9984
})
85+
86+
pmh := &parseModHandle{handle: h}
87+
s.mu.Lock()
88+
s.parseModHandles[modFH.URI()] = pmh
89+
s.mu.Unlock()
90+
91+
return pmh.parse(ctx, s)
92+
}
93+
94+
func (s *snapshot) sumFH(ctx context.Context, modFH source.FileHandle) (source.FileHandle, error) {
10095
// Get the go.sum file, either from the snapshot or directly from the
10196
// cache. Avoid (*snapshot).GetFile here, as we don't want to add
10297
// nonexistent file handles to the snapshot if the file does not exist.
10398
sumURI := span.URIFromPath(sumFilename(modFH.URI()))
10499
sumFH := s.FindFile(sumURI)
105100
if sumFH == nil {
106-
fh, err := s.view.session.cache.getFile(ctx, sumURI)
107-
if err != nil && !os.IsNotExist(err) {
101+
var err error
102+
sumFH, err = s.view.session.cache.getFile(ctx, sumURI)
103+
if err != nil {
108104
return nil, err
109105
}
110-
if fh.err != nil && !os.IsNotExist(fh.err) {
111-
return nil, fh.err
112-
}
113-
// If the file doesn't exist, we can just keep the go.sum nil.
114-
if err != nil || fh.err != nil {
115-
sumFH = nil
116-
} else {
117-
sumFH = fh
118-
}
119106
}
120-
s.mu.Lock()
121-
defer s.mu.Unlock()
122-
s.parseModHandles[modFH.URI()] = &parseModHandle{
123-
handle: h,
124-
mod: modFH,
125-
sum: sumFH,
107+
_, err := sumFH.Read()
108+
if err != nil {
109+
return nil, err
126110
}
127-
return s.parseModHandles[modFH.URI()], nil
111+
return sumFH, nil
128112
}
129113

130114
func sumFilename(modURI span.URI) string {
131-
return modURI.Filename()[:len(modURI.Filename())-len("mod")] + "sum"
115+
return strings.TrimSuffix(modURI.Filename(), ".mod") + ".sum"
132116
}
133117

134118
// extractModParseErrors processes the raw errors returned by modfile.Parse,
@@ -197,7 +181,7 @@ type modWhyData struct {
197181
err error
198182
}
199183

200-
func (mwh *modWhyHandle) Why(ctx context.Context, s source.Snapshot) (map[string]string, error) {
184+
func (mwh *modWhyHandle) why(ctx context.Context, s source.Snapshot) (map[string]string, error) {
201185
v, err := mwh.handle.Get(ctx, s.(*snapshot))
202186
if err != nil {
203187
return nil, err
@@ -206,15 +190,14 @@ func (mwh *modWhyHandle) Why(ctx context.Context, s source.Snapshot) (map[string
206190
return data.why, data.err
207191
}
208192

209-
func (s *snapshot) ModWhyHandle(ctx context.Context) (source.ModWhyHandle, error) {
193+
func (s *snapshot) ModWhy(ctx context.Context) (map[string]string, error) {
210194
if err := s.awaitLoaded(ctx); err != nil {
211195
return nil, err
212196
}
213197
fh, err := s.GetFile(ctx, s.view.modURI)
214198
if err != nil {
215199
return nil, err
216200
}
217-
cfg := s.config(ctx)
218201
key := modKey{
219202
sessionID: s.view.session.id,
220203
cfg: hashConfig(s.config(ctx)),
@@ -228,46 +211,42 @@ func (s *snapshot) ModWhyHandle(ctx context.Context) (source.ModWhyHandle, error
228211

229212
snapshot := arg.(*snapshot)
230213

231-
pmh, err := snapshot.ParseModHandle(ctx, fh)
232-
if err != nil {
233-
return &modWhyData{err: err}
234-
}
235-
236-
parsed, _, _, err := pmh.Parse(ctx, snapshot)
214+
pm, err := snapshot.ParseMod(ctx, fh)
237215
if err != nil {
238216
return &modWhyData{err: err}
239217
}
240218
// No requires to explain.
241-
if len(parsed.Require) == 0 {
219+
if len(pm.File.Require) == 0 {
242220
return &modWhyData{}
243221
}
244222
// Run `go mod why` on all the dependencies.
245223
args := []string{"why", "-m"}
246-
for _, req := range parsed.Require {
224+
for _, req := range pm.File.Require {
247225
args = append(args, req.Mod.Path)
248226
}
249-
_, stdout, err := runGoCommand(ctx, cfg, pmh, snapshot.view.tmpMod, "mod", args)
227+
stdout, err := snapshot.RunGoCommand(ctx, "mod", args)
250228
if err != nil {
251229
return &modWhyData{err: err}
252230
}
253231
whyList := strings.Split(stdout.String(), "\n\n")
254-
if len(whyList) != len(parsed.Require) {
232+
if len(whyList) != len(pm.File.Require) {
255233
return &modWhyData{
256-
err: fmt.Errorf("mismatched number of results: got %v, want %v", len(whyList), len(parsed.Require)),
234+
err: fmt.Errorf("mismatched number of results: got %v, want %v", len(whyList), len(pm.File.Require)),
257235
}
258236
}
259-
why := make(map[string]string, len(parsed.Require))
260-
for i, req := range parsed.Require {
237+
why := make(map[string]string, len(pm.File.Require))
238+
for i, req := range pm.File.Require {
261239
why[req.Mod.Path] = whyList[i]
262240
}
263241
return &modWhyData{why: why}
264242
})
243+
244+
mwh := &modWhyHandle{handle: h}
265245
s.mu.Lock()
266-
defer s.mu.Unlock()
267-
s.modWhyHandle = &modWhyHandle{
268-
handle: h,
269-
}
270-
return s.modWhyHandle, nil
246+
s.modWhyHandle = mwh
247+
s.mu.Unlock()
248+
249+
return s.modWhyHandle.why(ctx, s)
271250
}
272251

273252
type modUpgradeHandle struct {
@@ -290,7 +269,7 @@ func (muh *modUpgradeHandle) Upgrades(ctx context.Context, s source.Snapshot) (m
290269
return data.upgrades, data.err
291270
}
292271

293-
func (s *snapshot) ModUpgradeHandle(ctx context.Context) (source.ModUpgradeHandle, error) {
272+
func (s *snapshot) ModUpgrade(ctx context.Context) (map[string]string, error) {
294273
if err := s.awaitLoaded(ctx); err != nil {
295274
return nil, err
296275
}
@@ -312,28 +291,24 @@ func (s *snapshot) ModUpgradeHandle(ctx context.Context) (source.ModUpgradeHandl
312291

313292
snapshot := arg.(*snapshot)
314293

315-
pmh, err := s.ParseModHandle(ctx, fh)
294+
pm, err := s.ParseMod(ctx, fh)
316295
if err != nil {
317296
return &modUpgradeData{err: err}
318297
}
319298

320-
parsed, _, _, err := pmh.Parse(ctx, snapshot)
321-
if err != nil {
322-
return &modUpgradeData{err: err}
323-
}
324299
// No requires to upgrade.
325-
if len(parsed.Require) == 0 {
300+
if len(pm.File.Require) == 0 {
326301
return &modUpgradeData{}
327302
}
328303
// Run "go list -mod readonly -u -m all" to be able to see which deps can be
329304
// upgraded without modifying mod file.
330305
args := []string{"-u", "-m", "all"}
331-
if !snapshot.view.tmpMod || containsVendor(pmh.Mod().URI()) {
306+
if !snapshot.view.tmpMod || containsVendor(fh.URI()) {
332307
// Use -mod=readonly if the module contains a vendor directory
333308
// (see golang/go#38711).
334309
args = append([]string{"-mod", "readonly"}, args...)
335310
}
336-
_, stdout, err := runGoCommand(ctx, cfg, pmh, snapshot.view.tmpMod, "list", args)
311+
stdout, err := snapshot.RunGoCommand(ctx, "list", args)
337312
if err != nil {
338313
return &modUpgradeData{err: err}
339314
}
@@ -364,12 +339,12 @@ func (s *snapshot) ModUpgradeHandle(ctx context.Context) (source.ModUpgradeHandl
364339
upgrades: upgrades,
365340
}
366341
})
342+
muh := &modUpgradeHandle{handle: h}
367343
s.mu.Lock()
368-
defer s.mu.Unlock()
369-
s.modUpgradeHandle = &modUpgradeHandle{
370-
handle: h,
371-
}
372-
return s.modUpgradeHandle, nil
344+
s.modUpgradeHandle = muh
345+
s.mu.Unlock()
346+
347+
return s.modUpgradeHandle.Upgrades(ctx, s)
373348
}
374349

375350
// containsVendor reports whether the module has a vendor folder.

0 commit comments

Comments
 (0)