From b62b00ff9afbc56fa26cf70ff5a386aee2d72dab Mon Sep 17 00:00:00 2001 From: Robert Findley Date: Mon, 11 Apr 2022 13:53:45 -0400 Subject: [PATCH] internal/lsp: add an option to get notified of bug reports Our mechanism for reporting internal bugs doesn't work unless we actually notice them. Add an undocumented option to receive showMessage dialogs on the first bug occurring server-side. Change-Id: I259a4c13161271c350fae06dc6ab0e1621725c92 Reviewed-on: https://go-review.googlesource.com/c/tools/+/399624 TryBot-Result: Gopher Robot Run-TryBot: Robert Findley Reviewed-by: Alan Donovan gopls-CI: kokoro Reviewed-by: Hyang-Ah Hana Kim --- gopls/internal/regtest/debug/debug_test.go | 34 ++++++++++++++++++++++ internal/lsp/general.go | 17 +++++++++++ internal/lsp/source/options.go | 11 ++++++- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 gopls/internal/regtest/debug/debug_test.go diff --git a/gopls/internal/regtest/debug/debug_test.go b/gopls/internal/regtest/debug/debug_test.go new file mode 100644 index 0000000000..d60b3f780d --- /dev/null +++ b/gopls/internal/regtest/debug/debug_test.go @@ -0,0 +1,34 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package debug + +import ( + "testing" + + "golang.org/x/tools/gopls/internal/hooks" + "golang.org/x/tools/internal/lsp/bug" + . "golang.org/x/tools/internal/lsp/regtest" +) + +func TestMain(m *testing.M) { + Main(m, hooks.Options) +} + +func TestBugNotification(t *testing.T) { + // Verify that a properly configured session gets notified of a bug on the + // server. + WithOptions( + Modes(Singleton), // must be in-process to receive the bug report below + EditorConfig{ + Settings: map[string]interface{}{ + "showBugReports": true, + }, + }, + ).Run(t, "", func(t *testing.T, env *Env) { + const desc = "got a bug" + bug.Report(desc, nil) + env.Await(ShownMessage(desc)) + }) +} diff --git a/internal/lsp/general.go b/internal/lsp/general.go index aeb6c5b223..ab74778a5f 100644 --- a/internal/lsp/general.go +++ b/internal/lsp/general.go @@ -9,6 +9,7 @@ import ( "context" "encoding/json" "fmt" + "log" "os" "path" "path/filepath" @@ -16,6 +17,7 @@ import ( "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/jsonrpc2" + "golang.org/x/tools/internal/lsp/bug" "golang.org/x/tools/internal/lsp/debug" "golang.org/x/tools/internal/lsp/protocol" "golang.org/x/tools/internal/lsp/source" @@ -55,6 +57,21 @@ func (s *Server) initialize(ctx context.Context, params *protocol.ParamInitializ } options.ForClientCapabilities(params.Capabilities) + if options.ShowBugReports { + // Report the next bug that occurs on the server. + bugCh := bug.Notify() + go func() { + b := <-bugCh + msg := &protocol.ShowMessageParams{ + Type: protocol.Error, + Message: fmt.Sprintf("A bug occurred on the server: %s\nLocation:%s", b.Description, b.Key), + } + if err := s.eventuallyShowMessage(context.Background(), msg); err != nil { + log.Printf("error showing bug: %v", err) + } + }() + } + folders := params.WorkspaceFolders if len(folders) == 0 { if params.RootURI != "" { diff --git a/internal/lsp/source/options.go b/internal/lsp/source/options.go index de82cb2fe7..d1d34efe78 100644 --- a/internal/lsp/source/options.go +++ b/internal/lsp/source/options.go @@ -541,11 +541,17 @@ type InternalOptions struct { // } // ``` // - // At the location of the `<>` in this program, deep completion would suggest the result `x.str`. + // At the location of the `<>` in this program, deep completion would suggest + // the result `x.str`. DeepCompletion bool // TempModfile controls the use of the -modfile flag in Go 1.14. TempModfile bool + + // ShowBugReports causes a message to be shown when the first bug is reported + // on the server. + // This option applies only during initialization. + ShowBugReports bool } type ImportShortcut string @@ -953,6 +959,9 @@ func (o *Options) set(name string, value interface{}, seen map[string]struct{}) case "tempModfile": result.setBool(&o.TempModfile) + case "showBugReports": + result.setBool(&o.ShowBugReports) + case "gofumpt": result.setBool(&o.Gofumpt)