[clang-tools-extra] r320576 - [clangd] Implemented logging using Context

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 13 04:51:22 PST 2017


Author: ibiryukov
Date: Wed Dec 13 04:51:22 2017
New Revision: 320576

URL: http://llvm.org/viewvc/llvm-project?rev=320576&view=rev
Log:
[clangd] Implemented logging using Context

Reviewers: sammccall, ioeric, hokein

Reviewed By: sammccall

Subscribers: klimek, cfe-commits

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

Modified:
    clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
    clang-tools-extra/trunk/clangd/ClangdServer.cpp
    clang-tools-extra/trunk/clangd/ClangdServer.h
    clang-tools-extra/trunk/clangd/ClangdUnit.cpp
    clang-tools-extra/trunk/clangd/ClangdUnit.h
    clang-tools-extra/trunk/clangd/ClangdUnitStore.cpp
    clang-tools-extra/trunk/clangd/ClangdUnitStore.h
    clang-tools-extra/trunk/clangd/CodeComplete.cpp
    clang-tools-extra/trunk/clangd/CodeComplete.h
    clang-tools-extra/trunk/clangd/Function.h
    clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp
    clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h
    clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
    clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h
    clang-tools-extra/trunk/clangd/Logger.cpp
    clang-tools-extra/trunk/clangd/Logger.h
    clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
    clang-tools-extra/trunk/clangd/ProtocolHandlers.h
    clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
    clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
    clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Wed Dec 13 04:51:22 2017
