internal/lsp: hold notifications until gopls is initialized
Errors in options generate showMessage notifications, but these
were lost if they were sent before the initialization handshake completes.
Change-Id: I011da2387467bb6bf188201a7294e1bb30805cbc
Reviewed-on: https://go-review.googlesource.com/c/tools/+/263518
Run-TryBot: Peter Weinberger <pjw@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Peter Weinberger <pjw@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/general.go b/internal/lsp/general.go
index 307660b..11f2f3e 100644
--- a/internal/lsp/general.go
+++ b/internal/lsp/general.go
@@ -161,6 +161,11 @@
s.state = serverInitialized
s.stateMu.Unlock()
+ for _, not := range s.notifications {
+ s.client.ShowMessage(ctx, not)
+ }
+ s.notifications = nil
+
options := s.session.Options()
defer func() { s.session.SetOptions(options) }()
@@ -421,22 +426,34 @@
return nil
}
+func (s *Server) eventuallyShowMessage(ctx context.Context, msg *protocol.ShowMessageParams) error {
+ s.stateMu.Lock()
+ defer s.stateMu.Unlock()
+ if s.state == serverInitialized {
+ return s.client.ShowMessage(ctx, msg)
+ }
+ s.notifications = append(s.notifications, msg)
+ return nil
+}
+
func (s *Server) handleOptionResults(ctx context.Context, results source.OptionResults) error {
for _, result := range results {
if result.Error != nil {
- if err := s.client.ShowMessage(ctx, &protocol.ShowMessageParams{
+ msg := &protocol.ShowMessageParams{
Type: protocol.Error,
Message: result.Error.Error(),
- }); err != nil {
+ }
+ if err := s.eventuallyShowMessage(ctx, msg); err != nil {
return err
}
}
switch result.State {
case source.OptionUnexpected:
- if err := s.client.ShowMessage(ctx, &protocol.ShowMessageParams{
+ msg := &protocol.ShowMessageParams{
Type: protocol.Error,
Message: fmt.Sprintf("unexpected gopls setting %q", result.Name),
- }); err != nil {
+ }
+ if err := s.eventuallyShowMessage(ctx, msg); err != nil {
return err
}
case source.OptionDeprecated:
@@ -444,7 +461,7 @@
if result.Replacement != "" {
msg = fmt.Sprintf("%s, use %q instead", msg, result.Replacement)
}
- if err := s.client.ShowMessage(ctx, &protocol.ShowMessageParams{
+ if err := s.eventuallyShowMessage(ctx, &protocol.ShowMessageParams{
Type: protocol.Warning,
Message: msg,
}); err != nil {
diff --git a/internal/lsp/server.go b/internal/lsp/server.go
index 5533b1b..dceb2a7 100644
--- a/internal/lsp/server.go
+++ b/internal/lsp/server.go
@@ -67,6 +67,9 @@
session source.Session
+ // notifications generated before serverInitialized
+ notifications []*protocol.ShowMessageParams
+
// changedFiles tracks files for which there has been a textDocument/didChange.
changedFilesMu sync.Mutex
changedFiles map[span.URI]struct{}