зеркало из https://github.com/golang/tools.git
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>
This commit is contained in:
Родитель
c0d5e89189
Коммит
a7380940e0
|
@ -69,25 +69,24 @@ func (s *snapshot) ParseMod(ctx context.Context, modFH source.FileHandle) (*sour
|
|||
Converter: span.NewContentConverter(modFH.URI().Filename(), contents),
|
||||
Content: contents,
|
||||
}
|
||||
data := &parseModData{
|
||||
file, err := modfile.Parse(modFH.URI().Filename(), contents, nil)
|
||||
|
||||
// Attempt to convert the error to a standardized parse error.
|
||||
var parseErrors []source.Error
|
||||
if err != nil {
|
||||
if parseErr, extractErr := extractModParseErrors(modFH.URI(), m, err, contents); extractErr == nil {
|
||||
parseErrors = []source.Error{*parseErr}
|
||||
}
|
||||
}
|
||||
return &parseModData{
|
||||
parsed: &source.ParsedModule{
|
||||
Mapper: m,
|
||||
URI: modFH.URI(),
|
||||
Mapper: m,
|
||||
File: file,
|
||||
ParseErrors: parseErrors,
|
||||
},
|
||||
err: err,
|
||||
}
|
||||
data.parsed.File, data.err = modfile.Parse(modFH.URI().Filename(), contents, nil)
|
||||
if data.err != nil {
|
||||
// Attempt to convert the error to a standardized parse error.
|
||||
if parseErr, extractErr := extractModParseErrors(modFH.URI(), m, data.err, contents); extractErr == nil {
|
||||
data.parsed.ParseErrors = []source.Error{*parseErr}
|
||||
}
|
||||
// If the file was still parsed, we don't want to treat this as a
|
||||
// fatal error. Note: This currently cannot happen as modfile.Parse
|
||||
// always returns an error when the file is nil.
|
||||
if data.parsed.File != nil {
|
||||
data.err = nil
|
||||
}
|
||||
}
|
||||
return data
|
||||
}, nil)
|
||||
|
||||
pmh := &parseModHandle{handle: h}
|
||||
|
|
|
@ -53,13 +53,17 @@ func (mth *modTidyHandle) tidy(ctx context.Context, snapshot *snapshot) (*source
|
|||
return data.tidied, data.err
|
||||
}
|
||||
|
||||
func (s *snapshot) ModTidy(ctx context.Context, fh source.FileHandle) (*source.TidiedModule, error) {
|
||||
if fh.Kind() != source.Mod {
|
||||
return nil, fmt.Errorf("%s is not a go.mod file", fh.URI())
|
||||
func (s *snapshot) ModTidy(ctx context.Context, pm *source.ParsedModule) (*source.TidiedModule, error) {
|
||||
if pm.File == nil {
|
||||
return nil, fmt.Errorf("cannot tidy unparseable go.mod file: %v", pm.URI)
|
||||
}
|
||||
if handle := s.getModTidyHandle(fh.URI()); handle != nil {
|
||||
if handle := s.getModTidyHandle(pm.URI); handle != nil {
|
||||
return handle.tidy(ctx, s)
|
||||
}
|
||||
fh, err := s.GetFile(ctx, pm.URI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If the file handle is an overlay, it may not be written to disk.
|
||||
// The go.mod file has to be on disk for `go mod tidy` to work.
|
||||
if _, ok := fh.(*overlay); ok {
|
||||
|
@ -96,23 +100,6 @@ func (s *snapshot) ModTidy(ctx context.Context, fh source.FileHandle) (*source.T
|
|||
defer done()
|
||||
|
||||
snapshot := arg.(*snapshot)
|
||||
pm, err := snapshot.ParseMod(ctx, fh)
|
||||
if err != nil || len(pm.ParseErrors) > 0 {
|
||||
if err == nil {
|
||||
err = fmt.Errorf("could not parse module to tidy: %v", pm.ParseErrors)
|
||||
}
|
||||
var errors []source.Error
|
||||
if pm != nil {
|
||||
errors = pm.ParseErrors
|
||||
}
|
||||
return &modTidyData{
|
||||
tidied: &source.TidiedModule{
|
||||
Parsed: pm,
|
||||
Errors: errors,
|
||||
},
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
inv := &gocommand.Invocation{
|
||||
Verb: "mod",
|
||||
Args: []string{"tidy"},
|
||||
|
@ -149,7 +136,6 @@ func (s *snapshot) ModTidy(ctx context.Context, fh source.FileHandle) (*source.T
|
|||
return &modTidyData{
|
||||
tidied: &source.TidiedModule{
|
||||
Errors: errors,
|
||||
Parsed: pm,
|
||||
TidiedContent: tempContents,
|
||||
},
|
||||
}
|
||||
|
@ -187,7 +173,6 @@ func (s *snapshot) parseModErrors(ctx context.Context, fh source.FileHandle, err
|
|||
return nil, false
|
||||
}
|
||||
return &source.TidiedModule{
|
||||
Parsed: pmf,
|
||||
Errors: []source.Error{{
|
||||
URI: fh.URI(),
|
||||
Range: rng,
|
||||
|
|
|
@ -52,7 +52,14 @@ func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[source.Vers
|
|||
}
|
||||
|
||||
func ErrorsForMod(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]source.Error, error) {
|
||||
tidied, err := snapshot.ModTidy(ctx, fh)
|
||||
pm, err := snapshot.ParseMod(ctx, fh)
|
||||
if err != nil {
|
||||
if pm == nil || len(pm.ParseErrors) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return pm.ParseErrors, nil
|
||||
}
|
||||
tidied, err := snapshot.ModTidy(ctx, pm)
|
||||
|
||||
if source.IsNonFatalGoModError(err) {
|
||||
return nil, nil
|
||||
|
|
|
@ -111,7 +111,7 @@ type Snapshot interface {
|
|||
|
||||
// ModTidy returns the results of `go mod tidy` for the module specified by
|
||||
// the given go.mod file.
|
||||
ModTidy(ctx context.Context, fh FileHandle) (*TidiedModule, error)
|
||||
ModTidy(ctx context.Context, pm *ParsedModule) (*TidiedModule, error)
|
||||
|
||||
// GoModForFile returns the URI of the go.mod file for the given URI.
|
||||
GoModForFile(ctx context.Context, uri span.URI) span.URI
|
||||
|
@ -249,6 +249,7 @@ type ParsedGoFile struct {
|
|||
|
||||
// A ParsedModule contains the results of parsing a go.mod file.
|
||||
type ParsedModule struct {
|
||||
URI span.URI
|
||||
File *modfile.File
|
||||
Mapper *protocol.ColumnMapper
|
||||
ParseErrors []Error
|
||||
|
@ -256,8 +257,6 @@ type ParsedModule struct {
|
|||
|
||||
// A TidiedModule contains the results of running `go mod tidy` on a module.
|
||||
type TidiedModule struct {
|
||||
// The parsed module, which is guaranteed to have parsed successfully.
|
||||
Parsed *ParsedModule
|
||||
// Diagnostics representing changes made by `go mod tidy`.
|
||||
Errors []Error
|
||||
// The bytes of the go.mod file after it was tidied.
|
||||
|
|
Загрузка…
Ссылка в новой задаче