Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -418,6 +418,18 @@ reparseOpenedFiles(); } + + // Update to the compilation database. + if (Settings.compilationDatabaseChanges) { + const auto &CompileCommandUpdates = *Settings.compilationDatabaseChanges; + for (const auto &Entry : CompileCommandUpdates) { + NonCachedCDB.overrideCompilationCommandForFile(Entry.first, + std::move(Entry.second)); + } + CDB.clear(); + + reparseOpenedFiles(); + } } ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -424,6 +424,10 @@ /// since the data received is described as 'any' type in LSP. struct ClangdConfigurationParamsChange { llvm::Optional compilationDatabasePath; + + // The changes that happened to the compilation database. + llvm::Optional>> + compilationDatabaseChanges; }; bool fromJSON(const llvm::json::Value &, ClangdConfigurationParamsChange &); Index: clangd/Protocol.cpp =================================================================== --- clangd/Protocol.cpp +++ clangd/Protocol.cpp @@ -595,7 +595,8 @@ bool fromJSON(const json::Value &Params, ClangdConfigurationParamsChange &CCPC) { json::ObjectMapper O(Params); - return O && O.map("compilationDatabasePath", CCPC.compilationDatabasePath); + return O && O.map("compilationDatabasePath", CCPC.compilationDatabasePath) && + O.map("compilationDatabaseChanges", CCPC.compilationDatabaseChanges); } } // namespace clangd Index: test/clangd/did-change-configuration-params.test =================================================================== --- /dev/null +++ test/clangd/did-change-configuration-params.test @@ -0,0 +1,50 @@ +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"int main() { int i; return i; }"}}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [], +# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///bar.c","languageId":"c","version":1,"text":"int main() { int i; return i; }"}}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [], +# CHECK-NEXT: "uri": "file://{{.*}}/bar.c" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabaseChanges":{"/clangd-test/foo.c": ["clang", "-c", "foo.c", "-Wall", "-Werror"]}}}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [ +# CHECK-NEXT: { +# CHECK-NEXT: "message": "variable 'i' is uninitialized when used here", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 28, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 27, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "severity": 1 +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "uri": "file://{{.*}}/foo.c" +# CHECK-NEXT: } + +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [], +# CHECK-NEXT: "uri": "file://{{.*}}/bar.c" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":5,"method":"shutdown"} +--- +{"jsonrpc":"2.0":"method":"exit"} + +