diff options
| author | Ilya Biryukov <ibiryukov@google.com> | 2018-11-26 15:38:01 +0000 |
|---|---|---|
| committer | Ilya Biryukov <ibiryukov@google.com> | 2018-11-26 15:38:01 +0000 |
| commit | 647da3e8a5ada3d51b9ca09052c1876f08f4eb0a (patch) | |
| tree | 66f3d37112cff6545e519680dc9ad20a0904814d | |
| parent | f94c8f0d1b96510b851009adf7f741b7313f4c8f (diff) | |
| download | bcm5719-llvm-647da3e8a5ada3d51b9ca09052c1876f08f4eb0a.tar.gz bcm5719-llvm-647da3e8a5ada3d51b9ca09052c1876f08f4eb0a.zip | |
[clangd] Add type boosting in code completion
Reviewers: sammccall, ioeric
Reviewed By: sammccall
Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D52276
llvm-svn: 347562
| -rw-r--r-- | clang-tools-extra/clangd/CodeComplete.cpp | 28 | ||||
| -rw-r--r-- | clang-tools-extra/clangd/Quality.cpp | 7 | ||||
| -rw-r--r-- | clang-tools-extra/clangd/Quality.h | 8 | ||||
| -rw-r--r-- | clang-tools-extra/clangd/index/Index.h | 2 |
4 files changed, 43 insertions, 2 deletions
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index c79f0171761..28cc5837cef 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -24,6 +24,7 @@ #include "CodeCompletionStrings.h" #include "Compiler.h" #include "Diagnostics.h" +#include "ExpectedTypes.h" #include "FileDistance.h" #include "FuzzyMatch.h" #include "Headers.h" @@ -1225,6 +1226,7 @@ class CodeCompleteFlow { std::vector<std::string> QueryScopes; // Initialized once Sema runs. // Initialized once QueryScopes is initialized, if there are scopes. Optional<ScopeDistance> ScopeProximity; + llvm::Optional<OpaqueType> PreferredType; // Initialized once Sema runs. // Whether to query symbols from any scope. Initialized once Sema runs. bool AllScopes = false; // Include-insertion and proximity scoring rely on the include structure. @@ -1302,9 +1304,12 @@ public: Inserter.reset(); // Make sure this doesn't out-live Clang. SPAN_ATTACH(Tracer, "sema_completion_kind", getCompletionKindString(Recorder->CCContext.getKind())); - log("Code complete: sema context {0}, query scopes [{1}] (AnyScope={2})", + log("Code complete: sema context {0}, query scopes [{1}] (AnyScope={2}), " + "expected type {3}", getCompletionKindString(Recorder->CCContext.getKind()), - join(QueryScopes.begin(), QueryScopes.end(), ","), AllScopes); + join(QueryScopes.begin(), QueryScopes.end(), ","), AllScopes, + PreferredType ? Recorder->CCContext.getPreferredType().getAsString() + : "<none>"); }); Recorder = RecorderOwner.get(); @@ -1354,6 +1359,9 @@ private: getQueryScopes(Recorder->CCContext, *Recorder->CCSema, Opts); if (!QueryScopes.empty()) ScopeProximity.emplace(QueryScopes); + PreferredType = + OpaqueType::fromType(Recorder->CCSema->getASTContext(), + Recorder->CCContext.getPreferredType()); // 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. @@ -1492,6 +1500,8 @@ private: Relevance.FileProximityMatch = FileProximity.getPointer(); if (ScopeProximity) Relevance.ScopeProximityMatch = ScopeProximity.getPointer(); + if (PreferredType) + Relevance.HadContextType = true; auto &First = Bundle.front(); if (auto FuzzyScore = fuzzyScore(First)) @@ -1506,10 +1516,24 @@ private: Relevance.merge(*Candidate.IndexResult); Origin |= Candidate.IndexResult->Origin; FromIndex = true; + if (!Candidate.IndexResult->Type.empty()) + Relevance.HadSymbolType |= true; + if (PreferredType && + PreferredType->raw() == Candidate.IndexResult->Type) { + Relevance.TypeMatchesPreferred = true; + } } if (Candidate.SemaResult) { Quality.merge(*Candidate.SemaResult); Relevance.merge(*Candidate.SemaResult); + if (PreferredType) { + if (auto CompletionType = OpaqueType::fromCompletionResult( + Recorder->CCSema->getASTContext(), *Candidate.SemaResult)) { + Relevance.HadSymbolType |= true; + if (PreferredType == CompletionType) + Relevance.TypeMatchesPreferred = true; + } + } Origin |= SymbolOrigin::AST; } } diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp index 640f543275d..cb1f64adabc 100644 --- a/clang-tools-extra/clangd/Quality.cpp +++ b/clang-tools-extra/clangd/Quality.cpp @@ -369,6 +369,9 @@ float SymbolRelevanceSignals::evaluate() const { } } + if (TypeMatchesPreferred) + Score *= 5.0; + // Penalize non-instance members when they are accessed via a class instance. if (!IsInstanceMember && (Context == CodeCompletionContext::CCC_DotMemberAccess || @@ -412,6 +415,10 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolRelevanceSignals &S) { OS << formatv("\tIndex scope boost: {0}\n", scopeBoost(*S.ScopeProximityMatch, S.SymbolScope)); + OS << formatv( + "\tType matched preferred: {0} (Context type: {1}, Symbol type: {2}\n", + S.TypeMatchesPreferred, S.HadContextType, S.HadSymbolType); + return OS; } diff --git a/clang-tools-extra/clangd/Quality.h b/clang-tools-extra/clangd/Quality.h index d7185564077..f85e427fbe1 100644 --- a/clang-tools-extra/clangd/Quality.h +++ b/clang-tools-extra/clangd/Quality.h @@ -28,6 +28,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_QUALITY_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_QUALITY_H +#include "ExpectedTypes.h" #include "FileDistance.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "llvm/ADT/ArrayRef.h" @@ -122,6 +123,13 @@ struct SymbolRelevanceSignals { // Whether symbol is an instance member of a class. bool IsInstanceMember = false; + // Whether clang provided a preferred type in the completion context. + bool HadContextType = false; + // Whether a source completion item or a symbol had a type information. + bool HadSymbolType = false; + // Whether the item matches the type expected in the completion context. + bool TypeMatchesPreferred = false; + void merge(const CodeCompletionResult &SemaResult); void merge(const Symbol &IndexResult); diff --git a/clang-tools-extra/clangd/index/Index.h b/clang-tools-extra/clangd/index/Index.h index 0c1d58617dd..11c117613ce 100644 --- a/clang-tools-extra/clangd/index/Index.h +++ b/clang-tools-extra/clangd/index/Index.h @@ -494,6 +494,8 @@ struct FuzzyFindRequest { /// Paths should be absolute. std::vector<std::string> ProximityPaths; + // FIXME(ibiryukov): add expected type to the request. + bool operator==(const FuzzyFindRequest &Req) const { return std::tie(Query, Scopes, Limit, RestrictForCodeCompletion, ProximityPaths) == |

