[PATCH] D70445: [clangd] Show lambda signature for lambda autocompletions
Kirill Bobyrev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 19 07:56:26 PST 2019
kbobyrev created this revision.
kbobyrev added a reviewer: sammccall.
kbobyrev added projects: clang, clang-tools-extra.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay.
The original bug report can be found here <https://github.com/clangd/clangd/issues/85>.
Given the following code:
c++
void function() {
auto Lambda = [](int a, double &b) {return 1.f;};
La^
}
Triggering the completion at `^` would show `(lambda)` before this patch and would show signature `(int a, double &b) const`, build a snippet etc with this patch.
Repository:
rC Clang
https://reviews.llvm.org/D70445
Files:
clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
clang/lib/Sema/SemaCodeComplete.cpp
Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -3327,6 +3327,26 @@
return Result.TakeString();
}
+namespace {
+const CXXMethodDecl *extractLambdaCallOperator(const NamedDecl *ND) {
+ const auto *VD = dyn_cast<VarDecl>(ND);
+ if (!VD)
+ return nullptr;
+ const auto *LambdaType = VD->getType().getTypePtr();
+ if (const auto *SugaredType = dyn_cast<AutoType>(LambdaType))
+ LambdaType = SugaredType->desugar().getTypePtr();
+ LambdaType = dyn_cast<RecordType>(LambdaType);
+ if (!LambdaType)
+ return nullptr;
+ const auto *RecordDecl = LambdaType->getAsCXXRecordDecl();
+ // FIXME: Don't ignore generic lambdas.
+ return (RecordDecl && RecordDecl->isLambda() &&
+ !RecordDecl->isGenericLambda())
+ ? RecordDecl->getLambdaCallOperator()
+ : nullptr;
+}
+} // namespace
+
CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl(
Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
bool IncludeBriefComments, const CodeCompletionContext &CCContext,
@@ -3351,19 +3371,30 @@
for (const auto *I : ND->specific_attrs<AnnotateAttr>())
Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation()));
- AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result);
-
- if (const auto *Function = dyn_cast<FunctionDecl>(ND)) {
- AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
- Ctx, Policy);
+ auto handleFunctionlike = [&](const FunctionDecl *Function,
+ bool AddQualifier = true) {
+ AddResultTypeChunk(Ctx, Policy, Function, CCContext.getBaseType(), Result);
+ if (AddQualifier)
+ AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
+ Ctx, Policy);
AddTypedNameChunk(Ctx, Policy, ND, Result);
Result.AddChunk(CodeCompletionString::CK_LeftParen);
AddFunctionParameterChunks(PP, Policy, Function, Result);
Result.AddChunk(CodeCompletionString::CK_RightParen);
AddFunctionTypeQualsToCompletionString(Result, Function);
return Result.TakeString();
+ };
+
+ if (const auto *Function = dyn_cast<FunctionDecl>(ND)) {
+ return handleFunctionlike(Function);
}
+ if (const auto *CallOperator = extractLambdaCallOperator(ND)) {
+ return handleFunctionlike(CallOperator, false);
+ }
+
+ AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result);
+
if (const FunctionTemplateDecl *FunTmpl =
dyn_cast<FunctionTemplateDecl>(ND)) {
AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -2471,6 +2471,26 @@
EXPECT_THAT(C, ElementsAre(SnippetSuffix("")));
}
+TEST(CompletionTest, Lambda) {
+ clangd::CodeCompleteOptions Opts = {};
+ Opts.AllScopes = true;
+
+ auto Results = completions(R"cpp(
+ void function() {
+ auto Lambda = [](int a, const double &b) {return 1.f;};
+ Lam^
+ }
+ )cpp", {}, Opts);
+
+ EXPECT_EQ(Results.Completions.size(), 1u);
+ const auto A = Results.Completions.front();
+ EXPECT_EQ(A.Name, "Lambda");
+ EXPECT_EQ(A.Signature, "(int a, const double &b) const");
+ EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
+ EXPECT_EQ(A.ReturnType, "float");
+ EXPECT_EQ(A.SnippetSuffix, "(${1:int a}, ${2:const double &b})");
+}
+
TEST(CompletionTest, ObjectiveCMethodOneArgument) {
auto Results = completions(R"objc(
@interface Foo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70445.230072.patch
Type: text/x-patch
Size: 3868 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191119/665bbfd5/attachment-0001.bin>
More information about the cfe-commits
mailing list