[clang-tools-extra] r335334 - [clangd] Expose qualified symbol names in CompletionItem (C++ structure only, no json).
Eric Liu via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 22 03:46:59 PDT 2018
Author: ioeric
Date: Fri Jun 22 03:46:59 2018
New Revision: 335334
URL: http://llvm.org/viewvc/llvm-project?rev=335334&view=rev
Log:
[clangd] Expose qualified symbol names in CompletionItem (C++ structure only, no json).
Summary:
The qualified name can be used to match a completion item to its corresponding
symbol. This can be useful for tools that measure code completion quality.
Qualified names are not precise for identifying symbols; we need to figure out a
better way to identify completion items.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, cfe-commits
Differential Revision: https://reviews.llvm.org/D48425
Modified:
clang-tools-extra/trunk/clangd/AST.cpp
clang-tools-extra/trunk/clangd/AST.h
clang-tools-extra/trunk/clangd/CodeComplete.cpp
clang-tools-extra/trunk/clangd/Protocol.h
clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp
clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
Modified: clang-tools-extra/trunk/clangd/AST.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/AST.cpp?rev=335334&r1=335333&r2=335334&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/AST.cpp (original)
+++ clang-tools-extra/trunk/clangd/AST.cpp Fri Jun 22 03:46:59 2018
@@ -38,5 +38,20 @@ SourceLocation findNameLoc(const clang::
return SpellingLoc;
}
+std::string printQualifiedName(const NamedDecl &ND) {
+ std::string QName;
+ llvm::raw_string_ostream OS(QName);
+ PrintingPolicy Policy(ND.getASTContext().getLangOpts());
+ // Note that inline namespaces are treated as transparent scopes. This
+ // reflects the way they're most commonly used for lookup. Ideally we'd
+ // include them, but at query time it's hard to find all the inline
+ // namespaces to query: the preamble doesn't have a dedicated list.
+ Policy.SuppressUnwrittenScope = true;
+ ND.printQualifiedName(OS, Policy);
+ OS.flush();
+ assert(!StringRef(QName).startswith("::"));
+ return QName;
+}
+
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/AST.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/AST.h?rev=335334&r1=335333&r2=335334&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/AST.h (original)
+++ clang-tools-extra/trunk/clangd/AST.h Fri Jun 22 03:46:59 2018
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_
+#include "clang/AST/Decl.h"
#include "clang/Basic/SourceLocation.h"
namespace clang {
@@ -28,6 +29,10 @@ namespace clangd {
/// decl occurs in the code.
SourceLocation findNameLoc(const clang::Decl *D);
+/// Returns the qualified name of ND. The scope doesn't contain unwritten scopes
+/// like inline namespaces.
+std::string printQualifiedName(const NamedDecl &ND);
+
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=335334&r1=335333&r2=335334&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Fri Jun 22 03:46:59 2018
@@ -19,6 +19,7 @@
//===---------------------------------------------------------------------===//
#include "CodeComplete.h"
+#include "AST.h"
#include "CodeCompletionStrings.h"
#include "Compiler.h"
#include "FuzzyMatch.h"
@@ -243,6 +244,8 @@ struct CompletionCandidate {
const IncludeInserter &Includes,
llvm::StringRef SemaDocComment) const {
assert(bool(SemaResult) == bool(SemaCCS));
+ assert(SemaResult || IndexResult);
+
CompletionItem I;
bool InsertingInclude = false; // Whether a new #include will be added.
if (SemaResult) {
@@ -253,8 +256,14 @@ struct CompletionCandidate {
I.filterText = Text;
I.documentation = formatDocumentation(*SemaCCS, SemaDocComment);
I.detail = getDetail(*SemaCCS);
+ if (SemaResult->Kind == CodeCompletionResult::RK_Declaration)
+ if (const auto *D = SemaResult->getDeclaration())
+ if (const auto *ND = llvm::dyn_cast<NamedDecl>(D))
+ I.SymbolScope = splitQualifiedName(printQualifiedName(*ND)).first;
}
if (IndexResult) {
+ if (I.SymbolScope.empty())
+ I.SymbolScope = IndexResult->Scope;
if (I.kind == CompletionItemKind::Missing)
I.kind = toCompletionItemKind(IndexResult->SymInfo.Kind);
// FIXME: reintroduce a way to show the index source for debugging.
Modified: clang-tools-extra/trunk/clangd/Protocol.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=335334&r1=335333&r2=335334&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.h (original)
+++ clang-tools-extra/trunk/clangd/Protocol.h Fri Jun 22 03:46:59 2018
@@ -734,6 +734,12 @@ struct CompletionItem {
//
// data?: any - A data entry field that is preserved on a completion item
// between a completion and a completion resolve request.
+
+ // C++ extension that is only expected to be used by users of ClangdServer's
+ // C++ API. Not serialized from/to json.
+ /// The containing scope (e.g. namespace) of the symbol this item corresponds
+ /// to, e.g. "" (global scope), "ns::" (top-level namespace).
+ std::string SymbolScope;
};
json::Expr toJSON(const CompletionItem &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CompletionItem &);
Modified: clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp?rev=335334&r1=335333&r2=335334&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp Fri Jun 22 03:46:59 2018
@@ -363,20 +363,9 @@ const Symbol *SymbolCollector::addDeclar
auto &Ctx = ND.getASTContext();
auto &SM = Ctx.getSourceManager();
- std::string QName;
- llvm::raw_string_ostream OS(QName);
- PrintingPolicy Policy(ASTCtx->getLangOpts());
- // Note that inline namespaces are treated as transparent scopes. This
- // reflects the way they're most commonly used for lookup. Ideally we'd
- // include them, but at query time it's hard to find all the inline
- // namespaces to query: the preamble doesn't have a dedicated list.
- Policy.SuppressUnwrittenScope = true;
- ND.printQualifiedName(OS, Policy);
- OS.flush();
- assert(!StringRef(QName).startswith("::"));
-
Symbol S;
S.ID = std::move(ID);
+ std::string QName = printQualifiedName(ND);
std::tie(S.Scope, S.Name) = splitQualifiedName(QName);
// FIXME: this returns foo:bar: for objective-C methods, we prefer only foo:
// for consistency with CodeCompletionString and a clean name/signature split.
Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=335334&r1=335333&r2=335334&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Fri Jun 22 03:46:59 2018
@@ -44,6 +44,7 @@ class IgnoreDiagnostics : public Diagnos
// GMock helpers for matching completion items.
MATCHER_P(Named, Name, "") { return arg.insertText == Name; }
+MATCHER_P(Scope, Name, "") { return arg.SymbolScope == Name; }
MATCHER_P(Labeled, Label, "") {
std::string Indented;
if (!StringRef(Label).startswith(
@@ -1251,6 +1252,17 @@ TEST(CompletionTest, CompleteOnInvalidLi
Failed());
}
+TEST(CompletionTest, QualifiedNames) {
+ auto Results = completions(
+ R"cpp(
+ namespace ns { int local; void both(); }
+ void f() { ::ns::^ }
+ )cpp",
+ {func("ns::both"), cls("ns::Index")});
+ // We get results from both index and sema, with no duplicates.
+ EXPECT_THAT(Results.items, UnorderedElementsAre(Scope("ns::"), Scope("ns::"),
+ Scope("ns::")));
+}
} // namespace
} // namespace clangd
More information about the cfe-commits
mailing list