17#include "llvm/Support/ScopedPrinter.h"
18#include "gmock/gmock.h"
19#include "gtest/gtest.h"
23using ::testing::AnyOf;
24using ::testing::ElementsAre;
25using ::testing::IsEmpty;
26using ::testing::UnorderedElementsAre;
37std::vector<DocID> consumeIDs(Iterator &It) {
39 std::vector<DocID> IDs(IDAndScore.size());
40 for (
size_t I = 0; I < IDAndScore.size(); ++I)
41 IDs[I] = IDAndScore[I].first;
45TEST(DexIterators, DocumentIterator) {
46 const PostingList L({4, 7, 8, 20, 42, 100});
47 auto DocIterator = L.iterator();
49 EXPECT_EQ(DocIterator->peek(), 4U);
50 EXPECT_FALSE(DocIterator->reachedEnd());
52 DocIterator->advance();
53 EXPECT_EQ(DocIterator->peek(), 7U);
54 EXPECT_FALSE(DocIterator->reachedEnd());
56 DocIterator->advanceTo(20);
57 EXPECT_EQ(DocIterator->peek(), 20U);
58 EXPECT_FALSE(DocIterator->reachedEnd());
60 DocIterator->advanceTo(65);
61 EXPECT_EQ(DocIterator->peek(), 100U);
62 EXPECT_FALSE(DocIterator->reachedEnd());
64 DocIterator->advanceTo(420);
65 EXPECT_TRUE(DocIterator->reachedEnd());
68TEST(DexIterators, AndTwoLists) {
70 const PostingList L0({0, 5, 7, 10, 42, 320, 9000});
71 const PostingList L1({0, 4, 7, 10, 30, 60, 320, 9000});
73 auto And =
C.intersect(L1.iterator(), L0.iterator());
75 EXPECT_FALSE(And->reachedEnd());
76 EXPECT_THAT(consumeIDs(*And), ElementsAre(0U, 7U, 10U, 320U, 9000U));
78 And =
C.intersect(L0.iterator(), L1.iterator());
81 EXPECT_EQ(And->peek(), 0U);
83 EXPECT_EQ(And->peek(), 7U);
85 EXPECT_EQ(And->peek(), 10U);
87 EXPECT_EQ(And->peek(), 320U);
89 EXPECT_EQ(And->peek(), 9000U);
93TEST(DexIterators, AndThreeLists) {
95 const PostingList L0({0, 5, 7, 10, 42, 320, 9000});
96 const PostingList L1({0, 4, 7, 10, 30, 60, 320, 9000});
97 const PostingList L2({1, 4, 7, 11, 30, 60, 320, 9000});
99 auto And =
C.intersect(L0.iterator(), L1.iterator(), L2.iterator());
100 EXPECT_EQ(And->peek(), 7U);
102 EXPECT_EQ(And->peek(), 320U);
103 And->advanceTo(100000);
105 EXPECT_TRUE(And->reachedEnd());
108TEST(DexIterators, AndEmpty) {
110 const PostingList L1{1};
111 const PostingList L2{2};
113 auto Empty1 =
C.intersect(L1.iterator(), L2.iterator());
114 auto Empty2 =
C.intersect(L1.iterator(), L2.iterator());
116 auto And =
C.intersect(std::move(Empty1), std::move(Empty2));
117 EXPECT_TRUE(And->reachedEnd());
120TEST(DexIterators, OrTwoLists) {
122 const PostingList L0({0, 5, 7, 10, 42, 320, 9000});
123 const PostingList L1({0, 4, 7, 10, 30, 60, 320, 9000});
125 auto Or =
C.unionOf(L0.iterator(), L1.iterator());
127 EXPECT_FALSE(Or->reachedEnd());
128 EXPECT_EQ(Or->peek(), 0U);
130 EXPECT_EQ(Or->peek(), 4U);
132 EXPECT_EQ(Or->peek(), 5U);
134 EXPECT_EQ(Or->peek(), 7U);
136 EXPECT_EQ(Or->peek(), 10U);
138 EXPECT_EQ(Or->peek(), 30U);
140 EXPECT_EQ(Or->peek(), 42U);
142 EXPECT_EQ(Or->peek(), 320U);
144 EXPECT_EQ(Or->peek(), 9000U);
146 EXPECT_TRUE(Or->reachedEnd());
148 Or =
C.unionOf(L0.iterator(), L1.iterator());
150 EXPECT_THAT(consumeIDs(*Or),
151 ElementsAre(0U, 4U, 5U, 7U, 10U, 30U, 42U, 60U, 320U, 9000U));
154TEST(DexIterators, OrThreeLists) {
156 const PostingList L0({0, 5, 7, 10, 42, 320, 9000});
157 const PostingList L1({0, 4, 7, 10, 30, 60, 320, 9000});
158 const PostingList L2({1, 4, 7, 11, 30, 60, 320, 9000});
160 auto Or =
C.unionOf(L0.iterator(), L1.iterator(), L2.iterator());
162 EXPECT_FALSE(Or->reachedEnd());
163 EXPECT_EQ(Or->peek(), 0U);
166 EXPECT_EQ(Or->peek(), 1U);
169 EXPECT_EQ(Or->peek(), 4U);
174 EXPECT_EQ(Or->peek(), 60U);
177 EXPECT_TRUE(Or->reachedEnd());
185TEST(DexIterators, QueryTree) {
210 const PostingList L0({1, 3, 5, 8, 9});
211 const PostingList L1({1, 5, 7, 9});
212 const PostingList L2({1, 5});
213 const PostingList L3({0, 3, 5});
216 auto Root =
C.intersect(
218 C.intersect(L0.iterator(),
C.boost(L1.iterator(), 2U)),
220 C.unionOf(
C.boost(L2.iterator(), 3U),
C.boost(L3.iterator(), 4U)));
222 EXPECT_FALSE(
Root->reachedEnd());
223 EXPECT_EQ(
Root->peek(), 1U);
228 EXPECT_EQ(
Root->peek(), 1U);
229 auto ElementBoost =
Root->consume();
230 EXPECT_THAT(ElementBoost, 6);
232 EXPECT_EQ(
Root->peek(), 5U);
234 EXPECT_EQ(
Root->peek(), 5U);
235 ElementBoost =
Root->consume();
236 EXPECT_THAT(ElementBoost, 8);
237 Root->advanceTo(9000);
238 EXPECT_TRUE(
Root->reachedEnd());
241TEST(DexIterators, StringRepresentation) {
243 const PostingList L1({1, 3, 5});
244 const PostingList L2({1, 7, 9});
247 auto I1 = L1.iterator();
248 EXPECT_EQ(llvm::to_string(*I1),
"[1 3 5]");
252 auto I2 = L1.iterator(&Tok);
253 EXPECT_EQ(llvm::to_string(*I2),
"T=L2");
255 auto Tree =
C.limit(
C.intersect(std::move(I1), std::move(I2)), 10);
257 EXPECT_THAT(llvm::to_string(*Tree), AnyOf(
"(LIMIT 10 (& [1 3 5] T=L2))",
258 "(LIMIT 10 (& T=L2 [1 3 5]))"));
261TEST(DexIterators, Limit) {
263 const PostingList L0({3, 6, 7, 20, 42, 100});
264 const PostingList L1({1, 3, 5, 6, 7, 30, 100});
265 const PostingList L2({0, 3, 5, 7, 8, 100});
267 auto DocIterator =
C.limit(L0.iterator(), 42);
268 EXPECT_THAT(consumeIDs(*DocIterator), ElementsAre(3, 6, 7, 20, 42, 100));
270 DocIterator =
C.limit(L0.iterator(), 3);
271 EXPECT_THAT(consumeIDs(*DocIterator), ElementsAre(3, 6, 7));
273 DocIterator =
C.limit(L0.iterator(), 0);
274 EXPECT_THAT(consumeIDs(*DocIterator), ElementsAre());
277 C.intersect(
C.limit(
C.all(), 343),
C.limit(L0.iterator(), 2),
278 C.limit(L1.iterator(), 3),
C.limit(L2.iterator(), 42));
279 EXPECT_THAT(consumeIDs(*AndIterator), ElementsAre(3, 7));
282TEST(DexIterators, True) {
283 EXPECT_TRUE(Corpus{0}.all()->reachedEnd());
284 EXPECT_THAT(consumeIDs(*Corpus{4}.all()), ElementsAre(0, 1, 2, 3));
287TEST(DexIterators, Boost) {
289 auto BoostIterator =
C.boost(
C.all(), 42U);
290 EXPECT_FALSE(BoostIterator->reachedEnd());
291 auto ElementBoost = BoostIterator->consume();
292 EXPECT_THAT(ElementBoost, 42U);
294 const PostingList L0({2, 4});
295 const PostingList L1({1, 4});
296 auto Root =
C.unionOf(
C.all(),
C.boost(L0.iterator(), 2U),
297 C.boost(L1.iterator(), 3U));
299 ElementBoost =
Root->consume();
300 EXPECT_THAT(ElementBoost, 1);
302 EXPECT_THAT(
Root->peek(), 1U);
303 ElementBoost =
Root->consume();
304 EXPECT_THAT(ElementBoost, 3);
307 EXPECT_THAT(
Root->peek(), 2U);
308 ElementBoost =
Root->consume();
309 EXPECT_THAT(ElementBoost, 2);
312 ElementBoost =
Root->consume();
313 EXPECT_THAT(ElementBoost, 3);
316TEST(DexIterators, Optimizations) {
318 const PostingList L1{1};
319 const PostingList L2{2};
320 const PostingList L3{3};
323 EXPECT_EQ(llvm::to_string(*
C.intersect()),
"true");
324 EXPECT_EQ(llvm::to_string(*
C.unionOf()),
"false");
327 EXPECT_EQ(llvm::to_string(*
C.intersect(L1.iterator(),
C.all())),
"[1]");
328 EXPECT_EQ(llvm::to_string(*
C.intersect(L1.iterator(),
C.none())),
"false");
330 EXPECT_EQ(llvm::to_string(*
C.unionOf(L1.iterator(),
C.all())),
332 EXPECT_EQ(llvm::to_string(*
C.unionOf(L1.iterator(),
C.none())),
"[1]");
335 EXPECT_EQ(llvm::to_string(*
C.intersect(
336 L1.iterator(),
C.intersect(L1.iterator(), L1.iterator()))),
338 EXPECT_EQ(llvm::to_string(*
C.unionOf(
339 L1.iterator(),
C.unionOf(L2.iterator(), L3.iterator()))),
343 EXPECT_EQ(llvm::to_string(*
C.intersect(
344 C.intersect(L1.iterator(),
C.intersect()),
C.unionOf(
C.all()))),
352::testing::Matcher<std::vector<Token>>
354 std::vector<Token> Tokens;
355 for (
const auto &TokenData :
Strings) {
356 Tokens.push_back(Token(
Kind, TokenData));
358 return ::testing::UnorderedElementsAreArray(Tokens);
361::testing::Matcher<std::vector<Token>>
362trigramsAre(std::initializer_list<std::string> Trigrams) {
366std::vector<Token> identifierTrigramTokens(llvm::StringRef S) {
367 std::vector<Trigram> Trigrams;
369 std::vector<Token> Tokens;
370 for (Trigram T : Trigrams)
375TEST(DexTrigrams, IdentifierTrigrams) {
376 EXPECT_THAT(identifierTrigramTokens(
"X86"), trigramsAre({
"x86",
"x",
"x8"}));
378 EXPECT_THAT(identifierTrigramTokens(
"nl"), trigramsAre({
"nl",
"n"}));
380 EXPECT_THAT(identifierTrigramTokens(
"n"), trigramsAre({
"n"}));
382 EXPECT_THAT(identifierTrigramTokens(
"clangd"),
383 trigramsAre({
"c",
"cl",
"cla",
"lan",
"ang",
"ngd"}));
385 EXPECT_THAT(identifierTrigramTokens(
"abc_def"),
386 trigramsAre({
"a",
"d",
"ab",
"ad",
"de",
"abc",
"abd",
"ade",
387 "bcd",
"bde",
"cde",
"def"}));
389 EXPECT_THAT(identifierTrigramTokens(
"a_b_c_d_e_"),
390 trigramsAre({
"a",
"b",
"ab",
"bc",
"abc",
"bcd",
"cde"}));
392 EXPECT_THAT(identifierTrigramTokens(
"unique_ptr"),
393 trigramsAre({
"u",
"p",
"un",
"up",
"pt",
"uni",
"unp",
394 "upt",
"niq",
"nip",
"npt",
"iqu",
"iqp",
"ipt",
395 "que",
"qup",
"qpt",
"uep",
"ept",
"ptr"}));
397 EXPECT_THAT(identifierTrigramTokens(
"TUDecl"),
398 trigramsAre({
"t",
"d",
"tu",
"td",
"de",
"tud",
"tde",
"ude",
401 EXPECT_THAT(identifierTrigramTokens(
"IsOK"),
402 trigramsAre({
"i",
"o",
"is",
"ok",
"io",
"iso",
"iok",
"sok"}));
404 EXPECT_THAT(identifierTrigramTokens(
"_pb"),
405 trigramsAre({
"_",
"_p",
"p",
"pb"}));
406 EXPECT_THAT(identifierTrigramTokens(
"__pb"),
407 trigramsAre({
"_",
"_p",
"p",
"pb"}));
409 EXPECT_THAT(identifierTrigramTokens(
"abc_defGhij__klm"),
410 trigramsAre({
"a",
"d",
"ab",
"ad",
"dg",
"de",
"abc",
411 "abd",
"ade",
"adg",
"bcd",
"bde",
"bdg",
"cde",
412 "cdg",
"def",
"deg",
"dgh",
"dgk",
"efg",
"egh",
413 "egk",
"fgh",
"fgk",
"ghi",
"ghk",
"gkl",
"hij",
414 "hik",
"hkl",
"ijk",
"ikl",
"jkl",
"klm"}));
415 EXPECT_THAT(identifierTrigramTokens(
""), IsEmpty());
418TEST(DexTrigrams, QueryTrigrams) {
439 trigramsAre({
"cla",
"lan",
"ang",
"ngd"}));
442 trigramsAre({
"abc",
"bcd",
"cde",
"def"}));
445 trigramsAre({
"abc",
"bcd",
"cde"}));
448 trigramsAre({
"uni",
"niq",
"iqu",
"que",
"uep",
"ept",
"ptr"}));
451 trigramsAre({
"tud",
"ude",
"dec",
"ecl"}));
456 trigramsAre({
"abc",
"bcd",
"cde",
"def",
"efg",
"fgh",
"ghi",
457 "hij",
"ijk",
"jkl",
"klm"}));
460TEST(DexSearchTokens, SymbolPath) {
462 "unittest:///clang-tools-extra/clangd/index/Token.h"),
463 ElementsAre(
"unittest:///clang-tools-extra/clangd/index/Token.h",
464 "unittest:///clang-tools-extra/clangd/index",
465 "unittest:///clang-tools-extra/clangd",
466 "unittest:///clang-tools-extra",
"unittest:///"));
469 ElementsAre(
"unittest:///a/b/c.h",
"unittest:///a/b",
470 "unittest:///a",
"unittest:///"));
479 RelationSlab(),
true);
480 EXPECT_THAT(
lookup(*I,
SymbolID(
"ns::abc")), UnorderedElementsAre(
"ns::abc"));
482 UnorderedElementsAre(
"ns::abc",
"ns::xyz"));
484 UnorderedElementsAre(
"ns::xyz"));
485 EXPECT_THAT(
lookup(*I,
SymbolID(
"ns::nonono")), UnorderedElementsAre());
488TEST(Dex, FuzzyFind) {
491 "ns::nested::ABC",
"other::ABC",
"other::A"}),
492 RefSlab(), RelationSlab(),
true);
493 FuzzyFindRequest Req;
495 Req.Scopes = {
"ns::"};
496 EXPECT_THAT(
match(*Index, Req), UnorderedElementsAre(
"ns::ABC"));
497 Req.Scopes = {
"ns::",
"ns::nested::"};
498 EXPECT_THAT(
match(*Index, Req),
499 UnorderedElementsAre(
"ns::ABC",
"ns::nested::ABC"));
501 Req.Scopes = {
"other::"};
502 EXPECT_THAT(
match(*Index, Req),
503 UnorderedElementsAre(
"other::A",
"other::ABC"));
507 EXPECT_THAT(
match(*Index, Req),
508 UnorderedElementsAre(
"ns::ABC",
"ns::BCD",
"::ABC",
509 "ns::nested::ABC",
"other::ABC",
513TEST(DexTest, DexLimitedNumMatches) {
516 FuzzyFindRequest Req;
521 auto Matches =
match(*I, Req, &Incomplete);
522 EXPECT_TRUE(Req.Limit);
523 EXPECT_EQ(Matches.size(), *Req.Limit);
524 EXPECT_TRUE(Incomplete);
527TEST(DexTest, FuzzyMatch) {
529 generateSymbols({
"LaughingOutLoud",
"LionPopulation",
"LittleOldLady"}),
530 RefSlab(), RelationSlab(),
true);
531 FuzzyFindRequest Req;
535 EXPECT_THAT(
match(*I, Req),
536 UnorderedElementsAre(
"LaughingOutLoud",
"LittleOldLady"));
539TEST(DexTest, ShortQuery) {
541 RelationSlab(),
true);
542 FuzzyFindRequest Req;
546 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"_OneTwoFourSix"));
547 EXPECT_FALSE(Incomplete) <<
"Empty string is not a short query";
550 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"_OneTwoFourSix"));
551 EXPECT_TRUE(Incomplete) <<
"Using first head as unigram";
554 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"_OneTwoFourSix"));
555 EXPECT_TRUE(Incomplete) <<
"Using delimiter and first head as bigram";
558 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"_OneTwoFourSix"));
559 EXPECT_TRUE(Incomplete) <<
"Using first head and tail as bigram";
562 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"_OneTwoFourSix"));
563 EXPECT_TRUE(Incomplete) <<
"Using first two heads as bigram";
566 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"_OneTwoFourSix"));
567 EXPECT_TRUE(Incomplete) <<
"Using second head and tail as bigram";
570 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"_OneTwoFourSix"));
571 EXPECT_TRUE(Incomplete) <<
"Using second and third heads as bigram";
574 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre());
575 EXPECT_TRUE(Incomplete) <<
"Short queries have different semantics";
578 EXPECT_THAT(
match(*I, Req, &Incomplete), ElementsAre(
"_OneTwoFourSix"));
579 EXPECT_FALSE(Incomplete) <<
"3-char string is not a short query";
582TEST(DexTest, MatchQualifiedNamesWithoutSpecificScope) {
584 RelationSlab(),
true);
585 FuzzyFindRequest Req;
588 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"a::y1",
"b::y2",
"y3"));
591TEST(DexTest, MatchQualifiedNamesWithGlobalScope) {
593 RelationSlab(),
true);
594 FuzzyFindRequest Req;
597 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"y3"));
600TEST(DexTest, MatchQualifiedNamesWithOneScope) {
603 RefSlab(), RelationSlab(),
true);
604 FuzzyFindRequest Req;
606 Req.Scopes = {
"a::"};
607 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"a::y1",
"a::y2"));
610TEST(DexTest, MatchQualifiedNamesWithMultipleScopes) {
613 RefSlab(), RelationSlab(),
true);
614 FuzzyFindRequest Req;
616 Req.Scopes = {
"a::",
"b::"};
617 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"a::y1",
"a::y2",
"b::y3"));
620TEST(DexTest, NoMatchNestedScopes) {
622 RelationSlab(),
true);
623 FuzzyFindRequest Req;
625 Req.Scopes = {
"a::"};
626 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"a::y1"));
629TEST(DexTest, WildcardScope) {
631 RefSlab(), RelationSlab(),
true);
632 FuzzyFindRequest Req;
635 Req.Scopes = {
"a::"};
636 EXPECT_THAT(
match(*I, Req),
637 UnorderedElementsAre(
"a::y1",
"a::b::y2",
"c::y3"));
640TEST(DexTest, IgnoreCases) {
642 RelationSlab(),
true);
643 FuzzyFindRequest Req;
645 Req.Scopes = {
"ns::"};
646 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre(
"ns::ABC",
"ns::abc"));
649TEST(DexTest, UnknownPostingList) {
652 RelationSlab(),
true);
653 FuzzyFindRequest Req;
654 Req.Scopes = {
"ns2::"};
655 EXPECT_THAT(
match(*I, Req), UnorderedElementsAre());
658TEST(DexTest, Lookup) {
660 RelationSlab(),
true);
661 EXPECT_THAT(
lookup(*I,
SymbolID(
"ns::abc")), UnorderedElementsAre(
"ns::abc"));
663 UnorderedElementsAre(
"ns::abc",
"ns::xyz"));
665 UnorderedElementsAre(
"ns::xyz"));
666 EXPECT_THAT(
lookup(*I,
SymbolID(
"ns::nonono")), UnorderedElementsAre());
669TEST(DexTest, SymbolIndexOptionsFilter) {
670 auto CodeCompletionSymbol =
symbol(
"Completion");
671 auto NonCodeCompletionSymbol =
symbol(
"NoCompletion");
674 std::vector<Symbol>
Symbols{CodeCompletionSymbol, NonCodeCompletionSymbol};
675 Dex I(
Symbols, RefSlab(), RelationSlab(),
true);
676 FuzzyFindRequest Req;
678 Req.RestrictForCodeCompletion =
false;
679 EXPECT_THAT(
match(I, Req), ElementsAre(
"Completion",
"NoCompletion"));
680 Req.RestrictForCodeCompletion =
true;
681 EXPECT_THAT(
match(I, Req), ElementsAre(
"Completion"));
684TEST(DexTest, ProximityPathsBoosting) {
685 auto RootSymbol =
symbol(
"root::abc");
686 RootSymbol.CanonicalDeclaration.FileURI =
"unittest:///file.h";
687 auto CloseSymbol =
symbol(
"close::abc");
688 CloseSymbol.CanonicalDeclaration.FileURI =
"unittest:///a/b/c/d/e/f/file.h";
690 std::vector<Symbol>
Symbols{CloseSymbol, RootSymbol};
691 Dex I(
Symbols, RefSlab(), RelationSlab(),
true);
693 FuzzyFindRequest Req;
701 Req.ProximityPaths = {
testPath(
"a/b/c/d/e/f/file.h")};
702 EXPECT_THAT(
match(I, Req), ElementsAre(
"close::abc"));
706 Req.ProximityPaths = {
testPath(
"file.h")};
707 EXPECT_THAT(
match(I, Req), ElementsAre(
"root::abc"));
710TEST(DexTests, Refs) {
711 llvm::DenseMap<SymbolID, std::vector<Ref>> Refs;
713 auto &SymbolRefs = Refs[Sym.ID];
714 SymbolRefs.emplace_back();
715 SymbolRefs.back().Kind =
Kind;
716 SymbolRefs.back().Location.FileURI =
Filename;
726 Req.IDs.insert(
Foo.ID);
729 std::vector<std::string> Files;
730 EXPECT_FALSE(Dex(std::vector<Symbol>{
Foo,
Bar}, Refs, RelationSlab(),
true)
731 .refs(Req, [&](
const Ref &R) {
732 Files.push_back(R.Location.FileURI);
734 EXPECT_THAT(Files, UnorderedElementsAre(
"foo.h",
"foo.cc"));
738 EXPECT_TRUE(Dex(std::vector<Symbol>{
Foo,
Bar}, Refs, RelationSlab(),
true)
739 .refs(Req, [&](
const Ref &R) {
740 Files.push_back(R.Location.FileURI);
742 EXPECT_THAT(Files, ElementsAre(AnyOf(
"foo.h",
"foo.cc")));
745TEST(DexTests, Relations) {
747 auto Child1 =
symbol(
"Child1");
748 auto Child2 =
symbol(
"Child2");
755 Dex I{
Symbols, RefSlab(), Relations,
true};
758 RelationsRequest Req;
759 Req.Subjects.insert(
Parent.ID);
761 I.relations(Req, [&](
const SymbolID &Subject,
const Symbol &
Object) {
764 EXPECT_THAT(
Results, UnorderedElementsAre(Child1.ID, Child2.ID));
767TEST(DexIndex, IndexedFiles) {
770 auto Size =
Symbols.bytes() + Refs.bytes();
771 auto Data = std::make_pair(std::move(
Symbols), std::move(Refs));
772 llvm::StringSet<> Files = {
"unittest:///foo.cc",
"unittest:///bar.cc"};
773 Dex I(std::move(Data.first), std::move(Data.second), RelationSlab(),
775 auto ContainsFile = I.indexedFiles();
781TEST(DexTest, PreferredTypesBoosting) {
787 std::vector<Symbol>
Symbols{Sym1, Sym2};
788 Dex I(
Symbols, RefSlab(), RelationSlab(),
true);
790 FuzzyFindRequest Req;
796 Req.PreferredTypes = {std::string(Sym1.Type)};
797 EXPECT_THAT(
match(I, Req), ElementsAre(
"t1"));
799 Req.PreferredTypes = {std::string(Sym2.Type)};
800 EXPECT_THAT(
match(I, Req), ElementsAre(
"t2"));
803TEST(DexTest, TemplateSpecialization) {
804 SymbolSlab::Builder
B;
806 Symbol S =
symbol(
"TempSpec");
812 S.TemplateSpecializationArgs =
"<int, bool>";
813 S.SymInfo.Properties =
static_cast<index::SymbolPropertySet
>(
814 index::SymbolProperty::TemplateSpecialization);
819 S.TemplateSpecializationArgs =
"<int, U>";
820 S.SymInfo.Properties =
static_cast<index::SymbolPropertySet
>(
821 index::SymbolProperty::TemplatePartialSpecialization);
825 dex::Dex::build(std::move(B).build(), RefSlab(), RelationSlab(),
true);
826 FuzzyFindRequest Req;
829 Req.Query =
"TempSpec";
830 EXPECT_THAT(
match(*I, Req),
831 UnorderedElementsAre(
"TempSpec",
"TempSpec<int, bool>",
832 "TempSpec<int, U>"));
835 Req.Query =
"TempSpec<int";
836 EXPECT_THAT(
match(*I, Req), IsEmpty());
std::vector< CodeCompletionResult > Results
This defines Dex - a symbol index implementation based on query iterators over symbol tokens,...
std::string Filename
Filename as a string.
Symbol index queries consist of specific requirements for the requested symbol, such as high fuzzy ma...
std::vector< llvm::StringRef > Strings
Trigrams are attributes of the symbol unqualified name used to effectively extract symbols which can ...
static std::unique_ptr< SymbolIndex > build(SymbolSlab, RefSlab, RelationSlab, bool SupportContainedRefs)
Builds an index from slabs. The index takes ownership of the slab.
Kind
Kind specifies Token type which defines semantics for the internal representation.
@ Trigram
Represents trigram used for fuzzy search of unqualified symbol names.
Token objects represent a characteristic of a symbol, which can be used to perform efficient search.
llvm::SmallVector< llvm::StringRef, ProximityURILimit > generateProximityURIs(llvm::StringRef URI)
Returns Search Token for a number of parent directories of given Path.
std::vector< std::pair< DocID, float > > consume(Iterator &It)
Advances the iterator until it is exhausted.
void generateIdentifierTrigrams(llvm::StringRef Identifier, std::vector< Trigram > &Result)
Produces list of unique fuzzy-search trigrams from unqualified symbol.
std::vector< Token > generateQueryTrigrams(llvm::StringRef Query)
Returns list of unique fuzzy-search trigrams given a query.
std::string testPath(PathRef File, llvm::sys::path::Style Style)
std::vector< std::string > match(const SymbolIndex &I, const FuzzyFindRequest &Req, bool *Incomplete)
TEST(BackgroundQueueTest, Priority)
Symbol symbol(llvm::StringRef QName)
SymbolSlab generateSymbols(std::vector< std::string > QualifiedNames)
RefKind
Describes the kind of a cross-reference.
std::vector< std::string > lookup(const SymbolIndex &I, llvm::ArrayRef< SymbolID > IDs)
SymbolSlab generateNumSymbols(int Begin, int End)
std::array< uint8_t, 20 > SymbolID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
@ IndexedForCodeCompletion
Whether or not this symbol is meant to be used for the code completion.