diff options
author | Ilya Biryukov <ibiryukov@google.com> | 2018-09-26 05:45:31 +0000 |
---|---|---|
committer | Ilya Biryukov <ibiryukov@google.com> | 2018-09-26 05:45:31 +0000 |
commit | 4f98470deac92aeb7eb6e9cf208bd0b87c99b30d (patch) | |
tree | 53295d5b7716e1129bff89d8c19d83b8f6e56bf4 /clang-tools-extra/clangd/CodeComplete.cpp | |
parent | d8048675f4aad4ea216ad631e6612ae4de1bda87 (diff) | |
download | bcm5719-llvm-4f98470deac92aeb7eb6e9cf208bd0b87c99b30d.tar.gz bcm5719-llvm-4f98470deac92aeb7eb6e9cf208bd0b87c99b30d.zip |
[clangd] Handle template args for disabled function arg snippets
Reviewers: kadircet, ioeric, sammccall
Reviewed By: kadircet
Subscribers: MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D52422
llvm-svn: 343066
Diffstat (limited to 'clang-tools-extra/clangd/CodeComplete.cpp')
-rw-r--r-- | clang-tools-extra/clangd/CodeComplete.cpp | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index ca083964e9c..2328fc601d0 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -482,13 +482,43 @@ private: 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)"; - if (!Snippet->empty() && !EnableFunctionArgSnippets && - ((Completion.Kind == CompletionItemKind::Function) || - (Completion.Kind == CompletionItemKind::Method)) && - (Snippet->front() == '(') && (Snippet->back() == ')')) - // Check whether function has any parameters or not. - return Snippet->size() > 2 ? "($0)" : "()"; + if (EnableFunctionArgSnippets) + return *Snippet; + + // Replace argument snippets with a simplified pattern. + if (Snippet->empty()) + return ""; + if (Completion.Kind == CompletionItemKind::Function || + Completion.Kind == CompletionItemKind::Method) { + // Functions snippets can be of 2 types: + // - containing only function arguments, e.g. + // foo(${1:int p1}, ${2:int p2}); + // We transform this pattern to '($0)' or '()'. + // - template arguments and function arguments, e.g. + // foo<${1:class}>(${2:int p1}). + // We transform this pattern to '<$1>()$0' or '<$0>()'. + + bool EmptyArgs = llvm::StringRef(*Snippet).endswith("()"); + if (Snippet->front() == '<') + return EmptyArgs ? "<$1>()$0" : "<$1>($0)"; + if (Snippet->front() == '(') + return EmptyArgs ? "()" : "($0)"; + return *Snippet; // Not an arg snippet? + } + if (Completion.Kind == CompletionItemKind::Reference || + Completion.Kind == CompletionItemKind::Class) { + if (Snippet->front() != '<') + return *Snippet; // Not an arg snippet? + + // Classes and template using aliases can only have template arguments, + // e.g. Foo<${1:class}>. + if (llvm::StringRef(*Snippet).endswith("<>")) + return "<>"; // can happen with defaulted template arguments. + return "<$0>"; + } return *Snippet; } |