diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index f29dadde2b86d..632cdd04cf6fc 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -229,7 +229,7 @@ class ClangdLSPServer::MessageHandler : public Transport::MessageHandler { bool onCall(llvm::StringRef Method, llvm::json::Value Params, llvm::json::Value ID) override { - WithContext HandlerContext(handlerContext()); + WithContext HandlerContext(handlerContext(llvm::to_string(ID))); // Calls can be canceled by the client. Add cancellation context. WithContext WithCancel(cancelableRequestContext(ID)); trace::Span Tracer(Method, LSPLatency); @@ -252,7 +252,7 @@ class ClangdLSPServer::MessageHandler : public Transport::MessageHandler { bool onReply(llvm::json::Value ID, llvm::Expected Result) override { - WithContext HandlerContext(handlerContext()); + WithContext HandlerContext(handlerContext(llvm::to_string(ID))); Callback ReplyHandler = nullptr; if (auto IntID = ID.getAsInteger()) { @@ -415,6 +415,13 @@ class ClangdLSPServer::MessageHandler : public Transport::MessageHandler { Server.Opts.Encoding.value_or(OffsetEncoding::UTF16)); } + Context handlerContext(const std::string &ID) const { + return Context::current() + .derive(kCurrentOffsetEncoding, + Server.Opts.Encoding.value_or(OffsetEncoding::UTF16)) + .derive(trace::EventTracer::kRequestId, ID); + } + // We run cancelable requests in a context that does two things: // - allows cancellation using RequestCancelers[ID] // - cleans up the entry in RequestCancelers when it's no longer needed diff --git a/clang-tools-extra/clangd/index/YAMLSerialization.cpp b/clang-tools-extra/clangd/index/YAMLSerialization.cpp index 214a847b5eddb..495d8a2ff487a 100644 --- a/clang-tools-extra/clangd/index/YAMLSerialization.cpp +++ b/clang-tools-extra/clangd/index/YAMLSerialization.cpp @@ -319,6 +319,7 @@ template <> struct MappingTraits { MappingNormalization NKind(IO, R.Kind); IO.mapRequired("Kind", NKind->Kind); IO.mapRequired("Location", R.Location); + IO.mapOptional("Container", R.Container); } }; diff --git a/clang-tools-extra/clangd/index/remote/Index.proto b/clang-tools-extra/clangd/index/remote/Index.proto index 3072299d8f345..33bf095d88598 100644 --- a/clang-tools-extra/clangd/index/remote/Index.proto +++ b/clang-tools-extra/clangd/index/remote/Index.proto @@ -81,6 +81,7 @@ message Symbol { message Ref { optional SymbolLocation location = 1; optional uint32 kind = 2; + optional string container = 3; } message SymbolInfo { diff --git a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp index 7e31ada18a657..e9f0972ba91c3 100644 --- a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp +++ b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp @@ -189,6 +189,9 @@ llvm::Expected Marshaller::fromProtobuf(const Ref &Message) { return Location.takeError(); Result.Location = *Location; Result.Kind = static_cast(Message.kind()); + auto ContainerID = SymbolID::fromStr(Message.container()); + if (ContainerID) + Result.Container = *ContainerID; return Result; } @@ -296,6 +299,7 @@ llvm::Expected Marshaller::toProtobuf(const clangd::Ref &From) { if (!Location) return Location.takeError(); *Result.mutable_location() = *Location; + Result.set_container(From.Container.str()); return Result; } diff --git a/clang-tools-extra/clangd/support/Trace.cpp b/clang-tools-extra/clangd/support/Trace.cpp index 419c2eee99ec8..f1244c8025bf3 100644 --- a/clang-tools-extra/clangd/support/Trace.cpp +++ b/clang-tools-extra/clangd/support/Trace.cpp @@ -24,6 +24,8 @@ namespace clang { namespace clangd { namespace trace { +Key EventTracer::kRequestId; + namespace { // The current implementation is naive: each thread writes to Out guarded by Mu. // Perhaps we should replace this by something that disturbs performance less. @@ -159,6 +161,10 @@ class JSONTracer : public EventTracer { Out.object([&] { Out.attribute("pid", 0); Out.attribute("ph", Phase); + const auto *id = Context::current().get(kRequestId); + if (id) { + Out.attribute("rid", *id); + } for (const auto &KV : Event) Out.attribute(KV.first, KV.second); }); diff --git a/clang-tools-extra/clangd/support/Trace.h b/clang-tools-extra/clangd/support/Trace.h index 1bfc75b874d8a..ae00ea322fb39 100644 --- a/clang-tools-extra/clangd/support/Trace.h +++ b/clang-tools-extra/clangd/support/Trace.h @@ -99,6 +99,8 @@ class EventTracer { /// Called whenever a metrics records a measurement. virtual void record(const Metric &Metric, double Value, llvm::StringRef Label) {} + /// A key to store json request id in the context used in tracers + static Key kRequestId; }; /// Sets up a global EventTracer that consumes events produced by Span and diff --git a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp index a2b31698a059a..85e79eae331bc 100644 --- a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp +++ b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp @@ -223,6 +223,7 @@ TEST(RemoteMarshallingTest, RefSerialization) { Location.FileURI = testPathURI( "llvm-project/llvm/clang-tools-extra/clangd/Protocol.h", Strings); Ref.Location = Location; + Ref.Container = llvm::cantFail(SymbolID::fromStr("0000000000000001")); Marshaller ProtobufMarshaller(testPath("llvm-project/"), testPath("llvm-project/"));