Index: clang-tools-extra/trunk/clangd/Quality.h =================================================================== --- clang-tools-extra/trunk/clangd/Quality.h +++ clang-tools-extra/trunk/clangd/Quality.h @@ -50,12 +50,13 @@ unsigned References = 0; enum SymbolCategory { + Unknown = 0, Variable, Macro, Type, Function, Namespace, - Unknown, + Keyword, } Category = Unknown; void merge(const CodeCompletionResult &SemaCCResult); Index: clang-tools-extra/trunk/clangd/Quality.cpp =================================================================== --- clang-tools-extra/trunk/clangd/Quality.cpp +++ clang-tools-extra/trunk/clangd/Quality.cpp @@ -59,6 +59,29 @@ return Switch().Visit(&ND); } +static SymbolQualitySignals::SymbolCategory categorize(const CodeCompletionResult &R) { + if (R.Declaration) + return categorize(*R.Declaration); + if (R.Kind == CodeCompletionResult::RK_Macro) + return SymbolQualitySignals::Macro; + // Everything else is a keyword or a pattern. Patterns are mostly keywords + // too, except a few which we recognize by cursor kind. + switch (R.CursorKind) { + case CXCursor_CXXMethod: + return SymbolQualitySignals::Function; + case CXCursor_ModuleImportDecl: + return SymbolQualitySignals::Namespace; + case CXCursor_MacroDefinition: + return SymbolQualitySignals::Macro; + case CXCursor_TypeRef: + return SymbolQualitySignals::Type; + case CXCursor_MemberRef: + return SymbolQualitySignals::Variable; + default: + return SymbolQualitySignals::Keyword; + } +} + static SymbolQualitySignals::SymbolCategory categorize(const index::SymbolInfo &D) { switch (D.Kind) { @@ -103,10 +126,7 @@ if (SemaCCResult.Availability == CXAvailability_Deprecated) Deprecated = true; - if (SemaCCResult.Declaration) - Category = categorize(*SemaCCResult.Declaration); - else if (SemaCCResult.Kind == CodeCompletionResult::RK_Macro) - Category = Macro; + Category = categorize(SemaCCResult); if (SemaCCResult.Declaration) { if (auto *ID = SemaCCResult.Declaration->getIdentifier()) @@ -135,6 +155,9 @@ Score *= 0.1f; switch (Category) { + case Keyword: // Usually relevant, but misses most signals. + Score *= 10; + break; case Type: case Function: case Variable: Index: clang-tools-extra/trunk/unittests/clangd/QualityTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clangd/QualityTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/QualityTests.cpp @@ -58,6 +58,10 @@ EXPECT_FALSE(Quality.ReservedName); EXPECT_EQ(Quality.References, SymbolQualitySignals().References); EXPECT_EQ(Quality.Category, SymbolQualitySignals::Function); + + Quality = {}; + Quality.merge(CodeCompletionResult("if")); + EXPECT_EQ(Quality.Category, SymbolQualitySignals::Keyword); } TEST(QualityTests, SymbolRelevanceSignalExtraction) { @@ -125,10 +129,12 @@ EXPECT_GT(WithReferences.evaluate(), Default.evaluate()); EXPECT_GT(ManyReferences.evaluate(), WithReferences.evaluate()); - SymbolQualitySignals Variable, Macro; + SymbolQualitySignals Keyword, Variable, Macro; + Keyword.Category = SymbolQualitySignals::Keyword; Variable.Category = SymbolQualitySignals::Variable; Macro.Category = SymbolQualitySignals::Macro; EXPECT_GT(Variable.evaluate(), Default.evaluate()); + EXPECT_GT(Keyword.evaluate(), Variable.evaluate()); EXPECT_LT(Macro.evaluate(), Default.evaluate()); }