@@ -39,16 +39,29 @@ void appendEscapeSnippet(const llvm::StringRef Text, std::string *Out) {
3939 }
4040}
4141
42- void appendOptionalChunk (const CodeCompletionString &CCS, std::string *Out) {
42+ // / Removes the value for defaults arguments.
43+ static void addWithoutValue (std::string *Out, const std::string &ToAdd) {
44+ size_t Val = ToAdd.find (' =' );
45+ if (Val != ToAdd.npos )
46+ *Out += ToAdd.substr (0 , Val - 1 ); // removing value in definition
47+ else
48+ *Out += ToAdd;
49+ }
50+
51+ void appendOptionalChunk (const CodeCompletionString &CCS, std::string *Out,
52+ bool RemoveValues = false ) {
4353 for (const CodeCompletionString::Chunk &C : CCS) {
4454 switch (C.Kind ) {
4555 case CodeCompletionString::CK_Optional:
4656 assert (C.Optional &&
4757 " Expected the optional code completion string to be non-null." );
48- appendOptionalChunk (*C.Optional , Out);
58+ appendOptionalChunk (*C.Optional , Out, RemoveValues );
4959 break ;
5060 default :
51- *Out += C.Text ;
61+ if (RemoveValues)
62+ addWithoutValue (Out, C.Text );
63+ else
64+ *Out += C.Text ;
5265 break ;
5366 }
5467 }
@@ -184,6 +197,7 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature,
184197 unsigned SnippetArg = 0 ;
185198 bool HadObjCArguments = false ;
186199 bool HadInformativeChunks = false ;
200+ int IsTemplateArgument = 0 ;
187201
188202 std::optional<unsigned > TruncateSnippetAt;
189203 for (const auto &Chunk : CCS) {
@@ -252,33 +266,50 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature,
252266 }
253267 }
254268 break ;
255- case CodeCompletionString::CK_Text:
269+ case CodeCompletionString::CK_FunctionQualifier:
270+ if (!IncludeFunctionArguments) // if not a call
271+ *Snippet += Chunk.Text ;
256272 *Signature += Chunk.Text ;
273+ break ;
274+ case CodeCompletionString::CK_Text:
257275 *Snippet += Chunk.Text ;
276+ *Signature += Chunk.Text ;
258277 break ;
259278 case CodeCompletionString::CK_Optional:
260279 assert (Chunk.Optional );
261280 // No need to create placeholders for default arguments in Snippet.
262281 appendOptionalChunk (*Chunk.Optional , Signature);
282+ if (!IncludeFunctionArguments) { // complete args with default value in
283+ // definition
284+ appendOptionalChunk (*Chunk.Optional , Snippet, /* RemoveValues=*/ true );
285+ }
263286 break ;
264287 case CodeCompletionString::CK_Placeholder:
265288 *Signature += Chunk.Text ;
266- ++SnippetArg;
267- if (SnippetArg == CursorSnippetArg) {
268- // We'd like to make $0 a placeholder too, but vscode does not support
269- // this (https://github.com/microsoft/vscode/issues/152837).
270- *Snippet += " $0" ;
289+ if (IncludeFunctionArguments || IsTemplateArgument) {
290+ ++SnippetArg;
291+ if (SnippetArg == CursorSnippetArg) {
292+ // We'd like to make $0 a placeholder too, but vscode does not support
293+ // this (https://github.com/microsoft/vscode/issues/152837).
294+ *Snippet += " $0" ;
295+ } else {
296+ *Snippet += " ${" + std::to_string (SnippetArg) + ' :' ;
297+ appendEscapeSnippet (Chunk.Text , Snippet);
298+ *Snippet += ' }' ;
299+ }
271300 } else {
272- *Snippet += " ${" + std::to_string (SnippetArg) + ' :' ;
273- appendEscapeSnippet (Chunk.Text , Snippet);
274- *Snippet += ' }' ;
301+ *Snippet += Chunk.Text ;
275302 }
276303 break ;
277304 case CodeCompletionString::CK_Informative:
278305 HadInformativeChunks = true ;
279306 // For example, the word "const" for a const method, or the name of
280307 // the base class for methods that are part of the base class.
281308 *Signature += Chunk.Text ;
309+ if (strcmp (Chunk.Text , " const" ) == 0 ||
310+ strcmp (Chunk.Text , " volatile" ) == 0 ||
311+ strcmp (Chunk.Text , " restrict" ) == 0 )
312+ *Snippet += Chunk.Text ;
282313 // Don't put the informative chunks in the snippet.
283314 break ;
284315 case CodeCompletionString::CK_ResultType:
@@ -290,21 +321,22 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature,
290321 llvm_unreachable (" Unexpected CK_CurrentParameter while collecting "
291322 " CompletionItems" );
292323 break ;
324+ case CodeCompletionString::CK_LeftAngle:
325+ IsTemplateArgument++;
326+ *Signature += Chunk.Text ;
327+ *Snippet += Chunk.Text ;
328+ break ;
329+ case CodeCompletionString::CK_RightAngle:
330+ IsTemplateArgument--;
331+ *Signature += Chunk.Text ;
332+ *Snippet += Chunk.Text ;
333+ break ;
293334 case CodeCompletionString::CK_LeftParen:
294- // We're assuming that a LeftParen in a declaration starts a function
295- // call, and arguments following the parenthesis could be discarded if
296- // IncludeFunctionArguments is false.
297- if (!IncludeFunctionArguments &&
298- ResultKind == CodeCompletionResult::RK_Declaration)
299- TruncateSnippetAt.emplace (Snippet->size ());
300- [[fallthrough]];
301335 case CodeCompletionString::CK_RightParen:
302336 case CodeCompletionString::CK_LeftBracket:
303337 case CodeCompletionString::CK_RightBracket:
304338 case CodeCompletionString::CK_LeftBrace:
305339 case CodeCompletionString::CK_RightBrace:
306- case CodeCompletionString::CK_LeftAngle:
307- case CodeCompletionString::CK_RightAngle:
308340 case CodeCompletionString::CK_Comma:
309341 case CodeCompletionString::CK_Colon:
310342 case CodeCompletionString::CK_SemiColon:
@@ -319,8 +351,6 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature,
319351 break ;
320352 }
321353 }
322- if (TruncateSnippetAt)
323- *Snippet = Snippet->substr (0 , *TruncateSnippetAt);
324354}
325355
326356std::string formatDocumentation (const CodeCompletionString &CCS,
0 commit comments