[clang-tools-extra] r335360 - [clangd] More precise representation of symbol names/labels in the index.
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 22 09:11:35 PDT 2018
Author: sammccall
Date: Fri Jun 22 09:11:35 2018
New Revision: 335360
URL: http://llvm.org/viewvc/llvm-project?rev=335360&view=rev
Log:
[clangd] More precise representation of symbol names/labels in the index.
Summary:
Previously, the strings matched LSP completion pretty closely.
The completion label was a single string, for instance. This made
implementing completion itself easy but makes it hard to use the names
in other way, e.g. pretty-printed name in synthesized
documentation/hover.
It also limits our introspection into completion items, which can only
be as precise as the indexed symbols. This change is a prerequisite to
improvements to overload bundling which need to inspect e.g. signature
structure.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, cfe-commits
Differential Revision: https://reviews.llvm.org/D48475
Modified:
clang-tools-extra/trunk/clangd/CodeComplete.cpp
clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp
clang-tools-extra/trunk/clangd/CodeCompletionStrings.h
clang-tools-extra/trunk/clangd/index/Index.cpp
clang-tools-extra/trunk/clangd/index/Index.h
clang-tools-extra/trunk/clangd/index/Merge.cpp
clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp
clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
clang-tools-extra/trunk/unittests/clangd/CodeCompletionStringsTests.cpp
clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp
clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp
Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Fri Jun 22 09:11:35 2018
@@ -249,17 +249,21 @@ struct CompletionCandidate {
CompletionItem I;
bool InsertingInclude = false; // Whether a new #include will be added.
if (SemaResult) {
- I.kind = toCompletionItemKind(SemaResult->Kind, SemaResult->Declaration);
- getLabelAndInsertText(*SemaCCS, &I.label, &I.insertText,
- Opts.EnableSnippets);
- if (const char* Text = SemaCCS->getTypedText())
- I.filterText = Text;
+ llvm::StringRef Name(SemaCCS->getTypedText());
+ std::string Signature, SnippetSuffix, Qualifiers;
+ getSignature(*SemaCCS, &Signature, &SnippetSuffix, &Qualifiers);
+ I.label = (Qualifiers + Name + Signature).str();
+ I.filterText = Name;
+ I.insertText = (Qualifiers + Name).str();
+ if (Opts.EnableSnippets)
+ I.insertText += SnippetSuffix;
I.documentation = formatDocumentation(*SemaCCS, SemaDocComment);
- I.detail = getDetail(*SemaCCS);
+ I.detail = getReturnType(*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;
+ I.kind = toCompletionItemKind(SemaResult->Kind, SemaResult->Declaration);
}
if (IndexResult) {
if (I.SymbolScope.empty())
@@ -268,21 +272,22 @@ struct CompletionCandidate {
I.kind = toCompletionItemKind(IndexResult->SymInfo.Kind);
// FIXME: reintroduce a way to show the index source for debugging.
if (I.label.empty())
- I.label = IndexResult->CompletionLabel;
+ I.label = (IndexResult->Name + IndexResult->Signature).str();
if (I.filterText.empty())
I.filterText = IndexResult->Name;
// FIXME(ioeric): support inserting/replacing scope qualifiers.
- if (I.insertText.empty())
- I.insertText = Opts.EnableSnippets
- ? IndexResult->CompletionSnippetInsertText
- : IndexResult->CompletionPlainInsertText;
+ if (I.insertText.empty()) {
+ I.insertText = IndexResult->Name;
+ if (Opts.EnableSnippets)
+ I.insertText += IndexResult->CompletionSnippetSuffix;
+ }
if (auto *D = IndexResult->Detail) {
if (I.documentation.empty())
I.documentation = D->Documentation;
if (I.detail.empty())
- I.detail = D->CompletionDetail;
+ I.detail = D->ReturnType;
if (auto Inserted = headerToInsertIfNotPresent()) {
auto IncludePath = [&]() -> Expected<std::string> {
auto ResolvedDeclaring = toHeaderFile(
Modified: clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp (original)
+++ clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp Fri Jun 22 09:11:35 2018
@@ -24,31 +24,6 @@ bool isInformativeQualifierChunk(CodeCom
StringRef(Chunk.Text).endswith("::");
}
-void processPlainTextChunks(const CodeCompletionString &CCS,
- std::string *LabelOut, std::string *InsertTextOut) {
- std::string &Label = *LabelOut;
- std::string &InsertText = *InsertTextOut;
- for (const auto &Chunk : CCS) {
- // Informative qualifier chunks only clutter completion results, skip
- // them.
- if (isInformativeQualifierChunk(Chunk))
- continue;
-
- switch (Chunk.Kind) {
- case CodeCompletionString::CK_ResultType:
- case CodeCompletionString::CK_Optional:
- break;
- case CodeCompletionString::CK_TypedText:
- InsertText += Chunk.Text;
- Label += Chunk.Text;
- break;
- default:
- Label += Chunk.Text;
- break;
- }
- }
-}
-
void appendEscapeSnippet(const llvm::StringRef Text, std::string *Out) {
for (const auto Character : Text) {
if (Character == '$' || Character == '}' || Character == '\\')
@@ -57,73 +32,6 @@ void appendEscapeSnippet(const llvm::Str
}
}
-void processSnippetChunks(const CodeCompletionString &CCS,
- std::string *LabelOut, std::string *InsertTextOut) {
- std::string &Label = *LabelOut;
- std::string &InsertText = *InsertTextOut;
-
- unsigned ArgCount = 0;
- for (const auto &Chunk : CCS) {
- // Informative qualifier chunks only clutter completion results, skip
- // them.
- if (isInformativeQualifierChunk(Chunk))
- continue;
-
- switch (Chunk.Kind) {
- case CodeCompletionString::CK_TypedText:
- case CodeCompletionString::CK_Text:
- Label += Chunk.Text;
- InsertText += Chunk.Text;
- break;
- case CodeCompletionString::CK_Optional:
- // FIXME: Maybe add an option to allow presenting the optional chunks?
- break;
- case CodeCompletionString::CK_Placeholder:
- ++ArgCount;
- InsertText += "${" + std::to_string(ArgCount) + ':';
- appendEscapeSnippet(Chunk.Text, &InsertText);
- InsertText += '}';
- Label += Chunk.Text;
- break;
- case CodeCompletionString::CK_Informative:
- // For example, the word "const" for a const method, or the name of
- // the base class for methods that are part of the base class.
- Label += Chunk.Text;
- // Don't put the informative chunks in the insertText.
- break;
- case CodeCompletionString::CK_ResultType:
- // This is retrieved as detail.
- break;
- case CodeCompletionString::CK_CurrentParameter:
- // This should never be present while collecting completion items,
- // only while collecting overload candidates.
- llvm_unreachable("Unexpected CK_CurrentParameter while collecting "
- "CompletionItems");
- break;
- case CodeCompletionString::CK_LeftParen:
- case CodeCompletionString::CK_RightParen:
- case CodeCompletionString::CK_LeftBracket:
- case CodeCompletionString::CK_RightBracket:
- case CodeCompletionString::CK_LeftBrace:
- case CodeCompletionString::CK_RightBrace:
- case CodeCompletionString::CK_LeftAngle:
- case CodeCompletionString::CK_RightAngle:
- case CodeCompletionString::CK_Comma:
- case CodeCompletionString::CK_Colon:
- case CodeCompletionString::CK_SemiColon:
- case CodeCompletionString::CK_Equal:
- case CodeCompletionString::CK_HorizontalSpace:
- InsertText += Chunk.Text;
- Label += Chunk.Text;
- break;
- case CodeCompletionString::CK_VerticalSpace:
- InsertText += Chunk.Text;
- // Don't even add a space to the label.
- break;
- }
- }
-}
-
bool canRequestComment(const ASTContext &Ctx, const NamedDecl &D,
bool CommentsFromHeaders) {
if (CommentsFromHeaders)
@@ -199,10 +107,76 @@ getParameterDocComment(const ASTContext
return Doc;
}
-void getLabelAndInsertText(const CodeCompletionString &CCS, std::string *Label,
- std::string *InsertText, bool EnableSnippets) {
- return EnableSnippets ? processSnippetChunks(CCS, Label, InsertText)
- : processPlainTextChunks(CCS, Label, InsertText);
+void getSignature(const CodeCompletionString &CCS, std::string *Signature,
+ std::string *Snippet, std::string *RequiredQualifiers) {
+ unsigned ArgCount = 0;
+ for (const auto &Chunk : CCS) {
+ // Informative qualifier chunks only clutter completion results, skip
+ // them.
+ if (isInformativeQualifierChunk(Chunk))
+ continue;
+
+ switch (Chunk.Kind) {
+ case CodeCompletionString::CK_TypedText:
+ // The typed-text chunk is the actual name. We don't record this chunk.
+ // In general our string looks like <qualifiers><name><signature>.
+ // So once we see the name, any text we recorded so far should be
+ // reclassified as qualifiers.
+ if (RequiredQualifiers)
+ *RequiredQualifiers = std::move(*Signature);
+ Signature->clear();
+ Snippet->clear();
+ break;
+ case CodeCompletionString::CK_Text:
+ *Signature += Chunk.Text;
+ *Snippet += Chunk.Text;
+ break;
+ case CodeCompletionString::CK_Optional:
+ break;
+ case CodeCompletionString::CK_Placeholder:
+ *Signature += Chunk.Text;
+ ++ArgCount;
+ *Snippet += "${" + std::to_string(ArgCount) + ':';
+ appendEscapeSnippet(Chunk.Text, Snippet);
+ *Snippet += '}';
+ break;
+ case CodeCompletionString::CK_Informative:
+ // For example, the word "const" for a const method, or the name of
+ // the base class for methods that are part of the base class.
+ *Signature += Chunk.Text;
+ // Don't put the informative chunks in the snippet.
+ break;
+ case CodeCompletionString::CK_ResultType:
+ // This is not part of the signature.
+ break;
+ case CodeCompletionString::CK_CurrentParameter:
+ // This should never be present while collecting completion items,
+ // only while collecting overload candidates.
+ llvm_unreachable("Unexpected CK_CurrentParameter while collecting "
+ "CompletionItems");
+ break;
+ case CodeCompletionString::CK_LeftParen:
+ case CodeCompletionString::CK_RightParen:
+ case CodeCompletionString::CK_LeftBracket:
+ case CodeCompletionString::CK_RightBracket:
+ case CodeCompletionString::CK_LeftBrace:
+ case CodeCompletionString::CK_RightBrace:
+ case CodeCompletionString::CK_LeftAngle:
+ case CodeCompletionString::CK_RightAngle:
+ case CodeCompletionString::CK_Comma:
+ case CodeCompletionString::CK_Colon:
+ case CodeCompletionString::CK_SemiColon:
+ case CodeCompletionString::CK_Equal:
+ case CodeCompletionString::CK_HorizontalSpace:
+ *Signature += Chunk.Text;
+ *Snippet += Chunk.Text;
+ break;
+ case CodeCompletionString::CK_VerticalSpace:
+ *Snippet += Chunk.Text;
+ // Don't even add a space to the signature.
+ break;
+ }
+ }
}
std::string formatDocumentation(const CodeCompletionString &CCS,
@@ -235,17 +209,10 @@ std::string formatDocumentation(const Co
return Result;
}
-std::string getDetail(const CodeCompletionString &CCS) {
- for (const auto &Chunk : CCS) {
- // Informative qualifier chunks only clutter completion results, skip
- // them.
- switch (Chunk.Kind) {
- case CodeCompletionString::CK_ResultType:
+std::string getReturnType(const CodeCompletionString &CCS) {
+ for (const auto &Chunk : CCS)
+ if (Chunk.Kind == CodeCompletionString::CK_ResultType)
return Chunk.Text;
- default:
- break;
- }
- }
return "";
}
Modified: clang-tools-extra/trunk/clangd/CodeCompletionStrings.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeCompletionStrings.h?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeCompletionStrings.h (original)
+++ clang-tools-extra/trunk/clangd/CodeCompletionStrings.h Fri Jun 22 09:11:35 2018
@@ -45,13 +45,15 @@ getParameterDocComment(const ASTContext
const CodeCompleteConsumer::OverloadCandidate &Result,
unsigned ArgIndex, bool CommentsFromHeaders);
-/// Gets label and insert text for a completion item. For example, for function
-/// `Foo`, this returns <"Foo(int x, int y)", "Foo"> without snippts enabled.
-///
-/// If \p EnableSnippets is true, this will try to use snippet for the insert
-/// text. Otherwise, the insert text will always be plain text.
-void getLabelAndInsertText(const CodeCompletionString &CCS, std::string *Label,
- std::string *InsertText, bool EnableSnippets);
+/// Formats the signature for an item, as a display string and snippet.
+/// e.g. for const_reference std::vector<T>::at(size_type) const, this returns:
+/// *Signature = "(size_type) const"
+/// *Snippet = "(${0:size_type})"
+/// If set, RequiredQualifiers is the text that must be typed before the name.
+/// e.g "Base::" when calling a base class member function that's hidden.
+void getSignature(const CodeCompletionString &CCS, std::string *Signature,
+ std::string *Snippet,
+ std::string *RequiredQualifiers = nullptr);
/// Assembles formatted documentation for a completion result. This includes
/// documentation comments and other relevant information like annotations.
@@ -63,7 +65,7 @@ std::string formatDocumentation(const Co
/// Gets detail to be used as the detail field in an LSP completion item. This
/// is usually the return type of a function.
-std::string getDetail(const CodeCompletionString &CCS);
+std::string getReturnType(const CodeCompletionString &CCS);
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/index/Index.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Index.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/Index.cpp Fri Jun 22 09:11:35 2018
@@ -84,9 +84,8 @@ static void own(Symbol &S, DenseSet<Stri
Intern(S.CanonicalDeclaration.FileURI);
Intern(S.Definition.FileURI);
- Intern(S.CompletionLabel);
- Intern(S.CompletionPlainInsertText);
- Intern(S.CompletionSnippetInsertText);
+ Intern(S.Signature);
+ Intern(S.CompletionSnippetSuffix);
if (S.Detail) {
// Copy values of StringRefs into arena.
@@ -94,7 +93,7 @@ static void own(Symbol &S, DenseSet<Stri
*Detail = *S.Detail;
// Intern the actual strings.
Intern(Detail->Documentation);
- Intern(Detail->CompletionDetail);
+ Intern(Detail->ReturnType);
Intern(Detail->IncludeHeader);
// Replace the detail pointer with our copy.
S.Detail = Detail;
Modified: clang-tools-extra/trunk/clangd/index/Index.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.h?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Index.h (original)
+++ clang-tools-extra/trunk/clangd/index/Index.h Fri Jun 22 09:11:35 2018
@@ -125,6 +125,11 @@ namespace clangd {
// When adding new unowned data fields to Symbol, remember to update:
// - SymbolSlab::Builder in Index.cpp, to copy them to the slab's storage.
// - mergeSymbol in Merge.cpp, to properly combine two Symbols.
+//
+// A fully documented symbol can be split as:
+// size_type std::map<k, t>::count(const K& key) const
+// | Return | Scope |Name| Signature |
+// We split up these components to allow display flexibility later.
struct Symbol {
// The ID of the symbol.
SymbolID ID;
@@ -152,15 +157,13 @@ struct Symbol {
/// Whether or not this symbol is meant to be used for the code completion.
/// See also isIndexedForCodeCompletion().
bool IsIndexedForCodeCompletion = false;
- /// A brief description of the symbol that can be displayed in the completion
- /// candidate list. For example, "Foo(X x, Y y) const" is a label for a
- /// function.
- llvm::StringRef CompletionLabel;
- /// What to insert when completing this symbol (plain text version).
- llvm::StringRef CompletionPlainInsertText;
- /// What to insert when completing this symbol (snippet version). This is
- /// empty if it is the same as the plain insert text above.
- llvm::StringRef CompletionSnippetInsertText;
+ /// A brief description of the symbol that can be appended in the completion
+ /// candidate list. For example, "(X x, Y y) const" is a function signature.
+ llvm::StringRef Signature;
+ /// What to insert when completing this symbol, after the symbol name.
+ /// This is in LSP snippet syntax (e.g. "({$0})" for a no-args function).
+ /// (When snippets are disabled, the symbol name alone is used).
+ llvm::StringRef CompletionSnippetSuffix;
/// Optional symbol details that are not required to be set. For example, an
/// index fuzzy match can return a large number of symbol candidates, and it
@@ -170,9 +173,9 @@ struct Symbol {
struct Details {
/// Documentation including comment for the symbol declaration.
llvm::StringRef Documentation;
- /// This is what goes into the LSP detail field in a completion item. For
- /// example, the result type of a function.
- llvm::StringRef CompletionDetail;
+ /// Type when this symbol is used in an expression. (Short display form).
+ /// e.g. return type of a function, or type of a variable.
+ llvm::StringRef ReturnType;
/// This can be either a URI of the header to be #include'd for this symbol,
/// or a literal header quoted with <> or "" that is suitable to be included
/// directly. When this is a URI, the exact #include path needs to be
Modified: clang-tools-extra/trunk/clangd/index/Merge.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Merge.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Merge.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/Merge.cpp Fri Jun 22 09:11:35 2018
@@ -96,12 +96,10 @@ mergeSymbol(const Symbol &L, const Symbo
if (!S.CanonicalDeclaration)
S.CanonicalDeclaration = O.CanonicalDeclaration;
S.References += O.References;
- if (S.CompletionLabel == "")
- S.CompletionLabel = O.CompletionLabel;
- if (S.CompletionPlainInsertText == "")
- S.CompletionPlainInsertText = O.CompletionPlainInsertText;
- if (S.CompletionSnippetInsertText == "")
- S.CompletionSnippetInsertText = O.CompletionSnippetInsertText;
+ if (S.Signature == "")
+ S.Signature = O.Signature;
+ if (S.CompletionSnippetSuffix == "")
+ S.CompletionSnippetSuffix = O.CompletionSnippetSuffix;
if (O.Detail) {
if (S.Detail) {
@@ -109,8 +107,8 @@ mergeSymbol(const Symbol &L, const Symbo
*Scratch = *S.Detail;
if (Scratch->Documentation == "")
Scratch->Documentation = O.Detail->Documentation;
- if (Scratch->CompletionDetail == "")
- Scratch->CompletionDetail = O.Detail->CompletionDetail;
+ if (Scratch->ReturnType == "")
+ Scratch->ReturnType = O.Detail->ReturnType;
if (Scratch->IncludeHeader == "")
Scratch->IncludeHeader = O.Detail->IncludeHeader;
S.Detail = Scratch;
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=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp Fri Jun 22 09:11:35 2018
@@ -386,18 +386,13 @@ const Symbol *SymbolCollector::addDeclar
*ASTCtx, *PP, CodeCompletionContext::CCC_Name, *CompletionAllocator,
*CompletionTUInfo,
/*IncludeBriefComments*/ false);
- std::string Label;
- std::string SnippetInsertText;
- std::string IgnoredLabel;
- std::string PlainInsertText;
- getLabelAndInsertText(*CCS, &Label, &SnippetInsertText,
- /*EnableSnippets=*/true);
- getLabelAndInsertText(*CCS, &IgnoredLabel, &PlainInsertText,
- /*EnableSnippets=*/false);
+ std::string Signature;
+ std::string SnippetSuffix;
+ getSignature(*CCS, &Signature, &SnippetSuffix);
std::string Documentation =
formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
/*CommentsFromHeaders=*/true));
- std::string CompletionDetail = getDetail(*CCS);
+ std::string ReturnType = getReturnType(*CCS);
std::string Include;
if (Opts.CollectIncludePath && shouldCollectIncludePath(S.SymInfo.Kind)) {
@@ -407,12 +402,11 @@ const Symbol *SymbolCollector::addDeclar
QName, SM, SM.getExpansionLoc(ND.getLocation()), Opts))
Include = std::move(*Header);
}
- S.CompletionLabel = Label;
- S.CompletionPlainInsertText = PlainInsertText;
- S.CompletionSnippetInsertText = SnippetInsertText;
+ S.Signature = Signature;
+ S.CompletionSnippetSuffix = SnippetSuffix;
Symbol::Details Detail;
Detail.Documentation = Documentation;
- Detail.CompletionDetail = CompletionDetail;
+ Detail.ReturnType = ReturnType;
Detail.IncludeHeader = Include;
S.Detail = &Detail;
Modified: clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp Fri Jun 22 09:11:35 2018
@@ -69,7 +69,7 @@ template <> struct MappingTraits<SymbolI
template <> struct MappingTraits<Symbol::Details> {
static void mapping(IO &io, Symbol::Details &Detail) {
io.mapOptional("Documentation", Detail.Documentation);
- io.mapOptional("CompletionDetail", Detail.CompletionDetail);
+ io.mapOptional("ReturnType", Detail.ReturnType);
io.mapOptional("IncludeHeader", Detail.IncludeHeader);
}
};
@@ -110,11 +110,8 @@ template <> struct MappingTraits<Symbol>
IO.mapOptional("References", Sym.References, 0u);
IO.mapOptional("IsIndexedForCodeCompletion", Sym.IsIndexedForCodeCompletion,
false);
- IO.mapRequired("CompletionLabel", Sym.CompletionLabel);
- IO.mapRequired("CompletionPlainInsertText", Sym.CompletionPlainInsertText);
-
- IO.mapOptional("CompletionSnippetInsertText",
- Sym.CompletionSnippetInsertText);
+ IO.mapOptional("Signature", Sym.Signature);
+ IO.mapOptional("CompletionSnippetSuffix", Sym.CompletionSnippetSuffix);
IO.mapOptional("Detail", NDetail->Opt);
}
};
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=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Fri Jun 22 09:11:35 2018
@@ -164,9 +164,6 @@ Symbol sym(StringRef QName, index::Symbo
}
USR += Regex("^.*$").sub(USRFormat, Sym.Name); // e.g. func -> @F at func#
Sym.ID = SymbolID(USR);
- Sym.CompletionPlainInsertText = Sym.Name;
- Sym.CompletionSnippetInsertText = Sym.Name;
- Sym.CompletionLabel = Sym.Name;
Sym.SymInfo.Kind = Kind;
Sym.IsIndexedForCodeCompletion = true;
return Sym;
Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompletionStringsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompletionStringsTests.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CodeCompletionStringsTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/CodeCompletionStringsTests.cpp Fri Jun 22 09:11:35 2018
@@ -23,24 +23,23 @@ public:
CCTUInfo(Allocator), Builder(*Allocator, CCTUInfo) {}
protected:
- void labelAndInsertText(const CodeCompletionString &CCS,
- bool EnableSnippets = false) {
- Label.clear();
- InsertText.clear();
- getLabelAndInsertText(CCS, &Label, &InsertText, EnableSnippets);
+ void computeSignature(const CodeCompletionString &CCS) {
+ Signature.clear();
+ Snippet.clear();
+ getSignature(CCS, &Signature, &Snippet);
}
std::shared_ptr<clang::GlobalCodeCompletionAllocator> Allocator;
CodeCompletionTUInfo CCTUInfo;
CodeCompletionBuilder Builder;
- std::string Label;
- std::string InsertText;
+ std::string Signature;
+ std::string Snippet;
};
-TEST_F(CompletionStringTest, Detail) {
+TEST_F(CompletionStringTest, ReturnType) {
Builder.AddResultTypeChunk("result");
Builder.AddResultTypeChunk("redundant result no no");
- EXPECT_EQ(getDetail(*Builder.TakeString()), "result");
+ EXPECT_EQ(getReturnType(*Builder.TakeString()), "result");
}
TEST_F(CompletionStringTest, Documentation) {
@@ -65,31 +64,15 @@ TEST_F(CompletionStringTest, MultipleAnn
"Annotations: Ano1 Ano2 Ano3\n");
}
-TEST_F(CompletionStringTest, SimpleLabelAndInsert) {
+TEST_F(CompletionStringTest, EmptySignature) {
Builder.AddTypedTextChunk("X");
Builder.AddResultTypeChunk("result no no");
- labelAndInsertText(*Builder.TakeString());
- EXPECT_EQ(Label, "X");
- EXPECT_EQ(InsertText, "X");
+ computeSignature(*Builder.TakeString());
+ EXPECT_EQ(Signature, "");
+ EXPECT_EQ(Snippet, "");
}
-TEST_F(CompletionStringTest, FunctionPlainText) {
- Builder.AddResultTypeChunk("result no no");
- Builder.AddTypedTextChunk("Foo");
- Builder.AddChunk(CodeCompletionString::CK_LeftParen);
- Builder.AddPlaceholderChunk("p1");
- Builder.AddChunk(CodeCompletionString::CK_Comma);
- Builder.AddPlaceholderChunk("p2");
- Builder.AddChunk(CodeCompletionString::CK_RightParen);
- Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
- Builder.AddInformativeChunk("const");
-
- labelAndInsertText(*Builder.TakeString());
- EXPECT_EQ(Label, "Foo(p1, p2) const");
- EXPECT_EQ(InsertText, "Foo");
-}
-
-TEST_F(CompletionStringTest, FunctionSnippet) {
+TEST_F(CompletionStringTest, Function) {
Builder.AddResultTypeChunk("result no no");
Builder.addBriefComment("This comment is ignored");
Builder.AddTypedTextChunk("Foo");
@@ -100,13 +83,9 @@ TEST_F(CompletionStringTest, FunctionSni
Builder.AddChunk(CodeCompletionString::CK_RightParen);
auto *CCS = Builder.TakeString();
- labelAndInsertText(*CCS);
- EXPECT_EQ(Label, "Foo(p1, p2)");
- EXPECT_EQ(InsertText, "Foo");
-
- labelAndInsertText(*CCS, /*EnableSnippets=*/true);
- EXPECT_EQ(Label, "Foo(p1, p2)");
- EXPECT_EQ(InsertText, "Foo(${1:p1}, ${2:p2})");
+ computeSignature(*CCS);
+ EXPECT_EQ(Signature, "(p1, p2)");
+ EXPECT_EQ(Snippet, "(${1:p1}, ${2:p2})");
EXPECT_EQ(formatDocumentation(*CCS, "Foo's comment"), "Foo's comment");
}
@@ -116,18 +95,18 @@ TEST_F(CompletionStringTest, EscapeSnipp
Builder.AddPlaceholderChunk("$p}1\\");
Builder.AddChunk(CodeCompletionString::CK_RightParen);
- labelAndInsertText(*Builder.TakeString(), /*EnableSnippets=*/true);
- EXPECT_EQ(Label, "Foo($p}1\\)");
- EXPECT_EQ(InsertText, "Foo(${1:\\$p\\}1\\\\})");
+ computeSignature(*Builder.TakeString());
+ EXPECT_EQ(Signature, "($p}1\\)");
+ EXPECT_EQ(Snippet, "(${1:\\$p\\}1\\\\})");
}
TEST_F(CompletionStringTest, IgnoreInformativeQualifier) {
Builder.AddTypedTextChunk("X");
Builder.AddInformativeChunk("info ok");
Builder.AddInformativeChunk("info no no::");
- labelAndInsertText(*Builder.TakeString());
- EXPECT_EQ(Label, "Xinfo ok");
- EXPECT_EQ(InsertText, "X");
+ computeSignature(*Builder.TakeString());
+ EXPECT_EQ(Signature, "info ok");
+ EXPECT_EQ(Snippet, "");
}
} // namespace
Modified: clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp Fri Jun 22 09:11:35 2018
@@ -202,18 +202,15 @@ vector<Ty> make_vector(Arg A) {}
bool SeenMakeVector = false;
M.fuzzyFind(Req, [&](const Symbol &Sym) {
if (Sym.Name == "vector") {
- EXPECT_EQ(Sym.CompletionLabel, "vector<class Ty>");
- EXPECT_EQ(Sym.CompletionSnippetInsertText, "vector<${1:class Ty}>");
- EXPECT_EQ(Sym.CompletionPlainInsertText, "vector");
+ EXPECT_EQ(Sym.Signature, "<class Ty>");
+ EXPECT_EQ(Sym.CompletionSnippetSuffix, "<${1:class Ty}>");
SeenVector = true;
return;
}
if (Sym.Name == "make_vector") {
- EXPECT_EQ(Sym.CompletionLabel, "make_vector<class Ty>(Arg A)");
- EXPECT_EQ(Sym.CompletionSnippetInsertText,
- "make_vector<${1:class Ty}>(${2:Arg A})");
- EXPECT_EQ(Sym.CompletionPlainInsertText, "make_vector");
+ EXPECT_EQ(Sym.Signature, "<class Ty>(Arg A)");
+ EXPECT_EQ(Sym.CompletionSnippetSuffix, "<${1:class Ty}>(${2:Arg A})");
SeenMakeVector = true;
}
});
Modified: clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp Fri Jun 22 09:11:35 2018
@@ -274,11 +274,11 @@ TEST(MergeTest, Merge) {
R.CanonicalDeclaration.FileURI = "file:///right.h";
L.References = 1;
R.References = 2;
- L.CompletionPlainInsertText = "f00"; // present in left only
- R.CompletionSnippetInsertText = "f0{$1:0}"; // present in right only
+ L.Signature = "()"; // present in left only
+ R.CompletionSnippetSuffix = "{$1:0}"; // present in right only
Symbol::Details DetL, DetR;
- DetL.CompletionDetail = "DetL";
- DetR.CompletionDetail = "DetR";
+ DetL.ReturnType = "DetL";
+ DetR.ReturnType = "DetR";
DetR.Documentation = "--doc--";
L.Detail = &DetL;
R.Detail = &DetR;
@@ -288,10 +288,10 @@ TEST(MergeTest, Merge) {
EXPECT_EQ(M.Name, "Foo");
EXPECT_EQ(M.CanonicalDeclaration.FileURI, "file:///left.h");
EXPECT_EQ(M.References, 3u);
- EXPECT_EQ(M.CompletionPlainInsertText, "f00");
- EXPECT_EQ(M.CompletionSnippetInsertText, "f0{$1:0}");
+ EXPECT_EQ(M.Signature, "()");
+ EXPECT_EQ(M.CompletionSnippetSuffix, "{$1:0}");
ASSERT_TRUE(M.Detail);
- EXPECT_EQ(M.Detail->CompletionDetail, "DetL");
+ EXPECT_EQ(M.Detail->ReturnType, "DetL");
EXPECT_EQ(M.Detail->Documentation, "--doc--");
}
@@ -302,19 +302,19 @@ TEST(MergeTest, PreferSymbolWithDefn) {
L.ID = R.ID = SymbolID("hello");
L.CanonicalDeclaration.FileURI = "file:/left.h";
R.CanonicalDeclaration.FileURI = "file:/right.h";
- L.CompletionPlainInsertText = "left-insert";
- R.CompletionPlainInsertText = "right-insert";
+ L.Name = "left";
+ R.Name = "right";
Symbol M = mergeSymbol(L, R, &Scratch);
EXPECT_EQ(M.CanonicalDeclaration.FileURI, "file:/left.h");
EXPECT_EQ(M.Definition.FileURI, "");
- EXPECT_EQ(M.CompletionPlainInsertText, "left-insert");
+ EXPECT_EQ(M.Name, "left");
R.Definition.FileURI = "file:/right.cpp"; // Now right will be favored.
M = mergeSymbol(L, R, &Scratch);
EXPECT_EQ(M.CanonicalDeclaration.FileURI, "file:/right.h");
EXPECT_EQ(M.Definition.FileURI, "file:/right.cpp");
- EXPECT_EQ(M.CompletionPlainInsertText, "right-insert");
+ EXPECT_EQ(M.Name, "right");
}
} // namespace
Modified: clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp?rev=335360&r1=335359&r2=335360&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp Fri Jun 22 09:11:35 2018
@@ -36,15 +36,18 @@ using testing::UnorderedElementsAre;
using testing::UnorderedElementsAreArray;
// GMock helpers for matching Symbol.
-MATCHER_P(Labeled, Label, "") { return arg.CompletionLabel == Label; }
-MATCHER(HasDetail, "") { return arg.Detail; }
-MATCHER_P(Detail, D, "") {
- return arg.Detail && arg.Detail->CompletionDetail == D;
+MATCHER_P(Labeled, Label, "") {
+ return (arg.Name + arg.Signature).str() == Label;
+}
+MATCHER(HasReturnType, "") {
+ return arg.Detail && !arg.Detail->ReturnType.empty();
+}
+MATCHER_P(ReturnType, D, "") {
+ return arg.Detail && arg.Detail->ReturnType == D;
}
MATCHER_P(Doc, D, "") { return arg.Detail && arg.Detail->Documentation == D; }
-MATCHER_P(Plain, Text, "") { return arg.CompletionPlainInsertText == Text; }
MATCHER_P(Snippet, S, "") {
- return arg.CompletionSnippetInsertText == S;
+ return (arg.Name + arg.CompletionSnippetSuffix).str() == S;
}
MATCHER_P(QName, Name, "") { return (arg.Scope + arg.Name).str() == Name; }
MATCHER_P(DeclURI, P, "") { return arg.CanonicalDeclaration.FileURI == P; }
@@ -656,10 +659,10 @@ TEST_F(SymbolCollectorTest, SymbolWithDo
Symbols,
UnorderedElementsAre(
QName("nx"), AllOf(QName("nx::ff"), Labeled("ff(int x, double y)"),
- Detail("int"), Doc("Foo comment."))));
+ ReturnType("int"), Doc("Foo comment."))));
}
-TEST_F(SymbolCollectorTest, PlainAndSnippet) {
+TEST_F(SymbolCollectorTest, Snippet) {
const std::string Header = R"(
namespace nx {
void f() {}
@@ -667,13 +670,12 @@ TEST_F(SymbolCollectorTest, PlainAndSnip
}
)";
runSymbolCollector(Header, /*Main=*/"");
- EXPECT_THAT(
- Symbols,
- UnorderedElementsAre(
- QName("nx"),
- AllOf(QName("nx::f"), Labeled("f()"), Plain("f"), Snippet("f()")),
- AllOf(QName("nx::ff"), Labeled("ff(int x, double y)"), Plain("ff"),
- Snippet("ff(${1:int x}, ${2:double y})"))));
+ EXPECT_THAT(Symbols,
+ UnorderedElementsAre(
+ QName("nx"),
+ AllOf(QName("nx::f"), Labeled("f()"), Snippet("f()")),
+ AllOf(QName("nx::ff"), Labeled("ff(int x, double y)"),
+ Snippet("ff(${1:int x}, ${2:double y})"))));
}
TEST_F(SymbolCollectorTest, YAMLConversions) {
@@ -694,12 +696,9 @@ CanonicalDeclaration:
Line: 1
Column: 1
IsIndexedForCodeCompletion: true
-CompletionLabel: 'Foo1-label'
-CompletionFilterText: 'filter'
-CompletionPlainInsertText: 'plain'
Detail:
Documentation: 'Foo doc'
- CompletionDetail: 'int'
+ ReturnType: 'int'
...
)";
const std::string YAML2 = R"(
@@ -719,25 +718,23 @@ CanonicalDeclaration:
Line: 1
Column: 1
IsIndexedForCodeCompletion: false
-CompletionLabel: 'Foo2-label'
-CompletionFilterText: 'filter'
-CompletionPlainInsertText: 'plain'
-CompletionSnippetInsertText: 'snippet'
+Signature: '-sig'
+CompletionSnippetSuffix: '-snippet'
...
)";
auto Symbols1 = SymbolsFromYAML(YAML1);
EXPECT_THAT(Symbols1,
- UnorderedElementsAre(AllOf(
- QName("clang::Foo1"), Labeled("Foo1-label"), Doc("Foo doc"),
- Detail("int"), DeclURI("file:///path/foo.h"),
- ForCodeCompletion(true))));
+ UnorderedElementsAre(AllOf(QName("clang::Foo1"), Labeled("Foo1"),
+ Doc("Foo doc"), ReturnType("int"),
+ DeclURI("file:///path/foo.h"),
+ ForCodeCompletion(true))));
auto Symbols2 = SymbolsFromYAML(YAML2);
- EXPECT_THAT(Symbols2,
- UnorderedElementsAre(AllOf(
- QName("clang::Foo2"), Labeled("Foo2-label"), Not(HasDetail()),
- DeclURI("file:///path/bar.h"), ForCodeCompletion(false))));
+ EXPECT_THAT(Symbols2, UnorderedElementsAre(AllOf(
+ QName("clang::Foo2"), Labeled("Foo2-sig"),
+ Not(HasReturnType()), DeclURI("file:///path/bar.h"),
+ ForCodeCompletion(false))));
std::string ConcatenatedYAML;
{
More information about the cfe-commits
mailing list