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