ilya-biryukov updated this revision to Diff 148381.
ilya-biryukov added a comment.
- Simplify the change by boosting any Decls that have a redecl in the current
file
Repository:
rCTE Clang Tools Extra
https://reviews.llvm.org/D46943
Files:
clangd/Quality.cpp
clangd/Quality.h
unittests/clangd/QualityTests.cpp
unittests/clangd/TestTU.cpp
Index: unittests/clangd/TestTU.cpp
===================================================================
--- unittests/clangd/TestTU.cpp
+++ unittests/clangd/TestTU.cpp
@@ -1,5 +1,4 @@
-//===--- TestTU.cpp - Scratch source files for testing ------------*-
-//C++-*-===//
+//===--- TestTU.cpp - Scratch source files for testing -------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -78,11 +77,11 @@
auto *ND = dyn_cast<NamedDecl>(D);
if (!ND || ND->getNameAsString() != QName)
continue;
- if (Result) {
+ if (Result && ND->getCanonicalDecl() != Result) {
ADD_FAILURE() << "Multiple Decls named " << QName;
assert(false && "QName is not unique");
}
- Result = ND;
+ Result = cast<NamedDecl>(ND->getCanonicalDecl());
}
if (!Result) {
ADD_FAILURE() << "No Decl named " << QName << " in AST";
Index: unittests/clangd/QualityTests.cpp
===================================================================
--- unittests/clangd/QualityTests.cpp
+++ unittests/clangd/QualityTests.cpp
@@ -118,6 +118,45 @@
EXPECT_LT(sortText(0, "a"), sortText(0, "z"));
}
+TEST(QualityTests, BoostCurrentFileDecls) {
+ TestTU Test;
+ Test.HeaderFilename = "foo.h";
+ Test.HeaderCode = R"cpp(
+ int test_func_in_header();
+ int test_func_in_header_and_cpp();
+ )cpp";
+ Test.Code = R"cpp(
+ #include "foo.h"
+ int ::test_func_in_header_and_cpp() {
+ }
+ int test_func_in_cpp();
+ )cpp";
+
+ ParsedAST AST = Test.build();
+
+ SymbolQualitySignals FuncInCpp;
+ FuncInCpp.merge(CodeCompletionResult(&findDecl(AST, "test_func_in_cpp"),
+ CCP_Declaration));
+ /// Decls in the current file should get a proximity score of 1.0.
+ EXPECT_FLOAT_EQ(FuncInCpp.ProximityScore, 1.0);
+
+ SymbolQualitySignals FuncInHeader;
+ FuncInHeader.merge(CodeCompletionResult(&findDecl(AST, "test_func_in_header"),
+ CCP_Declaration));
+ /// Decls outside current file currently don't get a proximity score boost.
+ EXPECT_FLOAT_EQ(FuncInHeader.ProximityScore, 0.0);
+
+ SymbolQualitySignals FuncInHeaderAndCpp;
+ FuncInHeaderAndCpp.merge(CodeCompletionResult(
+ &findDecl(AST, "test_func_in_header_and_cpp"), CCP_Declaration));
+ /// Decls in both header **and** the main file get the same boost.
+ EXPECT_FLOAT_EQ(FuncInHeaderAndCpp.ProximityScore, 1.0);
+
+ /// Check the boost in proximity translates into a better score.
+ EXPECT_LE(FuncInHeader.evaluate(), FuncInCpp.evaluate());
+ EXPECT_FLOAT_EQ(FuncInHeaderAndCpp.evaluate(), FuncInCpp.evaluate());
+}
+
} // namespace
} // namespace clangd
} // namespace clang
Index: clangd/Quality.h
===================================================================
--- clangd/Quality.h
+++ clangd/Quality.h
@@ -49,6 +49,7 @@
// quality and relevance. Untangle this.
bool Deprecated = false;
unsigned References = 0;
+ float ProximityScore = 0.0; /// Proximity score, in a [0,1] interval.
void merge(const CodeCompletionResult &SemaCCResult);
void merge(const Symbol &IndexResult);
Index: clangd/Quality.cpp
===================================================================
--- clangd/Quality.cpp
+++ clangd/Quality.cpp
@@ -8,6 +8,8 @@
//===---------------------------------------------------------------------===//
#include "Quality.h"
#include "index/Index.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
@@ -17,9 +19,27 @@
namespace clangd {
using namespace llvm;
+namespace {
+bool hasDeclInMainFile(const Decl &D) {
+ auto &SourceMgr = D.getASTContext().getSourceManager();
+ for (auto *Redecl : D.redecls()) {
+ auto Loc = SourceMgr.getSpellingLoc(Redecl->getLocation());
+ if (SourceMgr.isWrittenInMainFile(Loc))
+ return true;
+ }
+ return false;
+}
+} // namespace
+
void SymbolQualitySignals::merge(const CodeCompletionResult &SemaCCResult) {
SemaCCPriority = SemaCCResult.Priority;
-
+ if (SemaCCResult.Declaration) {
+ // We boost things that have decls in the main file.
+ // The real proximity scores would be more general when we have them.
+ float DeclProximity =
+ hasDeclInMainFile(*SemaCCResult.Declaration) ? 1.0 : 0.0;
+ ProximityScore = std::max(DeclProximity, ProximityScore);
+ }
if (SemaCCResult.Availability == CXAvailability_Deprecated)
Deprecated = true;
}
@@ -41,6 +61,10 @@
// Priority 80 is a really bad score.
Score *= 2 - std::min<float>(80, SemaCCPriority) / 40;
+ // Proximity scores are [0,1] and we translate them into a multiplier in the
+ // range from 1 to 2.
+ Score *= 1 + ProximityScore;
+
if (Deprecated)
Score *= 0.1f;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits