diff options
author | Eric Liu <ioeric@google.com> | 2018-10-17 11:19:02 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2018-10-17 11:19:02 +0000 |
commit | 3fac4ef1fdb4e6b2b4743f33498612c233da325d (patch) | |
tree | f3dbf1cda024228cff98f9e00d8dbd50188144e6 /clang-tools-extra/clangd/FileDistance.cpp | |
parent | e2566b5d877c415f128a9f3d75ef2173bf32c347 (diff) | |
download | bcm5719-llvm-3fac4ef1fdb4e6b2b4743f33498612c233da325d.tar.gz bcm5719-llvm-3fac4ef1fdb4e6b2b4743f33498612c233da325d.zip |
[clangd] Support scope proximity in code completion.
Summary:
This should make all-scope completion more usable. Scope proximity for
indexes will be added in followup patch.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53131
llvm-svn: 344688
Diffstat (limited to 'clang-tools-extra/clangd/FileDistance.cpp')
-rw-r--r-- | clang-tools-extra/clangd/FileDistance.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/clang-tools-extra/clangd/FileDistance.cpp b/clang-tools-extra/clangd/FileDistance.cpp index 2ae9043a0fc..ecf8200f7f2 100644 --- a/clang-tools-extra/clangd/FileDistance.cpp +++ b/clang-tools-extra/clangd/FileDistance.cpp @@ -176,5 +176,46 @@ FileDistance &URIDistance::forScheme(llvm::StringRef Scheme) { return *Delegate; } +static std::pair<std::string, int> scopeToPath(llvm::StringRef Scope) { + SmallVector<StringRef, 4> Split; + Scope.split(Split, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false); + return {"/" + llvm::join(Split, "/"), Split.size()}; +} + +static FileDistance +createScopeFileDistance(llvm::ArrayRef<std::string> QueryScopes) { + FileDistanceOptions Opts; + Opts.UpCost = 2; + Opts.DownCost = 4; + Opts.AllowDownTraversalFromRoot = false; + + StringMap<SourceParams> Sources; + StringRef Preferred = QueryScopes.empty() ? "" : QueryScopes.front().c_str(); + for (StringRef S : QueryScopes) { + SourceParams Param; + // Penalize the global scope even it's preferred, as all projects can define + // symbols in it, and there is pattern where using-namespace is used in + // place of enclosing namespaces (e.g. in implementation files). + if (S == Preferred) + Param.Cost = S == "" ? 2 : 0; + else if (Preferred.startswith(S) && !S.empty()) + continue; // just rely on up-traversals. + else + Param.Cost = S == "" ? 5 : 2; + auto Path = scopeToPath(S); + // The global namespace is not 'near' its children. + Param.MaxUpTraversals = std::max(Path.second - 1, 0); + Sources[Path.first] = std::move(Param); + } + return FileDistance(Sources, Opts); +} + +ScopeDistance::ScopeDistance(llvm::ArrayRef<std::string> QueryScopes) + : Distance(createScopeFileDistance(QueryScopes)) {} + +unsigned ScopeDistance::distance(llvm::StringRef SymbolScope) { + return Distance.distance(scopeToPath(SymbolScope).first); +} + } // namespace clangd } // namespace clang |