internal/lsp: move generated file check out of didModifyFiles

This check doesn't need to be super precise about the snapshot it uses,
and it's only needed in the case of a didChange. We can refactor this
code to simplify it a bit.

Change-Id: I360be78bed236cb188b32b17cc7515bc4a3e42ba
Reviewed-on: https://go-review.googlesource.com/c/tools/+/274451
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Rebecca Stambler 2020-12-02 23:16:55 -05:00
parent 090fee60cc
commit fe8bd3ca09
1 changed files with 33 additions and 32 deletions

View File

@ -117,12 +117,42 @@ func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDo
if err := s.didModifyFiles(ctx, []source.FileModification{c}, FromDidChange); err != nil {
return err
}
return s.warnAboutModifyingGeneratedFiles(ctx, uri)
}
// warnAboutModifyingGeneratedFiles shows a warning if a user tries to edit a
// generated file for the first time.
func (s *Server) warnAboutModifyingGeneratedFiles(ctx context.Context, uri span.URI) error {
s.changedFilesMu.Lock()
defer s.changedFilesMu.Unlock()
_, ok := s.changedFiles[uri]
if !ok {
s.changedFiles[uri] = struct{}{}
}
s.changedFilesMu.Unlock()
s.changedFiles[uri] = struct{}{}
return nil
// This file has already been edited before.
if ok {
return nil
}
// Ideally, we should be able to specify that a generated file should
// be opened as read-only. Tell the user that they should not be
// editing a generated file.
view, err := s.session.ViewOf(uri)
if err != nil {
return err
}
snapshot, release := view.Snapshot(ctx)
isGenerated := source.IsGenerated(ctx, snapshot, uri)
release()
if !isGenerated {
return nil
}
return s.client.ShowMessage(ctx, &protocol.ShowMessageParams{
Message: fmt.Sprintf("Do not edit this file! %s is a generated file.", uri.Filename()),
Type: protocol.Warning,
})
}
func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.DidChangeWatchedFilesParams) error {
@ -196,27 +226,6 @@ func (s *Server) didModifyFiles(ctx context.Context, modifications []source.File
return err
}
// Check if the user is trying to modify a generated file.
for _, mod := range modifications {
if mod.OnDisk || mod.Action != source.Change {
continue
}
snapshot := snapshots[views[mod.URI]]
if snapshot == nil {
panic("no snapshot assigned for file " + mod.URI)
}
// Ideally, we should be able to specify that a generated file should be opened as read-only.
// Tell the user that they should not be editing a generated file.
if s.wasFirstChange(mod.URI) && source.IsGenerated(ctx, snapshot, mod.URI) {
if err := s.client.ShowMessage(ctx, &protocol.ShowMessageParams{
Message: fmt.Sprintf("Do not edit this file! %s is a generated file.", mod.URI.Filename()),
Type: protocol.Warning,
}); err != nil {
return err
}
}
}
// Group files by best view and diagnose them.
viewURIs := map[source.View][]span.URI{}
for uri, view := range views {
@ -253,14 +262,6 @@ func DiagnosticWorkTitle(cause ModificationSource) string {
return fmt.Sprintf("diagnosing %v", cause)
}
func (s *Server) wasFirstChange(uri span.URI) bool {
s.changedFilesMu.Lock()
defer s.changedFilesMu.Unlock()
_, ok := s.changedFiles[uri]
return !ok
}
func (s *Server) changedText(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) {
if len(changes) == 0 {
return nil, errors.Errorf("%w: no content changes provided", jsonrpc2.ErrInternal)