[clang-tools-extra] 7ba0779 - [clangd] Extract options struct for ClangdLSPServer. NFC

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 30 01:10:25 PDT 2020


Author: Sam McCall
Date: 2020-09-30T10:09:52+02:00
New Revision: 7ba0779fbb41b6fa8213aa31622ff45484037eb4

URL: https://github.com/llvm/llvm-project/commit/7ba0779fbb41b6fa8213aa31622ff45484037eb4
DIFF: https://github.com/llvm/llvm-project/commit/7ba0779fbb41b6fa8213aa31622ff45484037eb4.diff

LOG: [clangd] Extract options struct for ClangdLSPServer. NFC

In preparation for making moving TweakFilter from ClangdServer::Options to
a ClangdLSPServer option, and letting it vary per-request.
(In order to implement CodeActionParams.only)

Also a general overdue cleanup.

Differential Revision: https://reviews.llvm.org/D88470

Added: 
    

Modified: 
    clang-tools-extra/clangd/ClangdLSPServer.cpp
    clang-tools-extra/clangd/ClangdLSPServer.h
    clang-tools-extra/clangd/tool/ClangdMain.cpp
    clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index fa4a4ab86a8c..a85736b94830 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -395,7 +395,7 @@ class ClangdLSPServer::MessageHandler : public Transport::MessageHandler {
   Context handlerContext() const {
     return Context::current().derive(
         kCurrentOffsetEncoding,
-        Server.NegotiatedOffsetEncoding.getValueOr(OffsetEncoding::UTF16));
+        Server.Opts.OffsetEncoding.getValueOr(OffsetEncoding::UTF16));
   }
 
   // We run cancelable requests in a context that does two things:
@@ -465,43 +465,42 @@ static std::vector<llvm::StringRef> semanticTokenTypes() {
 void ClangdLSPServer::onInitialize(const InitializeParams &Params,
                                    Callback<llvm::json::Value> Reply) {
   // Determine character encoding first as it affects constructed ClangdServer.
-  if (Params.capabilities.offsetEncoding && !NegotiatedOffsetEncoding) {
-    NegotiatedOffsetEncoding = OffsetEncoding::UTF16; // fallback
+  if (Params.capabilities.offsetEncoding && !Opts.OffsetEncoding) {
+    Opts.OffsetEncoding = OffsetEncoding::UTF16; // fallback
     for (OffsetEncoding Supported : *Params.capabilities.offsetEncoding)
       if (Supported != OffsetEncoding::UnsupportedEncoding) {
-        NegotiatedOffsetEncoding = Supported;
+        Opts.OffsetEncoding = Supported;
         break;
       }
   }
 
-  ClangdServerOpts.TheiaSemanticHighlighting =
+  Opts.TheiaSemanticHighlighting =
       Params.capabilities.TheiaSemanticHighlighting;
   if (Params.capabilities.TheiaSemanticHighlighting &&
       Params.capabilities.SemanticTokens) {
     log("Client supports legacy semanticHighlights notification and standard "
         "semanticTokens request, choosing the latter (no notifications).");
-    ClangdServerOpts.TheiaSemanticHighlighting = false;
+    Opts.TheiaSemanticHighlighting = false;
   }
 
   if (Params.rootUri && *Params.rootUri)
-    ClangdServerOpts.WorkspaceRoot = std::string(Params.rootUri->file());
+    Opts.WorkspaceRoot = std::string(Params.rootUri->file());
   else if (Params.rootPath && !Params.rootPath->empty())
-    ClangdServerOpts.WorkspaceRoot = *Params.rootPath;
+    Opts.WorkspaceRoot = *Params.rootPath;
   if (Server)
     return Reply(llvm::make_error<LSPError>("server already initialized",
                                             ErrorCode::InvalidRequest));
   if (const auto &Dir = Params.initializationOptions.compilationDatabasePath)
-    CompileCommandsDir = Dir;
-  if (UseDirBasedCDB) {
+    Opts.CompileCommandsDir = Dir;
+  if (Opts.UseDirBasedCDB) {
     BaseCDB = std::make_unique<DirectoryBasedGlobalCompilationDatabase>(
-        CompileCommandsDir);
-    BaseCDB = getQueryDriverDatabase(
-        llvm::makeArrayRef(ClangdServerOpts.QueryDriverGlobs),
-        std::move(BaseCDB));
+        Opts.CompileCommandsDir);
+    BaseCDB = getQueryDriverDatabase(llvm::makeArrayRef(Opts.QueryDriverGlobs),
+                                     std::move(BaseCDB));
   }
   auto Mangler = CommandMangler::detect();
-  if (ClangdServerOpts.ResourceDir)
-    Mangler.ResourceDir = *ClangdServerOpts.ResourceDir;
+  if (Opts.ResourceDir)
+    Mangler.ResourceDir = *Opts.ResourceDir;
   CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags,
               tooling::ArgumentsAdjuster(std::move(Mangler)));
   {
@@ -510,19 +509,18 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
     // Server, CDB, etc.
     WithContext MainContext(BackgroundContext.clone());
     llvm::Optional<WithContextValue> WithOffsetEncoding;
-    if (NegotiatedOffsetEncoding)
-      WithOffsetEncoding.emplace(kCurrentOffsetEncoding,
-                                 *NegotiatedOffsetEncoding);
-    Server.emplace(*CDB, TFS, ClangdServerOpts,
+    if (Opts.OffsetEncoding)
+      WithOffsetEncoding.emplace(kCurrentOffsetEncoding, *Opts.OffsetEncoding);
+    Server.emplace(*CDB, TFS, Opts,
                    static_cast<ClangdServer::Callbacks *>(this));
   }
   applyConfiguration(Params.initializationOptions.ConfigSettings);
 
-  CCOpts.EnableSnippets = Params.capabilities.CompletionSnippets;
-  CCOpts.IncludeFixIts = Params.capabilities.CompletionFixes;
-  if (!CCOpts.BundleOverloads.hasValue())
-    CCOpts.BundleOverloads = Params.capabilities.HasSignatureHelp;
-  CCOpts.DocumentationFormat =
+  Opts.CodeComplete.EnableSnippets = Params.capabilities.CompletionSnippets;
+  Opts.CodeComplete.IncludeFixIts = Params.capabilities.CompletionFixes;
+  if (!Opts.CodeComplete.BundleOverloads.hasValue())
+    Opts.CodeComplete.BundleOverloads = Params.capabilities.HasSignatureHelp;
+  Opts.CodeComplete.DocumentationFormat =
       Params.capabilities.CompletionDocumentationFormat;
   DiagOpts.EmbedFixesInDiagnostics = Params.capabilities.DiagnosticFixes;
   DiagOpts.SendDiagnosticCategory = Params.capabilities.DiagnosticCategory;
@@ -622,14 +620,14 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
              }},
             {"typeHierarchyProvider", true},
         }}}};
