Index: clangd/Quality.h =================================================================== --- clangd/Quality.h +++ clangd/Quality.h @@ -58,6 +58,7 @@ Macro, Type, Function, + Constructor, Namespace, Keyword, } Category = Unknown; Index: clangd/Quality.cpp =================================================================== --- clangd/Quality.cpp +++ clangd/Quality.cpp @@ -67,6 +67,7 @@ MAP(TypeDecl, Type); MAP(TypeAliasTemplateDecl, Type); MAP(ClassTemplateDecl, Type); + MAP(CXXConstructorDecl, Constructor); MAP(ValueDecl, Variable); MAP(VarTemplateDecl, Variable); MAP(FunctionDecl, Function); @@ -96,6 +97,8 @@ return SymbolQualitySignals::Type; case CXCursor_MemberRef: return SymbolQualitySignals::Variable; + case CXCursor_Constructor: + return SymbolQualitySignals::Constructor; default: return SymbolQualitySignals::Keyword; } @@ -124,10 +127,11 @@ case index::SymbolKind::InstanceProperty: case index::SymbolKind::ClassProperty: case index::SymbolKind::StaticProperty: - case index::SymbolKind::Constructor: case index::SymbolKind::Destructor: case index::SymbolKind::ConversionFunction: return SymbolQualitySignals::Function; + case index::SymbolKind::Constructor: + return SymbolQualitySignals::Constructor; case index::SymbolKind::Variable: case index::SymbolKind::Field: case index::SymbolKind::EnumConstant: @@ -210,6 +214,7 @@ Score *= 0.2f; break; case Unknown: + case Constructor: // No boost constructors so they are after class types. break; } Index: unittests/clangd/QualityTests.cpp =================================================================== --- unittests/clangd/QualityTests.cpp +++ unittests/clangd/QualityTests.cpp @@ -23,6 +23,7 @@ #include "TestTU.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "llvm/Support/Casting.h" #include "gmock/gmock.h" @@ -185,13 +186,16 @@ EXPECT_GT(WithReferences.evaluate(), Default.evaluate()); EXPECT_GT(ManyReferences.evaluate(), WithReferences.evaluate()); - SymbolQualitySignals Keyword, Variable, Macro; + SymbolQualitySignals Keyword, Variable, Macro, Constructor, Function; Keyword.Category = SymbolQualitySignals::Keyword; Variable.Category = SymbolQualitySignals::Variable; Macro.Category = SymbolQualitySignals::Macro; + Constructor.Category = SymbolQualitySignals::Constructor; + Function.Category = SymbolQualitySignals::Function; EXPECT_GT(Variable.evaluate(), Default.evaluate()); EXPECT_GT(Keyword.evaluate(), Variable.evaluate()); EXPECT_LT(Macro.evaluate(), Default.evaluate()); + EXPECT_LT(Constructor.evaluate(), Function.evaluate()); } TEST(QualityTests, SymbolRelevanceSignalsSanity) { @@ -317,6 +321,31 @@ EXPECT_TRUE(Rel.IsInstanceMember); } +TEST(QualityTests, ConstructorQuality) { + auto Header = TestTU::withHeaderCode(R"cpp( + class Foo { + public: + Foo(int); + }; + )cpp"); + auto Symbols = Header.headerSymbols(); + auto AST = Header.build(); + + const NamedDecl *CtorDecl = &findAnyDecl(AST, [](const NamedDecl &ND) { + return (ND.getQualifiedNameAsString() == "Foo::Foo") && + llvm::isa(&ND); + }); + + SymbolQualitySignals Q; + Q.merge(CodeCompletionResult(CtorDecl, /*Priority=*/0)); + EXPECT_EQ(Q.Category, SymbolQualitySignals::Constructor); + + Q.Category = SymbolQualitySignals::Unknown; + const Symbol &CtorSym = findSymbol(Symbols, "Foo::Foo"); + Q.merge(CtorSym); + EXPECT_EQ(Q.Category, SymbolQualitySignals::Constructor); +} + } // namespace } // namespace clangd } // namespace clang