19 #include "llvm/Support/ScopedPrinter.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include "gmock/gmock.h" 22 #include "gtest/gtest.h" 26 using ::testing::AnyOf;
27 using ::testing::ElementsAre;
28 using ::testing::IsEmpty;
29 using ::testing::UnorderedElementsAre;
40 std::vector<DocID> consumeIDs(Iterator &It) {
42 std::vector<DocID> IDs(IDAndScore.size());
43 for (
size_t I = 0; I < IDAndScore.size(); ++I)
44 IDs[I] = IDAndScore[I].first;
48 TEST(DexIterators, DocumentIterator) {
49 const PostingList L({4, 7, 8, 20, 42, 100});
50 auto DocIterator = L.iterator();
52 EXPECT_EQ(DocIterator->peek(), 4U);
53 EXPECT_FALSE(DocIterator->reachedEnd());
55 DocIterator->advance();
56 EXPECT_EQ(DocIterator->peek(), 7U);
57 EXPECT_FALSE(DocIterator->reachedEnd());
59 DocIterator->advanceTo(20);
60 EXPECT_EQ(DocIterator->peek(), 20U);
61 EXPECT_FALSE(DocIterator->reachedEnd());
63 DocIterator->advanceTo(65);
64 EXPECT_EQ(DocIterator->peek(), 100U);
65 EXPECT_FALSE(DocIterator->reachedEnd());
67 DocIterator->advanceTo(420);
68 EXPECT_TRUE(DocIterator->reachedEnd());
71 TEST(DexIterators, AndTwoLists) {
73 const PostingList L0({0, 5, 7, 10, 42, 320, 9000});
74 const PostingList L1({0, 4, 7, 10, 30, 60, 320, 9000});
76 auto And = C.intersect(L1.iterator(), L0.iterator());
78 EXPECT_FALSE(And->reachedEnd());
79 EXPECT_THAT(consumeIDs(*And), ElementsAre(0U, 7U, 10U, 320U, 9000U));
81 And = C.intersect(L0.iterator(), L1.iterator());
84 EXPECT_EQ(And->peek(), 0U);
86 EXPECT_EQ(And->peek(), 7U);
88 EXPECT_EQ(And->peek(), 10U);
90 EXPECT_EQ(And->peek(), 320U);
92 EXPECT_EQ(And->peek(), 9000U);
96 TEST(DexIterators, AndThreeLists) {
98 const PostingList L0({0, 5, 7, 10, 42, 320, 9000});
99 const PostingList L1({0, 4, 7, 10, 30, 60, 320, 9000});
100 const PostingList L2({1, 4, 7, 11, 30, 60, 320, 9000});
102 auto And = C.intersect(L0.iterator(), L1.iterator(), L2.iterator());
103 EXPECT_EQ(And->peek(), 7U);
105 EXPECT_EQ(And->peek(), 320U);
106 And->advanceTo(100000);
108 EXPECT_TRUE(And->reachedEnd());
111 TEST(DexIterators, AndEmpty) {
113 const PostingList L1{1};
114 const PostingList L2{2};
116 auto Empty1 = C.intersect(L1.iterator(), L2.iterator());
117 auto Empty2 = C.intersect(L1.iterator(), L2.iterator());
119 auto And = C.intersect(std::move(Empty1), std::move(Empty2));
120 EXPECT_TRUE(And->reachedEnd());
123 TEST(DexIterators, OrTwoLists) {
125 const PostingList L0({0, 5, 7, 10, 42, 320, 9000});
126 const PostingList L1({0, 4, 7, 10, 30, 60, 320, 9000});
128 auto Or = C.unionOf(L0.iterator(), L1.iterator());
130 EXPECT_FALSE(Or->reachedEnd());
131 EXPECT_EQ(Or->peek(), 0U);
133 EXPECT_EQ(Or->peek(), 4U);
135 EXPECT_EQ(Or->peek(), 5U);
137 EXPECT_EQ(Or->peek(), 7U);
139 EXPECT_EQ(Or->peek(), 10U);
141 EXPECT_EQ(Or->peek(), 30U);
143 EXPECT_EQ(Or->peek(), 42U);
145 EXPECT_EQ(Or->peek(), 320U);
147 EXPECT_EQ(Or->peek(), 9000U);
149 EXPECT_TRUE(Or->reachedEnd());
151 Or = C.unionOf(L0.iterator(), L1.iterator());
153 EXPECT_THAT(consumeIDs(*Or),
154 ElementsAre(0U, 4U, 5U, 7U, 10U, 30U, 42U, 60U, 320U, 9000U));
157 TEST(DexIterators, OrThreeLists) {
159 const PostingList L0({0, 5, 7, 10, 42, 320, 9000});
160 const PostingList L1({0, 4, 7, 10, 30, 60, 320, 9000});
161 const PostingList L2({1, 4, 7, 11, 30, 60, 320, 9000});
163 auto Or = C.unionOf(L0.iterator(), L1.iterator(), L2.iterator());
165 EXPECT_FALSE(Or->reachedEnd());
166 EXPECT_EQ(Or->peek(), 0U);
169 EXPECT_EQ(Or->peek(), 1U);
172 EXPECT_EQ(Or->peek(), 4U);
177 EXPECT_EQ(Or->peek(), 60U);
180 EXPECT_TRUE(Or->reachedEnd());
188 TEST(DexIterators, QueryTree) {
213 const PostingList L0({1, 3, 5, 8, 9});
214 const PostingList L1({1, 5, 7, 9});
215 const PostingList L2({1, 5});
216 const PostingList L3({0, 3, 5});
219 auto Root = C.intersect(
221 C.intersect(L0.iterator(), C.boost(L1.iterator(), 2U)),
223 C.unionOf(C.boost(L2.iterator(), 3U), C.boost(L3.iterator(), 4U)));
225 EXPECT_FALSE(Root->reachedEnd());
226 EXPECT_EQ(Root->peek(), 1U);
231 EXPECT_EQ(Root->peek(), 1U);
232 auto ElementBoost = Root->consume();
233 EXPECT_THAT(ElementBoost, 6);
235 EXPECT_EQ(Root->peek(), 5U);
237 EXPECT_EQ(Root->peek(), 5U);
238 ElementBoost = Root->consume();
239 EXPECT_THAT(ElementBoost, 8);
240 Root->advanceTo(9000);
241 EXPECT_TRUE(Root->reachedEnd());
244 TEST(DexIterators, StringRepresentation) {
246 const PostingList L1({1, 3, 5});
247 const PostingList L2({1, 7, 9});
250 auto I1 = L1.iterator();
251 EXPECT_EQ(llvm::to_string(*I1),
"[1 3 5]");
255 auto I2 = L1.iterator(&Tok);
256 EXPECT_EQ(llvm::to_string(*I2),
"T=L2");
258 auto Tree = C.limit(C.intersect(move(I1), move(I2)), 10);
260 EXPECT_THAT(llvm::to_string(*Tree), AnyOf(
"(LIMIT 10 (& [1 3 5] T=L2))",
261 "(LIMIT 10 (& T=L2 [1 3 5]))"));
266 const PostingList L0({3, 6, 7, 20, 42, 100});
267 const PostingList L1({1, 3, 5, 6, 7, 30, 100});
268 const PostingList L2({0, 3, 5, 7, 8, 100});
270 auto DocIterator = C.limit(L0.iterator(), 42);
271 EXPECT_THAT(consumeIDs(*DocIterator), ElementsAre(3, 6, 7, 20, 42, 100));
273 DocIterator = C.limit(L0.iterator(), 3);
274 EXPECT_THAT(consumeIDs(*DocIterator), ElementsAre(3, 6, 7));
276 DocIterator = C.limit(L0.iterator(), 0);
277 EXPECT_THAT(consumeIDs(*DocIterator), ElementsAre());
280 C.intersect(C.limit(C.all(), 343), C.limit(L0.iterator(), 2),
281 C.limit(L1.iterator(), 3), C.limit(L2.iterator(), 42));
282 EXPECT_THAT(consumeIDs(*AndIterator), ElementsAre(3, 7));
285 TEST(DexIterators, True) {
286 EXPECT_TRUE(Corpus{0}.all()->reachedEnd());
287 EXPECT_THAT(consumeIDs(*Corpus{4}.all()), ElementsAre(0, 1, 2, 3));
290 TEST(DexIterators, Boost) {
292 auto BoostIterator = C.boost(C.all(), 42U);
293 EXPECT_FALSE(BoostIterator->reachedEnd());
294 auto ElementBoost = BoostIterator->consume();
295 EXPECT_THAT(ElementBoost, 42U);
297 const PostingList L0({2, 4});
298 const PostingList L1({1, 4});
299 auto Root = C.unionOf(C.all(), C.boost(L0.iterator(), 2U),
300 C.boost(L1.iterator(), 3U));
302 ElementBoost = Root->consume();
303 EXPECT_THAT(ElementBoost, 1);
305 EXPECT_THAT(Root->peek(), 1U);
306 ElementBoost = Root->consume();
307 EXPECT_THAT(ElementBoost, 3);
310 EXPECT_THAT(Root->peek(), 2U);
311 ElementBoost = Root->consume();
312 EXPECT_THAT(ElementBoost, 2);
315 ElementBoost = Root->consume();
316 EXPECT_THAT(ElementBoost, 3);
319 TEST(DexIterators, Optimizations) {
321 const PostingList L1{1};
322 const PostingList L2{2};
323 const PostingList L3{3};
326 EXPECT_EQ(llvm::to_string(*C.intersect()),
"true");
327 EXPECT_EQ(llvm::to_string(*C.unionOf()),
"false");
330 EXPECT_EQ(llvm::to_string(*C.intersect(L1.iterator(), C.all())),
"[1]");
331 EXPECT_EQ(llvm::to_string(*C.intersect(L1.iterator(), C.none())),
"false");
333 EXPECT_EQ(llvm::to_string(*C.unionOf(L1.iterator(), C.all())),
335 EXPECT_EQ(llvm::to_string(*C.unionOf(L1.iterator(), C.none())),
"[1]");
338 EXPECT_EQ(llvm::to_string(*C.intersect(
339 L1.iterator(), C.intersect(L1.iterator(), L1.iterator()))),
341 EXPECT_EQ(llvm::to_string(*C.unionOf(
342 L1.iterator(), C.unionOf(L2.iterator(), L3.iterator()))),
346 EXPECT_EQ(llvm::to_string(*C.intersect(
347 C.intersect(L1.iterator(), C.intersect()), C.unionOf(C.all()))),
355 ::testing::Matcher<std::vector<Token>>
357 std::vector<Token> Tokens;
358 for (
const auto &TokenData : Strings) {
359 Tokens.push_back(Token(Kind, TokenData));
361 return ::testing::UnorderedElementsAreArray(Tokens);
364 ::testing::Matcher<std::vector<Token>>
365 trigramsAre(std::initializer_list<std::string> Trigrams) {
369 TEST(DexTrigrams, IdentifierTrigrams) {
371 trigramsAre({
"x86",
"x",
"x8"}));
378 trigramsAre({
"c",
"cl",
"cla",
"lan",
"ang",
"ngd"}));
381 trigramsAre({
"a",
"ab",
"ad",
"abc",
"abd",
"ade",
"bcd",
"bde",
385 trigramsAre({
"a",
"a_",
"ab",
"abc",
"bcd",
"cde"}));
388 trigramsAre({
"u",
"un",
"up",
"uni",
"unp",
"upt",
"niq",
"nip",
389 "npt",
"iqu",
"iqp",
"ipt",
"que",
"qup",
"qpt",
390 "uep",
"ept",
"ptr"}));
394 trigramsAre({
"t",
"tu",
"td",
"tud",
"tde",
"ude",
"dec",
"ecl"}));
397 trigramsAre({
"i",
"is",
"io",
"iso",
"iok",
"sok"}));
401 trigramsAre({
"a",
"ab",
"ad",
"abc",
"abd",
"ade",
"adg",
"bcd",
402 "bde",
"bdg",
"cde",
"cdg",
"def",
"deg",
"dgh",
"dgk",
403 "efg",
"egh",
"egk",
"fgh",
"fgk",
"ghi",
"ghk",
"gkl",
404 "hij",
"hik",
"hkl",
"ijk",
"ikl",
"jkl",
"klm"}));
407 TEST(DexTrigrams, QueryTrigrams) {
420 trigramsAre({
"cla",
"lan",
"ang",
"ngd"}));
423 trigramsAre({
"abc",
"bcd",
"cde",
"def"}));
426 trigramsAre({
"abc",
"bcd",
"cde"}));
429 trigramsAre({
"uni",
"niq",
"iqu",
"que",
"uep",
"ept",
"ptr"}));
432 trigramsAre({
"tud",
"ude",
"dec",
"ecl"}));
437 trigramsAre({
"abc",
"bcd",
"cde",
"def",
"efg",
"fgh",
"ghi",
438 "hij",
"ijk",
"jkl",
"klm"}));
441 TEST(DexSearchTokens, SymbolPath) {
443 "unittest:///clang-tools-extra/clangd/index/Token.h"),
444 ElementsAre(
"unittest:///clang-tools-extra/clangd/index/Token.h",
445 "unittest:///clang-tools-extra/clangd/index",
446 "unittest:///clang-tools-extra/clangd",
447 "unittest:///clang-tools-extra",
"unittest:///"));
450 ElementsAre(
"unittest:///a/b/c.h",
"unittest:///a/b",
451 "unittest:///a",
"unittest:///"));
461 EXPECT_THAT(
lookup(*I,
SymbolID(
"ns::abc")), UnorderedElementsAre(
"ns::abc"));
463 UnorderedElementsAre(
"ns::abc",
"ns::xyz"));
465 UnorderedElementsAre(
"ns::xyz"));
466 EXPECT_THAT(
lookup(*I,
SymbolID(
"ns::nonono")), UnorderedElementsAre());
469 TEST(Dex, FuzzyFind) {
472 "ns::nested::ABC",
"other::ABC",
"other::A"}),
473 RefSlab(), RelationSlab());
474 FuzzyFindRequest Req;
476 Req.Scopes = {
"ns::"};
477 EXPECT_THAT(
match(*
Index, Req), UnorderedElementsAre(
"ns::ABC"));
478 Req.Scopes = {
"ns::",
"ns::nested::"};
480 UnorderedElementsAre(
"ns::ABC",
"ns::nested::ABC"));
482 Req.Scopes = {
"other::"};
484 UnorderedElementsAre(
"other::A",
"other::ABC"));
489 UnorderedElementsAre(
"ns::ABC",
"ns::BCD",
"::ABC",
490 "ns::nested::ABC",
"other::ABC",
494 TEST(DexTest, DexLimitedNumMatches) {
496 FuzzyFindRequest Req;
501 auto Matches =
match(*I, Req, &Incomplete);
502 EXPECT_TRUE(Req.Limit);
503 EXPECT_EQ(Matches.size(), *Req.Limit);
504 EXPECT_TRUE(Incomplete);
507 TEST(DexTest, FuzzyMatch) {
509 generateSymbols({
"LaughingOutLoud",
"LionPopulation",
"LittleOldLady"}),
510 RefSlab(), RelationSlab());
511 FuzzyFindRequest Req;
515 EXPECT_THAT(
match(*I, Req),
516 UnorderedElementsAre(
"LaughingOutLoud",
"LittleOldLady"));
519 TEST(DexTest, ShortQuery) {
522 FuzzyFindRequest Req;
526 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"OneTwoThreeFour"));
527 EXPECT_FALSE(Incomplete) <<
"Empty string is not a short query";
530 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre());
531 EXPECT_TRUE(Incomplete) <<
"Short queries have different semantics";
534 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre());
535 EXPECT_TRUE(Incomplete) <<
"Short queries have different semantics";
538 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"OneTwoThreeFour"));
539 EXPECT_FALSE(Incomplete) <<
"3-char string is not a short query";
542 TEST(DexTest, MatchQualifiedNamesWithoutSpecificScope) {
545 FuzzyFindRequest Req;
548 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"a::y1",
"b::y2",
"y3"));
551 TEST(DexTest, MatchQualifiedNamesWithGlobalScope) {
554 FuzzyFindRequest Req;
557 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"y3"));
560 TEST(DexTest, MatchQualifiedNamesWithOneScope) {
563 RefSlab(), RelationSlab());
564 FuzzyFindRequest Req;
566 Req.Scopes = {
"a::"};
567 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"a::y1",
"a::y2"));
570 TEST(DexTest, MatchQualifiedNamesWithMultipleScopes) {
573 RefSlab(), RelationSlab());
574 FuzzyFindRequest Req;
576 Req.Scopes = {
"a::",
"b::"};
577 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"a::y1",
"a::y2",
"b::y3"));
580 TEST(DexTest, NoMatchNestedScopes) {
583 FuzzyFindRequest Req;
585 Req.Scopes = {
"a::"};
586 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"a::y1"));
589 TEST(DexTest, WildcardScope) {
591 RefSlab(), RelationSlab());
592 FuzzyFindRequest Req;
595 Req.Scopes = {
"a::"};
596 EXPECT_THAT(
match(*I, Req),
597 UnorderedElementsAre(
"a::y1",
"a::b::y2",
"c::y3"));
600 TEST(DexTest, IgnoreCases) {
603 FuzzyFindRequest Req;
605 Req.Scopes = {
"ns::"};
606 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"ns::ABC",
"ns::abc"));
609 TEST(DexTest, UnknownPostingList) {
613 FuzzyFindRequest Req;
614 Req.Scopes = {
"ns2::"};
615 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre());
618 TEST(DexTest, Lookup) {
621 EXPECT_THAT(
lookup(*I,
SymbolID(
"ns::abc")), UnorderedElementsAre(
"ns::abc"));
623 UnorderedElementsAre(
"ns::abc",
"ns::xyz"));
625 UnorderedElementsAre(
"ns::xyz"));
626 EXPECT_THAT(
lookup(*I,
SymbolID(
"ns::nonono")), UnorderedElementsAre());
629 TEST(DexTest, SymbolIndexOptionsFilter) {
630 auto CodeCompletionSymbol =
symbol(
"Completion");
631 auto NonCodeCompletionSymbol =
symbol(
"NoCompletion");
632 CodeCompletionSymbol.Flags = Symbol::SymbolFlag::IndexedForCodeCompletion;
633 NonCodeCompletionSymbol.Flags = Symbol::SymbolFlag::None;
634 std::vector<Symbol>
Symbols{CodeCompletionSymbol, NonCodeCompletionSymbol};
635 Dex I(
Symbols, RefSlab(), RelationSlab());
636 FuzzyFindRequest Req;
638 Req.RestrictForCodeCompletion =
false;
639 EXPECT_THAT(
match(I, Req), ElementsAre(
"Completion",
"NoCompletion"));
640 Req.RestrictForCodeCompletion =
true;
641 EXPECT_THAT(
match(I, Req), ElementsAre(
"Completion"));
644 TEST(DexTest, ProximityPathsBoosting) {
645 auto RootSymbol =
symbol(
"root::abc");
646 RootSymbol.CanonicalDeclaration.FileURI =
"unittest:///file.h";
647 auto CloseSymbol =
symbol(
"close::abc");
648 CloseSymbol.CanonicalDeclaration.FileURI =
"unittest:///a/b/c/d/e/f/file.h";
650 std::vector<Symbol>
Symbols{CloseSymbol, RootSymbol};
651 Dex I(
Symbols, RefSlab(), RelationSlab());
653 FuzzyFindRequest Req;
661 Req.ProximityPaths = {
testPath(
"a/b/c/d/e/f/file.h")};
662 EXPECT_THAT(
match(I, Req), ElementsAre(
"close::abc"));
666 Req.ProximityPaths = {
testPath(
"file.h")};
667 EXPECT_THAT(
match(I, Req), ElementsAre(
"root::abc"));
671 llvm::DenseMap<SymbolID, std::vector<Ref>>
Refs;
673 auto &SymbolRefs = Refs[Sym.ID];
674 SymbolRefs.emplace_back();
675 SymbolRefs.back().Kind =
Kind;
676 SymbolRefs.back().Location.FileURI =
Filename;
686 Req.IDs.insert(Foo.ID);
689 std::vector<std::string>
Files;
690 EXPECT_FALSE(Dex(std::vector<Symbol>{Foo, Bar},
Refs, RelationSlab())
691 .refs(Req, [&](
const Ref &R) {
692 Files.push_back(R.Location.FileURI);
694 EXPECT_THAT(Files, UnorderedElementsAre(
"foo.h",
"foo.cc"));
698 EXPECT_TRUE(Dex(std::vector<Symbol>{Foo, Bar},
Refs, RelationSlab())
699 .refs(Req, [&](
const Ref &R) {
700 Files.push_back(R.Location.FileURI);
702 EXPECT_THAT(Files, ElementsAre(AnyOf(
"foo.h",
"foo.cc")));
705 TEST(DexTests, Relations) {
707 auto Child1 =
symbol(
"Child1");
708 auto Child2 =
symbol(
"Child2");
715 Dex I{
Symbols, RefSlab(), Relations};
718 RelationsRequest Req;
719 Req.Subjects.insert(
Parent.ID);
721 I.relations(Req, [&](
const SymbolID &Subject,
const Symbol &Object) {
722 Results.push_back(Object.ID);
724 EXPECT_THAT(Results, UnorderedElementsAre(Child1.ID, Child2.ID));
727 TEST(DexTest, PreferredTypesBoosting) {
733 std::vector<Symbol>
Symbols{Sym1, Sym2};
734 Dex I(
Symbols, RefSlab(), RelationSlab());
736 FuzzyFindRequest Req;
742 Req.PreferredTypes = {Sym1.Type};
743 EXPECT_THAT(
match(I, Req), ElementsAre(
"t1"));
745 Req.PreferredTypes = {Sym2.Type};
746 EXPECT_THAT(
match(I, Req), ElementsAre(
"t2"));
749 TEST(DexTest, TemplateSpecialization) {
752 Symbol S =
symbol(
"TempSpec");
758 S.TemplateSpecializationArgs =
"<int, bool>";
759 S.SymInfo.Properties =
static_cast<index::SymbolPropertySet
>(
760 index::SymbolProperty::TemplateSpecialization);
765 S.TemplateSpecializationArgs =
"<int, U>";
766 S.SymInfo.Properties =
static_cast<index::SymbolPropertySet
>(
767 index::SymbolProperty::TemplatePartialSpecialization);
770 auto I =
dex::Dex::build(std::move(B).build(), RefSlab(), RelationSlab());
771 FuzzyFindRequest Req;
774 Req.Query =
"TempSpec";
775 EXPECT_THAT(
match(*I, Req),
776 UnorderedElementsAre(
"TempSpec",
"TempSpec<int, bool>",
777 "TempSpec<int, U>"));
780 Req.Query =
"TempSpec<int";
781 EXPECT_THAT(
match(*I, Req), IsEmpty());
Symbol symbol(llvm::StringRef QName)
This defines Dex - a symbol index implementation based on query iterators over symbol tokens...
std::vector< CodeCompletionResult > Results
std::vector< Token > generateIdentifierTrigrams(llvm::StringRef Identifier)
Returns list of unique fuzzy-search trigrams from unqualified symbol.
Represents trigram used for fuzzy search of unqualified symbol names.
std::vector< std::pair< DocID, float > > consume(Iterator &It)
Advances the iterator until it is exhausted.
std::string Filename
Filename as a string.
std::vector< std::string > generateProximityURIs(llvm::StringRef URIPath)
Returns Search Token for a number of parent directories of given Path.
std::vector< std::string > lookup(const SymbolIndex &I, llvm::ArrayRef< SymbolID > IDs)
std::vector< Token > generateQueryTrigrams(llvm::StringRef Query)
Returns list of unique fuzzy-search trigrams given a query.
TEST(BackgroundQueueTest, Priority)
std::vector< std::string > match(const SymbolIndex &I, const FuzzyFindRequest &Req, bool *Incomplete)
std::string testPath(PathRef File)
SymbolSlab generateSymbols(std::vector< std::string > QualifiedNames)
static std::unique_ptr< SymbolIndex > build(SymbolSlab, RefSlab, RelationSlab)
Builds an index from slabs. The index takes ownership of the slab.
RefKind
Describes the kind of a cross-reference.
std::vector< llvm::StringRef > Strings
CodeCompletionBuilder Builder
SymbolSlab generateNumSymbols(int Begin, int End)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Trigrams are attributes of the symbol unqualified name used to effectively extract symbols which can ...
Symbol index queries consist of specific requirements for the requested symbol, such as high fuzzy ma...
Kind
Kind specifies Token type which defines semantics for the internal representation.
std::array< uint8_t, 20 > SymbolID
llvm::StringMap< std::string > Files
Token objects represent a characteristic of a symbol, which can be used to perform efficient search...
const SymbolIndex * Index