Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -23,6 +23,7 @@ #include "CodeCompletionStrings.h" #include "Compiler.h" #include "Diagnostics.h" +#include "ExpectedTypes.h" #include "FileDistance.h" #include "FuzzyMatch.h" #include "Headers.h" @@ -1224,6 +1225,7 @@ bool Incomplete = false; // Would more be available with a higher limit? llvm::Optional Filter; // Initialized once Sema runs. std::vector QueryScopes; // Initialized once Sema runs. + llvm::DenseMap ExpectedTypes; // Initialized once Sema runs. // Include-insertion and proximity scoring rely on the include structure. // This is available after Sema has run. llvm::Optional Inserter; // Available during runWithSema. @@ -1349,6 +1351,10 @@ Recorder->CCSema->getPreprocessor().getCodeCompletionFilter()); QueryScopes = getQueryScopes(Recorder->CCContext, Recorder->CCSema->getSourceManager()); + ExpectedTypes = + SType::forCopyInitOf(Recorder->CCSema->getASTContext(), + Recorder->CCContext.getPreferredType()); + vlog("Added {0} expected types", ExpectedTypes.size()); // Sema provides the needed context to query the index. // FIXME: in addition to querying for extra/overlapping symbols, we should // explicitly request symbols corresponding to Sema results. @@ -1511,10 +1517,32 @@ Relevance.merge(*Candidate.IndexResult); Origin |= Candidate.IndexResult->Origin; FromIndex = true; + if (!ExpectedTypes.empty()) { + // FIXME(ibiryukov): this should live in Quality.cpp + auto TypeMatchMult = + typesMatch(ExpectedTypes, Candidate.IndexResult->Types); + if (TypeMatchMult) { + vlog("Types matched in sema for {0}", Candidate.Name); + Relevance.TypeMatchMultiplier = + std::max(*TypeMatchMult, Relevance.TypeMatchMultiplier); + } + } } if (Candidate.SemaResult) { Quality.merge(*Candidate.SemaResult); Relevance.merge(*Candidate.SemaResult); + if (!ExpectedTypes.empty()) { + // FIXME(ibiryukov): this should live in Quality.cpp + auto TypeMatchMult = typesMatch( + ExpectedTypes, + SType::fromCompletionResult(Recorder->CCSema->getASTContext(), + *Candidate.SemaResult)); + if (TypeMatchMult) { + vlog("Types matched in sema for {0}", Candidate.Name); + Relevance.TypeMatchMultiplier = + std::max(*TypeMatchMult, Relevance.TypeMatchMultiplier); + } + } Origin |= SymbolOrigin::AST; } } Index: clangd/Quality.h =================================================================== --- clangd/Quality.h +++ clangd/Quality.h @@ -27,7 +27,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_QUALITY_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_QUALITY_H - +#include "ExpectedTypes.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -90,6 +90,8 @@ /// This is used to calculate proximity between the index symbol and the /// query. llvm::StringRef SymbolURI; + /// A multiplier to be applied due to matching type. + float TypeMatchMultiplier = 1.0; /// Proximity between best declaration and the query. [0-1], 1 is closest. /// FIXME: unify with index proximity score - signals should be /// source-independent. Index: clangd/Quality.cpp =================================================================== --- clangd/Quality.cpp +++ clangd/Quality.cpp @@ -348,6 +348,8 @@ if (NeedsFixIts) Score *= 0.5; + Score *= TypeMatchMultiplier; + return Score; }