summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/FileDistance.cpp
diff options
context:
space:
mode:
authorEric Liu <ioeric@google.com>2018-10-17 11:19:02 +0000
committerEric Liu <ioeric@google.com>2018-10-17 11:19:02 +0000
commit3fac4ef1fdb4e6b2b4743f33498612c233da325d (patch)
treef3dbf1cda024228cff98f9e00d8dbd50188144e6 /clang-tools-extra/clangd/FileDistance.cpp
parente2566b5d877c415f128a9f3d75ef2173bf32c347 (diff)
downloadbcm5719-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.cpp41
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
OpenPOWER on IntegriCloud