-  if (NegotiatedOffsetEncoding)
-    Result["offsetEncoding"] = *NegotiatedOffsetEncoding;
-  if (ClangdServerOpts.TheiaSemanticHighlighting)
+  if (Opts.OffsetEncoding)
+    Result["offsetEncoding"] = *Opts.OffsetEncoding;
+  if (Opts.TheiaSemanticHighlighting)
     Result.getObject("capabilities")
         ->insert(
             {"semanticHighlighting",
              llvm::json::Object{{"scopes", buildHighlightScopeLookupTable()}}});
-  if (ClangdServerOpts.FoldingRanges)
+  if (Opts.FoldingRanges)
     Result.getObject("capabilities")->insert({"foldingRangeProvider", true});
   Reply(std::move(Result));
 }
@@ -788,7 +786,7 @@ void ClangdLSPServer::onWorkspaceSymbol(
     const WorkspaceSymbolParams &Params,
     Callback<std::vector<SymbolInformation>> Reply) {
   Server->workspaceSymbols(
-      Params.query, CCOpts.Limit,
+      Params.query, Opts.CodeComplete.Limit,
       [Reply = std::move(Reply),
        this](llvm::Expected<std::vector<SymbolInformation>> Items) mutable {
         if (!Items)
@@ -803,7 +801,7 @@ void ClangdLSPServer::onWorkspaceSymbol(
 void ClangdLSPServer::onPrepareRename(const TextDocumentPositionParams &Params,
                                       Callback<llvm::Optional<Range>> Reply) {
   Server->prepareRename(Params.textDocument.uri.file(), Params.position,
-                        RenameOpts, std::move(Reply));
+                        Opts.Rename, std::move(Reply));
 }
 
 void ClangdLSPServer::onRename(const RenameParams &Params,
@@ -813,7 +811,7 @@ void ClangdLSPServer::onRename(const RenameParams &Params,
     return Reply(llvm::make_error<LSPError>(
         "onRename called for non-added file", ErrorCode::InvalidParams));
   Server->rename(
-      File, Params.position, Params.newName, RenameOpts,
+      File, Params.position, Params.newName, Opts.Rename,
       [File, Params, Reply = std::move(Reply),
        this](llvm::Expected<FileEdits> Edits) mutable {
         if (!Edits)
@@ -1030,7 +1028,8 @@ void ClangdLSPServer::onCompletion(const CompletionParams &Params,
     vlog("ignored auto-triggered completion, preceding char did not match");
     return Reply(CompletionList());
   }
-  Server->codeComplete(Params.textDocument.uri.file(), Params.position, CCOpts,
+  Server->codeComplete(Params.textDocument.uri.file(), Params.position,
+                       Opts.CodeComplete,
                        [Reply = std::move(Reply),
                         this](llvm::Expected<CodeCompleteResult> List) mutable {
                          if (!List)
@@ -1038,7 +1037,7 @@ void ClangdLSPServer::onCompletion(const CompletionParams &Params,
                          CompletionList LSPList;
                          LSPList.isIncomplete = List->HasMore;
                          for (const auto &R : List->Completions) {
-                           CompletionItem C = R.render(CCOpts);
+                           CompletionItem C = R.render(Opts.CodeComplete);
                            C.kind = adjustKindToCapability(
                                C.kind, SupportedCompletionItemKinds);
                            LSPList.items.push_back(std::move(C));
@@ -1224,7 +1223,7 @@ void ClangdLSPServer::onChangeConfiguration(
 void ClangdLSPServer::onReference(const ReferenceParams &Params,
                                   Callback<std::vector<Location>> Reply) {
   Server->findReferences(Params.textDocument.uri.file(), Params.position,
-                         CCOpts.Limit,
+                         Opts.CodeComplete.Limit,
                          [Reply = std::move(Reply)](
                              llvm::Expected<ReferencesResult> Refs) mutable {
                            if (!Refs)
@@ -1340,20 +1339,13 @@ void ClangdLSPServer::onSemanticTokensDelta(
       });
 }
 
-ClangdLSPServer::ClangdLSPServer(
-    class Transport &Transp, const ThreadsafeFS &TFS,
-    const clangd::CodeCompleteOptions &CCOpts,
-    const clangd::RenameOptions &RenameOpts,
-    llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
-    llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
-    const ClangdServer::Options &Opts)
+ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
+                                 const ThreadsafeFS &TFS,
+                                 const ClangdLSPServer::Options &Opts)
     : BackgroundContext(Context::current().clone()), Transp(Transp),
-      MsgHandler(new MessageHandler(*this)), TFS(TFS), CCOpts(CCOpts),
-      RenameOpts(RenameOpts), SupportedSymbolKinds(defaultSymbolKinds()),
-      SupportedCompletionItemKinds(defaultCompletionItemKinds()),
-      UseDirBasedCDB(UseDirBasedCDB),
-      CompileCommandsDir(std::move(CompileCommandsDir)), ClangdServerOpts(Opts),
-      NegotiatedOffsetEncoding(ForcedOffsetEncoding) {
+      MsgHandler(new MessageHandler(*this)), TFS(TFS),
+      SupportedSymbolKinds(defaultSymbolKinds()),
+      SupportedCompletionItemKinds(defaultCompletionItemKinds()), Opts(Opts) {
   // clang-format off
   MsgHandler->bind("initialize", &ClangdLSPServer::onInitialize);
   MsgHandler->bind("initialized", &ClangdLSPServer::onInitialized);

diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h
index ab34ea7be748..3dc679c59510 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -36,17 +36,24 @@ class SymbolIndex;
 /// The server also supports $/cancelRequest (MessageHandler provides this).
 class ClangdLSPServer : private ClangdServer::Callbacks {
 public:
-  /// If \p CompileCommandsDir has a value, compile_commands.json will be
-  /// loaded only from \p CompileCommandsDir. Otherwise, clangd will look
-  /// for compile_commands.json in all parent directories of each file.
-  /// If UseDirBasedCDB is false, compile commands are not read from disk.
-  // FIXME: Clean up signature around CDBs.
+  struct Options : ClangdServer::Options {
+    /// Look for compilation databases, rather than using compile commands
+    /// set via LSP (extensions) only.
+    bool UseDirBasedCDB = true;
+    /// A fixed directory to search for a compilation database in.
+    /// If not set, we search upward from the source file.
+    llvm::Optional<Path> CompileCommandsDir;
+    /// The offset-encoding to use, or None to negotiate it over LSP.
+    llvm::Optional<OffsetEncoding> OffsetEncoding;
+
+    /// Per-feature options. Generally ClangdServer lets these vary
+    /// per-request, but LSP allows limited/no customizations.
+    clangd::CodeCompleteOptions CodeComplete;
+    clangd::RenameOptions Rename;
+  };
+
   ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS,
-                  const clangd::CodeCompleteOptions &CCOpts,
-                  const clangd::RenameOptions &RenameOpts,
-                  llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
-                  llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
-                  const ClangdServer::Options &Opts);
+                  const ClangdLSPServer::Options &Opts);
   /// The destructor blocks on any outstanding background tasks.
   ~ClangdLSPServer();
 
@@ -227,10 +234,6 @@ class ClangdLSPServer : private ClangdServer::Callbacks {
   }
 
   const ThreadsafeFS &TFS;
-  /// Options used for code completion
-  clangd::CodeCompleteOptions CCOpts;
-  /// Options used for rename.
-  clangd::RenameOptions RenameOpts;
   /// Options used for diagnostics.
   ClangdDiagnosticOptions DiagOpts;
   /// The supported kinds of the client.
@@ -268,14 +271,11 @@ class ClangdLSPServer : private ClangdServer::Callbacks {
   // Store of the current versions of the open documents.
   DraftStore DraftMgr;
 
+  Options Opts;
   // The CDB is created by the "initialize" LSP method.
-  bool UseDirBasedCDB;                     // FIXME: make this a capability.
-  llvm::Optional<Path> CompileCommandsDir; // FIXME: merge with capability?
   std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
   // CDB is BaseCDB plus any commands overridden via LSP extensions.
   llvm::Optional<OverlayCDB> CDB;
-  ClangdServer::Options ClangdServerOpts;
-  llvm::Optional<OffsetEncoding> NegotiatedOffsetEncoding;
   // The ClangdServer is created by the "initialize" LSP method.
   llvm::Optional<ClangdServer> Server;
 };

diff  --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 8e5d6cb97a32..60a6c267591c 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -670,9 +670,11 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
   if (auto EnvFlags = llvm::sys::Process::GetEnv(FlagsEnvVar))
     log("{0}: {1}", FlagsEnvVar, *EnvFlags);
 
+  ClangdLSPServer::Options Opts;
+  Opts.UseDirBasedCDB = (CompileArgsFrom == FilesystemCompileArgs);
+
   // If --compile-commands-dir arg was invoked, check value and override default
   // path.
-  llvm::Optional<Path> CompileCommandsDirPath;
   if (!CompileCommandsDir.empty()) {
     if (llvm::sys::fs::exists(CompileCommandsDir)) {
       // We support passing both relative and absolute paths to the
@@ -686,7 +688,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
              "will be ignored.",
              EC.message());
       } else {
-        CompileCommandsDirPath = std::string(Path.str());
+        Opts.CompileCommandsDir = std::string(Path.str());
       }
     } else {
       elog("Path specified by --compile-commands-dir does not exist. The "
@@ -694,7 +696,6 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
     }
   }
 
-  ClangdServer::Options Opts;
   switch (PCHStorage) {
   case PCHStorageFlag::Memory:
     Opts.StorePreamblesInMemory = true;
@@ -744,23 +745,22 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
   Opts.PreserveRecoveryASTType = RecoveryASTType;
   Opts.FoldingRanges = FoldingRanges;
 
-  clangd::CodeCompleteOptions CCOpts;
-  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
-  CCOpts.Limit = LimitResults;
+  Opts.CodeComplete.IncludeIneligibleResults = IncludeIneligibleResults;
+  Opts.CodeComplete.Limit = LimitResults;
   if (CompletionStyle.getNumOccurrences())
-    CCOpts.BundleOverloads = CompletionStyle != Detailed;
-  CCOpts.ShowOrigins = ShowOrigins;
-  CCOpts.InsertIncludes = HeaderInsertion;
+    Opts.CodeComplete.BundleOverloads = CompletionStyle != Detailed;
+  Opts.CodeComplete.ShowOrigins = ShowOrigins;
+  Opts.CodeComplete.InsertIncludes = HeaderInsertion;
   if (!HeaderInsertionDecorators) {
-    CCOpts.IncludeIndicator.Insert.clear();
-    CCOpts.IncludeIndicator.NoInsert.clear();
+    Opts.CodeComplete.IncludeIndicator.Insert.clear();
+    Opts.CodeComplete.IncludeIndicator.NoInsert.clear();
   }
-  CCOpts.SpeculativeIndexRequest = Opts.StaticIndex;
-  CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
-  CCOpts.AllScopes = AllScopesCompletion;
-  CCOpts.RunParser = CodeCompletionParse;
-  CCOpts.RankingModel = RankingModel;
-  CCOpts.DecisionForestBase = DecisionForestBase;
+  Opts.CodeComplete.SpeculativeIndexRequest = Opts.StaticIndex;
+  Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
+  Opts.CodeComplete.AllScopes = AllScopesCompletion;
+  Opts.CodeComplete.RunParser = CodeCompletionParse;
+  Opts.CodeComplete.RankingModel = RankingModel;
+  Opts.CodeComplete.DecisionForestBase = DecisionForestBase;
 
   RealThreadsafeFS TFS;
   std::vector<std::unique_ptr<config::Provider>> ProviderStack;
@@ -819,13 +819,11 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
       return llvm::is_contained(TweakList, T.id());
     return true;
   };
-  llvm::Optional<OffsetEncoding> OffsetEncodingFromFlag;
   if (ForceOffsetEncoding != OffsetEncoding::UnsupportedEncoding)
-    OffsetEncodingFromFlag = ForceOffsetEncoding;
+    Opts.OffsetEncoding = ForceOffsetEncoding;
 
-  clangd::RenameOptions RenameOpts;
   // Shall we allow to customize the file limit?
-  RenameOpts.AllowCrossFile = CrossFileRename;
+  Opts.Rename.AllowCrossFile = CrossFileRename;
 
   // Initialize and run ClangdLSPServer.
   // Change stdin to binary to not lose \r\n on windows.
@@ -856,10 +854,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
                                                 std::move(*Mappings));
   }
 
-  ClangdLSPServer LSPServer(
-      *TransportLayer, TFS, CCOpts, RenameOpts, CompileCommandsDirPath,
-      /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs,
-      OffsetEncodingFromFlag, Opts);
+  ClangdLSPServer LSPServer(*TransportLayer, TFS, Opts);
   llvm::set_thread_name("clangd.main");
   int ExitCode = LSPServer.run()
                      ? 0

diff  --git a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
index eaa6035df5ea..9bf45881dc47 100644
--- a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
@@ -8,11 +8,9 @@
 
 #include "Annotations.h"
 #include "ClangdLSPServer.h"
-#include "CodeComplete.h"
 #include "LSPClient.h"
 #include "Protocol.h"
 #include "TestFS.h"
-#include "refactor/Rename.h"
 #include "support/Logger.h"
 #include "support/TestTracer.h"
 #include "llvm/ADT/StringRef.h"
@@ -36,13 +34,14 @@ MATCHER_P(DiagMessage, M, "") {
 
 class LSPTest : public ::testing::Test, private clangd::Logger {
 protected:
-  LSPTest() : LogSession(*this) {}
+  LSPTest() : LogSession(*this) {
+    ClangdServer::Options &Base = Opts;
+    Base = ClangdServer::optsForTest();
+  }
 
   LSPClient &start() {
     EXPECT_FALSE(Server.hasValue()) << "Already initialized";
-    Server.emplace(Client.transport(), FS, CCOpts, RenameOpts,
-                   /*CompileCommandsDir=*/llvm::None, /*UseDirBasedCDB=*/false,
-                   /*ForcedOffsetEncoding=*/llvm::None, Opts);
+    Server.emplace(Client.transport(), FS, Opts);
     ServerThread.emplace([&] { EXPECT_TRUE(Server->run()); });
     Client.call("initialize", llvm::json::Object{});
     return Client;
@@ -64,9 +63,7 @@ class LSPTest : public ::testing::Test, private clangd::Logger {
   }
 
   MockFS FS;
-  CodeCompleteOptions CCOpts;
-  RenameOptions RenameOpts;
-  ClangdServer::Options Opts = ClangdServer::optsForTest();
+  ClangdLSPServer::Options Opts;
 
 private:
   // Color logs so we can distinguish them from test output.


        


More information about the cfe-commits mailing list