From fc6e2057e7f6701ef9b5ef49a089bff4da7f4610 Mon Sep 17 00:00:00 2001 From: Ian Cottrell Date: Sat, 27 Jul 2019 11:59:14 -0700 Subject: [PATCH] internal/lsp: process configuration per workspace folder Change-Id: Ibd72a13166b65e418a40bf850401573a6b9caf0f Reviewed-on: https://go-review.googlesource.com/c/tools/+/187819 Run-TryBot: Ian Cottrell Reviewed-by: Rebecca Stambler TryBot-Result: Gobot Gobot --- internal/lsp/general.go | 43 +++++++++++++++++++++++++-------------- internal/lsp/server.go | 11 +++++++++- internal/lsp/workspace.go | 5 ++++- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/internal/lsp/general.go b/internal/lsp/general.go index eea37a5d..a6549beb 100644 --- a/internal/lsp/general.go +++ b/internal/lsp/general.go @@ -23,10 +23,10 @@ import ( func (s *Server) initialize(ctx context.Context, params *protocol.InitializeParams) (*protocol.InitializeResult, error) { s.initializedMu.Lock() defer s.initializedMu.Unlock() - if s.isInitialized { + if s.state >= serverInitializing { return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidRequest, "server already initialized") } - s.isInitialized = true // mark server as initialized now + s.state = serverInitializing // TODO: Remove the option once we are certain there are no issues here. s.textDocumentSyncKind = protocol.Incremental @@ -140,16 +140,7 @@ func (s *Server) initialized(ctx context.Context, params *protocol.InitializedPa }) } for _, view := range s.session.Views() { - config, err := s.client.Configuration(ctx, &protocol.ConfigurationParams{ - Items: []protocol.ConfigurationItem{{ - ScopeURI: protocol.NewURI(view.Folder()), - Section: "gopls", - }}, - }) - if err != nil { - return err - } - if err := s.processConfig(ctx, view, config[0]); err != nil { + if err := s.fetchConfig(ctx, view); err != nil { return err } } @@ -160,6 +151,28 @@ func (s *Server) initialized(ctx context.Context, params *protocol.InitializedPa return nil } +func (s *Server) fetchConfig(ctx context.Context, view source.View) error { + configs, err := s.client.Configuration(ctx, &protocol.ConfigurationParams{ + Items: []protocol.ConfigurationItem{{ + ScopeURI: protocol.NewURI(view.Folder()), + Section: "gopls", + }, { + ScopeURI: protocol.NewURI(view.Folder()), + Section: view.Name(), + }, + }, + }) + if err != nil { + return err + } + for _, config := range configs { + if err := s.processConfig(ctx, view, config); err != nil { + return err + } + } + return nil +} + func (s *Server) processConfig(ctx context.Context, view source.View, config interface{}) error { // TODO: We should probably store and process more of the config. if config == nil { @@ -238,17 +251,17 @@ func (s *Server) processConfig(ctx context.Context, view source.View, config int func (s *Server) shutdown(ctx context.Context) error { s.initializedMu.Lock() defer s.initializedMu.Unlock() - if !s.isInitialized { + if s.state < serverInitialized { return jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidRequest, "server not initialized") } // drop all the active views s.session.Shutdown(ctx) - s.isInitialized = false + s.state = serverShutDown return nil } func (s *Server) exit(ctx context.Context) error { - if s.isInitialized { + if s.state != serverShutDown { os.Exit(1) } os.Exit(0) diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 088bdcae..ae9333d5 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -60,12 +60,21 @@ func (s *Server) Run(ctx context.Context) error { return s.Conn.Run(ctx) } +type serverState int + +const ( + serverCreated = serverState(iota) + serverInitializing // set once the server has received "initialize" request + serverInitialized // set once the server has received "initialized" request + serverShutDown +) + type Server struct { Conn *jsonrpc2.Conn client protocol.Client initializedMu sync.Mutex - isInitialized bool // set once the server has received "initialize" request + state serverState // Configurations. // TODO(rstambler): Separate these into their own struct? diff --git a/internal/lsp/workspace.go b/internal/lsp/workspace.go index ddb597ec..9ad21d17 100644 --- a/internal/lsp/workspace.go +++ b/internal/lsp/workspace.go @@ -31,6 +31,9 @@ func (s *Server) changeFolders(ctx context.Context, event protocol.WorkspaceFold } func (s *Server) addView(ctx context.Context, name string, uri span.URI) error { - s.session.NewView(ctx, name, uri) + view := s.session.NewView(ctx, name, uri) + if s.state >= serverInitialized { + s.fetchConfig(ctx, view) + } return nil }