ilya-biryukov created this revision.
ilya-biryukov added reviewers: ioeric, sammccall.
Herald added subscribers: mgrang, jkorous, MaskRay, klimek.

This should, arguably, give better ranking.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D46943

Files:
  clangd/AST.cpp
  clangd/AST.h
  clangd/Quality.cpp
  clangd/Quality.h
  unittests/clangd/CodeCompleteTests.cpp

Index: unittests/clangd/CodeCompleteTests.cpp
===================================================================
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -962,6 +962,48 @@
   }
 }
 
+TEST(CompletionTest, BoostCurrentFileDecls) {
+  MockFSProvider FS;
+  FS.Files[testPath("foo.h")] = R"cpp(
+    int test_func_in_header();
+    int test_func_in_header_and_cpp();
+    )cpp";
+
+  MockCompilationDatabase CDB;
+  IgnoreDiagnostics DiagConsumer;
+  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
+  llvm::StringLiteral Text = R"cpp(
+    #include "foo.h"
+    int ::test_func_in_header_and_cpp() {
+    }
+    int test_func_in_cpp();
+
+    int test() {
+      test_func_^
+    }
+  )cpp";
+
+  auto Results =
+      completions(Server, Text, {}, clangd::CodeCompleteOptions()).items;
+  std::sort(Results.begin(), Results.end(),
+            [](const CompletionItem &L, const CompletionItem &R) {
+              return L.sortText < R.sortText;
+            });
+  ASSERT_THAT(Results,
+              UnorderedElementsAre(Named("test_func_in_cpp"),
+                                   Named("test_func_in_header"),
+                                   Named("test_func_in_header_and_cpp")));
+
+  auto &FuncInCpp = Results[0];
+  auto &FuncInHeader = Results[1];
+  auto &FuncInHeaderAndCpp = Results[2];
+
+  EXPECT_LE(FuncInHeader.scoreInfo->finalScore,
+            FuncInCpp.scoreInfo->finalScore);
+  EXPECT_FLOAT_EQ(FuncInHeader.scoreInfo->finalScore,
+                  FuncInHeaderAndCpp.scoreInfo->finalScore);
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clangd/Quality.h
===================================================================
--- clangd/Quality.h
+++ clangd/Quality.h
@@ -47,6 +47,7 @@
   unsigned SemaCCPriority = 0; // 1-80, 1 is best. 0 means absent.
                                // FIXME: this is actually a mix of symbol
                                //        quality and relevance. Untangle this.
+  bool AllDeclsInMainFile = false;
   bool Deprecated = false;
   unsigned References = 0;
 
Index: clangd/Quality.cpp
===================================================================
--- clangd/Quality.cpp
+++ clangd/Quality.cpp
@@ -7,6 +7,7 @@
 //
 //===---------------------------------------------------------------------===//
 #include "Quality.h"
+#include "AST.h"
 #include "index/Index.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/Support/FormatVariadic.h"
@@ -19,7 +20,8 @@
 
 void SymbolQualitySignals::merge(const CodeCompletionResult &SemaCCResult) {
   SemaCCPriority = SemaCCResult.Priority;
-
+  if (SemaCCResult.Declaration)
+    AllDeclsInMainFile = allDeclsInMainFile(SemaCCResult.Declaration);
   if (SemaCCResult.Availability == CXAvailability_Deprecated)
     Deprecated = true;
 }
@@ -41,6 +43,10 @@
     // Priority 80 is a really bad score.
     Score *= 2 - std::min<float>(80, SemaCCPriority) / 40;
 
+  // Things declared in the main file get a large boost.
+  if (AllDeclsInMainFile)
+    Score *= 2;
+
   if (Deprecated)
     Score *= 0.1;
 
Index: clangd/AST.h
===================================================================
--- clangd/AST.h
+++ clangd/AST.h
@@ -26,7 +26,10 @@
 ///
 /// The returned location is usually the spelling location where the name of the
 /// decl occurs in the code.
-SourceLocation findNameLoc(const clang::Decl* D);
+SourceLocation findNameLoc(const Decl *D);
+
+/// Returns true iff all redecls of \p D are in the main file.
+bool allDeclsInMainFile(const Decl *D);
 
 } // namespace clangd
 } // namespace clang
Index: clangd/AST.cpp
===================================================================
--- clangd/AST.cpp
+++ clangd/AST.cpp
@@ -17,8 +17,8 @@
 namespace clangd {
 using namespace llvm;
 
-SourceLocation findNameLoc(const clang::Decl* D) {
-  const auto& SM = D->getASTContext().getSourceManager();
+SourceLocation findNameLoc(const Decl *D) {
+  const auto &SM = D->getASTContext().getSourceManager();
   // FIXME: Revisit the strategy, the heuristic is limitted when handling
   // macros, we should use the location where the whole definition occurs.
   SourceLocation SpellingLoc = SM.getSpellingLoc(D->getLocation());
@@ -38,5 +38,15 @@
   return SpellingLoc;
 }
 
+bool allDeclsInMainFile(const Decl *D) {
+  const SourceManager &SM = D->getASTContext().getSourceManager();
+  for (auto *Redecl : D->redecls()) {
+    auto Loc = Redecl->getLocation();
+    if (!SM.isWrittenInMainFile(Loc))
+      return false;
+  }
+  return true;
+}
+
 } // namespace clangd
 } // namespace clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to