kadircet updated this revision to Diff 458769.
kadircet added a comment.

I agree this is creating confusing state for constructors of ClangdLSPServer. It
would be interesting to create LSPServer after the initialize request one day.

- Make client-capability related options private again.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133339/new/

https://reviews.llvm.org/D133339

Files:
  clang-tools-extra/clangd/ClangdLSPServer.cpp
  clang-tools-extra/clangd/ClangdLSPServer.h

Index: clang-tools-extra/clangd/ClangdLSPServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.h
+++ clang-tools-extra/clangd/ClangdLSPServer.h
@@ -77,6 +77,9 @@
   void profile(MemoryTree &MT) const;
 
 private:
+  // Configure server using client capabilities to adjust response types and
+  // request handling.
+  void alignWithClient(const InitializeParams &Params);
   // Implement ClangdServer::Callbacks.
   void onDiagnosticsReady(PathRef File, llvm::StringRef Version,
                           std::vector<Diag> Diagnostics) override;
@@ -250,22 +253,6 @@
   LSPBinder::RawHandlers Handlers;
 
   const ThreadsafeFS &TFS;
-  /// Options used for diagnostics.
-  ClangdDiagnosticOptions DiagOpts;
-  /// The supported kinds of the client.
-  SymbolKindBitset SupportedSymbolKinds;
-  /// The supported completion item kinds of the client.
-  CompletionItemKindBitset SupportedCompletionItemKinds;
-  /// Whether the client supports CodeAction response objects.
-  bool SupportsCodeAction = false;
-  /// From capabilities of textDocument/documentSymbol.
-  bool SupportsHierarchicalDocumentSymbol = false;
-  /// Whether the client supports showing file status.
-  bool SupportFileStatus = false;
-  /// Which kind of markup should we use in textDocument/hover responses.
-  MarkupKind HoverContentFormat = MarkupKind::PlainText;
-  /// Whether the client supports offsets for parameter info labels.
-  bool SupportsOffsetsInSignatureHelp = false;
   std::mutex BackgroundIndexProgressMutex;
   enum class BackgroundIndexProgress {
     // Client doesn't support reporting progress. No transitions possible.
@@ -282,10 +269,28 @@
   // The progress to send when the progress bar is created.
   // Only valid in state Creating.
   BackgroundQueue::Stats PendingBackgroundIndexProgress;
-  /// LSP extension: skip WorkDoneProgressCreate, just send progress streams.
-  bool BackgroundIndexSkipCreate = false;
 
   Options Opts;
+  struct {
+    // Options used for diagnostics.
+    ClangdDiagnosticOptions DiagOpts;
+    // Set of symbol kinds to use.
+    SymbolKindBitset SymbolKinds;
+    // Set of completion item kinds to use.
+    CompletionItemKindBitset CompletionItemKinds;
+    // Whether to emit code actions or commands as code action responses.
+    bool EmitCodeAction = false;
+    // Whether to emit hierarchical or flat document symbol responses.
+    bool HierarchicalDocumentSymbol = false;
+    // Whether to send file status updates.
+    bool EmitFileStatus = false;
+    // Which kind of markup should we use in textDocument/hover responses.
+    MarkupKind HoverContentFormat = MarkupKind::PlainText;
+    // Whether to have offsets for parameter info labels.
+    bool OffsetsInSignatureHelp = false;
+    // LSP extension: skip WorkDoneProgressCreate, just send progress streams.
+    bool BackgroundIndexSkipCreate = false;
+  } ClientCapabilities;
   // The CDB is created by the "initialize" LSP method.
   std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
   // CDB is BaseCDB plus any commands overridden via LSP extensions.
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -441,8 +441,7 @@
   return Modifiers;
 }
 