@@ -46,7 +46,7 @@ std::vector<TextEdit> replacementsToEdit
 } // namespace
 
 void ClangdLSPServer::onInitialize(Ctx C, InitializeParams &Params) {
-  C.reply(json::obj{
+  reply(C, json::obj{
       {{"capabilities",
         json::obj{
             {"textDocumentSync", 1},
@@ -84,7 +84,7 @@ void ClangdLSPServer::onInitialize(Ctx C
 void ClangdLSPServer::onShutdown(Ctx C, ShutdownParams &Params) {
   // Do essentially nothing, just say we're ready to exit.
   ShutdownRequestReceived = true;
-  C.reply(nullptr);
+  reply(C, nullptr);
 }
 
 void ClangdLSPServer::onExit(Ctx C, ExitParams &Params) { IsDone = true; }
@@ -94,16 +94,17 @@ void ClangdLSPServer::onDocumentDidOpen(
   if (Params.metadata && !Params.metadata->extraFlags.empty())
     CDB.setExtraFlagsForFile(Params.textDocument.uri.file,
                              std::move(Params.metadata->extraFlags));
-  Server.addDocument(Params.textDocument.uri.file, Params.textDocument.text);
+  Server.addDocument(std::move(C), Params.textDocument.uri.file,
+                     Params.textDocument.text);
 }
 
 void ClangdLSPServer::onDocumentDidChange(Ctx C,
                                           DidChangeTextDocumentParams &Params) {
   if (Params.contentChanges.size() != 1)
-    return C.replyError(ErrorCode::InvalidParams,
-                        "can only apply one change at a time");
+    return replyError(C, ErrorCode::InvalidParams,
+                      "can only apply one change at a time");
   // We only support full syncing right now.
-  Server.addDocument(Params.textDocument.uri.file,
+  Server.addDocument(std::move(C), Params.textDocument.uri.file,
                      Params.contentChanges[0].text);
 }
 
@@ -125,39 +126,39 @@ void ClangdLSPServer::onCommand(Ctx C, E
 
     ApplyWorkspaceEditParams ApplyEdit;
     ApplyEdit.edit = *Params.workspaceEdit;
-    C.reply("Fix applied.");
+    reply(C, "Fix applied.");
     // We don't need the response so id == 1 is OK.
     // Ideally, we would wait for the response and if there is no error, we
     // would reply success/failure to the original RPC.
-    C.call("workspace/applyEdit", ApplyEdit);
+    call(C, "workspace/applyEdit", ApplyEdit);
   } else {
     // We should not get here because ExecuteCommandParams would not have
     // parsed in the first place and this handler should not be called. But if
     // more commands are added, this will be here has a safe guard.
-    C.replyError(
-        ErrorCode::InvalidParams,
+    replyError(
+        C, ErrorCode::InvalidParams,
         llvm::formatv("Unsupported command \"{0}\".", Params.command).str());
   }
 }
 
 void ClangdLSPServer::onRename(Ctx C, RenameParams &Params) {
   auto File = Params.textDocument.uri.file;
-  auto Replacements = Server.rename(File, Params.position, Params.newName);
+  auto Replacements = Server.rename(C, File, Params.position, Params.newName);
   if (!Replacements) {
-    C.replyError(ErrorCode::InternalError,
-                 llvm::toString(Replacements.takeError()));
+    replyError(C, ErrorCode::InternalError,
+               llvm::toString(Replacements.takeError()));
     return;
   }
   std::string Code = Server.getDocument(File);
   std::vector<TextEdit> Edits = replacementsToEdits(Code, *Replacements);
   WorkspaceEdit WE;
   WE.changes = {{Params.textDocument.uri.uri, Edits}};
-  C.reply(WE);
+  reply(C, WE);
 }
 
 void ClangdLSPServer::onDocumentDidClose(Ctx C,
                                          DidCloseTextDocumentParams &Params) {
-  Server.removeDocument(Params.textDocument.uri.file);
+  Server.removeDocument(std::move(C), Params.textDocument.uri.file);
 }
 
 void ClangdLSPServer::onDocumentOnTypeFormatting(
@@ -166,10 +167,10 @@ void ClangdLSPServer::onDocumentOnTypeFo
   std::string Code = Server.getDocument(File);
   auto ReplacementsOrError = Server.formatOnType(Code, File, Params.position);
   if (ReplacementsOrError)
-    C.reply(json::ary(replacementsToEdits(Code, ReplacementsOrError.get())));
+    reply(C, json::ary(replacementsToEdits(Code, ReplacementsOrError.get())));
   else
-    C.replyError(ErrorCode::UnknownErrorCode,
-                 llvm::toString(ReplacementsOrError.takeError()));
+    replyError(C, ErrorCode::UnknownErrorCode,
+               llvm::toString(ReplacementsOrError.takeError()));
 }
 
 void ClangdLSPServer::onDocumentRangeFormatting(
@@ -178,10 +179,10 @@ void ClangdLSPServer::onDocumentRangeFor
   std::string Code = Server.getDocument(File);
   auto ReplacementsOrError = Server.formatRange(Code, File, Params.range);
   if (ReplacementsOrError)
-    C.reply(json::ary(replacementsToEdits(Code, ReplacementsOrError.get())));
+    reply(C, json::ary(replacementsToEdits(Code, ReplacementsOrError.get())));
   else
-    C.replyError(ErrorCode::UnknownErrorCode,
-                 llvm::toString(ReplacementsOrError.takeError()));
+    replyError(C, ErrorCode::UnknownErrorCode,
+               llvm::toString(ReplacementsOrError.takeError()));
 }
 
 void ClangdLSPServer::onDocumentFormatting(Ctx C,
@@ -190,10 +191,10 @@ void ClangdLSPServer::onDocumentFormatti
   std::string Code = Server.getDocument(File);
   auto ReplacementsOrError = Server.formatFile(Code, File);
   if (ReplacementsOrError)
-    C.reply(json::ary(replacementsToEdits(Code, ReplacementsOrError.get())));
+    reply(C, json::ary(replacementsToEdits(Code, ReplacementsOrError.get())));
   else
-    C.replyError(ErrorCode::UnknownErrorCode,
-                 llvm::toString(ReplacementsOrError.takeError()));
+    replyError(C, ErrorCode::UnknownErrorCode,
+               llvm::toString(ReplacementsOrError.takeError()));
 }
 
 void ClangdLSPServer::onCodeAction(Ctx C, CodeActionParams &Params) {
@@ -213,65 +214,68 @@ void ClangdLSPServer::onCodeAction(Ctx C
       });
     }
   }
-  C.reply(std::move(Commands));
+  reply(C, std::move(Commands));
 }
 
 void ClangdLSPServer::onCompletion(Ctx C, TextDocumentPositionParams &Params) {
-  auto List =
-      Server
-          .codeComplete(
-              Params.textDocument.uri.file,
-              Position{Params.position.line, Params.position.character}, CCOpts)
-          .get() // FIXME(ibiryukov): This could be made async if we
-                 // had an API that would allow to attach callbacks to
-                 // futures returned by ClangdServer.
-          .Value;
-  C.reply(List);
+  auto Reply = Server
+                   .codeComplete(std::move(C), Params.textDocument.uri.file,
+                                 Position{Params.position.line,
+                                          Params.position.character},
+                                 CCOpts)
+                   .get(); // FIXME(ibiryukov): This could be made async if we
+                           // had an API that would allow to attach callbacks to
+                           // futures returned by ClangdServer.
+
+  // We have std::move'd from C, now restore it from response of codeComplete.
+  C = std::move(Reply.first);
+  auto List = std::move(Reply.second.Value);
+  reply(C, List);
 }
 
 void ClangdLSPServer::onSignatureHelp(Ctx C,
                                       TextDocumentPositionParams &Params) {
   auto SignatureHelp = Server.signatureHelp(
-      Params.textDocument.uri.file,
+      C, Params.textDocument.uri.file,
       Position{Params.position.line, Params.position.character});
   if (!SignatureHelp)
-    return C.replyError(ErrorCode::InvalidParams,
-                        llvm::toString(SignatureHelp.takeError()));
-  C.reply(SignatureHelp->Value);
+    return replyError(C, ErrorCode::InvalidParams,
+                      llvm::toString(SignatureHelp.takeError()));
+  reply(C, SignatureHelp->Value);
 }
 
 void ClangdLSPServer::onGoToDefinition(Ctx C,
                                        TextDocumentPositionParams &Params) {
   auto Items = Server.findDefinitions(
-      Params.textDocument.uri.file,
+      C, Params.textDocument.uri.file,
       Position{Params.position.line, Params.position.character});
   if (!Items)
-    return C.replyError(ErrorCode::InvalidParams,
-                        llvm::toString(Items.takeError()));
-  C.reply(json::ary(Items->Value));
+    return replyError(C, ErrorCode::InvalidParams,
+                      llvm::toString(Items.takeError()));
+  reply(C, json::ary(Items->Value));
 }
 
 void ClangdLSPServer::onSwitchSourceHeader(Ctx C,
                                            TextDocumentIdentifier &Params) {
   llvm::Optional<Path> Result = Server.switchSourceHeader(Params.uri.file);
   std::string ResultUri;
-  C.reply(Result ? URI::fromFile(*Result).uri : "");
+  reply(C, Result ? URI::fromFile(*Result).uri : "");
 }
 
 void ClangdLSPServer::onDocumentHighlight(Ctx C,
                                           TextDocumentPositionParams &Params) {
 
   auto Highlights = Server.findDocumentHighlights(
-      Params.textDocument.uri.file,
+      C, Params.textDocument.uri.file,
       Position{Params.position.line, Params.position.character});
 
   if (!Highlights) {
-    C.replyError(ErrorCode::InternalError,
-                 llvm::toString(Highlights.takeError()));
+    replyError(C, ErrorCode::InternalError,
+               llvm::toString(Highlights.takeError()));
     return;
   }
 
-  C.reply(json::ary(Highlights->Value));
+  reply(C, json::ary(Highlights->Value));
 }
 
 ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount,
@@ -279,19 +283,17 @@ ClangdLSPServer::ClangdLSPServer(JSONOut
                                  const clangd::CodeCompleteOptions &CCOpts,
                                  llvm::Optional<StringRef> ResourceDir,
                                  llvm::Optional<Path> CompileCommandsDir)
-    : Out(Out), CDB(/*Logger=*/Out, std::move(CompileCommandsDir)),
-      CCOpts(CCOpts), Server(CDB, /*DiagConsumer=*/*this, FSProvider,
-                             AsyncThreadsCount, StorePreamblesInMemory,
-                             /*Logger=*/Out, ResourceDir) {}
+    : Out(Out), CDB(std::move(CompileCommandsDir)), CCOpts(CCOpts),
+      Server(CDB, /*DiagConsumer=*/*this, FSProvider, AsyncThreadsCount,
+             StorePreamblesInMemory, ResourceDir) {}
 
 bool ClangdLSPServer::run(std::istream &In) {
   assert(!IsDone && "Run was called before");
 
   // Set up JSONRPCDispatcher.
-  JSONRPCDispatcher Dispatcher(
-      [](RequestContext Ctx, const json::Expr &Params) {
-        Ctx.replyError(ErrorCode::MethodNotFound, "method not found");
-      });
+  JSONRPCDispatcher Dispatcher([](Context Ctx, const json::Expr &Params) {
+    replyError(Ctx, ErrorCode::MethodNotFound, "method not found");
+  });
   registerCallbackHandlers(Dispatcher, Out, /*Callbacks=*/*this);
 
   // Run the Language Server loop.

Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Wed Dec 13 04:51:22 2017
@@ -28,16 +28,6 @@ using namespace clang::clangd;
 
 namespace {
 
-class FulfillPromiseGuard {
-public:
-  FulfillPromiseGuard(std::promise<void> &Promise) : Promise(Promise) {}
-
-  ~FulfillPromiseGuard() { Promise.set_value(); }
-
-private:
-  std::promise<void> &Promise;
-};
-
 std::string getStandardResourceDir() {
   static int Dummy; // Just an address in this process.
   return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy);
@@ -163,10 +153,9 @@ ClangdServer::ClangdServer(GlobalCompila
                            DiagnosticsConsumer &DiagConsumer,
                            FileSystemProvider &FSProvider,
                            unsigned AsyncThreadsCount,
-                           bool StorePreamblesInMemory, clangd::Logger &Logger,
+                           bool StorePreamblesInMemory,
                            llvm::Optional<StringRef> ResourceDir)
-    : Logger(Logger), CDB(CDB), DiagConsumer(DiagConsumer),
-      FSProvider(FSProvider),
+    : CDB(CDB), DiagConsumer(DiagConsumer), FSProvider(FSProvider),
       ResourceDir(ResourceDir ? ResourceDir->str() : getStandardResourceDir()),
       PCHs(std::make_shared<PCHContainerOperations>()),
       StorePreamblesInMemory(StorePreamblesInMemory),
@@ -179,65 +168,69 @@ void ClangdServer::setRootPath(PathRef R
     this->RootPath = NewRootPath;
 }
 
-std::future<void> ClangdServer::addDocument(PathRef File, StringRef Contents) {
+std::future<Context> ClangdServer::addDocument(Context Ctx, PathRef File,
+                                               StringRef Contents) {
   DocVersion Version = DraftMgr.updateDraft(File, Contents);
 
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
   std::shared_ptr<CppFile> Resources = Units.getOrCreateFile(
-      File, ResourceDir, CDB, StorePreamblesInMemory, PCHs, Logger);
-  return scheduleReparseAndDiags(File, VersionedDraft{Version, Contents.str()},
+      File, ResourceDir, CDB, StorePreamblesInMemory, PCHs);
+  return scheduleReparseAndDiags(std::move(Ctx), File,
+                                 VersionedDraft{Version, Contents.str()},
                                  std::move(Resources), std::move(TaggedFS));
 }
 
-std::future<void> ClangdServer::removeDocument(PathRef File) {
+std::future<Context> ClangdServer::removeDocument(Context Ctx, PathRef File) {
   DraftMgr.removeDraft(File);
   std::shared_ptr<CppFile> Resources = Units.removeIfPresent(File);
-  return scheduleCancelRebuild(std::move(Resources));
+  return scheduleCancelRebuild(std::move(Ctx), std::move(Resources));
 }
 
-std::future<void> ClangdServer::forceReparse(PathRef File) {
+std::future<Context> ClangdServer::forceReparse(Context Ctx, PathRef File) {
   auto FileContents = DraftMgr.getDraft(File);
   assert(FileContents.Draft &&
          "forceReparse() was called for non-added document");
 
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
   auto Recreated = Units.recreateFileIfCompileCommandChanged(
-      File, ResourceDir, CDB, StorePreamblesInMemory, PCHs, Logger);
+      File, ResourceDir, CDB, StorePreamblesInMemory, PCHs);
 
   // Note that std::future from this cleanup action is ignored.
-  scheduleCancelRebuild(std::move(Recreated.RemovedFile));
+  scheduleCancelRebuild(Ctx.clone(), std::move(Recreated.RemovedFile));
   // Schedule a reparse.
-  return scheduleReparseAndDiags(File, std::move(FileContents),
+  return scheduleReparseAndDiags(std::move(Ctx), File, std::move(FileContents),
                                  std::move(Recreated.FileInCollection),
                                  std::move(TaggedFS));
 }
 
-std::future<Tagged<CompletionList>>
-ClangdServer::codeComplete(PathRef File, Position Pos,
+std::future<std::pair<Context, Tagged<CompletionList>>>
+ClangdServer::codeComplete(Context Ctx, PathRef File, Position Pos,
                            const clangd::CodeCompleteOptions &Opts,
                            llvm::Optional<StringRef> OverridenContents,
                            IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) {
-  using ResultType = Tagged<CompletionList>;
+  using ResultType = std::pair<Context, Tagged<CompletionList>>;
 
   std::promise<ResultType> ResultPromise;
 
-  auto Callback = [](std::promise<ResultType> ResultPromise,
-                     ResultType Result) -> void {
-    ResultPromise.set_value(std::move(Result));
+  auto Callback = [](std::promise<ResultType> ResultPromise, Context Ctx,
+                     Tagged<CompletionList> Result) -> void {
+    ResultPromise.set_value({std::move(Ctx), std::move(Result)});
   };
 
   std::future<ResultType> ResultFuture = ResultPromise.get_future();
-  codeComplete(BindWithForward(Callback, std::move(ResultPromise)), File, Pos,
-               Opts, OverridenContents, UsedFS);
+  codeComplete(std::move(Ctx), File, Pos, Opts,
+               BindWithForward(Callback, std::move(ResultPromise)),
+               OverridenContents, UsedFS);
   return ResultFuture;
 }
 
 void ClangdServer::codeComplete(
-    UniqueFunction<void(Tagged<CompletionList>)> Callback, PathRef File,
-    Position Pos, const clangd::CodeCompleteOptions &Opts,
+    Context Ctx, PathRef File, Position Pos,
+    const clangd::CodeCompleteOptions &Opts,
+    UniqueFunction<void(Context, Tagged<CompletionList>)> Callback,
     llvm::Optional<StringRef> OverridenContents,
     IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) {
-  using CallbackType = UniqueFunction<void(Tagged<CompletionList>)>;
+  using CallbackType = UniqueFunction<void(Context, Tagged<CompletionList>)>;
 
   std::string Contents;
   if (OverridenContents) {
@@ -268,7 +261,7 @@ void ClangdServer::codeComplete(
   // A task that will be run asynchronously.
   auto Task =
       // 'mutable' to reassign Preamble variable.
-      [=](CallbackType Callback) mutable {
+      [=](Context Ctx, CallbackType Callback) mutable {
         if (!Preamble) {
           // Maybe we built some preamble before processing this request.
           Preamble = Resources->getPossiblyStalePreamble();
@@ -277,18 +270,20 @@ void ClangdServer::codeComplete(
         // both the old and the new version in case only one of them matches.
 
         CompletionList Result = clangd::codeComplete(
-            File, Resources->getCompileCommand(),
+            Ctx, File, Resources->getCompileCommand(),
             Preamble ? &Preamble->Preamble : nullptr, Contents, Pos,
-            TaggedFS.Value, PCHs, CodeCompleteOpts, Logger);
+            TaggedFS.Value, PCHs, CodeCompleteOpts);
 
-        Callback(make_tagged(std::move(Result), std::move(TaggedFS.Tag)));
+        Callback(std::move(Ctx),
+                 make_tagged(std::move(Result), std::move(TaggedFS.Tag)));
       };
 
-  WorkScheduler.addToFront(std::move(Task), std::move(Callback));
+  WorkScheduler.addToFront(std::move(Task), std::move(Ctx),
+                           std::move(Callback));
 }
 
 llvm::Expected<Tagged<SignatureHelp>>
-ClangdServer::signatureHelp(PathRef File, Position Pos,
+ClangdServer::signatureHelp(const Context &Ctx, PathRef File, Position Pos,
                             llvm::Optional<StringRef> OverridenContents,
                             IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) {
   std::string DraftStorage;
@@ -314,10 +309,10 @@ ClangdServer::signatureHelp(PathRef File
         llvm::errc::invalid_argument);
 
   auto Preamble = Resources->getPossiblyStalePreamble();
-  auto Result = clangd::signatureHelp(File, Resources->getCompileCommand(),
-                                      Preamble ? &Preamble->Preamble : nullptr,
-                                      *OverridenContents, Pos, TaggedFS.Value,
-                                      PCHs, Logger);
+  auto Result =
+      clangd::signatureHelp(Ctx, File, Resources->getCompileCommand(),
+                            Preamble ? &Preamble->Preamble : nullptr,
+                            *OverridenContents, Pos, TaggedFS.Value, PCHs);
   return make_tagged(std::move(Result), TaggedFS.Tag);
 }
 
@@ -348,7 +343,8 @@ ClangdServer::formatOnType(StringRef Cod
 }
 
 Expected<std::vector<tooling::Replacement>>
-ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName) {
+ClangdServer::rename(const Context &Ctx, PathRef File, Position Pos,
+                     llvm::StringRef NewName) {
   std::string Code = getDocument(File);
   std::shared_ptr<CppFile> Resources = Units.getFile(File);
   RefactoringResultCollector ResultCollector;
@@ -419,7 +415,7 @@ std::string ClangdServer::dumpAST(PathRe
 }
 
 llvm::Expected<Tagged<std::vector<Location>>>
-ClangdServer::findDefinitions(PathRef File, Position Pos) {
+ClangdServer::findDefinitions(const Context &Ctx, PathRef File, Position Pos) {
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
 
   std::shared_ptr<CppFile> Resources = Units.getFile(File);
@@ -429,10 +425,10 @@ ClangdServer::findDefinitions(PathRef Fi
         llvm::errc::invalid_argument);
 
   std::vector<Location> Result;
-  Resources->getAST().get()->runUnderLock([Pos, &Result, this](ParsedAST *AST) {
+  Resources->getAST().get()->runUnderLock([Pos, &Result, &Ctx](ParsedAST *AST) {
     if (!AST)
       return;
-    Result = clangd::findDefinitions(*AST, Pos, Logger);
+    Result = clangd::findDefinitions(Ctx, *AST, Pos);
   });
   return make_tagged(std::move(Result), TaggedFS.Tag);
 }
@@ -511,7 +507,8 @@ ClangdServer::formatCode(llvm::StringRef
 }
 
 llvm::Expected<Tagged<std::vector<DocumentHighlight>>>
-ClangdServer::findDocumentHighlights(PathRef File, Position Pos) {
+ClangdServer::findDocumentHighlights(const Context &Ctx, PathRef File,
+                                     Position Pos) {
   auto FileContents = DraftMgr.getDraft(File);
   if (!FileContents.Draft)
     return llvm::make_error<llvm::StringError>(
@@ -528,14 +525,14 @@ ClangdServer::findDocumentHighlights(Pat
 
   std::vector<DocumentHighlight> Result;
   llvm::Optional<llvm::Error> Err;
-  Resources->getAST().get()->runUnderLock([Pos, &Result, &Err,
-                                           this](ParsedAST *AST) {
+  Resources->getAST().get()->runUnderLock([Pos, &Ctx, &Err,
+                                           &Result](ParsedAST *AST) {
     if (!AST) {
       Err = llvm::make_error<llvm::StringError>("Invalid AST",
                                                 llvm::errc::invalid_argument);
       return;
     }
-    Result = clangd::findDocumentHighlights(*AST, Pos, Logger);
+    Result = clangd::findDocumentHighlights(Ctx, *AST, Pos);
   });
 
   if (Err)
@@ -543,32 +540,34 @@ ClangdServer::findDocumentHighlights(Pat
   return make_tagged(Result, TaggedFS.Tag);
 }
 
-std::future<void> ClangdServer::scheduleReparseAndDiags(
-    PathRef File, VersionedDraft Contents, std::shared_ptr<CppFile> Resources,
+std::future<Context> ClangdServer::scheduleReparseAndDiags(
+    Context Ctx, PathRef File, VersionedDraft Contents,
+    std::shared_ptr<CppFile> Resources,
     Tagged<IntrusiveRefCntPtr<vfs::FileSystem>> TaggedFS) {
 
   assert(Contents.Draft && "Draft must have contents");
-  UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>()>
+  UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>(const Context &)>
       DeferredRebuild =
           Resources->deferRebuild(*Contents.Draft, TaggedFS.Value);
-  std::promise<void> DonePromise;
-  std::future<void> DoneFuture = DonePromise.get_future();
+  std::promise<Context> DonePromise;
+  std::future<Context> DoneFuture = DonePromise.get_future();
 
   DocVersion Version = Contents.Version;
   Path FileStr = File;
   VFSTag Tag = TaggedFS.Tag;
   auto ReparseAndPublishDiags =
       [this, FileStr, Version,
-       Tag](UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>()>
+       Tag](UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>(
+                const Context &)>
                 DeferredRebuild,
-            std::promise<void> DonePromise) -> void {
-    FulfillPromiseGuard Guard(DonePromise);
+            std::promise<Context> DonePromise, Context Ctx) -> void {
+    auto Guard = onScopeExit([&]() { DonePromise.set_value(std::move(Ctx)); });
 
     auto CurrentVersion = DraftMgr.getVersion(FileStr);
     if (CurrentVersion != Version)
       return; // This request is outdated
 
-    auto Diags = DeferredRebuild();
+    auto Diags = DeferredRebuild(Ctx);
     if (!Diags)
       return; // A new reparse was requested before this one completed.
 
@@ -589,28 +588,31 @@ std::future<void> ClangdServer::schedule
   };
 
   WorkScheduler.addToFront(std::move(ReparseAndPublishDiags),
-                           std::move(DeferredRebuild), std::move(DonePromise));
+                           std::move(DeferredRebuild), std::move(DonePromise),
+                           std::move(Ctx));
   return DoneFuture;
 }
 
-std::future<void>
-ClangdServer::scheduleCancelRebuild(std::shared_ptr<CppFile> Resources) {
-  std::promise<void> DonePromise;
-  std::future<void> DoneFuture = DonePromise.get_future();
+std::future<Context>
+ClangdServer::scheduleCancelRebuild(Context Ctx,
+                                    std::shared_ptr<CppFile> Resources) {
+  std::promise<Context> DonePromise;
+  std::future<Context> DoneFuture = DonePromise.get_future();
   if (!Resources) {
     // No need to schedule any cleanup.
-    DonePromise.set_value();
+    DonePromise.set_value(std::move(Ctx));
     return DoneFuture;
   }
 
   UniqueFunction<void()> DeferredCancel = Resources->deferCancelRebuild();
-  auto CancelReparses = [Resources](std::promise<void> DonePromise,
-                                    UniqueFunction<void()> DeferredCancel) {
-    FulfillPromiseGuard Guard(DonePromise);
+  auto CancelReparses = [Resources](std::promise<Context> DonePromise,
+                                    UniqueFunction<void()> DeferredCancel,
+                                    Context Ctx) {
     DeferredCancel();
+    DonePromise.set_value(std::move(Ctx));
   };
   WorkScheduler.addToFront(std::move(CancelReparses), std::move(DonePromise),
-                           std::move(DeferredCancel));
+                           std::move(DeferredCancel), std::move(Ctx));
   return DoneFuture;
 }
 

Modified: clang-tools-extra/trunk/clangd/ClangdServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.h Wed Dec 13 04:51:22 2017
@@ -37,8 +37,6 @@ class PCHContainerOperations;
 
 namespace clangd {
 
-class Logger;
-
 /// Turn a [line, column] pair into an offset in Code.
 size_t positionToOffset(StringRef Code, Position P);
 
@@ -205,12 +203,10 @@ public:
   ///
   /// \p StorePreamblesInMemory defines whether the Preambles generated by
   /// clangd are stored in-memory or on disk.
-  ///
-  /// Various messages are logged using \p Logger.
   ClangdServer(GlobalCompilationDatabase &CDB,
                DiagnosticsConsumer &DiagConsumer,
                FileSystemProvider &FSProvider, unsigned AsyncThreadsCount,
-               bool StorePreamblesInMemory, clangd::Logger &Logger,
+               bool StorePreamblesInMemory,
                llvm::Optional<StringRef> ResourceDir = llvm::None);
 
   /// Set the root path of the workspace.
@@ -222,17 +218,18 @@ public:
   /// constructor will receive onDiagnosticsReady callback.
   /// \return A future that will become ready when the rebuild (including
   /// diagnostics) is finished.
-  std::future<void> addDocument(PathRef File, StringRef Contents);
+  std::future<Context> addDocument(Context Ctx, PathRef File,
+                                   StringRef Contents);
   /// Remove \p File from list of tracked files, schedule a request to free
   /// resources associated with it.
   /// \return A future that will become ready when the file is removed and all
   /// associated resources are freed.
-  std::future<void> removeDocument(PathRef File);
+  std::future<Context> removeDocument(Context Ctx, PathRef File);
   /// Force \p File to be reparsed using the latest contents.
   /// Will also check if CompileCommand, provided by GlobalCompilationDatabase
   /// for \p File has changed. If it has, will remove currently stored Preamble
   /// and AST and rebuild them from scratch.
-  std::future<void> forceReparse(PathRef File);
+  std::future<Context> forceReparse(Context Ctx, PathRef File);
 
   /// DEPRECATED. Please use a callback-based version, this API is deprecated
   /// and will soon be removed.
@@ -251,19 +248,20 @@ public:
   /// This method should only be called for currently tracked files. However, it
   /// is safe to call removeDocument for \p File after this method returns, even
   /// while returned future is not yet ready.
-  std::future<Tagged<CompletionList>>
-  codeComplete(PathRef File, Position Pos,
+  std::future<std::pair<Context, Tagged<CompletionList>>>
+  codeComplete(Context Ctx, PathRef File, Position Pos,
                const clangd::CodeCompleteOptions &Opts,
                llvm::Optional<StringRef> OverridenContents = llvm::None,
                IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
 
   /// A version of `codeComplete` that runs \p Callback on the processing thread
   /// when codeComplete results become available.
-  void codeComplete(UniqueFunction<void(Tagged<CompletionList>)> Callback,
-                    PathRef File, Position Pos,
-                    const clangd::CodeCompleteOptions &Opts,
-                    llvm::Optional<StringRef> OverridenContents = llvm::None,
-                    IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
+  void
+  codeComplete(Context Ctx, PathRef File, Position Pos,
+               const clangd::CodeCompleteOptions &Opts,
+               UniqueFunction<void(Context, Tagged<CompletionList>)> Callback,
+               llvm::Optional<StringRef> OverridenContents = llvm::None,
+               IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
 
   /// Provide signature help for \p File at \p Pos. If \p OverridenContents is
   /// not None, they will used only for signature help, i.e. no diagnostics
@@ -273,13 +271,13 @@ public:
   /// vfs::FileSystem used for signature help. This method should only be called
   /// for currently tracked files.
   llvm::Expected<Tagged<SignatureHelp>>
-  signatureHelp(PathRef File, Position Pos,
+  signatureHelp(const Context &Ctx, PathRef File, Position Pos,
                 llvm::Optional<StringRef> OverridenContents = llvm::None,
                 IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
 
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
-  llvm::Expected<Tagged<std::vector<Location>>> findDefinitions(PathRef File,
-                                                                Position Pos);
+  llvm::Expected<Tagged<std::vector<Location>>>
+  findDefinitions(const Context &Ctx, PathRef File, Position Pos);
 
   /// Helper function that returns a path to the corresponding source file when
   /// given a header file and vice versa.
@@ -287,7 +285,7 @@ public:
 
   /// Get document highlights for a given position.
   llvm::Expected<Tagged<std::vector<DocumentHighlight>>>
-  findDocumentHighlights(PathRef File, Position Pos);
+  findDocumentHighlights(const Context &Ctx, PathRef File, Position Pos);
 
   /// Run formatting for \p Rng inside \p File with content \p Code.
   llvm::Expected<tooling::Replacements> formatRange(StringRef Code,
@@ -304,7 +302,8 @@ public:
 
   /// Rename all occurrences of the symbol at the \p Pos in \p File to
   /// \p NewName.
-  Expected<std::vector<tooling::Replacement>> rename(PathRef File, Position Pos,
+  Expected<std::vector<tooling::Replacement>> rename(const Context &Ctx,
+                                                     PathRef File, Position Pos,
                                                      llvm::StringRef NewName);
 
   /// Gets current document contents for \p File. \p File must point to a
@@ -321,21 +320,20 @@ public:
   void onFileEvent(const DidChangeWatchedFilesParams &Params);
 
 private:
-
   /// FIXME: This stats several files to find a .clang-format file. I/O can be
   /// slow. Think of a way to cache this.
   llvm::Expected<tooling::Replacements>
   formatCode(llvm::StringRef Code, PathRef File,
              ArrayRef<tooling::Range> Ranges);
 
-  std::future<void>
-  scheduleReparseAndDiags(PathRef File, VersionedDraft Contents,
+  std::future<Context>
+  scheduleReparseAndDiags(Context Ctx, PathRef File, VersionedDraft Contents,
                           std::shared_ptr<CppFile> Resources,
                           Tagged<IntrusiveRefCntPtr<vfs::FileSystem>> TaggedFS);
 
-  std::future<void> scheduleCancelRebuild(std::shared_ptr<CppFile> Resources);
+  std::future<Context>
+  scheduleCancelRebuild(Context Ctx, std::shared_ptr<CppFile> Resources);
 
-  clangd::Logger &Logger;
   GlobalCompilationDatabase &CDB;
   DiagnosticsConsumer &DiagConsumer;
   FileSystemProvider &FSProvider;

Modified: clang-tools-extra/trunk/clangd/ClangdUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp Wed Dec 13 04:51:22 2017
@@ -227,12 +227,12 @@ void clangd::dumpAST(ParsedAST &AST, llv
 }
 
 llvm::Optional<ParsedAST>
-ParsedAST::Build(std::unique_ptr<clang::CompilerInvocation> CI,
+ParsedAST::Build(const Context &Ctx,
+                 std::unique_ptr<clang::CompilerInvocation> CI,
                  std::shared_ptr<const PreambleData> Preamble,
                  std::unique_ptr<llvm::MemoryBuffer> Buffer,
                  std::shared_ptr<PCHContainerOperations> PCHs,
-                 IntrusiveRefCntPtr<vfs::FileSystem> VFS,
-                 clangd::Logger &Logger) {
+                 IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
 
   std::vector<DiagWithFixIts> ASTDiags;
   StoreDiagsConsumer UnitDiagsConsumer(/*ref*/ ASTDiags);
@@ -250,12 +250,12 @@ ParsedAST::Build(std::unique_ptr<clang::
   auto Action = llvm::make_unique<ClangdFrontendAction>();
   const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
   if (!Action->BeginSourceFile(*Clang, MainInput)) {
-    Logger.log("BeginSourceFile() failed when building AST for " +
-               MainInput.getFile());
+    log(Ctx, "BeginSourceFile() failed when building AST for " +
+                 MainInput.getFile());
     return llvm::None;
   }
   if (!Action->Execute())
-    Logger.log("Execute() failed when building AST for " + MainInput.getFile());
+    log(Ctx, "Execute() failed when building AST for " + MainInput.getFile());
 
   // UnitDiagsConsumer is local, we can not store it in CompilerInstance that
   // has a longer lifetime.
@@ -457,8 +457,8 @@ getDeclarationLocation(ParsedAST &AST, c
   return L;
 }
 
-std::vector<Location> clangd::findDefinitions(ParsedAST &AST, Position Pos,
-                                              clangd::Logger &Logger) {
+std::vector<Location> clangd::findDefinitions(const Context &Ctx,
+                                              ParsedAST &AST, Position Pos) {
   const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
   const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
   if (!FE)
@@ -499,8 +499,8 @@ std::vector<Location> clangd::findDefini
 }
 
 std::vector<DocumentHighlight>
-clangd::findDocumentHighlights(ParsedAST &AST, Position Pos,
-                               clangd::Logger &Logger) {
+clangd::findDocumentHighlights(const Context &Ctx, ParsedAST &AST,
+                               Position Pos) {
   const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
   const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
   if (!FE)
@@ -612,23 +612,21 @@ ParsedASTWrapper::ParsedASTWrapper(llvm:
 std::shared_ptr<CppFile>
 CppFile::Create(PathRef FileName, tooling::CompileCommand Command,
                 bool StorePreamblesInMemory,
-                std::shared_ptr<PCHContainerOperations> PCHs,
-                clangd::Logger &Logger) {
-  return std::shared_ptr<CppFile>(new CppFile(FileName, std::move(Command),
-                                              StorePreamblesInMemory,
-                                              std::move(PCHs), Logger));
+                std::shared_ptr<PCHContainerOperations> PCHs) {
+  return std::shared_ptr<CppFile>(new CppFile(
+      FileName, std::move(Command), StorePreamblesInMemory, std::move(PCHs)));
 }
 
 CppFile::CppFile(PathRef FileName, tooling::CompileCommand Command,
                  bool StorePreamblesInMemory,
-                 std::shared_ptr<PCHContainerOperations> PCHs,
-                 clangd::Logger &Logger)
+                 std::shared_ptr<PCHContainerOperations> PCHs)
     : FileName(FileName), Command(std::move(Command)),
       StorePreamblesInMemory(StorePreamblesInMemory), RebuildCounter(0),
-      RebuildInProgress(false), PCHs(std::move(PCHs)), Logger(Logger) {
-  Logger.log("Opened file " + FileName + " with command [" +
-             this->Command.Directory + "] " +
-             llvm::join(this->Command.CommandLine, " "));
+      RebuildInProgress(false), PCHs(std::move(PCHs)) {
+  // FIXME(ibiryukov): we should pass a proper Context here.
+  log(Context::empty(), "Opened file " + FileName + " with command [" +
+                            this->Command.Directory + "] " +
+                            llvm::join(this->Command.CommandLine, " "));
 
   std::lock_guard<std::mutex> Lock(Mutex);
   LatestAvailablePreamble = nullptr;
@@ -680,12 +678,12 @@ UniqueFunction<void()> CppFile::deferCan
 }
 
 llvm::Optional<std::vector<DiagWithFixIts>>
-CppFile::rebuild(StringRef NewContents,
+CppFile::rebuild(const Context &Ctx, StringRef NewContents,
                  IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
-  return deferRebuild(NewContents, std::move(VFS))();
+  return deferRebuild(NewContents, std::move(VFS))(Ctx);
 }
 
-UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>()>
+UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>(const Context &)>
 CppFile::deferRebuild(StringRef NewContents,
                       IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
   std::shared_ptr<const PreambleData> OldPreamble;
@@ -721,10 +719,10 @@ CppFile::deferRebuild(StringRef NewConte
 
   // Don't let this CppFile die before rebuild is finished.
   std::shared_ptr<CppFile> That = shared_from_this();
-  auto FinishRebuild = [OldPreamble, VFS, RequestRebuildCounter, PCHs,
-                        That](std::string NewContents) mutable // 'mutable' to
-                                                               // allow changing
-                                                               // OldPreamble.
+  auto FinishRebuild =
+      [OldPreamble, VFS, RequestRebuildCounter, PCHs,
+       That](std::string NewContents,
+             const Context &Ctx) mutable /* to allow changing OldPreamble. */
       -> llvm::Optional<std::vector<DiagWithFixIts>> {
     // Only one execution of this method is possible at a time.
     // RebuildGuard will wait for any ongoing rebuilds to finish and will put us
@@ -820,9 +818,8 @@ CppFile::deferRebuild(StringRef NewConte
     {
       trace::Span Tracer("Build");
       SPAN_ATTACH(Tracer, "File", That->FileName);
-      NewAST =
-          ParsedAST::Build(std::move(CI), std::move(NewPreamble),
-                           std::move(ContentsBuffer), PCHs, VFS, That->Logger);
+      NewAST = ParsedAST::Build(Ctx, std::move(CI), std::move(NewPreamble),
+                                std::move(ContentsBuffer), PCHs, VFS);
     }
 
     if (NewAST) {

Modified: clang-tools-extra/trunk/clangd/ClangdUnit.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.h Wed Dec 13 04:51:22 2017
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H
 
+#include "Context.h"
 #include "Function.h"
 #include "Path.h"
 #include "Protocol.h"
@@ -40,8 +41,6 @@ struct CompileCommand;
 
 namespace clangd {
 
-class Logger;
-
 /// A diagnostic with its FixIts.
 struct DiagWithFixIts {
   clangd::Diagnostic Diag;
@@ -65,11 +64,11 @@ public:
   /// Attempts to run Clang and store parsed AST. If \p Preamble is non-null
   /// it is reused during parsing.
   static llvm::Optional<ParsedAST>
-  Build(std::unique_ptr<clang::CompilerInvocation> CI,
+  Build(const Context &Ctx, std::unique_ptr<clang::CompilerInvocation> CI,
         std::shared_ptr<const PreambleData> Preamble,
         std::unique_ptr<llvm::MemoryBuffer> Buffer,
         std::shared_ptr<PCHContainerOperations> PCHs,
-        IntrusiveRefCntPtr<vfs::FileSystem> VFS, clangd::Logger &Logger);
+        IntrusiveRefCntPtr<vfs::FileSystem> VFS);
 
   ParsedAST(ParsedAST &&Other);
   ParsedAST &operator=(ParsedAST &&Other);
@@ -146,12 +145,12 @@ public:
   static std::shared_ptr<CppFile>
   Create(PathRef FileName, tooling::CompileCommand Command,
          bool StorePreamblesInMemory,
-         std::shared_ptr<PCHContainerOperations> PCHs, clangd::Logger &Logger);
+         std::shared_ptr<PCHContainerOperations> PCHs);
 
 private:
   CppFile(PathRef FileName, tooling::CompileCommand Command,
           bool StorePreamblesInMemory,
-          std::shared_ptr<PCHContainerOperations> PCHs, clangd::Logger &Logger);
+          std::shared_ptr<PCHContainerOperations> PCHs);
 
 public:
   CppFile(CppFile const &) = delete;
@@ -173,7 +172,8 @@ public:
   /// requested in parallel (effectively cancelling this rebuild) before
   /// diagnostics were produced.
   llvm::Optional<std::vector<DiagWithFixIts>>
-  rebuild(StringRef NewContents, IntrusiveRefCntPtr<vfs::FileSystem> VFS);
+  rebuild(const Context &Ctx, StringRef NewContents,
+          IntrusiveRefCntPtr<vfs::FileSystem> VFS);
 
   /// Schedule a rebuild and return a deferred computation that will finish the
   /// rebuild, that can be called on a different thread.
@@ -189,7 +189,7 @@ public:
   /// The future to finish rebuild returns a list of diagnostics built during
   /// reparse, or None, if another deferRebuild was called before this
   /// rebuild was finished.
-  UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>()>
+  UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>(const Context &)>
   deferRebuild(StringRef NewContents, IntrusiveRefCntPtr<vfs::FileSystem> VFS);
 
   /// Returns a future to get the most fresh PreambleData for a file. The
@@ -252,8 +252,6 @@ private:
   std::shared_ptr<const PreambleData> LatestAvailablePreamble;
   /// Utility class, required by clang.
   std::shared_ptr<PCHContainerOperations> PCHs;
-  /// Used for logging various messages.
-  clangd::Logger &Logger;
 };
 
 /// Get the beginning SourceLocation at a specified \p Pos.
@@ -261,11 +259,11 @@ SourceLocation getBeginningOfIdentifier(
                                         const FileEntry *FE);
 
 /// Get definition of symbol at a specified \p Pos.
-std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos,
-                                      clangd::Logger &Logger);
+std::vector<Location> findDefinitions(const Context &Ctx, ParsedAST &AST,
+                                      Position Pos);
 
 std::vector<DocumentHighlight>
-findDocumentHighlights(ParsedAST &AST, Position Pos, clangd::Logger &Logger);
+findDocumentHighlights(const Context &Ctx, ParsedAST &AST, Position Pos);
 
 /// For testing/debugging purposes. Note that this method deserializes all
 /// unserialized Decls, so use with care.

Modified: clang-tools-extra/trunk/clangd/ClangdUnitStore.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnitStore.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnitStore.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnitStore.cpp Wed Dec 13 04:51:22 2017
@@ -29,8 +29,7 @@ std::shared_ptr<CppFile> CppFileCollecti
 CppFileCollection::RecreateResult
 CppFileCollection::recreateFileIfCompileCommandChanged(
     PathRef File, PathRef ResourceDir, GlobalCompilationDatabase &CDB,
-    bool StorePreamblesInMemory, std::shared_ptr<PCHContainerOperations> PCHs,
-    clangd::Logger &Logger) {
+    bool StorePreamblesInMemory, std::shared_ptr<PCHContainerOperations> PCHs) {
   auto NewCommand = getCompileCommand(CDB, File, ResourceDir);
 
   std::lock_guard<std::mutex> Lock(Mutex);
@@ -42,14 +41,13 @@ CppFileCollection::recreateFileIfCompile
     It = OpenedFiles
              .try_emplace(File, CppFile::Create(File, std::move(NewCommand),
                                                 StorePreamblesInMemory,
-                                                std::move(PCHs), Logger))
+                                                std::move(PCHs)))
              .first;
   } else if (!compileCommandsAreEqual(It->second->getCompileCommand(),
                                       NewCommand)) {
     Result.RemovedFile = std::move(It->second);
-    It->second =
-        CppFile::Create(File, std::move(NewCommand), StorePreamblesInMemory,
-                        std::move(PCHs), Logger);
+    It->second = CppFile::Create(File, std::move(NewCommand),
+                                 StorePreamblesInMemory, std::move(PCHs));
   }
   Result.FileInCollection = It->second;
   return Result;

Modified: clang-tools-extra/trunk/clangd/ClangdUnitStore.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnitStore.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnitStore.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnitStore.h Wed Dec 13 04:51:22 2017
@@ -14,6 +14,7 @@
 
 #include "ClangdUnit.h"
 #include "GlobalCompilationDatabase.h"
+#include "Logger.h"
 #include "Path.h"
 #include "clang/Tooling/CompilationDatabase.h"
 
@@ -28,8 +29,7 @@ public:
   std::shared_ptr<CppFile>
   getOrCreateFile(PathRef File, PathRef ResourceDir,
                   GlobalCompilationDatabase &CDB, bool StorePreamblesInMemory,
-                  std::shared_ptr<PCHContainerOperations> PCHs,
-                  clangd::Logger &Logger) {
+                  std::shared_ptr<PCHContainerOperations> PCHs) {
     std::lock_guard<std::mutex> Lock(Mutex);
 
     auto It = OpenedFiles.find(File);
@@ -39,7 +39,7 @@ public:
       It = OpenedFiles
                .try_emplace(File, CppFile::Create(File, std::move(Command),
                                                   StorePreamblesInMemory,
-                                                  std::move(PCHs), Logger))
+                                                  std::move(PCHs)))
                .first;
     }
     return It->second;
@@ -61,8 +61,8 @@ public:
   /// will be returned in RecreateResult.RemovedFile.
   RecreateResult recreateFileIfCompileCommandChanged(
       PathRef File, PathRef ResourceDir, GlobalCompilationDatabase &CDB,
-      bool StorePreamblesInMemory, std::shared_ptr<PCHContainerOperations> PCHs,
-      clangd::Logger &Logger);
+      bool StorePreamblesInMemory,
+      std::shared_ptr<PCHContainerOperations> PCHs);
 
   std::shared_ptr<CppFile> getFile(PathRef File) {
     std::lock_guard<std::mutex> Lock(Mutex);

Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Wed Dec 13 04:51:22 2017
@@ -584,14 +584,14 @@ private:
 
 }; // SignatureHelpCollector
 
-bool invokeCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
+bool invokeCodeComplete(const Context &Ctx,
+                        std::unique_ptr<CodeCompleteConsumer> Consumer,
                         const clang::CodeCompleteOptions &Options,
                         PathRef FileName,
                         const tooling::CompileCommand &Command,
                         PrecompiledPreamble const *Preamble, StringRef Contents,
                         Position Pos, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
-                        std::shared_ptr<PCHContainerOperations> PCHs,
-                        Logger &Logger) {
+                        std::shared_ptr<PCHContainerOperations> PCHs) {
   std::vector<const char *> ArgStrs;
   for (const auto &S : Command.CommandLine)
     ArgStrs.push_back(S.c_str());
@@ -634,12 +634,12 @@ bool invokeCodeComplete(std::unique_ptr<
 
   SyntaxOnlyAction Action;
   if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
-    Logger.log("BeginSourceFile() failed when running codeComplete for " +
-               FileName);
+    log(Ctx,
+        "BeginSourceFile() failed when running codeComplete for " + FileName);
     return false;
   }
   if (!Action.Execute()) {
-    Logger.log("Execute() failed when running codeComplete for " + FileName);
+    log(Ctx, "Execute() failed when running codeComplete for " + FileName);
     return false;
   }
 
@@ -660,13 +660,13 @@ clang::CodeCompleteOptions CodeCompleteO
   return Result;
 }
 
-CompletionList codeComplete(PathRef FileName,
+CompletionList codeComplete(const Context &Ctx, PathRef FileName,
                             const tooling::CompileCommand &Command,
                             PrecompiledPreamble const *Preamble,
                             StringRef Contents, Position Pos,
                             IntrusiveRefCntPtr<vfs::FileSystem> VFS,
                             std::shared_ptr<PCHContainerOperations> PCHs,
-                            CodeCompleteOptions Opts, Logger &Logger) {
+                            CodeCompleteOptions Opts) {
   CompletionList Results;
   std::unique_ptr<CodeCompleteConsumer> Consumer;
   if (Opts.EnableSnippets) {
@@ -676,26 +676,28 @@ CompletionList codeComplete(PathRef File
     Consumer =
         llvm::make_unique<PlainTextCompletionItemsCollector>(Opts, Results);
   }
-  invokeCodeComplete(std::move(Consumer), Opts.getClangCompleteOpts(), FileName,
-                     Command, Preamble, Contents, Pos, std::move(VFS),
-                     std::move(PCHs), Logger);
+  invokeCodeComplete(Ctx, std::move(Consumer), Opts.getClangCompleteOpts(),
+                     FileName, Command, Preamble, Contents, Pos, std::move(VFS),
+                     std::move(PCHs));
   return Results;
 }
 
-SignatureHelp
-signatureHelp(PathRef FileName, const tooling::CompileCommand &Command,
-              PrecompiledPreamble const *Preamble, StringRef Contents,
-              Position Pos, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
-              std::shared_ptr<PCHContainerOperations> PCHs, Logger &Logger) {
+SignatureHelp signatureHelp(const Context &Ctx, PathRef FileName,
+                            const tooling::CompileCommand &Command,
+                            PrecompiledPreamble const *Preamble,
+                            StringRef Contents, Position Pos,
+                            IntrusiveRefCntPtr<vfs::FileSystem> VFS,
+                            std::shared_ptr<PCHContainerOperations> PCHs) {
   SignatureHelp Result;
   clang::CodeCompleteOptions Options;
   Options.IncludeGlobals = false;
   Options.IncludeMacros = false;
   Options.IncludeCodePatterns = false;
   Options.IncludeBriefComments = true;
-  invokeCodeComplete(llvm::make_unique<SignatureHelpCollector>(Options, Result),
+  invokeCodeComplete(Ctx,
+                     llvm::make_unique<SignatureHelpCollector>(Options, Result),
                      Options, FileName, Command, Preamble, Contents, Pos,
-                     std::move(VFS), std::move(PCHs), Logger);
+                     std::move(VFS), std::move(PCHs));
   return Result;
 }
 

Modified: clang-tools-extra/trunk/clangd/CodeComplete.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.h (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.h Wed Dec 13 04:51:22 2017
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
 
+#include "Context.h"
 #include "Logger.h"
 #include "Path.h"
 #include "Protocol.h"
@@ -61,20 +62,21 @@ struct CodeCompleteOptions {
 };
 
 /// Get code completions at a specified \p Pos in \p FileName.
-CompletionList codeComplete(PathRef FileName,
+CompletionList codeComplete(const Context &Ctx, PathRef FileName,
                             const tooling::CompileCommand &Command,
                             PrecompiledPreamble const *Preamble,
                             StringRef Contents, Position Pos,
                             IntrusiveRefCntPtr<vfs::FileSystem> VFS,
                             std::shared_ptr<PCHContainerOperations> PCHs,
-                            CodeCompleteOptions Opts, Logger &Logger);
+                            CodeCompleteOptions Opts);
 
 /// Get signature help at a specified \p Pos in \p FileName.
-SignatureHelp
-signatureHelp(PathRef FileName, const tooling::CompileCommand &Command,
-              PrecompiledPreamble const *Preamble, StringRef Contents,
-              Position Pos, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
-              std::shared_ptr<PCHContainerOperations> PCHs, Logger &Logger);
+SignatureHelp signatureHelp(const Context &Ctx, PathRef FileName,
+                            const tooling::CompileCommand &Command,
+                            PrecompiledPreamble const *Preamble,
+                            StringRef Contents, Position Pos,
+                            IntrusiveRefCntPtr<vfs::FileSystem> VFS,
+                            std::shared_ptr<PCHContainerOperations> PCHs);
 
 } // namespace clangd
 } // namespace clang

Modified: clang-tools-extra/trunk/clangd/Function.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Function.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Function.h (original)
+++ clang-tools-extra/trunk/clangd/Function.h Wed Dec 13 04:51:22 2017
@@ -39,7 +39,11 @@ public:
   UniqueFunction(UniqueFunction &&) noexcept = default;
   UniqueFunction &operator=(UniqueFunction &&) noexcept = default;
 
-  template <class Callable>
+  template <class Callable,
+            /// A sfinae-check that Callable can be called with Args... and
+            class = typename std::enable_if<std::is_convertible<
+                decltype(std::declval<Callable>()(std::declval<Args>()...)),
+                Ret>::value>::type>
   UniqueFunction(Callable &&Func)
       : CallablePtr(llvm::make_unique<
                     FunctionCallImpl<typename std::decay<Callable>::type>>(
@@ -133,6 +137,40 @@ ForwardBinder<Func, Args...> BindWithFor
       std::make_tuple(std::forward<Func>(F), std::forward<Args>(As)...));
 }
 
+namespace detail {
+/// Runs provided callback in destructor. Use onScopeExit helper function to
+/// create this object.
+template <class Func> struct ScopeExitGuard {
+  static_assert(std::is_same<typename std::decay<Func>::type, Func>::value,
+                "Func must be decayed");
+
+  ScopeExitGuard(Func F) : F(std::move(F)) {}
+  ~ScopeExitGuard() {
+    if (!F)
+      return;
+    (*F)();
+  }
+
+  // Move-only.
+  ScopeExitGuard(const ScopeExitGuard &) = delete;
+  ScopeExitGuard &operator=(const ScopeExitGuard &) = delete;
+
+  ScopeExitGuard(ScopeExitGuard &&Other) = default;
+  ScopeExitGuard &operator=(ScopeExitGuard &&Other) = default;
+
+private:
+  llvm::Optional<Func> F;
+};
+} // namespace detail
+
+/// Creates a RAII object that will run \p F in its destructor.
+template <class Func>
+auto onScopeExit(Func &&F)
+    -> detail::ScopeExitGuard<typename std::decay<Func>::type> {
+  return detail::ScopeExitGuard<typename std::decay<Func>::type>(
+      std::forward<Func>(F));
+}
+
 } // namespace clangd
 } // namespace clang
 

Modified: clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp (original)
+++ clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp Wed Dec 13 04:51:22 2017
@@ -26,8 +26,8 @@ GlobalCompilationDatabase::getFallbackCo
 
 DirectoryBasedGlobalCompilationDatabase::
     DirectoryBasedGlobalCompilationDatabase(
-        clangd::Logger &Logger, llvm::Optional<Path> CompileCommandsDir)
-    : Logger(Logger), CompileCommandsDir(std::move(CompileCommandsDir)) {}
+        llvm::Optional<Path> CompileCommandsDir)
+    : CompileCommandsDir(std::move(CompileCommandsDir)) {}
 
 llvm::Optional<tooling::CompileCommand>
 DirectoryBasedGlobalCompilationDatabase::getCompileCommand(PathRef File) const {
@@ -103,9 +103,12 @@ DirectoryBasedGlobalCompilationDatabase:
   if (CompileCommandsDir.hasValue()) {
     tooling::CompilationDatabase *ReturnValue =
         tryLoadDatabaseFromPath(CompileCommandsDir.getValue());
-    if (ReturnValue == nullptr)
-      Logger.log("Failed to find compilation database for " + Twine(File) +
-                 "in overriden directory " + CompileCommandsDir.getValue());
+    if (ReturnValue == nullptr) {
+      // FIXME(ibiryukov): pass a proper Context here.
+      log(Context::empty(), "Failed to find compilation database for " +
+                                Twine(File) + "in overriden directory " +
+                                CompileCommandsDir.getValue());
+    }
     return ReturnValue;
   }
 
@@ -118,7 +121,9 @@ DirectoryBasedGlobalCompilationDatabase:
     return CDB;
   }
 
-  Logger.log("Failed to find compilation database for " + Twine(File));
+  // FIXME(ibiryukov): pass a proper Context here.
+  log(Context::empty(),
+      "Failed to find compilation database for " + Twine(File));
   return nullptr;
 }
 

Modified: clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h (original)
+++ clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h Wed Dec 13 04:51:22 2017
@@ -51,7 +51,7 @@ class DirectoryBasedGlobalCompilationDat
     : public GlobalCompilationDatabase {
 public:
   DirectoryBasedGlobalCompilationDatabase(
-      clangd::Logger &Logger, llvm::Optional<Path> CompileCommandsDir);
+      llvm::Optional<Path> CompileCommandsDir);
 
   /// Scans File's parents looking for compilation databases.
   /// Any extra flags will be added.
@@ -77,8 +77,6 @@ private:
 
   /// Stores extra flags per file.
   llvm::StringMap<std::vector<std::string>> ExtraFlagsForFile;
-  /// Used for logging.
-  clangd::Logger &Logger;
   /// Used for command argument pointing to folder where compile_commands.json
   /// is located.
   llvm::Optional<Path> CompileCommandsDir;

Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp Wed Dec 13 04:51:22 2017
@@ -19,6 +19,12 @@
 using namespace clang;
 using namespace clangd;
 
+namespace {
+static Key<std::unique_ptr<trace::Span>> RequestSpan;
+static Key<json::Expr> RequestID;
+static Key<JSONOutput *> RequestOut;
+} // namespace
+
 void JSONOutput::writeMessage(const json::Expr &Message) {
   std::string S;
   llvm::raw_string_ostream OS(S);
@@ -38,7 +44,7 @@ void JSONOutput::writeMessage(const json
   Outs.flush();
 }
 
-void JSONOutput::log(const Twine &Message) {
+void JSONOutput::log(const Context &Ctx, const Twine &Message) {
   trace::log(Message);
   std::lock_guard<std::mutex> Guard(StreamMutex);
   Logs << Message << '\n';
@@ -53,46 +59,56 @@ void JSONOutput::mirrorInput(const Twine
   InputMirror->flush();
 }
 
-void RequestContext::reply(json::Expr &&Result) {
+void clangd::reply(const Context &Ctx, json::Expr &&Result) {
+  auto ID = Ctx.get(RequestID);
   if (!ID) {
-    Out.log("Attempted to reply to a notification!");
+    log(Ctx, "Attempted to reply to a notification!");
     return;
   }
-  SPAN_ATTACH(tracer(), "Reply", Result);
-  Out.writeMessage(json::obj{
-      {"jsonrpc", "2.0"},
-      {"id", *ID},
-      {"result", std::move(Result)},
-  });
-}
-
-void RequestContext::replyError(ErrorCode code,
-                                const llvm::StringRef &Message) {
-  Out.log("Error " + Twine(static_cast<int>(code)) + ": " + Message);
-  SPAN_ATTACH(tracer(), "Error",
-              (json::obj{{"code", static_cast<int>(code)},
-                         {"message", Message.str()}}));
-  if (ID) {
-    Out.writeMessage(json::obj{
-        {"jsonrpc", "2.0"},
-        {"id", *ID},
-        {"error",
-         json::obj{{"code", static_cast<int>(code)}, {"message", Message}}},
-    });
+
+  if (auto *Span = Ctx.get(RequestSpan))
+    SPAN_ATTACH(**Span, "Reply", Result);
+
+  Ctx.getExisting(RequestOut)
+      ->writeMessage(json::obj{
+          {"jsonrpc", "2.0"},
+          {"id", *ID},
+          {"result", std::move(Result)},
+      });
+}
+
+void clangd::replyError(const Context &Ctx, ErrorCode code,
+                        const llvm::StringRef &Message) {
+  log(Ctx, "Error " + Twine(static_cast<int>(code)) + ": " + Message);
+  if (auto *Span = Ctx.get(RequestSpan))
+    SPAN_ATTACH(**Span, "Error",
+                (json::obj{{"code", static_cast<int>(code)},
+                           {"message", Message.str()}}));
+
+  if (auto ID = Ctx.get(RequestID)) {
+    Ctx.getExisting(RequestOut)
+        ->writeMessage(json::obj{
+            {"jsonrpc", "2.0"},
+            {"id", *ID},
+            {"error",
+             json::obj{{"code", static_cast<int>(code)}, {"message", Message}}},
+        });
   }
 }
 
-void RequestContext::call(StringRef Method, json::Expr &&Params) {
+void clangd::call(const Context &Ctx, StringRef Method, json::Expr &&Params) {
   // FIXME: Generate/Increment IDs for every request so that we can get proper
   // replies once we need to.
-  SPAN_ATTACH(tracer(), "Call",
-              (json::obj{{"method", Method.str()}, {"params", Params}}));
-  Out.writeMessage(json::obj{
-      {"jsonrpc", "2.0"},
-      {"id", 1},
-      {"method", Method},
-      {"params", std::move(Params)},
-  });
+  if (auto *Span = Ctx.get(RequestSpan))
+    SPAN_ATTACH(**Span, "Call",
+                (json::obj{{"method", Method.str()}, {"params", Params}}));
+  Ctx.getExisting(RequestOut)
+      ->writeMessage(json::obj{
+          {"jsonrpc", "2.0"},
+          {"id", 1},
+          {"method", Method},
+          {"params", std::move(Params)},
+      });
 }
 
 void JSONRPCDispatcher::registerHandler(StringRef Method, Handler H) {
@@ -120,8 +136,18 @@ bool JSONRPCDispatcher::call(const json:
 
   auto I = Handlers.find(*Method);
   auto &Handler = I != Handlers.end() ? I->second : UnknownHandler;
-  RequestContext Ctx(Out, *Method, std::move(ID));
-  SPAN_ATTACH(Ctx.tracer(), "Params", Params);
+
+  auto Tracer = llvm::make_unique<trace::Span>(*Method);
+  if (ID)
+    SPAN_ATTACH(*Tracer, "ID", *ID);
+  SPAN_ATTACH(*Tracer, "Params", Params);
+
+  auto Ctx = Context::empty()
+                 .derive(RequestOut, &Out)
+                 .derive(RequestSpan, std::move(Tracer));
+  if (ID)
+    Ctx = std::move(Ctx).derive(RequestID, *ID);
+
   Handler(std::move(Ctx), std::move(Params));
   return true;
 }
@@ -164,9 +190,10 @@ void clangd::runLanguageServerLoop(std::
       // The end of headers is signified by an empty line.
       if (LineRef.consume_front("Content-Length: ")) {
         if (ContentLength != 0) {
-          Out.log("Warning: Duplicate Content-Length header received. "
-                  "The previous value for this message (" +
-                  std::to_string(ContentLength) + ") was ignored.");
+          log(Context::empty(),
+              "Warning: Duplicate Content-Length header received. "
+              "The previous value for this message (" +
+                  std::to_string(ContentLength) + ") was ignored.\n");
         }
 
         llvm::getAsUnsignedInteger(LineRef.trim(), 0, ContentLength);
@@ -185,8 +212,8 @@ void clangd::runLanguageServerLoop(std::
     // and we don't want to crash downstream because of it.
     if (ContentLength > 1 << 30) { // 1024M
       In.ignore(ContentLength);
-      Out.log("Skipped overly large message of " + Twine(ContentLength) +
-              " bytes.");
+      log(Context::empty(), "Skipped overly large message of " +
+                                Twine(ContentLength) + " bytes.\n");
       continue;
     }
 
@@ -200,9 +227,10 @@ void clangd::runLanguageServerLoop(std::
         // If the stream is aborted before we read ContentLength bytes, In
         // will have eofbit and failbit set.
         if (!In) {
-          Out.log("Input was aborted. Read only " +
-                  std::to_string(In.gcount()) + " bytes of expected " +
-                  std::to_string(ContentLength) + ".");
+          log(Context::empty(), "Input was aborted. Read only " +
+                                    std::to_string(In.gcount()) +
+                                    " bytes of expected " +
+                                    std::to_string(ContentLength) + ".\n");
           break;
         }
 
@@ -211,23 +239,25 @@ void clangd::runLanguageServerLoop(std::
 
       if (auto Doc = json::parse(JSONRef)) {
         // Log the formatted message.
-        Out.log(llvm::formatv(Out.Pretty ? "<-- {0:2}" : "<-- {0}", *Doc));
+        log(Context::empty(),
+            llvm::formatv(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc));
         // Finally, execute the action for this JSON message.
         if (!Dispatcher.call(*Doc, Out))
-          Out.log("JSON dispatch failed!");
+          log(Context::empty(), "JSON dispatch failed!\n");
       } else {
         // Parse error. Log the raw message.
-        Out.log("<-- " + JSONRef);
-        Out.log(llvm::Twine("JSON parse error: ") +
-                llvm::toString(Doc.takeError()));
+        log(Context::empty(), "<-- " + JSONRef + "\n");
+        log(Context::empty(), llvm::Twine("JSON parse error: ") +
+                                  llvm::toString(Doc.takeError()) + "\n");
       }
 
       // If we're done, exit the loop.
       if (IsDone)
         break;
     } else {
-      Out.log("Warning: Missing Content-Length header, or message has zero "
-              "length.");
+      log(Context::empty(),
+          "Warning: Missing Content-Length header, or message has zero "
+          "length.\n");
     }
   }
 }

Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h Wed Dec 13 04:51:22 2017
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_JSONRPCDISPATCHER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_JSONRPCDISPATCHER_H
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "Logger.h"
 #include "Protocol.h"
@@ -26,6 +27,8 @@ namespace clangd {
 /// Encapsulates output and logs streams and provides thread-safe access to
 /// them.
 class JSONOutput : public Logger {
+  // FIXME(ibiryukov): figure out if we can shrink the public interface of
+  // JSONOutput now that we pass Context everywhere.
 public:
   JSONOutput(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs,
              llvm::raw_ostream *InputMirror = nullptr, bool Pretty = false)
@@ -35,7 +38,7 @@ public:
   void writeMessage(const json::Expr &Result);
 
   /// Write a line to the logging stream.
-  void log(const Twine &Message) override;
+  void log(const Context &Ctx, const Twine &Message) override;
 
   /// Mirror \p Message into InputMirror stream. Does nothing if InputMirror is
   /// null.
@@ -53,38 +56,23 @@ private:
   std::mutex StreamMutex;
 };
 
-/// Context object passed to handlers to allow replies.
-class RequestContext {
-public:
-  RequestContext(JSONOutput &Out, StringRef Method,
-                 llvm::Optional<json::Expr> ID)
-      : Out(Out), ID(std::move(ID)),
-        Tracer(llvm::make_unique<trace::Span>(Method)) {
-    if (this->ID)
-      SPAN_ATTACH(tracer(), "ID", *this->ID);
-  }
-
-  /// Sends a successful reply.
-  void reply(json::Expr &&Result);
-  /// Sends an error response to the client, and logs it.
-  void replyError(ErrorCode code, const llvm::StringRef &Message);
-  /// Sends a request to the client.
-  void call(llvm::StringRef Method, json::Expr &&Params);
-
-  trace::Span &tracer() { return *Tracer; }
-
-private:
-  JSONOutput &Out;
-  llvm::Optional<json::Expr> ID;
-  std::unique_ptr<trace::Span> Tracer;
-};
+/// Sends a successful reply. \p Ctx must either be the Context accepted by
+/// JSONRPCDispatcher::Handler or be derived from it.
+void reply(const Context &Ctx, json::Expr &&Result);
+/// Sends an error response to the client, and logs it. \p Ctx must either be
+/// the Context accepted by JSONRPCDispatcher::Handler or be derived from it.
+void replyError(const Context &Ctx, ErrorCode code,
+                const llvm::StringRef &Message);
+/// Sends a request to the client. \p Ctx must either be the Context accepted by
+/// JSONRPCDispatcher::Handler or be derived from it.
+void call(const Context &Ctx, llvm::StringRef Method, json::Expr &&Params);
 
 /// Main JSONRPC entry point. This parses the JSONRPC "header" and calls the
 /// registered Handler for the method received.
 class JSONRPCDispatcher {
 public:
   // A handler responds to requests for a particular method name.
-  using Handler = std::function<void(RequestContext, const json::Expr &)>;
+  using Handler = std::function<void(Context, const json::Expr &)>;
 
   /// Create a new JSONRPCDispatcher. UnknownHandler is called when an unknown
   /// method is received.

Modified: clang-tools-extra/trunk/clangd/Logger.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Logger.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Logger.cpp (original)
+++ clang-tools-extra/trunk/clangd/Logger.cpp Wed Dec 13 04:51:22 2017
@@ -9,11 +9,25 @@
 
 #include "Logger.h"
 
-using namespace clang::clangd;
+namespace clang {
+namespace clangd {
 
-EmptyLogger &EmptyLogger::getInstance() {
-  static EmptyLogger Logger;
-  return Logger;
+namespace {
+Logger *L = nullptr;
+} // namespace
+
+LoggingSession::LoggingSession(clangd::Logger &Instance) {
+  assert(!L);
+  L = &Instance;
+}
+
+LoggingSession::~LoggingSession() { L = nullptr; }
+
+void log(const Context &Ctx, const llvm::Twine &Message) {
+  if (!L)
+    return;
+  L->log(Ctx, Message);
 }
 
-void EmptyLogger::log(const llvm::Twine &Message) {}
+} // namespace clangd
+} // namespace clang

Modified: clang-tools-extra/trunk/clangd/Logger.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Logger.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Logger.h (original)
+++ clang-tools-extra/trunk/clangd/Logger.h Wed Dec 13 04:51:22 2017
@@ -10,29 +10,36 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_LOGGER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_LOGGER_H
 
+#include "Context.h"
 #include "llvm/ADT/Twine.h"
 
 namespace clang {
 namespace clangd {
 
+/// Main logging function. Logs messages to a global logger, which can be set up
+/// by LoggingSesssion.
+void log(const Context &Ctx, const llvm::Twine &Message);
+
 /// Interface to allow custom logging in clangd.
 class Logger {
 public:
   virtual ~Logger() = default;
 
   /// Implementations of this method must be thread-safe.
-  virtual void log(const llvm::Twine &Message) = 0;
+  virtual void log(const Context &Ctx, const llvm::Twine &Message) = 0;
 };
 
-/// Logger implementation that ignores all messages.
-class EmptyLogger : public Logger {
+/// Only one LoggingSession can be active at a time.
+class LoggingSession {
 public:
-  static EmptyLogger &getInstance();
+  LoggingSession(clangd::Logger &Instance);
+  ~LoggingSession();
 
-  void log(const llvm::Twine &Message) override;
+  LoggingSession(LoggingSession &&) = delete;
+  LoggingSession &operator=(LoggingSession &&) = delete;
 
-private:
-  EmptyLogger() = default;
+  LoggingSession(LoggingSession const &) = delete;
+  LoggingSession &operator=(LoggingSession const &) = delete;
 };
 
 } // namespace clangd

Modified: clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp (original)
+++ clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp Wed Dec 13 04:51:22 2017
@@ -25,17 +25,16 @@ namespace {
 struct HandlerRegisterer {
   template <typename Param>
   void operator()(StringRef Method,
-                  void (ProtocolCallbacks::*Handler)(RequestContext, Param)) {
+                  void (ProtocolCallbacks::*Handler)(Context, Param)) {
     // Capture pointers by value, as the lambda will outlive this object.
-    auto *Out = this->Out;
     auto *Callbacks = this->Callbacks;
     Dispatcher.registerHandler(
-        Method, [=](RequestContext C, const json::Expr &RawParams) {
+        Method, [=](Context C, const json::Expr &RawParams) {
           typename std::remove_reference<Param>::type P;
           if (fromJSON(RawParams, P)) {
             (Callbacks->*Handler)(std::move(C), P);
           } else {
-            Out->log("Failed to decode " + Method + " request.");
+            log(C, "Failed to decode " + Method + " request.");
           }
         });
   }

Modified: clang-tools-extra/trunk/clangd/ProtocolHandlers.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.h?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ProtocolHandlers.h (original)
+++ clang-tools-extra/trunk/clangd/ProtocolHandlers.h Wed Dec 13 04:51:22 2017
@@ -29,7 +29,8 @@ namespace clangd {
 // The interface implemented by ClangLSPServer to handle incoming requests.
 class ProtocolCallbacks {
 public:
-  using Ctx = RequestContext;
+  // FIXME(ibiryukov): remove this typedef, inline its usages.
+  using Ctx = Context;
   virtual ~ProtocolCallbacks() = default;
 
   virtual void onInitialize(Ctx C, InitializeParams &Params) = 0;

Modified: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp (original)
+++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp Wed Dec 13 04:51:22 2017
@@ -134,6 +134,8 @@ int main(int argc, char *argv[]) {
                  InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
                  PrettyPrint);
 
+  clangd::LoggingSession LoggingSession(Out);
+
   // If --compile-commands-dir arg was invoked, check value and override default
   // path.
   llvm::Optional<Path> CompileCommandsDirPath;

Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Wed Dec 13 04:51:22 2017
@@ -9,7 +9,7 @@
 
 #include "ClangdLSPServer.h"
 #include "ClangdServer.h"
-#include "Logger.h"
+#include "Context.h"
 #include "TestFS.h"
 #include "clang/Config/config.h"
 #include "llvm/ADT/SmallVector.h"
@@ -123,8 +123,7 @@ protected:
     ErrorCheckingDiagConsumer DiagConsumer;
     MockCompilationDatabase CDB;
     ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
-                        /*StorePreamblesInMemory=*/true,
-                        EmptyLogger::getInstance());
+                        /*StorePreamblesInMemory=*/true);
     for (const auto &FileWithContents : ExtraFiles)
       FS.Files[getVirtualTestFilePath(FileWithContents.first)] =
           FileWithContents.second;
@@ -135,7 +134,8 @@ protected:
 
     // Have to sync reparses because requests are processed on the calling
     // thread.
-    auto AddDocFuture = Server.addDocument(SourceFilename, SourceContents);
+    auto AddDocFuture =
+        Server.addDocument(Context::empty(), SourceFilename, SourceContents);
 
     auto Result = dumpASTWithoutMemoryLocs(Server, SourceFilename);
 
@@ -187,8 +187,7 @@ TEST_F(ClangdVFSTest, Reparse) {
   ErrorCheckingDiagConsumer DiagConsumer;
   MockCompilationDatabase CDB;
   ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
-                      /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
+                      /*StorePreamblesInMemory=*/true);
 
   const auto SourceContents = R"cpp(
 #include "foo.h"
@@ -203,21 +202,21 @@ int b = a;
   FS.ExpectedFile = FooCpp;
 
   // To sync reparses before checking for errors.
-  std::future<void> ParseFuture;
+  std::future<Context> ParseFuture;
 
-  ParseFuture = Server.addDocument(FooCpp, SourceContents);
+  ParseFuture = Server.addDocument(Context::empty(), FooCpp, SourceContents);
   auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 
-  ParseFuture = Server.addDocument(FooCpp, "");
+  ParseFuture = Server.addDocument(Context::empty(), FooCpp, "");
   auto DumpParseEmpty = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 
-  ParseFuture = Server.addDocument(FooCpp, SourceContents);
+  ParseFuture = Server.addDocument(Context::empty(), FooCpp, SourceContents);
   auto DumpParse2 = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
@@ -233,8 +232,7 @@ TEST_F(ClangdVFSTest, ReparseOnHeaderCha
   MockCompilationDatabase CDB;
 
   ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
-                      /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
+                      /*StorePreamblesInMemory=*/true);
 
   const auto SourceContents = R"cpp(
 #include "foo.h"
@@ -249,23 +247,23 @@ int b = a;
   FS.ExpectedFile = FooCpp;
 
   // To sync reparses before checking for errors.
-  std::future<void> ParseFuture;
+  std::future<Context> ParseFuture;
 
-  ParseFuture = Server.addDocument(FooCpp, SourceContents);
+  ParseFuture = Server.addDocument(Context::empty(), FooCpp, SourceContents);
   auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 
   FS.Files[FooH] = "";
-  ParseFuture = Server.forceReparse(FooCpp);
+  ParseFuture = Server.forceReparse(Context::empty(), FooCpp);
   auto DumpParseDifferent = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
 
   FS.Files[FooH] = "int a;";
-  ParseFuture = Server.forceReparse(FooCpp);
+  ParseFuture = Server.forceReparse(Context::empty(), FooCpp);
   auto DumpParse2 = dumpASTWithoutMemoryLocs(Server, FooCpp);
   EXPECT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
@@ -282,8 +280,7 @@ TEST_F(ClangdVFSTest, CheckVersions) {
   // Run ClangdServer synchronously.
   ClangdServer Server(CDB, DiagConsumer, FS,
                       /*AsyncThreadsCount=*/0,
-                      /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
+                      /*StorePreamblesInMemory=*/true);
 
   auto FooCpp = getVirtualTestFilePath("foo.cpp");
   const auto SourceContents = "int a;";
@@ -296,16 +293,22 @@ TEST_F(ClangdVFSTest, CheckVersions) {
   // No need to sync reparses, because requests are processed on the calling
   // thread.
   FS.Tag = "123";
-  Server.addDocument(FooCpp, SourceContents);
-  EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}, CCOpts).get().Tag,
-            FS.Tag);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents);
+  EXPECT_EQ(
+      Server.codeComplete(Context::empty(), FooCpp, Position{0, 0}, CCOpts)
+          .get()
+          .second.Tag,
+      FS.Tag);
   EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag);
 
   FS.Tag = "321";
-  Server.addDocument(FooCpp, SourceContents);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents);
   EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag);
-  EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}, CCOpts).get().Tag,
-            FS.Tag);
+  EXPECT_EQ(
+      Server.codeComplete(Context::empty(), FooCpp, Position{0, 0}, CCOpts)
+          .get()
+          .second.Tag,
+      FS.Tag);
 }
 
 // Only enable this test on Unix
@@ -322,8 +325,7 @@ TEST_F(ClangdVFSTest, SearchLibDir) {
   // Run ClangdServer synchronously.
   ClangdServer Server(CDB, DiagConsumer, FS,
                       /*AsyncThreadsCount=*/0,
-                      /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
+                      /*StorePreamblesInMemory=*/true);
 
   // Just a random gcc version string
   SmallString<8> Version("4.9.3");
@@ -354,14 +356,14 @@ mock_string x;
 
   // No need to sync reparses, because requests are processed on the calling
   // thread.
-  Server.addDocument(FooCpp, SourceContents);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 
   const auto SourceContentsWithError = R"cpp(
 #include <string>
 std::string x;
 )cpp";
-  Server.addDocument(FooCpp, SourceContentsWithError);
+  Server.addDocument(Context::empty(), FooCpp, SourceContentsWithError);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
 }
 #endif // LLVM_ON_UNIX
@@ -372,11 +374,10 @@ TEST_F(ClangdVFSTest, ForceReparseCompil
   MockCompilationDatabase CDB;
   ClangdServer Server(CDB, DiagConsumer, FS,
                       /*AsyncThreadsCount=*/0,
-                      /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
-  // No need to sync reparses, because reparses are performed on the calling
-  // thread to true.
+                      /*StorePreamblesInMemory=*/true);
 
+  // No need to sync reparses, because reparses are performed on the calling
+  // thread.
   auto FooCpp = getVirtualTestFilePath("foo.cpp");
   const auto SourceContents1 = R"cpp(
 template <class T>
@@ -392,26 +393,26 @@ struct bar { T x; };
 
   // First parse files in C mode and check they produce errors.
   CDB.ExtraClangFlags = {"-xc"};
-  Server.addDocument(FooCpp, SourceContents1);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents1);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
-  Server.addDocument(FooCpp, SourceContents2);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents2);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
 
   // Now switch to C++ mode.
   CDB.ExtraClangFlags = {"-xc++"};
   // Currently, addDocument never checks if CompileCommand has changed, so we
   // expect to see the errors.
-  Server.addDocument(FooCpp, SourceContents1);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents1);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
-  Server.addDocument(FooCpp, SourceContents2);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents2);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
   // But forceReparse should reparse the file with proper flags.
-  Server.forceReparse(FooCpp);
+  Server.forceReparse(Context::empty(), FooCpp);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
   // Subsequent addDocument calls should finish without errors too.
-  Server.addDocument(FooCpp, SourceContents1);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents1);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
-  Server.addDocument(FooCpp, SourceContents2);
+  Server.addDocument(Context::empty(), FooCpp, SourceContents2);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 }
 
@@ -501,7 +502,7 @@ int d;
     unsigned RequestsWithErrors = 0;
     bool LastContentsHadErrors = false;
     bool FileIsRemoved = true;
-    std::future<void> LastRequestFuture;
+    std::future<Context> LastRequestFuture;
   };
 
   std::vector<RequestStats> ReqStats;
@@ -513,8 +514,7 @@ int d;
   {
     MockCompilationDatabase CDB;
     ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
-                        /*StorePreamblesInMemory=*/true,
-                        EmptyLogger::getInstance());
+                        /*StorePreamblesInMemory=*/true);
 
     // Prepare some random distributions for the test.
     std::random_device RandGen;
@@ -529,7 +529,7 @@ int d;
 
     // Some helpers.
     auto UpdateStatsOnAddDocument = [&](unsigned FileIndex, bool HadErrors,
-                                        std::future<void> Future) {
+                                        std::future<Context> Future) {
       auto &Stats = ReqStats[FileIndex];
 
       if (HadErrors)
@@ -542,7 +542,7 @@ int d;
     };
 
     auto UpdateStatsOnRemoveDocument = [&](unsigned FileIndex,
-                                           std::future<void> Future) {
+                                           std::future<Context> Future) {
       auto &Stats = ReqStats[FileIndex];
 
       Stats.FileIsRemoved = true;
@@ -550,7 +550,7 @@ int d;
     };
 
     auto UpdateStatsOnForceReparse = [&](unsigned FileIndex,
-                                         std::future<void> Future) {
+                                         std::future<Context> Future) {
       auto &Stats = ReqStats[FileIndex];
 
       Stats.LastRequestFuture = std::move(Future);
@@ -562,9 +562,10 @@ int d;
 
     auto AddDocument = [&](unsigned FileIndex) {
       bool ShouldHaveErrors = ShouldHaveErrorsDist(RandGen);
-      auto Future = Server.addDocument(
-          FilePaths[FileIndex], ShouldHaveErrors ? SourceContentsWithErrors
-                                                 : SourceContentsWithoutErrors);
+      auto Future =
+          Server.addDocument(Context::empty(), FilePaths[FileIndex],
+                             ShouldHaveErrors ? SourceContentsWithErrors
+                                              : SourceContentsWithoutErrors);
       UpdateStatsOnAddDocument(FileIndex, ShouldHaveErrors, std::move(Future));
     };
 
@@ -580,7 +581,7 @@ int d;
       if (ReqStats[FileIndex].FileIsRemoved)
         AddDocument(FileIndex);
 
-      auto Future = Server.forceReparse(FilePaths[FileIndex]);
+      auto Future = Server.forceReparse(Context::empty(), FilePaths[FileIndex]);
       UpdateStatsOnForceReparse(FileIndex, std::move(Future));
     };
 
@@ -590,7 +591,8 @@ int d;
       if (ReqStats[FileIndex].FileIsRemoved)
         AddDocument(FileIndex);
 
-      auto Future = Server.removeDocument(FilePaths[FileIndex]);
+      auto Future =
+          Server.removeDocument(Context::empty(), FilePaths[FileIndex]);
       UpdateStatsOnRemoveDocument(FileIndex, std::move(Future));
     };
 
@@ -608,7 +610,7 @@ int d;
       // cancelled by any subsequent AddDocument/RemoveDocument request to the
       // same file.
       Server
-          .codeComplete(FilePaths[FileIndex], Pos,
+          .codeComplete(Context::empty(), FilePaths[FileIndex], Pos,
                         clangd::CodeCompleteOptions())
           .wait();
     };
@@ -620,7 +622,8 @@ int d;
         AddDocument(FileIndex);
 
       Position Pos{LineDist(RandGen), ColumnDist(RandGen)};
-      ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos));
+      ASSERT_TRUE(!!Server.findDefinitions(Context::empty(),
+                                           FilePaths[FileIndex], Pos));
     };
 
     std::vector<std::function<void()>> AsyncRequests = {
@@ -676,8 +679,7 @@ TEST_F(ClangdVFSTest, CheckSourceHeaderS
   MockCompilationDatabase CDB;
 
   ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
-                      /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
+                      /*StorePreamblesInMemory=*/true);
 
   auto SourceContents = R"cpp(
   #include "foo.h"
@@ -802,12 +804,13 @@ int d;
       std::move(StartSecondReparsePromise));
 
   MockCompilationDatabase CDB;
-  ClangdServer Server(CDB, DiagConsumer, FS, 4, /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
-  Server.addDocument(FooCpp, SourceContentsWithErrors);
+  ClangdServer Server(CDB, DiagConsumer, FS, 4,
+                      /*StorePreamblesInMemory=*/true);
+  Server.addDocument(Context::empty(), FooCpp, SourceContentsWithErrors);
   StartSecondReparse.wait();
 
-  auto Future = Server.addDocument(FooCpp, SourceContentsWithoutErrors);
+  auto Future =
+      Server.addDocument(Context::empty(), FooCpp, SourceContentsWithoutErrors);
   Future.wait();
 }
 

Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=320576&r1=320575&r2=320576&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Wed Dec 13 04:51:22 2017
@@ -9,6 +9,7 @@
 #include "ClangdServer.h"
 #include "Compiler.h"
 #include "Matchers.h"
+#include "Context.h"
 #include "Protocol.h"
 #include "TestFS.h"
 #include "gmock/gmock.h"
@@ -92,12 +93,13 @@ CompletionList completions(StringRef Tex
   MockCompilationDatabase CDB;
   IgnoreDiagnostics DiagConsumer;
   ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
-                      /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
+                      /*StorePreamblesInMemory=*/true);
   auto File = getVirtualTestFilePath("foo.cpp");
   auto Test = parseTextMarker(Text);
-  Server.addDocument(File, Test.Text);
-  return Server.codeComplete(File, Test.MarkerPos, Opts).get().Value;
+  Server.addDocument(Context::empty(), File, Test.Text);
+  return Server.codeComplete(Context::empty(), File, Test.MarkerPos, Opts)
+      .get()
+      .second.Value;
 }
 
 TEST(CompletionTest, Limit) {
@@ -127,7 +129,6 @@ TEST(CompletionTest, Filter) {
       int Qux;
     };
   )cpp";
-
   EXPECT_THAT(completions(Body + "int main() { S().Foba^ }").items,
               AllOf(Has("FooBar"), Has("FooBaz"), Not(Has("Qux"))));
 
@@ -269,18 +270,17 @@ TEST(CompletionTest, CheckContentsOverri
   IgnoreDiagnostics DiagConsumer;
   MockCompilationDatabase CDB;
   ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
-                      /*StorePreamblesInMemory=*/true,
-                      EmptyLogger::getInstance());
+                      /*StorePreamblesInMemory=*/true);
   auto File = getVirtualTestFilePath("foo.cpp");
-  Server.addDocument(File, "ignored text!");
+  Server.addDocument(Context::empty(), File, "ignored text!");
 
   auto Example = parseTextMarker("int cbc; int b = ^;");
   auto Results =
       Server
-          .codeComplete(File, Example.MarkerPos, clangd::CodeCompleteOptions(),
-                        StringRef(Example.Text))
+          .codeComplete(Context::empty(), File, Example.MarkerPos,
+                        clangd::CodeCompleteOptions(), StringRef(Example.Text))
           .get()
-          .Value;
+          .second.Value;
   EXPECT_THAT(Results.items, Contains(Named("cbc")));
 }
 




More information about the cfe-commits mailing list