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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits