simark created this revision.
Herald added subscribers: cfe-commits, kadircet, arphaman, jkorous, ioeric, 
ilya-biryukov.

It is currently possible to tell clangd where to find the
compile_commands.json file through the initializationOptions or the
didChangeConfiguration message.  However, it is not possible to tell
clangd to deselect any explicit compilation database path (i.e. go back
to the default).

This patch makes it possible by sending the value null:

  params: {
    "settings": {
      "compilationDatabasePath": null
    }
  }

Not including the compilationDatabasePath field doesn't change the value
(which means it doesn't deselect it if one is already set).  I chose to
do it this way because the other possible field,
compilationDatabaseChanges, just contains a delta.  So I think it makes
sense if compilationDatabasePath works the same way.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D51725

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  test/clangd/compile-commands-path.test

Index: test/clangd/compile-commands-path.test
===================================================================
--- test/clangd/compile-commands-path.test
+++ test/clangd/compile-commands-path.test
@@ -39,4 +39,11 @@
 # CHECK-NEXT:       {
 # CHECK-NEXT:         "message": "MACRO is two",
 ---
+{"jsonrpc":"2.0","id":0,"method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":null}}}
+# CHECK:   "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT:   "params": {
+# CHECK-NEXT:     "diagnostics": [
+# CHECK-NEXT:       {
+# CHECK-NEXT:         "message": "MACRO is not defined",
+---
 {"jsonrpc":"2.0","id":10000,"method":"shutdown"}
Index: clangd/Protocol.h
===================================================================
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -358,7 +358,14 @@
 /// "initialize" request and for the "workspace/didChangeConfiguration"
 /// notification since the data received is described as 'any' type in LSP.
 struct ClangdConfigurationParamsChange {
-  llvm::Optional<std::string> compilationDatabasePath;
+  /// Path to the directory containing the compile_commands.json file to use.
+  /// The outer Optional is empty if the compilationDatabasePath field was not
+  /// present at all in the request.
+  /// The inner Optional is empty if the compilationDatabasePath field was
+  /// preset, but the value was null.
+  /// If the value of the compilationDatabasePath in the request is a string,
+  /// both Optionals are instantiated.
+  llvm::Optional<llvm::Optional<std::string>> compilationDatabasePath;
 
   // The changes that happened to the compilation database.
   // The key of the map is a file name.
Index: clangd/Protocol.cpp
===================================================================
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -609,11 +609,22 @@
          O.map("compilationCommand", CDbUpdate.compilationCommand);
 }
 
-bool fromJSON(const json::Value &Params,
+bool fromJSON(const json::Value &Settings,
               ClangdConfigurationParamsChange &CCPC) {
-  json::ObjectMapper O(Params);
-  return O && O.map("compilationDatabasePath", CCPC.compilationDatabasePath) &&
-         O.map("compilationDatabaseChanges", CCPC.compilationDatabaseChanges);
+  json::ObjectMapper O(Settings);
+  const json::Value *P = Settings.getAsObject()->get("compilationDatabasePath");
+
+  if (P) {
+    // The field is present.
+    CCPC.compilationDatabasePath.emplace();
+    llvm::Optional<StringRef> S = P->getAsString();
+    if (S) {
+      // The field has a string value.
+      CCPC.compilationDatabasePath->emplace(*S);
+    }
+  }
+
+  return O && O.map("compilationDatabaseChanges", CCPC.compilationDatabaseChanges);
 }
 
 bool fromJSON(const json::Value &Params, ReferenceParams &R) {
Index: clangd/GlobalCompilationDatabase.h
===================================================================
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -63,7 +63,7 @@
   tooling::CompileCommand getFallbackCommand(PathRef File) const override;
 
   /// Set the compile commands directory to \p P.
-  void setCompileCommandsDir(Path P);
+  void setCompileCommandsDir(llvm::Optional<Path> P);
 
   /// Sets the extra flags that should be added to a file.
   void setExtraFlagsForFile(PathRef File, std::vector<std::string> ExtraFlags);
Index: clangd/GlobalCompilationDatabase.cpp
===================================================================
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -60,7 +60,7 @@
   return C;
 }
 
-void DirectoryBasedGlobalCompilationDatabase::setCompileCommandsDir(Path P) {
+void DirectoryBasedGlobalCompilationDatabase::setCompileCommandsDir(llvm::Optional<Path> P) {
   std::lock_guard<std::mutex> Lock(Mutex);
   CompileCommandsDir = P;
   CompilationDatabases.clear();
Index: clangd/ClangdLSPServer.h
===================================================================
--- clangd/ClangdLSPServer.h
+++ clangd/ClangdLSPServer.h
@@ -126,9 +126,10 @@
     void setExtraFlagsForFile(PathRef File,
                               std::vector<std::string> ExtraFlags);
 
-    /// Set the compile commands directory to \p P.
+    /// Set the compile commands directory to \p P.  An empty Optional value
+    /// means to not use an explicit compile commands directory path.
     /// Only valid for directory-based CDB, no-op and error log on InMemoryCDB;
-    void setCompileCommandsDir(Path P);
+    void setCompileCommandsDir(llvm::Optional<Path> P);
 
     /// Returns a CDB that should be used to get compile commands for the
     /// current instance of ClangdLSPServer.
Index: clangd/ClangdLSPServer.cpp
===================================================================
--- clangd/ClangdLSPServer.cpp
+++ clangd/ClangdLSPServer.cpp
@@ -613,14 +613,14 @@
   CachingCDB->invalidate(File);
 }
 
-void ClangdLSPServer::CompilationDB::setCompileCommandsDir(Path P) {
+void ClangdLSPServer::CompilationDB::setCompileCommandsDir(llvm::Optional<Path> P) {
   if (!IsDirectoryBased) {
     elog("Trying to set compile commands dir while using in-memory compilation "
          "database");
     return;
   }
   static_cast<DirectoryBasedGlobalCompilationDatabase *>(CDB.get())
-      ->setCompileCommandsDir(P);
+      ->setCompileCommandsDir(std::move (P));
   CachingCDB->clear();
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to