Author: ibiryukov Date: Tue Jun 4 02:36:59 2019 New Revision: 362481 URL: http://llvm.org/viewvc/llvm-project?rev=362481&view=rev Log: [clangd] Support offsets for parameters in signatureHelp
Summary: Added to LSP in version 3.14 Reviewers: hokein Reviewed By: hokein Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D62476 Added: clang-tools-extra/trunk/clangd/test/signature-help-with-offsets.test Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdLSPServer.h clang-tools-extra/trunk/clangd/CodeComplete.cpp clang-tools-extra/trunk/clangd/Protocol.cpp clang-tools-extra/trunk/clangd/Protocol.h clang-tools-extra/trunk/clangd/unittests/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=362481&r1=362480&r2=362481&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Tue Jun 4 02:36:59 2019 @@ -360,6 +360,7 @@ void ClangdLSPServer::onInitialize(const Params.capabilities.HierarchicalDocumentSymbol; SupportFileStatus = Params.initializationOptions.FileStatus; HoverContentFormat = Params.capabilities.HoverContentFormat; + SupportsOffsetsInSignatureHelp = Params.capabilities.OffsetsInSignatureHelp; llvm::json::Object Result{ {{"capabilities", llvm::json::Object{ @@ -761,7 +762,22 @@ void ClangdLSPServer::onCompletion(const void ClangdLSPServer::onSignatureHelp(const TextDocumentPositionParams &Params, Callback<SignatureHelp> Reply) { Server->signatureHelp(Params.textDocument.uri.file(), Params.position, - std::move(Reply)); + Bind( + [this](decltype(Reply) Reply, + llvm::Expected<SignatureHelp> Signature) { + if (!Signature) + return Reply(Signature.takeError()); + if (SupportsOffsetsInSignatureHelp) + return Reply(std::move(*Signature)); + // Strip out the offsets from signature help for + // clients that only support string labels. + for (auto &Signature : Signature->signatures) { + for (auto &Param : Signature.parameters) + Param.labelOffsets.reset(); + } + return Reply(std::move(*Signature)); + }, + std::move(Reply))); } // Go to definition has a toggle function: if def and decl are distinct, then Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=362481&r1=362480&r2=362481&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Tue Jun 4 02:36:59 2019 @@ -156,8 +156,9 @@ private: bool SupportFileStatus = false; /// Which kind of markup should we use in textDocument/hover responses. MarkupKind HoverContentFormat = MarkupKind::PlainText; - - /// Store of the current versions of the open documents. + /// Whether the client supports offsets for parameter info labels. + bool SupportsOffsetsInSignatureHelp = false; + // Store of the current versions of the open documents. DraftStore DraftMgr; // The CDB is created by the "initialize" LSP method. Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=362481&r1=362480&r2=362481&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original) +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Tue Jun 4 02:36:59 2019 @@ -28,6 +28,7 @@ #include "FuzzyMatch.h" #include "Headers.h" #include "Logger.h" +#include "Protocol.h" #include "Quality.h" #include "SourceCode.h" #include "TUScheduler.h" @@ -56,6 +57,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" #include "llvm/Support/Format.h" @@ -148,46 +150,6 @@ toCompletionItemKind(CodeCompletionResul llvm_unreachable("Unhandled CodeCompletionResult::ResultKind."); } -/// Get the optional chunk as a string. This function is possibly recursive. -/// -/// The parameter info for each parameter is appended to the Parameters. -std::string getOptionalParameters(const CodeCompletionString &CCS, - std::vector<ParameterInformation> &Parameters, - SignatureQualitySignals &Signal) { - std::string Result; - for (const auto &Chunk : CCS) { - switch (Chunk.Kind) { - case CodeCompletionString::CK_Optional: - assert(Chunk.Optional && - "Expected the optional code completion string to be non-null."); - Result += getOptionalParameters(*Chunk.Optional, Parameters, Signal); - break; - case CodeCompletionString::CK_VerticalSpace: - break; - case CodeCompletionString::CK_Placeholder: - // A string that acts as a placeholder for, e.g., a function call - // argument. - // Intentional fallthrough here. - case CodeCompletionString::CK_CurrentParameter: { - // A piece of text that describes the parameter that corresponds to - // the code-completion location within a function call, message send, - // macro invocation, etc. - Result += Chunk.Text; - ParameterInformation Info; - Info.label = Chunk.Text; - Parameters.push_back(std::move(Info)); - Signal.ContainsActiveParameter = true; - Signal.NumberOfOptionalParameters++; - break; - } - default: - Result += Chunk.Text; - break; - } - } - return Result; -} - // Identifier code completion result. struct RawIdentifier { llvm::StringRef Name; @@ -830,8 +792,7 @@ class SignatureHelpCollector final : pub public: SignatureHelpCollector(const clang::CodeCompleteOptions &CodeCompleteOpts, const SymbolIndex *Index, SignatureHelp &SigHelp) - : CodeCompleteConsumer(CodeCompleteOpts), - SigHelp(SigHelp), + : CodeCompleteConsumer(CodeCompleteOpts), SigHelp(SigHelp), Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()), CCTUInfo(Allocator), Index(Index) {} @@ -944,6 +905,50 @@ public: CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } private: + void processParameterChunk(llvm::StringRef ChunkText, + SignatureInformation &Signature, + SignatureQualitySignals Signal) const { + // (!) this is O(n), should still be fast compared to building ASTs. + unsigned ParamStartOffset = lspLength(Signature.label); + unsigned ParamEndOffset = ParamStartOffset + lspLength(ChunkText); + // A piece of text that describes the parameter that corresponds to + // the code-completion location within a function call, message send, + // macro invocation, etc. + Signature.label += ChunkText; + ParameterInformation Info; + Info.labelOffsets.emplace(ParamStartOffset, ParamEndOffset); + // FIXME: only set 'labelOffsets' when all clients migrate out of it. + Info.labelString = ChunkText; + + Signature.parameters.push_back(std::move(Info)); + // FIXME: this should only be set on CK_CurrentParameter. + Signal.ContainsActiveParameter = true; + } + + void processOptionalChunk(const CodeCompletionString &CCS, + SignatureInformation &Signature, + SignatureQualitySignals &Signal) const { + for (const auto &Chunk : CCS) { + switch (Chunk.Kind) { + case CodeCompletionString::CK_Optional: + assert(Chunk.Optional && + "Expected the optional code completion string to be non-null."); + processOptionalChunk(*Chunk.Optional, Signature, Signal); + break; + case CodeCompletionString::CK_VerticalSpace: + break; + case CodeCompletionString::CK_CurrentParameter: + case CodeCompletionString::CK_Placeholder: + processParameterChunk(Chunk.Text, Signature, Signal); + Signal.NumberOfOptionalParameters++; + break; + default: + Signature.label += Chunk.Text; + break; + } + } + } + // FIXME(ioeric): consider moving CodeCompletionString logic here to // CompletionString.h. ScoredSignature processOverloadCandidate(const OverloadCandidate &Candidate, @@ -964,28 +969,16 @@ private: assert(!ReturnType && "Unexpected CK_ResultType"); ReturnType = Chunk.Text; break; + case CodeCompletionString::CK_CurrentParameter: case CodeCompletionString::CK_Placeholder: - // A string that acts as a placeholder for, e.g., a function call - // argument. - // Intentional fallthrough here. - case CodeCompletionString::CK_CurrentParameter: { - // A piece of text that describes the parameter that corresponds to - // the code-completion location within a function call, message send, - // macro invocation, etc. - Signature.label += Chunk.Text; - ParameterInformation Info; - Info.label = Chunk.Text; - Signature.parameters.push_back(std::move(Info)); + processParameterChunk(Chunk.Text, Signature, Signal); Signal.NumberOfParameters++; - Signal.ContainsActiveParameter = true; break; - } case CodeCompletionString::CK_Optional: { // The rest of the parameters are defaulted/optional. assert(Chunk.Optional && "Expected the optional code completion string to be non-null."); - Signature.label += getOptionalParameters(*Chunk.Optional, - Signature.parameters, Signal); + processOptionalChunk(*Chunk.Optional, Signature, Signal); break; } case CodeCompletionString::CK_VerticalSpace: @@ -1037,7 +1030,7 @@ void loadMainFilePreambleMacros(const Pr PP.getIdentifierTable().getExternalIdentifierLookup(); if (!PreambleIdentifiers || !PreambleMacros) return; - for (const auto& MacroName : Preamble.MainFileMacros) + for (const auto &MacroName : Preamble.MainFileMacros) if (auto *II = PreambleIdentifiers->get(MacroName)) if (II->isOutOfDate()) PreambleMacros->updateOutOfDateIdentifier(*II); @@ -1213,7 +1206,7 @@ class CodeCompleteFlow { int NSema = 0, NIndex = 0, NSemaAndIndex = 0, NIdent = 0; bool Incomplete = false; // Would more be available with a higher limit? CompletionPrefix HeuristicPrefix; - llvm::Optional<FuzzyMatcher> Filter; // Initialized once Sema runs. + llvm::Optional<FuzzyMatcher> Filter; // Initialized once Sema runs. Range ReplacedRange; std::vector<std::string> QueryScopes; // Initialized once Sema runs. // Initialized once QueryScopes is initialized, if there are scopes. @@ -1707,8 +1700,8 @@ clang::CodeCompleteOptions CodeCompleteO return Result; } -CompletionPrefix -guessCompletionPrefix(llvm::StringRef Content, unsigned Offset) { +CompletionPrefix guessCompletionPrefix(llvm::StringRef Content, + unsigned Offset) { assert(Offset <= Content.size()); StringRef Rest = Content.take_front(Offset); CompletionPrefix Result; Modified: clang-tools-extra/trunk/clangd/Protocol.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=362481&r1=362480&r2=362481&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/Protocol.cpp (original) +++ clang-tools-extra/trunk/clangd/Protocol.cpp Tue Jun 4 02:36:59 2019 @@ -314,6 +314,14 @@ bool fromJSON(const llvm::json::Value &P } } } + if (auto *Help = TextDocument->getObject("signatureHelp")) { + if (auto *Info = Help->getObject("signatureInformation")) { + if (auto *Parameter = Info->getObject("parameterInformation")) { + if (auto OffsetSupport = Parameter->getBoolean("labelOffsetSupport")) + R.OffsetsInSignatureHelp = *OffsetSupport; + } + } + } } if (auto *Workspace = O->getObject("workspace")) { if (auto *Symbol = Workspace->getObject("symbol")) { @@ -824,8 +832,14 @@ llvm::json::Value toJSON(const Completio } llvm::json::Value toJSON(const ParameterInformation &PI) { - assert(!PI.label.empty() && "parameter information label is required"); - llvm::json::Object Result{{"label", PI.label}}; + assert(PI.labelOffsets.hasValue() || + !PI.labelString.empty() && "parameter information label is required"); + llvm::json::Object Result; + if (PI.labelOffsets) + Result["label"] = + llvm::json::Array({PI.labelOffsets->first, PI.labelOffsets->second}); + else + Result["label"] = PI.labelString; if (!PI.documentation.empty()) Result["documentation"] = PI.documentation; return std::move(Result); Modified: clang-tools-extra/trunk/clangd/Protocol.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=362481&r1=362480&r2=362481&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/Protocol.h (original) +++ clang-tools-extra/trunk/clangd/Protocol.h Tue Jun 4 02:36:59 2019 @@ -390,6 +390,9 @@ struct ClientCapabilities { /// Client supports hierarchical document symbols. bool HierarchicalDocumentSymbol = false; + /// Client supports processing label offsets instead of a simple label string. + bool OffsetsInSignatureHelp = false; + /// The supported set of CompletionItemKinds for textDocument/completion. /// textDocument.completion.completionItemKind.valueSet llvm::Optional<CompletionItemKindBitset> CompletionItemKinds; @@ -979,8 +982,14 @@ llvm::json::Value toJSON(const Completio /// A single parameter of a particular signature. struct ParameterInformation { - /// The label of this parameter. Mandatory. - std::string label; + /// The label of this parameter. Ignored when labelOffsets is set. + std::string labelString; + + /// Inclusive start and exclusive end offsets withing the containing signature + /// label. + /// Offsets are computed by lspLength(), which counts UTF-16 code units by + /// default but that can be overriden, see its documentation for details. + llvm::Optional<std::pair<unsigned, unsigned>> labelOffsets; /// The documentation of this parameter. Optional. std::string documentation; Added: clang-tools-extra/trunk/clangd/test/signature-help-with-offsets.test URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/test/signature-help-with-offsets.test?rev=362481&view=auto ============================================================================== --- clang-tools-extra/trunk/clangd/test/signature-help-with-offsets.test (added) +++ clang-tools-extra/trunk/clangd/test/signature-help-with-offsets.test Tue Jun 4 02:36:59 2019 @@ -0,0 +1,50 @@ +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +# Start a session. +{ + "jsonrpc": "2.0", + "id": 0, + "method": "initialize", + "params": { + "processId": 123, + "rootPath": "clangd", + "capabilities": { + "textDocument": { + "signatureHelp": { + "signatureInformation": { + "parameterInformation": { + "labelOffsetSupport": true + } + } + } + } + }, + "trace": "off" + } +} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void x(int);\nint main(){\nx("}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/signatureHelp","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":2}}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "activeParameter": 0, +# CHECK-NEXT: "activeSignature": 0, +# CHECK-NEXT: "signatures": [ +# CHECK-NEXT: { +# CHECK-NEXT: "label": "x(int) -> void", +# CHECK-NEXT: "parameters": [ +# CHECK-NEXT: { +# CHECK-NEXT: "label": [ +# CHECK-NEXT: 2, +# CHECK-NEXT: 5 +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":100000,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} Modified: clang-tools-extra/trunk/clangd/unittests/CodeCompleteTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/CodeCompleteTests.cpp?rev=362481&r1=362480&r2=362481&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/unittests/CodeCompleteTests.cpp (original) +++ clang-tools-extra/trunk/clangd/unittests/CodeCompleteTests.cpp Tue Jun 4 02:36:59 2019 @@ -967,19 +967,37 @@ SignatureHelp signatures(llvm::StringRef return signatures(Test.code(), Test.point(), std::move(IndexSymbols)); } +struct ExpectedParameter { + std::string Text; + std::pair<unsigned, unsigned> Offsets; +}; MATCHER_P(ParamsAre, P, "") { if (P.size() != arg.parameters.size()) return false; - for (unsigned I = 0; I < P.size(); ++I) - if (P[I] != arg.parameters[I].label) + for (unsigned I = 0; I < P.size(); ++I) { + if (P[I].Text != arg.parameters[I].labelString || + P[I].Offsets != arg.parameters[I].labelOffsets) return false; + } return true; } MATCHER_P(SigDoc, Doc, "") { return arg.documentation == Doc; } -Matcher<SignatureInformation> Sig(std::string Label, - std::vector<std::string> Params) { - return AllOf(SigHelpLabeled(Label), ParamsAre(Params)); +/// \p AnnotatedLabel is a signature label with ranges marking parameters, e.g. +/// foo([[int p1]], [[double p2]]) -> void +Matcher<SignatureInformation> Sig(llvm::StringRef AnnotatedLabel) { + llvm::Annotations A(AnnotatedLabel); + std::string Label = A.code(); + std::vector<ExpectedParameter> Parameters; + for (auto Range : A.ranges()) { + Parameters.emplace_back(); + + ExpectedParameter &P = Parameters.back(); + P.Text = Label.substr(Range.Begin, Range.End - Range.Begin); + P.Offsets.first = lspLength(llvm::StringRef(Label).substr(0, Range.Begin)); + P.Offsets.second = lspLength(llvm::StringRef(Label).substr(1, Range.End)); + } + return AllOf(SigHelpLabeled(Label), ParamsAre(Parameters)); } TEST(SignatureHelpTest, Overloads) { @@ -992,11 +1010,10 @@ TEST(SignatureHelpTest, Overloads) { int main() { foo(^); } )cpp"); EXPECT_THAT(Results.signatures, - UnorderedElementsAre( - Sig("foo(float x, float y) -> void", {"float x", "float y"}), - Sig("foo(float x, int y) -> void", {"float x", "int y"}), - Sig("foo(int x, float y) -> void", {"int x", "float y"}), - Sig("foo(int x, int y) -> void", {"int x", "int y"}))); + UnorderedElementsAre(Sig("foo([[float x]], [[float y]]) -> void"), + Sig("foo([[float x]], [[int y]]) -> void"), + Sig("foo([[int x]], [[float y]]) -> void"), + Sig("foo([[int x]], [[int y]]) -> void"))); // We always prefer the first signature. EXPECT_EQ(0, Results.activeSignature); EXPECT_EQ(0, Results.activeParameter); @@ -1010,9 +1027,8 @@ TEST(SignatureHelpTest, DefaultArgs) { )cpp"); EXPECT_THAT(Results.signatures, UnorderedElementsAre( - Sig("bar(int x, int y = 0) -> void", {"int x", "int y = 0"}), - Sig("bar(float x = 0, int y = 42) -> void", - {"float x = 0", "int y = 42"}))); + Sig("bar([[int x]], [[int y = 0]]) -> void"), + Sig("bar([[float x = 0]], [[int y = 42]]) -> void"))); EXPECT_EQ(0, Results.activeSignature); EXPECT_EQ(0, Results.activeParameter); } @@ -1023,8 +1039,7 @@ TEST(SignatureHelpTest, ActiveArg) { int main() { baz(baz(1,2,3), ^); } )cpp"); EXPECT_THAT(Results.signatures, - ElementsAre(Sig("baz(int a, int b, int c) -> int", - {"int a", "int b", "int c"}))); + ElementsAre(Sig("baz([[int a]], [[int b]], [[int c]]) -> int"))); EXPECT_EQ(0, Results.activeSignature); EXPECT_EQ(1, Results.activeParameter); } @@ -1761,14 +1776,12 @@ TEST(SignatureHelpTest, OverloadsOrderin void foo(int x, int y = 0); int main() { foo(^); } )cpp"); - EXPECT_THAT( - Results.signatures, - ElementsAre( - Sig("foo(int x) -> void", {"int x"}), - Sig("foo(int x, int y = 0) -> void", {"int x", "int y = 0"}), - Sig("foo(float x, int y) -> void", {"float x", "int y"}), - Sig("foo(int x, float y) -> void", {"int x", "float y"}), - Sig("foo(float x, float y) -> void", {"float x", "float y"}))); + EXPECT_THAT(Results.signatures, + ElementsAre(Sig("foo([[int x]]) -> void"), + Sig("foo([[int x]], [[int y = 0]]) -> void"), + Sig("foo([[float x]], [[int y]]) -> void"), + Sig("foo([[int x]], [[float y]]) -> void"), + Sig("foo([[float x]], [[float y]]) -> void"))); // We always prefer the first signature. EXPECT_EQ(0, Results.activeSignature); EXPECT_EQ(0, Results.activeParameter); @@ -1785,7 +1798,7 @@ TEST(SignatureHelpTest, InstantiatedSign )cpp"; EXPECT_THAT(signatures(Sig0).signatures, - ElementsAre(Sig("foo(T, T, T) -> void", {"T", "T", "T"}))); + ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void"))); StringRef Sig1 = R"cpp( template <class T> @@ -1796,7 +1809,7 @@ TEST(SignatureHelpTest, InstantiatedSign })cpp"; EXPECT_THAT(signatures(Sig1).signatures, - ElementsAre(Sig("foo(T, T, T) -> void", {"T", "T", "T"}))); + ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void"))); StringRef Sig2 = R"cpp( template <class ...T> @@ -1808,7 +1821,7 @@ TEST(SignatureHelpTest, InstantiatedSign )cpp"; EXPECT_THAT(signatures(Sig2).signatures, - ElementsAre(Sig("foo(T...) -> void", {"T..."}))); + ElementsAre(Sig("foo([[T...]]) -> void"))); // It is debatable whether we should substitute the outer template parameter // ('T') in that case. Currently we don't substitute it in signature help, but @@ -1828,7 +1841,7 @@ TEST(SignatureHelpTest, InstantiatedSign )cpp"; EXPECT_THAT(signatures(Sig3).signatures, - ElementsAre(Sig("foo(T, U) -> void", {"T", "U"}))); + ElementsAre(Sig("foo([[T]], [[U]]) -> void"))); } TEST(SignatureHelpTest, IndexDocumentation) { @@ -1849,8 +1862,8 @@ TEST(SignatureHelpTest, IndexDocumentati EXPECT_THAT( signatures(Sig0, {Foo0}).signatures, - ElementsAre(AllOf(Sig("foo() -> int", {}), SigDoc("Doc from the index")), - AllOf(Sig("foo(double) -> int", {"double"}), SigDoc("")))); + ElementsAre(AllOf(Sig("foo() -> int"), SigDoc("Doc from the index")), + AllOf(Sig("foo([[double]]) -> int"), SigDoc("")))); StringRef Sig1 = R"cpp( int foo(); @@ -1866,11 +1879,10 @@ TEST(SignatureHelpTest, IndexDocumentati EXPECT_THAT( signatures(Sig1, {Foo0, Foo1, Foo2}).signatures, - ElementsAre(AllOf(Sig("foo() -> int", {}), SigDoc("Doc from the index")), - AllOf(Sig("foo(int) -> int", {"int"}), - SigDoc("Overriden doc from sema")), - AllOf(Sig("foo(int, int) -> int", {"int", "int"}), - SigDoc("Doc from sema")))); + ElementsAre( + AllOf(Sig("foo() -> int"), SigDoc("Doc from the index")), + AllOf(Sig("foo([[int]]) -> int"), SigDoc("Overriden doc from sema")), + AllOf(Sig("foo([[int]], [[int]]) -> int"), SigDoc("Doc from sema")))); } TEST(SignatureHelpTest, DynamicIndexDocumentation) { @@ -1901,7 +1913,7 @@ TEST(SignatureHelpTest, DynamicIndexDocu EXPECT_THAT( llvm::cantFail(runSignatureHelp(Server, File, FileContent.point())) .signatures, - ElementsAre(AllOf(Sig("foo() -> int", {}), SigDoc("Member doc")))); + ElementsAre(AllOf(Sig("foo() -> int"), SigDoc("Member doc")))); } TEST(CompletionTest, CompletionFunctionArgsDisabled) { @@ -2179,10 +2191,9 @@ TEST(SignatureHelpTest, InsideArgument) void foo(int x, int y); int main() { foo(1+^); } )cpp"); - EXPECT_THAT( - Results.signatures, - ElementsAre(Sig("foo(int x) -> void", {"int x"}), - Sig("foo(int x, int y) -> void", {"int x", "int y"}))); + EXPECT_THAT(Results.signatures, + ElementsAre(Sig("foo([[int x]]) -> void"), + Sig("foo([[int x]], [[int y]]) -> void"))); EXPECT_EQ(0, Results.activeParameter); } { @@ -2191,10 +2202,9 @@ TEST(SignatureHelpTest, InsideArgument) void foo(int x, int y); int main() { foo(1^); } )cpp"); - EXPECT_THAT( - Results.signatures, - ElementsAre(Sig("foo(int x) -> void", {"int x"}), - Sig("foo(int x, int y) -> void", {"int x", "int y"}))); + EXPECT_THAT(Results.signatures, + ElementsAre(Sig("foo([[int x]]) -> void"), + Sig("foo([[int x]], [[int y]]) -> void"))); EXPECT_EQ(0, Results.activeParameter); } { @@ -2203,10 +2213,9 @@ TEST(SignatureHelpTest, InsideArgument) void foo(int x, int y); int main() { foo(1^0); } )cpp"); - EXPECT_THAT( - Results.signatures, - ElementsAre(Sig("foo(int x) -> void", {"int x"}), - Sig("foo(int x, int y) -> void", {"int x", "int y"}))); + EXPECT_THAT(Results.signatures, + ElementsAre(Sig("foo([[int x]]) -> void"), + Sig("foo([[int x]], [[int y]]) -> void"))); EXPECT_EQ(0, Results.activeParameter); } { @@ -2216,8 +2225,8 @@ TEST(SignatureHelpTest, InsideArgument) int bar(int x, int y); int main() { bar(foo(2, 3^)); } )cpp"); - EXPECT_THAT(Results.signatures, ElementsAre(Sig("foo(int x, int y) -> void", - {"int x", "int y"}))); + EXPECT_THAT(Results.signatures, + ElementsAre(Sig("foo([[int x]], [[int y]]) -> void"))); EXPECT_EQ(1, Results.activeParameter); } } @@ -2234,9 +2243,8 @@ TEST(SignatureHelpTest, ConstructorIniti }; )cpp"); EXPECT_THAT(Results.signatures, - UnorderedElementsAre(Sig("A(int)", {"int"}), - Sig("A(A &&)", {"A &&"}), - Sig("A(const A &)", {"const A &"}))); + UnorderedElementsAre(Sig("A([[int]])"), Sig("A([[A &&]])"), + Sig("A([[const A &]])"))); } { const auto Results = signatures(R"cpp( @@ -2253,9 +2261,8 @@ TEST(SignatureHelpTest, ConstructorIniti }; )cpp"); EXPECT_THAT(Results.signatures, - UnorderedElementsAre(Sig("A(int)", {"int"}), - Sig("A(A &&)", {"A &&"}), - Sig("A(const A &)", {"const A &"}))); + UnorderedElementsAre(Sig("A([[int]])"), Sig("A([[A &&]])"), + Sig("A([[const A &]])"))); } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits