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)