Skip to content

Commit a738094

Browse files
committed
internal/lsp: pass a parsed module to go mod tidy
This allows us to show parsing errors as part of module diagnostics. Change-Id: I558b95c145135482fdfceef8a5c68c62a6d32721 Reviewed-on: https://go-review.googlesource.com/c/tools/+/271630 Trust: Rebecca Stambler <rstambler@golang.org> Run-TryBot: Rebecca Stambler <rstambler@golang.org> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
1 parent c0d5e89 commit a738094

File tree

4 files changed

+33
-43
lines changed

4 files changed

+33
-43
lines changed

internal/lsp/cache/mod.go

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,25 +69,24 @@ func (s *snapshot) ParseMod(ctx context.Context, modFH source.FileHandle) (*sour
6969
Converter: span.NewContentConverter(modFH.URI().Filename(), contents),
7070
Content: contents,
7171
}
72-
data := &parseModData{
72+
file, err := modfile.Parse(modFH.URI().Filename(), contents, nil)
73+
74+
// Attempt to convert the error to a standardized parse error.
75+
var parseErrors []source.Error
76+
if err != nil {
77+
if parseErr, extractErr := extractModParseErrors(modFH.URI(), m, err, contents); extractErr == nil {
78+
parseErrors = []source.Error{*parseErr}
79+
}
80+
}
81+
return &parseModData{
7382
parsed: &source.ParsedModule{
74-
Mapper: m,
83+
URI: modFH.URI(),
84+
Mapper: m,
85+
File: file,
86+
ParseErrors: parseErrors,
7587
},
88+
err: err,
7689
}
77-
data.parsed.File, data.err = modfile.Parse(modFH.URI().Filename(), contents, nil)
78-
if data.err != nil {
79-
// Attempt to convert the error to a standardized parse error.
80-
if parseErr, extractErr := extractModParseErrors(modFH.URI(), m, data.err, contents); extractErr == nil {
81-
data.parsed.ParseErrors = []source.Error{*parseErr}
82-
}
83-
// If the file was still parsed, we don't want to treat this as a
84-
// fatal error. Note: This currently cannot happen as modfile.Parse
85-
// always returns an error when the file is nil.
86-
if data.parsed.File != nil {
87-
data.err = nil
88-
}
89-
}
90-
return data
9190
}, nil)
9291

9392
pmh := &parseModHandle{handle: h}

internal/lsp/cache/mod_tidy.go

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,17 @@ func (mth *modTidyHandle) tidy(ctx context.Context, snapshot *snapshot) (*source
5353
return data.tidied, data.err
5454
}
5555

56-
func (s *snapshot) ModTidy(ctx context.Context, fh source.FileHandle) (*source.TidiedModule, error) {
57-
if fh.Kind() != source.Mod {
58-
return nil, fmt.Errorf("%s is not a go.mod file", fh.URI())
56+
func (s *snapshot) ModTidy(ctx context.Context, pm *source.ParsedModule) (*source.TidiedModule, error) {
57+
if pm.File == nil {
58+
return nil, fmt.Errorf("cannot tidy unparseable go.mod file: %v", pm.URI)
5959
}
60-
if handle := s.getModTidyHandle(fh.URI()); handle != nil {
60+
if handle := s.getModTidyHandle(pm.URI); handle != nil {
6161
return handle.tidy(ctx, s)
6262
}
63+
fh, err := s.GetFile(ctx, pm.URI)
64+
if err != nil {
65+
return nil, err
66+
}
6367
// If the file handle is an overlay, it may not be written to disk.
6468
// The go.mod file has to be on disk for `go mod tidy` to work.
6569
if _, ok := fh.(*overlay); ok {
@@ -96,23 +100,6 @@ func (s *snapshot) ModTidy(ctx context.Context, fh source.FileHandle) (*source.T
96100
defer done()
97101

98102
snapshot := arg.(*snapshot)
99-
pm, err := snapshot.ParseMod(ctx, fh)
100-
if err != nil || len(pm.ParseErrors) > 0 {
101-
if err == nil {
102-
err = fmt.Errorf("could not parse module to tidy: %v", pm.ParseErrors)
103-
}
104-
var errors []source.Error
105-
if pm != nil {
106-
errors = pm.ParseErrors
107-
}
108-
return &modTidyData{
109-
tidied: &source.TidiedModule{
110-
Parsed: pm,
111-
Errors: errors,
112-
},
113-
err: err,
114-
}
115-
}
116103
inv := &gocommand.Invocation{
117104
Verb: "mod",
118105
Args: []string{"tidy"},
@@ -149,7 +136,6 @@ func (s *snapshot) ModTidy(ctx context.Context, fh source.FileHandle) (*source.T
149136
return &modTidyData{
150137
tidied: &source.TidiedModule{
151138
Errors: errors,
152-
Parsed: pm,
153139
TidiedContent: tempContents,
154140
},
155141
}
@@ -187,7 +173,6 @@ func (s *snapshot) parseModErrors(ctx context.Context, fh source.FileHandle, err
187173
return nil, false
188174
}
189175
return &source.TidiedModule{
190-
Parsed: pmf,
191176
Errors: []source.Error{{
192177
URI: fh.URI(),
193178
Range: rng,

internal/lsp/mod/diagnostics.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@ func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[source.Vers
5252
}
5353

5454
func ErrorsForMod(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]source.Error, error) {
55-
tidied, err := snapshot.ModTidy(ctx, fh)
55+
pm, err := snapshot.ParseMod(ctx, fh)
56+
if err != nil {
57+
if pm == nil || len(pm.ParseErrors) == 0 {
58+
return nil, err
59+
}
60+
return pm.ParseErrors, nil
61+
}
62+
tidied, err := snapshot.ModTidy(ctx, pm)
5663

5764
if source.IsNonFatalGoModError(err) {
5865
return nil, nil

internal/lsp/source/view.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ type Snapshot interface {
111111

112112
// ModTidy returns the results of `go mod tidy` for the module specified by
113113
// the given go.mod file.
114-
ModTidy(ctx context.Context, fh FileHandle) (*TidiedModule, error)
114+
ModTidy(ctx context.Context, pm *ParsedModule) (*TidiedModule, error)
115115

116116
// GoModForFile returns the URI of the go.mod file for the given URI.
117117
GoModForFile(ctx context.Context, uri span.URI) span.URI
@@ -249,15 +249,14 @@ type ParsedGoFile struct {
249249

250250
// A ParsedModule contains the results of parsing a go.mod file.
251251
type ParsedModule struct {
252+
URI span.URI
252253
File *modfile.File
253254
Mapper *protocol.ColumnMapper
254255
ParseErrors []Error
255256
}
256257

257258
// A TidiedModule contains the results of running `go mod tidy` on a module.
258259
type TidiedModule struct {
259-
// The parsed module, which is guaranteed to have parsed successfully.
260-
Parsed *ParsedModule
261260
// Diagnostics representing changes made by `go mod tidy`.
262261
Errors []Error
263262
// The bytes of the go.mod file after it was tidied.

0 commit comments

Comments
 (0)