[PATCH] D89870: [clangd] Drop template argument lists from completions followed by <
Kirill Bobyrev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 18 04:10:37 PST 2021
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG19db870a0dd1: [clangd] Drop template argument lists from completions followed by < (authored by kbobyrev).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D89870/new/
https://reviews.llvm.org/D89870
Files:
clang-tools-extra/clangd/CodeComplete.cpp
clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -3114,10 +3114,13 @@
Contains(AllOf(Labeled("Container<typename T>(int Size)"),
SnippetSuffix("<${1:typename T}>(${2:int Size})"),
Kind(CompletionItemKind::Constructor))));
- // FIXME(kirillbobyrev): It would be nice to still produce the template
- // snippet part: in this case it should be "<${1:typename T}>".
EXPECT_THAT(
completions(Context + "Container c = Cont^()", {}, Opts).Completions,
+ Contains(AllOf(Labeled("Container<typename T>(int Size)"),
+ SnippetSuffix("<${1:typename T}>"),
+ Kind(CompletionItemKind::Constructor))));
+ EXPECT_THAT(
+ completions(Context + "Container c = Cont^<int>()", {}, Opts).Completions,
Contains(AllOf(Labeled("Container<typename T>(int Size)"),
SnippetSuffix(""),
Kind(CompletionItemKind::Constructor))));
Index: clang-tools-extra/clangd/CodeComplete.cpp
===================================================================
--- clang-tools-extra/clangd/CodeComplete.cpp
+++ clang-tools-extra/clangd/CodeComplete.cpp
@@ -452,18 +452,52 @@
std::string summarizeSnippet() const {
if (IsUsingDeclaration)
return "";
- // Suppress function argument snippets if args are already present.
- if ((Completion.Kind == CompletionItemKind::Function ||
- Completion.Kind == CompletionItemKind::Method ||
- Completion.Kind == CompletionItemKind::Constructor) &&
- NextTokenKind == tok::l_paren)
- return "";
auto *Snippet = onlyValue<&BundledEntry::SnippetSuffix>();
if (!Snippet)
// All bundles are function calls.
// FIXME(ibiryukov): sometimes add template arguments to a snippet, e.g.
// we need to complete 'forward<$1>($0)'.
return "($0)";
+ // Suppress function argument snippets cursor is followed by left
+ // parenthesis (and potentially arguments) or if there are potentially
+ // template arguments. There are cases where it would be wrong (e.g. next
+ // '<' token is a comparison rather than template argument list start) but
+ // it is less common and suppressing snippet provides better UX.
+ if (Completion.Kind == CompletionItemKind::Function ||
+ Completion.Kind == CompletionItemKind::Method ||
+ Completion.Kind == CompletionItemKind::Constructor) {
+ // If there is a potential template argument list, drop snippet and just
+ // complete symbol name. Ideally, this could generate an edit that would
+ // paste function arguments after template argument list but it would be
+ // complicated. Example:
+ //
+ // fu^<int> -> function<int>
+ if (NextTokenKind == tok::less && Snippet->front() == '<')
+ return "";
+ // Potentially followed by argument list.
+ if (NextTokenKind == tok::l_paren) {
+ // If snippet contains template arguments we will emit them and drop
+ // function arguments. Example:
+ //
+ // fu^(42) -> function<int>(42);
+ if (Snippet->front() == '<') {
+ // Find matching '>'. Snippet->find('>') will not work in cases like
+ // template <typename T=std::vector<int>>. Hence, iterate through
+ // the snippet until the angle bracket balance reaches zero.
+ int Balance = 0;
+ size_t I = 0;
+ do {
+ if (Snippet->at(I) == '>')
+ --Balance;
+ else if (Snippet->at(I) == '<')
+ ++Balance;
+ ++I;
+ } while (Balance > 0);
+ return Snippet->substr(0, I);
+ }
+ return "";
+ }
+ }
if (EnableFunctionArgSnippets)
return *Snippet;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D89870.324594.patch
Type: text/x-patch
Size: 3989 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210218/abad3d7f/attachment-0001.bin>
More information about the cfe-commits
mailing list