-void ClangdLSPServer::onInitialize(const InitializeParams &Params,
-                                   Callback<llvm::json::Value> Reply) {
+void ClangdLSPServer::alignWithClient(const InitializeParams &Params) {
   // Determine character encoding first as it affects constructed ClangdServer.
   if (Params.capabilities.offsetEncoding && !Opts.Encoding) {
     Opts.Encoding = OffsetEncoding::UTF16; // fallback
@@ -463,9 +462,6 @@
     Opts.WorkspaceRoot = std::string(Params.rootUri->file());
   else if (Params.rootPath && !Params.rootPath->empty())
     Opts.WorkspaceRoot = *Params.rootPath;
-  if (Server)
-    return Reply(llvm::make_error<LSPError>("server already initialized",
-                                            ErrorCode::InvalidRequest));
 
   Opts.CodeComplete.EnableSnippets = Params.capabilities.CompletionSnippets;
   Opts.CodeComplete.IncludeFixIts = Params.capabilities.CompletionFixes;
@@ -475,25 +471,40 @@
       Params.capabilities.CompletionDocumentationFormat;
   Opts.SignatureHelpDocumentationFormat =
       Params.capabilities.SignatureHelpDocumentationFormat;
-  DiagOpts.EmbedFixesInDiagnostics = Params.capabilities.DiagnosticFixes;
-  DiagOpts.SendDiagnosticCategory = Params.capabilities.DiagnosticCategory;
-  DiagOpts.EmitRelatedLocations =
+  Opts.LineFoldingOnly = Params.capabilities.LineFoldingOnly;
+  Opts.ImplicitCancellation = !Params.capabilities.CancelsStaleRequests;
+
+  ClientCapabilities.DiagOpts.EmbedFixesInDiagnostics =
+      Params.capabilities.DiagnosticFixes;
+  ClientCapabilities.DiagOpts.SendDiagnosticCategory =
+      Params.capabilities.DiagnosticCategory;
+  ClientCapabilities.DiagOpts.EmitRelatedLocations =
       Params.capabilities.DiagnosticRelatedInformation;
   if (Params.capabilities.WorkspaceSymbolKinds)
-    SupportedSymbolKinds |= *Params.capabilities.WorkspaceSymbolKinds;
+    ClientCapabilities.SymbolKinds |= *Params.capabilities.WorkspaceSymbolKinds;
   if (Params.capabilities.CompletionItemKinds)
-    SupportedCompletionItemKinds |= *Params.capabilities.CompletionItemKinds;
-  SupportsCodeAction = Params.capabilities.CodeActionStructure;
-  SupportsHierarchicalDocumentSymbol =
+    ClientCapabilities.CompletionItemKinds |=
+        *Params.capabilities.CompletionItemKinds;
+  ClientCapabilities.EmitCodeAction = Params.capabilities.CodeActionStructure;
+  ClientCapabilities.HierarchicalDocumentSymbol =
       Params.capabilities.HierarchicalDocumentSymbol;
-  SupportFileStatus = Params.initializationOptions.FileStatus;
-  HoverContentFormat = Params.capabilities.HoverContentFormat;
-  Opts.LineFoldingOnly = Params.capabilities.LineFoldingOnly;
-  SupportsOffsetsInSignatureHelp = Params.capabilities.OffsetsInSignatureHelp;
+  ClientCapabilities.EmitFileStatus = Params.initializationOptions.FileStatus;
+  ClientCapabilities.HoverContentFormat =
+      Params.capabilities.HoverContentFormat;
+  ClientCapabilities.OffsetsInSignatureHelp =
+      Params.capabilities.OffsetsInSignatureHelp;
+  ClientCapabilities.BackgroundIndexSkipCreate =
+      Params.capabilities.ImplicitProgressCreation;
+}
+
+void ClangdLSPServer::onInitialize(const InitializeParams &Params,
+                                   Callback<llvm::json::Value> Reply) {
+  if (Server)
+    return Reply(llvm::make_error<LSPError>("server already initialized",
+                                            ErrorCode::InvalidRequest));
+  alignWithClient(Params);
   if (Params.capabilities.WorkDoneProgress)
     BackgroundIndexProgressState = BackgroundIndexProgress::Empty;
-  BackgroundIndexSkipCreate = Params.capabilities.ImplicitProgressCreation;
-  Opts.ImplicitCancellation = !Params.capabilities.CancelsStaleRequests;
 
   if (Opts.UseDirBasedCDB) {
     DirectoryBasedGlobalCompilationDatabase::Options CDBOpts(TFS);
@@ -615,7 +626,6 @@
                                  CodeAction::INFO_KIND}}}
           : llvm::json::Value(true);
 
-
   std::vector<llvm::StringRef> Commands;
   for (llvm::StringRef Command : Handlers.CommandHandlers.keys())
     Commands.push_back(Command);
@@ -800,7 +810,7 @@
         if (!Items)
           return Reply(Items.takeError());
         for (auto &Sym : *Items)
-          Sym.kind = adjustKindToCapability(Sym.kind, SupportedSymbolKinds);
+          Sym.kind = adjustKindToCapability(Sym.kind, Opts.SymbolKinds);
 
         Reply(std::move(*Items));
       });
