From 3fac4ef1fdb4e6b2b4743f33498612c233da325d Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 17 Oct 2018 11:19:02 +0000 Subject: [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 --- clang-tools-extra/clangd/FileDistance.cpp | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'clang-tools-extra/clangd/FileDistance.cpp') 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 scopeToPath(llvm::StringRef Scope) { + SmallVector Split; + Scope.split(Split, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false); + return {"/" + llvm::join(Split, "/"), Split.size()}; +} + +static FileDistance +createScopeFileDistance(llvm::ArrayRef QueryScopes) { + FileDistanceOptions Opts; + Opts.UpCost = 2; + Opts.DownCost = 4; + Opts.AllowDownTraversalFromRoot = false; + + StringMap 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 QueryScopes) + : Distance(createScopeFileDistance(QueryScopes)) {} + +unsigned ScopeDistance::distance(llvm::StringRef SymbolScope) { + return Distance.distance(scopeToPath(SymbolScope).first); +} + } // namespace clangd } // namespace clang -- cgit v1.2.3