zyounan created this revision.
zyounan added reviewers: nridge, tom-anders, sammccall.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
zyounan added a comment.
zyounan updated this revision to Diff 540687.
zyounan published this revision for review.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.

Changing the code completion string to `RK_Pattern` makes the completion 
clearer, in a way that showing candidates with signatures in the completion 
items if `FunctionCanBeCall` while a mere name otherwise.

F28256820: image.png <https://reviews.llvm.org/F28256820>

F28256841: image.png <https://reviews.llvm.org/F28256841>

(Comparing to that we always show signatures even if no parameters are produced 
when hit the item.)

F28256859: image.png <https://reviews.llvm.org/F28256859> -> F28256863: 
image.png <https://reviews.llvm.org/F28256863>

---

P.S. Despite the fact that I changed many associated tests, I still hope people 
don't rely on the former behavior so that this patch could be marked as NFC. :D

I discovered that patch when trying to figure out why clangd doesn't complete 
function parameters for members in global scope while it produces parameters 
when I'm inside a call expression. Regard to the heuristic itself, it's 
currently a bit inconvenient that I have to switch headers and sources back and 
forth and do copy-pastes when I'm writing member function definitions outside 
of a class. I think we could be more lenient here e.g., don't set the flag on 
if we're in the global scope. What do you guys think? (I'm working on another 
follow-up patch to address this, although it is not strightforward to tell 
which scope the building Declarator is in inside Sema. )


zyounan added a comment.

Format


This tries to avoid extra calculations in D137040 
<https://reviews.llvm.org/D137040>.

In that patch the extra completion strings were dropped at the client
site, after function parameters became available, to implement the
heuristic. However, we can make the process a bit more terse. In the
context where a call isn't required, we could teach the Sema to emit
the completion string without additional parameters by changing the Decl
to a Pattern with the function name.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155370

Files:
  clang-tools-extra/clangd/CodeComplete.cpp
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/test/CodeCompletion/member-access.cpp
  clang/test/Index/complete-qualified.cpp
  clang/unittests/Sema/CodeCompleteTest.cpp

Index: clang/unittests/Sema/CodeCompleteTest.cpp
===================================================================
--- clang/unittests/Sema/CodeCompleteTest.cpp
+++ clang/unittests/Sema/CodeCompleteTest.cpp
@@ -59,14 +59,12 @@
                                   unsigned NumResults) override {
     for (unsigned I = 0; I < NumResults; ++I) {
       auto R = Results[I];
-      if (R.Kind == CodeCompletionResult::RK_Declaration) {
-        if (const auto *FD = llvm::dyn_cast<FunctionDecl>(R.getDeclaration())) {
-          CompletedFunctionDecl D;
-          D.Name = FD->getNameAsString();
-          D.CanBeCall = R.FunctionCanBeCall;
-          D.IsStatic = FD->isStatic();
-          CompletedFuncDecls.emplace_back(std::move(D));
-        }
+      if (const auto *FD = llvm::dyn_cast<FunctionDecl>(R.getDeclaration())) {
+        CompletedFunctionDecl D;
+        D.Name = FD->getNameAsString();
+        D.CanBeCall = R.FunctionCanBeCall;
+        D.IsStatic = FD->isStatic();
+        CompletedFuncDecls.emplace_back(std::move(D));
       }
     }
   }
Index: clang/test/Index/complete-qualified.cpp
===================================================================
--- clang/test/Index/complete-qualified.cpp
+++ clang/test/Index/complete-qualified.cpp
@@ -16,5 +16,6 @@
 // RUN: c-index-test -code-completion-at=%s:14:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: FieldDecl:{ResultType C<Foo, class Bar>}{TypedText c} (35)
 // CHECK-CC1: ClassDecl:{TypedText Foo} (35)
-// CHECK-CC1: CXXMethod:{ResultType Foo &}{TypedText operator=}{LeftParen (}{Placeholder const Foo &}{RightParen )}
-// CHECK-CC1: CXXDestructor:{ResultType void}{TypedText ~Foo}{LeftParen (}{RightParen )} (80)
+// CHECK-CC1: CXXMethod:{TypedText operator=} (50)
+// CHECK-CC1: CXXMethod:{TypedText operator=} (50)
+// CHECK-CC1: CXXMethod:{TypedText ~Foo} (50)
Index: clang/test/CodeCompletion/member-access.cpp
===================================================================
--- clang/test/CodeCompletion/member-access.cpp
+++ clang/test/CodeCompletion/member-access.cpp
@@ -171,7 +171,7 @@
 template<typename T>
 void dependentColonColonCompletion() {
   Template<T>::staticFn();
-// CHECK-CC7: function : [#void#]function()
+// CHECK-CC7: Pattern : function
 // CHECK-CC7: Nested : Nested
 // CHECK-CC7: o1 : [#BaseTemplate<int>#]o1
 // CHECK-CC7: o2 : [#BaseTemplate<T>#]o2
Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -1211,6 +1211,13 @@
   R.InBaseClass = true;
 }
 
+static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
+                              const NamedDecl *ND,
+                              CodeCompletionBuilder &Result);
+
+static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
+                                                  const Preprocessor &PP);
+
 enum class OverloadCompare { BothViable, Dominates, Dominated };
 // Will Candidate ever be called on the object, when overloaded with Incumbent?
 // Returns Dominates if Candidate is always called, Dominated if Incumbent is
@@ -1400,10 +1407,29 @@
         return nullptr;
       }();
 
-      R.FunctionCanBeCall =
+      bool FunctionCanBeCall =
           CurrentClassScope &&
           (CurrentClassScope == Method->getParent() ||
            CurrentClassScope->isDerivedFrom(Method->getParent()));
+
+      // Instead of doing calculation for parameters later whose results would
+      // be dropped eventually, we only emit the function name.
+      if (!FunctionCanBeCall) {
+        CodeCompletionBuilder Builder(getAllocator(),
+                                      getCodeCompletionTUInfo());
+        auto &ASTContext = SemaRef.getASTContext();
+        AddTypedNameChunk(
+            ASTContext,
+            getCompletionPrintingPolicy(ASTContext, SemaRef.getPreprocessor()),
+            Method, Builder);
+        Result R(Builder.TakeString(), /*Priority=*/CCP_Declaration,
+                 /*CursorKind=*/CXCursor_CXXMethod,
+                 /*Availability=*/CXAvailability_Available,
+                 /*D=*/Method);
+        R.FunctionCanBeCall = false;
+        AddResult(std::move(R));
+        return;
+      }
     }
   }
 
Index: clang-tools-extra/clangd/CodeComplete.cpp
===================================================================
--- clang-tools-extra/clangd/CodeComplete.cpp
+++ clang-tools-extra/clangd/CodeComplete.cpp
@@ -438,8 +438,6 @@
     if (C.SemaResult) {
       getSignature(*SemaCCS, &S.Signature, &S.SnippetSuffix, C.SemaResult->Kind,
                    C.SemaResult->CursorKind, &Completion.RequiredQualifier);
-      if (!C.SemaResult->FunctionCanBeCall)
-        S.SnippetSuffix.clear();
       S.ReturnType = getReturnType(*SemaCCS);
     } else if (C.IndexResult) {
       S.Signature = std::string(C.IndexResult->Signature);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to