@@ -936,8 +946,8 @@
           llvm::Expected<std::vector<DocumentSymbol>> Items) mutable {
         if (!Items)
           return Reply(Items.takeError());
-        adjustSymbolKinds(*Items, SupportedSymbolKinds);
-        if (SupportsHierarchicalDocumentSymbol)
+        adjustSymbolKinds(*Items, Opts.SymbolKinds);
+        if (Opts.HierarchicalDocumentSymbol)
           return Reply(std::move(*Items));
         return Reply(flattenSymbolHierarchy(*Items, FileURI));
       });
@@ -1021,7 +1031,7 @@
             OnlyFix->diagnostics = {Diags.front()};
         }
 
-        if (SupportsCodeAction)
+        if (Opts.EmitCodeAction)
           return Reply(llvm::json::Array(Actions));
         std::vector<Command> Commands;
         for (const auto &Action : Actions) {
@@ -1059,7 +1069,7 @@
                          for (const auto &R : List->Completions) {
                            CompletionItem C = R.render(Opts);
                            C.kind = adjustKindToCapability(
-                               C.kind, SupportedCompletionItemKinds);
+                               C.kind, this->Opts.CompletionItemKinds);
                            LSPList.items.push_back(std::move(C));
                          }
                          return Reply(std::move(LSPList));
@@ -1074,7 +1084,7 @@
                             llvm::Expected<SignatureHelp> Signature) mutable {
                           if (!Signature)
                             return Reply(Signature.takeError());
-                          if (SupportsOffsetsInSignatureHelp)
+                          if (Opts.OffsetsInSignatureHelp)
                             return Reply(std::move(*Signature));
                           // Strip out the offsets from signature help for
                           // clients that only support string labels.
@@ -1176,9 +1186,9 @@
                         return Reply(llvm::None);
 
                       Hover R;
-                      R.contents.kind = HoverContentFormat;
+                      R.contents.kind = Opts.HoverContentFormat;
                       R.range = (*H)->SymRange;
-                      switch (HoverContentFormat) {
+                      switch (Opts.HoverContentFormat) {
                       case MarkupKind::PlainText:
                         R.contents.value = (*H)->present().asPlainText();
                         return Reply(std::move(R));
@@ -1558,9 +1568,9 @@
       ShouldCleanupMemory(/*Period=*/std::chrono::minutes(1),
                           /*Delay=*/std::chrono::minutes(1)),
       BackgroundContext(Context::current().clone()), Transp(Transp),
-      MsgHandler(new MessageHandler(*this)), TFS(TFS),
-      SupportedSymbolKinds(defaultSymbolKinds()),
-      SupportedCompletionItemKinds(defaultCompletionItemKinds()), Opts(Opts) {
+      MsgHandler(new MessageHandler(*this)), TFS(TFS), Opts(Opts) {
+  this->Opts.SymbolKinds = defaultSymbolKinds();
+  this->Opts.CompletionItemKinds = defaultCompletionItemKinds();
   if (Opts.ConfigProvider) {
     assert(!Opts.ContextProvider &&
            "Only one of ConfigProvider and ContextProvider allowed!");
@@ -1703,7 +1713,7 @@
   Notification.uri = URIForFile::canonicalize(File, /*TUPath=*/File);
   DiagnosticToReplacementMap LocalFixIts; // Temporary storage
   for (auto &Diag : Diagnostics) {
-    toLSPDiags(Diag, Notification.uri, DiagOpts,
+    toLSPDiags(Diag, Notification.uri, Opts.DiagOpts,
                [&](clangd::Diagnostic Diag, llvm::ArrayRef<Fix> Fixes) {
                  auto &FixItsForDiagnostic = LocalFixIts[Diag];
                  llvm::copy(Fixes, std::back_inserter(FixItsForDiagnostic));
@@ -1763,7 +1773,7 @@
     PendingBackgroundIndexProgress = Stats;
     return;
   case BackgroundIndexProgress::Empty: {
-    if (BackgroundIndexSkipCreate) {
+    if (Opts.BackgroundIndexSkipCreate) {
       NotifyProgress(Stats);
       break;
     }
@@ -1794,7 +1804,7 @@
 }
 
 void ClangdLSPServer::onFileUpdated(PathRef File, const TUStatus &Status) {
-  if (!SupportFileStatus)
+  if (!Opts.EmitFileStatus)
     return;
   // FIXME: we don't emit "BuildingFile" and `RunningAction`, as these
   // two statuses are running faster in practice, which leads the UI constantly
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to