2017-12-14 19:25:49 +08:00
|
|
|
//===-- IndexTests.cpp -------------------------------*- C++ -*-----------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2017-12-14 19:25:49 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2018-09-01 03:53:37 +08:00
|
|
|
#include "Annotations.h"
|
2018-08-20 22:39:32 +08:00
|
|
|
#include "TestIndex.h"
|
2018-09-01 03:53:37 +08:00
|
|
|
#include "TestTU.h"
|
|
|
|
#include "index/FileIndex.h"
|
2017-12-14 19:25:49 +08:00
|
|
|
#include "index/Index.h"
|
|
|
|
#include "index/MemIndex.h"
|
2018-01-15 20:33:00 +08:00
|
|
|
#include "index/Merge.h"
|
[clangd] Store explicit template specializations in index for code navigation purposes
Summary:
This introduces ~4k new symbols, and ~10k refs for LLVM. We need that
information for providing better code navigation support:
- When references for a class template is requested, we should return these specializations as well.
- When children of a specialization is requested, we should be able to query for those symbols(instead of just class template)
Number of symbols: 378574 -> 382784
Number of refs: 5098857 -> 5110689
Reviewers: hokein, gribozavr
Reviewed By: gribozavr
Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59083
llvm-svn: 356125
2019-03-14 16:35:17 +08:00
|
|
|
#include "index/Symbol.h"
|
|
|
|
#include "clang/Index/IndexSymbol.h"
|
2018-09-10 19:46:07 +08:00
|
|
|
#include "gmock/gmock.h"
|
2017-12-14 19:25:49 +08:00
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
2019-05-06 18:08:47 +08:00
|
|
|
using ::testing::_;
|
|
|
|
using ::testing::AllOf;
|
|
|
|
using ::testing::AnyOf;
|
|
|
|
using ::testing::ElementsAre;
|
|
|
|
using ::testing::IsEmpty;
|
|
|
|
using ::testing::Pair;
|
|
|
|
using ::testing::Pointee;
|
|
|
|
using ::testing::UnorderedElementsAre;
|
2017-12-14 19:25:49 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
|
|
|
namespace {
|
|
|
|
|
2017-12-24 03:38:03 +08:00
|
|
|
MATCHER_P(Named, N, "") { return arg.Name == N; }
|
[clangd] SymbolOccurrences -> Refs and cleanup
Summary:
A few things that I noticed while merging the SwapIndex patch:
- SymbolOccurrences and particularly SymbolOccurrenceSlab are unwieldy names,
and these names appear *a lot*. Ref, RefSlab, etc seem clear enough
and read/format much better.
- The asymmetry between SymbolSlab and RefSlab (build() vs freeze()) is
confusing and irritating, and doesn't even save much code.
Avoiding RefSlab::Builder was my idea, but it was a bad one; add it.
- DenseMap<SymbolID, ArrayRef<Ref>> seems like a reasonable compromise for
constructing MemIndex - and means many less wasted allocations than the
current DenseMap<SymbolID, vector<Ref*>> for FileIndex, and none for
slabs.
- RefSlab::find() is not actually used for anything, so we can throw
away the DenseMap and keep the representation much more compact.
- A few naming/consistency fixes: e.g. Slabs,Refs -> Symbols,Refs.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51605
llvm-svn: 341368
2018-09-04 22:39:56 +08:00
|
|
|
MATCHER_P(RefRange, Range, "") {
|
[clangd] Encode Line/Column as a 32-bits integer.
Summary:
This would buy us more memory. Using a 32-bits integer is enough for
most human-readable source code (up to 4M lines and 4K columns).
Previsouly, we used 8 bytes for a position, now 4 bytes, it would save
us 8 bytes for each Ref and each Symbol instance.
For LLVM-project binary index file, we save ~13% memory.
| Before | After |
| 412MB | 355MB |
Reviewers: sammccall
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53363
llvm-svn: 344735
2018-10-18 18:43:50 +08:00
|
|
|
return std::make_tuple(arg.Location.Start.line(), arg.Location.Start.column(),
|
|
|
|
arg.Location.End.line(), arg.Location.End.column()) ==
|
|
|
|
std::make_tuple(Range.start.line, Range.start.character,
|
|
|
|
Range.end.line, Range.end.character);
|
2018-09-01 03:53:37 +08:00
|
|
|
}
|
2018-11-14 19:55:45 +08:00
|
|
|
MATCHER_P(FileURI, F, "") { return StringRef(arg.Location.FileURI) == F; }
|
2017-12-24 03:38:03 +08:00
|
|
|
|
[clangd] Encode Line/Column as a 32-bits integer.
Summary:
This would buy us more memory. Using a 32-bits integer is enough for
most human-readable source code (up to 4M lines and 4K columns).
Previsouly, we used 8 bytes for a position, now 4 bytes, it would save
us 8 bytes for each Ref and each Symbol instance.
For LLVM-project binary index file, we save ~13% memory.
| Before | After |
| 412MB | 355MB |
Reviewers: sammccall
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53363
llvm-svn: 344735
2018-10-18 18:43:50 +08:00
|
|
|
TEST(SymbolLocation, Position) {
|
|
|
|
using Position = SymbolLocation::Position;
|
|
|
|
Position Pos;
|
|
|
|
|
|
|
|
Pos.setLine(1);
|
|
|
|
EXPECT_EQ(1u, Pos.line());
|
|
|
|
Pos.setColumn(2);
|
|
|
|
EXPECT_EQ(2u, Pos.column());
|
2018-10-19 16:35:24 +08:00
|
|
|
EXPECT_FALSE(Pos.hasOverflow());
|
[clangd] Encode Line/Column as a 32-bits integer.
Summary:
This would buy us more memory. Using a 32-bits integer is enough for
most human-readable source code (up to 4M lines and 4K columns).
Previsouly, we used 8 bytes for a position, now 4 bytes, it would save
us 8 bytes for each Ref and each Symbol instance.
For LLVM-project binary index file, we save ~13% memory.
| Before | After |
| 412MB | 355MB |
Reviewers: sammccall
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53363
llvm-svn: 344735
2018-10-18 18:43:50 +08:00
|
|
|
|
|
|
|
Pos.setLine(Position::MaxLine + 1); // overflow
|
2018-10-19 16:35:24 +08:00
|
|
|
EXPECT_TRUE(Pos.hasOverflow());
|
[clangd] Encode Line/Column as a 32-bits integer.
Summary:
This would buy us more memory. Using a 32-bits integer is enough for
most human-readable source code (up to 4M lines and 4K columns).
Previsouly, we used 8 bytes for a position, now 4 bytes, it would save
us 8 bytes for each Ref and each Symbol instance.
For LLVM-project binary index file, we save ~13% memory.
| Before | After |
| 412MB | 355MB |
Reviewers: sammccall
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53363
llvm-svn: 344735
2018-10-18 18:43:50 +08:00
|
|
|
EXPECT_EQ(Pos.line(), Position::MaxLine);
|
2018-10-19 16:35:24 +08:00
|
|
|
Pos.setLine(1); // reset the overflowed line.
|
|
|
|
|
[clangd] Encode Line/Column as a 32-bits integer.
Summary:
This would buy us more memory. Using a 32-bits integer is enough for
most human-readable source code (up to 4M lines and 4K columns).
Previsouly, we used 8 bytes for a position, now 4 bytes, it would save
us 8 bytes for each Ref and each Symbol instance.
For LLVM-project binary index file, we save ~13% memory.
| Before | After |
| 412MB | 355MB |
Reviewers: sammccall
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53363
llvm-svn: 344735
2018-10-18 18:43:50 +08:00
|
|
|
Pos.setColumn(Position::MaxColumn + 1); // overflow
|
2018-10-19 16:35:24 +08:00
|
|
|
EXPECT_TRUE(Pos.hasOverflow());
|
[clangd] Encode Line/Column as a 32-bits integer.
Summary:
This would buy us more memory. Using a 32-bits integer is enough for
most human-readable source code (up to 4M lines and 4K columns).
Previsouly, we used 8 bytes for a position, now 4 bytes, it would save
us 8 bytes for each Ref and each Symbol instance.
For LLVM-project binary index file, we save ~13% memory.
| Before | After |
| 412MB | 355MB |
Reviewers: sammccall
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53363
llvm-svn: 344735
2018-10-18 18:43:50 +08:00
|
|
|
EXPECT_EQ(Pos.column(), Position::MaxColumn);
|
|
|
|
}
|
|
|
|
|
2017-12-24 03:38:03 +08:00
|
|
|
TEST(SymbolSlab, FindAndIterate) {
|
|
|
|
SymbolSlab::Builder B;
|
|
|
|
B.insert(symbol("Z"));
|
|
|
|
B.insert(symbol("Y"));
|
|
|
|
B.insert(symbol("X"));
|
|
|
|
EXPECT_EQ(nullptr, B.find(SymbolID("W")));
|
|
|
|
for (const char *Sym : {"X", "Y", "Z"})
|
|
|
|
EXPECT_THAT(B.find(SymbolID(Sym)), Pointee(Named(Sym)));
|
|
|
|
|
|
|
|
SymbolSlab S = std::move(B).build();
|
|
|
|
EXPECT_THAT(S, UnorderedElementsAre(Named("X"), Named("Y"), Named("Z")));
|
|
|
|
EXPECT_EQ(S.end(), S.find(SymbolID("W")));
|
|
|
|
for (const char *Sym : {"X", "Y", "Z"})
|
|
|
|
EXPECT_THAT(*S.find(SymbolID(Sym)), Named(Sym));
|
|
|
|
}
|
|
|
|
|
2019-06-03 12:55:46 +08:00
|
|
|
TEST(RelationSlab, Lookup) {
|
|
|
|
SymbolID A{"A"};
|
|
|
|
SymbolID B{"B"};
|
|
|
|
SymbolID C{"C"};
|
|
|
|
SymbolID D{"D"};
|
|
|
|
|
|
|
|
RelationSlab::Builder Builder;
|
|
|
|
Builder.insert(Relation{A, index::SymbolRole::RelationBaseOf, B});
|
|
|
|
Builder.insert(Relation{A, index::SymbolRole::RelationBaseOf, C});
|
|
|
|
Builder.insert(Relation{B, index::SymbolRole::RelationBaseOf, D});
|
|
|
|
Builder.insert(Relation{C, index::SymbolRole::RelationBaseOf, D});
|
|
|
|
Builder.insert(Relation{B, index::SymbolRole::RelationChildOf, A});
|
|
|
|
Builder.insert(Relation{C, index::SymbolRole::RelationChildOf, A});
|
|
|
|
Builder.insert(Relation{D, index::SymbolRole::RelationChildOf, B});
|
|
|
|
Builder.insert(Relation{D, index::SymbolRole::RelationChildOf, C});
|
|
|
|
|
|
|
|
RelationSlab Slab = std::move(Builder).build();
|
|
|
|
EXPECT_THAT(
|
|
|
|
Slab.lookup(A, index::SymbolRole::RelationBaseOf),
|
|
|
|
UnorderedElementsAre(Relation{A, index::SymbolRole::RelationBaseOf, B},
|
|
|
|
Relation{A, index::SymbolRole::RelationBaseOf, C}));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(RelationSlab, Duplicates) {
|
|
|
|
SymbolID A{"A"};
|
|
|
|
SymbolID B{"B"};
|
|
|
|
SymbolID C{"C"};
|
|
|
|
|
|
|
|
RelationSlab::Builder Builder;
|
|
|
|
Builder.insert(Relation{A, index::SymbolRole::RelationBaseOf, B});
|
|
|
|
Builder.insert(Relation{A, index::SymbolRole::RelationBaseOf, C});
|
|
|
|
Builder.insert(Relation{A, index::SymbolRole::RelationBaseOf, B});
|
|
|
|
|
|
|
|
RelationSlab Slab = std::move(Builder).build();
|
|
|
|
EXPECT_THAT(Slab, UnorderedElementsAre(
|
|
|
|
Relation{A, index::SymbolRole::RelationBaseOf, B},
|
|
|
|
Relation{A, index::SymbolRole::RelationBaseOf, C}));
|
|
|
|
}
|
|
|
|
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
TEST(SwapIndexTest, OldIndexRecycled) {
|
|
|
|
auto Token = std::make_shared<int>();
|
|
|
|
std::weak_ptr<int> WeakToken = Token;
|
2017-12-14 19:25:49 +08:00
|
|
|
|
2019-08-15 07:52:23 +08:00
|
|
|
SwapIndex S(std::make_unique<MemIndex>(SymbolSlab(), RefSlab(),
|
2019-06-15 10:26:47 +08:00
|
|
|
RelationSlab(), std::move(Token),
|
|
|
|
/*BackingDataSize=*/0));
|
2018-09-10 19:46:07 +08:00
|
|
|
EXPECT_FALSE(WeakToken.expired()); // Current MemIndex keeps it alive.
|
2019-08-15 07:52:23 +08:00
|
|
|
S.reset(std::make_unique<MemIndex>()); // Now the MemIndex is destroyed.
|
2018-09-10 19:46:07 +08:00
|
|
|
EXPECT_TRUE(WeakToken.expired()); // So the token is too.
|
2017-12-14 19:25:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MemIndexTest, MemIndexDeduplicate) {
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
std::vector<Symbol> Symbols = {symbol("1"), symbol("2"), symbol("3"),
|
|
|
|
symbol("2") /* duplicate */};
|
2017-12-14 19:25:49 +08:00
|
|
|
FuzzyFindRequest Req;
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
Req.Query = "2";
|
2018-11-06 19:08:17 +08:00
|
|
|
Req.AnyScope = true;
|
2019-06-15 10:26:47 +08:00
|
|
|
MemIndex I(Symbols, RefSlab(), RelationSlab());
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(match(I, Req), ElementsAre("2"));
|
2017-12-14 19:25:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MemIndexTest, MemIndexLimitedNumMatches) {
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I =
|
|
|
|
MemIndex::build(generateNumSymbols(0, 100), RefSlab(), RelationSlab());
|
2017-12-14 19:25:49 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "5";
|
2018-11-06 19:08:17 +08:00
|
|
|
Req.AnyScope = true;
|
2018-09-13 22:27:03 +08:00
|
|
|
Req.Limit = 3;
|
2018-02-19 21:04:41 +08:00
|
|
|
bool Incomplete;
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
auto Matches = match(*I, Req, &Incomplete);
|
2018-09-13 22:27:03 +08:00
|
|
|
EXPECT_TRUE(Req.Limit);
|
|
|
|
EXPECT_EQ(Matches.size(), *Req.Limit);
|
2018-02-19 21:04:41 +08:00
|
|
|
EXPECT_TRUE(Incomplete);
|
2017-12-14 19:25:49 +08:00
|
|
|
}
|
|
|
|
|
2018-01-18 16:35:04 +08:00
|
|
|
TEST(MemIndexTest, FuzzyMatch) {
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
auto I = MemIndex::build(
|
2018-09-01 03:53:37 +08:00
|
|
|
generateSymbols({"LaughingOutLoud", "LionPopulation", "LittleOldLady"}),
|
2019-06-15 10:26:47 +08:00
|
|
|
RefSlab(), RelationSlab());
|
2018-01-18 16:35:04 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "lol";
|
2018-11-06 19:08:17 +08:00
|
|
|
Req.AnyScope = true;
|
2018-09-13 22:27:03 +08:00
|
|
|
Req.Limit = 2;
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(match(*I, Req),
|
2018-01-18 16:35:04 +08:00
|
|
|
UnorderedElementsAre("LaughingOutLoud", "LittleOldLady"));
|
|
|
|
}
|
|
|
|
|
2017-12-19 19:37:40 +08:00
|
|
|
TEST(MemIndexTest, MatchQualifiedNamesWithoutSpecificScope) {
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I = MemIndex::build(generateSymbols({"a::y1", "b::y2", "y3"}), RefSlab(),
|
|
|
|
RelationSlab());
|
2017-12-19 19:37:40 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "y";
|
2018-11-06 19:08:17 +08:00
|
|
|
Req.AnyScope = true;
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(match(*I, Req), UnorderedElementsAre("a::y1", "b::y2", "y3"));
|
2017-12-19 19:37:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MemIndexTest, MatchQualifiedNamesWithGlobalScope) {
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I = MemIndex::build(generateSymbols({"a::y1", "b::y2", "y3"}), RefSlab(),
|
|
|
|
RelationSlab());
|
2017-12-19 19:37:40 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "y";
|
2017-12-20 00:50:37 +08:00
|
|
|
Req.Scopes = {""};
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(match(*I, Req), UnorderedElementsAre("y3"));
|
2017-12-19 19:37:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MemIndexTest, MatchQualifiedNamesWithOneScope) {
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
auto I = MemIndex::build(
|
2019-06-15 10:26:47 +08:00
|
|
|
generateSymbols({"a::y1", "a::y2", "a::x", "b::y2", "y3"}), RefSlab(),
|
|
|
|
RelationSlab());
|
2017-12-19 19:37:40 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "y";
|
2018-03-14 17:48:05 +08:00
|
|
|
Req.Scopes = {"a::"};
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(match(*I, Req), UnorderedElementsAre("a::y1", "a::y2"));
|
2017-12-19 19:37:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MemIndexTest, MatchQualifiedNamesWithMultipleScopes) {
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
auto I = MemIndex::build(
|
2019-06-15 10:26:47 +08:00
|
|
|
generateSymbols({"a::y1", "a::y2", "a::x", "b::y3", "y3"}), RefSlab(),
|
|
|
|
RelationSlab());
|
2017-12-19 19:37:40 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "y";
|
2018-03-14 17:48:05 +08:00
|
|
|
Req.Scopes = {"a::", "b::"};
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(match(*I, Req), UnorderedElementsAre("a::y1", "a::y2", "b::y3"));
|
2017-12-19 19:37:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MemIndexTest, NoMatchNestedScopes) {
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I = MemIndex::build(generateSymbols({"a::y1", "a::b::y2"}), RefSlab(),
|
|
|
|
RelationSlab());
|
2017-12-19 19:37:40 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "y";
|
2018-03-14 17:48:05 +08:00
|
|
|
Req.Scopes = {"a::"};
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(match(*I, Req), UnorderedElementsAre("a::y1"));
|
2017-12-19 19:37:40 +08:00
|
|
|
}
|
|
|
|
|
2017-12-20 17:29:54 +08:00
|
|
|
TEST(MemIndexTest, IgnoreCases) {
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I = MemIndex::build(generateSymbols({"ns::ABC", "ns::abc"}), RefSlab(),
|
|
|
|
RelationSlab());
|
2017-12-20 17:29:54 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "AB";
|
2018-03-14 17:48:05 +08:00
|
|
|
Req.Scopes = {"ns::"};
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(match(*I, Req), UnorderedElementsAre("ns::ABC", "ns::abc"));
|
2017-12-20 17:29:54 +08:00
|
|
|
}
|
|
|
|
|
2018-03-14 17:48:05 +08:00
|
|
|
TEST(MemIndexTest, Lookup) {
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I = MemIndex::build(generateSymbols({"ns::abc", "ns::xyz"}), RefSlab(),
|
|
|
|
RelationSlab());
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(lookup(*I, SymbolID("ns::abc")), UnorderedElementsAre("ns::abc"));
|
|
|
|
EXPECT_THAT(lookup(*I, {SymbolID("ns::abc"), SymbolID("ns::xyz")}),
|
2018-03-14 17:48:05 +08:00
|
|
|
UnorderedElementsAre("ns::abc", "ns::xyz"));
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(lookup(*I, {SymbolID("ns::nonono"), SymbolID("ns::xyz")}),
|
2018-03-14 17:48:05 +08:00
|
|
|
UnorderedElementsAre("ns::xyz"));
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
EXPECT_THAT(lookup(*I, SymbolID("ns::nonono")), UnorderedElementsAre());
|
2018-03-14 17:48:05 +08:00
|
|
|
}
|
|
|
|
|
[clangd] Store explicit template specializations in index for code navigation purposes
Summary:
This introduces ~4k new symbols, and ~10k refs for LLVM. We need that
information for providing better code navigation support:
- When references for a class template is requested, we should return these specializations as well.
- When children of a specialization is requested, we should be able to query for those symbols(instead of just class template)
Number of symbols: 378574 -> 382784
Number of refs: 5098857 -> 5110689
Reviewers: hokein, gribozavr
Reviewed By: gribozavr
Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59083
llvm-svn: 356125
2019-03-14 16:35:17 +08:00
|
|
|
TEST(MemIndexTest, TemplateSpecialization) {
|
|
|
|
SymbolSlab::Builder B;
|
|
|
|
|
|
|
|
Symbol S = symbol("TempSpec");
|
2019-04-12 18:09:37 +08:00
|
|
|
S.ID = SymbolID("1");
|
[clangd] Store explicit template specializations in index for code navigation purposes
Summary:
This introduces ~4k new symbols, and ~10k refs for LLVM. We need that
information for providing better code navigation support:
- When references for a class template is requested, we should return these specializations as well.
- When children of a specialization is requested, we should be able to query for those symbols(instead of just class template)
Number of symbols: 378574 -> 382784
Number of refs: 5098857 -> 5110689
Reviewers: hokein, gribozavr
Reviewed By: gribozavr
Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59083
llvm-svn: 356125
2019-03-14 16:35:17 +08:00
|
|
|
B.insert(S);
|
|
|
|
|
2019-03-21 06:51:56 +08:00
|
|
|
S = symbol("TempSpec");
|
2019-04-12 18:09:37 +08:00
|
|
|
S.ID = SymbolID("2");
|
|
|
|
S.TemplateSpecializationArgs = "<int, bool>";
|
[clangd] Store explicit template specializations in index for code navigation purposes
Summary:
This introduces ~4k new symbols, and ~10k refs for LLVM. We need that
information for providing better code navigation support:
- When references for a class template is requested, we should return these specializations as well.
- When children of a specialization is requested, we should be able to query for those symbols(instead of just class template)
Number of symbols: 378574 -> 382784
Number of refs: 5098857 -> 5110689
Reviewers: hokein, gribozavr
Reviewed By: gribozavr
Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59083
llvm-svn: 356125
2019-03-14 16:35:17 +08:00
|
|
|
S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
|
|
|
|
index::SymbolProperty::TemplateSpecialization);
|
|
|
|
B.insert(S);
|
|
|
|
|
2019-03-21 06:51:56 +08:00
|
|
|
S = symbol("TempSpec");
|
2019-04-12 18:09:37 +08:00
|
|
|
S.ID = SymbolID("3");
|
|
|
|
S.TemplateSpecializationArgs = "<int, U>";
|
[clangd] Store explicit template specializations in index for code navigation purposes
Summary:
This introduces ~4k new symbols, and ~10k refs for LLVM. We need that
information for providing better code navigation support:
- When references for a class template is requested, we should return these specializations as well.
- When children of a specialization is requested, we should be able to query for those symbols(instead of just class template)
Number of symbols: 378574 -> 382784
Number of refs: 5098857 -> 5110689
Reviewers: hokein, gribozavr
Reviewed By: gribozavr
Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59083
llvm-svn: 356125
2019-03-14 16:35:17 +08:00
|
|
|
S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
|
|
|
|
index::SymbolProperty::TemplatePartialSpecialization);
|
|
|
|
B.insert(S);
|
|
|
|
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I = MemIndex::build(std::move(B).build(), RefSlab(), RelationSlab());
|
[clangd] Store explicit template specializations in index for code navigation purposes
Summary:
This introduces ~4k new symbols, and ~10k refs for LLVM. We need that
information for providing better code navigation support:
- When references for a class template is requested, we should return these specializations as well.
- When children of a specialization is requested, we should be able to query for those symbols(instead of just class template)
Number of symbols: 378574 -> 382784
Number of refs: 5098857 -> 5110689
Reviewers: hokein, gribozavr
Reviewed By: gribozavr
Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59083
llvm-svn: 356125
2019-03-14 16:35:17 +08:00
|
|
|
FuzzyFindRequest Req;
|
2019-03-21 06:51:56 +08:00
|
|
|
Req.AnyScope = true;
|
2019-03-20 17:43:38 +08:00
|
|
|
|
2019-04-12 18:09:37 +08:00
|
|
|
Req.Query = "TempSpec";
|
|
|
|
EXPECT_THAT(match(*I, Req),
|
|
|
|
UnorderedElementsAre("TempSpec", "TempSpec<int, bool>",
|
|
|
|
"TempSpec<int, U>"));
|
|
|
|
|
|
|
|
// FIXME: Add filtering for template argument list.
|
|
|
|
Req.Query = "TempSpec<int";
|
|
|
|
EXPECT_THAT(match(*I, Req), IsEmpty());
|
[clangd] Store explicit template specializations in index for code navigation purposes
Summary:
This introduces ~4k new symbols, and ~10k refs for LLVM. We need that
information for providing better code navigation support:
- When references for a class template is requested, we should return these specializations as well.
- When children of a specialization is requested, we should be able to query for those symbols(instead of just class template)
Number of symbols: 378574 -> 382784
Number of refs: 5098857 -> 5110689
Reviewers: hokein, gribozavr
Reviewed By: gribozavr
Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59083
llvm-svn: 356125
2019-03-14 16:35:17 +08:00
|
|
|
}
|
|
|
|
|
2018-03-14 17:48:05 +08:00
|
|
|
TEST(MergeIndexTest, Lookup) {
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I = MemIndex::build(generateSymbols({"ns::A", "ns::B"}), RefSlab(),
|
|
|
|
RelationSlab()),
|
|
|
|
J = MemIndex::build(generateSymbols({"ns::B", "ns::C"}), RefSlab(),
|
|
|
|
RelationSlab());
|
2018-10-04 22:20:22 +08:00
|
|
|
MergedIndex M(I.get(), J.get());
|
|
|
|
EXPECT_THAT(lookup(M, SymbolID("ns::A")), UnorderedElementsAre("ns::A"));
|
|
|
|
EXPECT_THAT(lookup(M, SymbolID("ns::B")), UnorderedElementsAre("ns::B"));
|
|
|
|
EXPECT_THAT(lookup(M, SymbolID("ns::C")), UnorderedElementsAre("ns::C"));
|
|
|
|
EXPECT_THAT(lookup(M, {SymbolID("ns::A"), SymbolID("ns::B")}),
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
UnorderedElementsAre("ns::A", "ns::B"));
|
2018-10-04 22:20:22 +08:00
|
|
|
EXPECT_THAT(lookup(M, {SymbolID("ns::A"), SymbolID("ns::C")}),
|
[clangd] Factor out the data-swapping functionality from MemIndex/DexIndex.
Summary:
This is now handled by a wrapper class SwapIndex, so MemIndex/DexIndex can be
immutable and focus on their job.
Old and busted:
I have a MemIndex, which holds a shared_ptr<vector<Symbol*>>, which keeps the
symbol slab alive. I update by calling build(shared_ptr<vector<Symbol*>>).
New hotness: I have a SwapIndex, which holds a unique_ptr<SymbolIndex>, which
holds a MemIndex, which holds a shared_ptr<void>, which keeps backing
data alive.
I update by building a new MemIndex and calling SwapIndex::reset().
Reviewers: kbobyrev, ioeric
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51422
llvm-svn: 341318
2018-09-03 22:37:43 +08:00
|
|
|
UnorderedElementsAre("ns::A", "ns::C"));
|
2018-10-04 22:20:22 +08:00
|
|
|
EXPECT_THAT(lookup(M, SymbolID("ns::D")), UnorderedElementsAre());
|
|
|
|
EXPECT_THAT(lookup(M, {}), UnorderedElementsAre());
|
2018-03-14 17:48:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MergeIndexTest, FuzzyFind) {
|
2019-06-15 10:26:47 +08:00
|
|
|
auto I = MemIndex::build(generateSymbols({"ns::A", "ns::B"}), RefSlab(),
|
|
|
|
RelationSlab()),
|
|
|
|
J = MemIndex::build(generateSymbols({"ns::B", "ns::C"}), RefSlab(),
|
|
|
|
RelationSlab());
|
2018-01-15 20:33:00 +08:00
|
|
|
FuzzyFindRequest Req;
|
2018-03-14 17:48:05 +08:00
|
|
|
Req.Scopes = {"ns::"};
|
2018-10-04 22:20:22 +08:00
|
|
|
EXPECT_THAT(match(MergedIndex(I.get(), J.get()), Req),
|
2018-01-15 20:33:00 +08:00
|
|
|
UnorderedElementsAre("ns::A", "ns::B", "ns::C"));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MergeTest, Merge) {
|
|
|
|
Symbol L, R;
|
|
|
|
L.ID = R.ID = SymbolID("hello");
|
2018-08-20 22:39:32 +08:00
|
|
|
L.Name = R.Name = "Foo"; // same in both
|
2018-02-07 00:10:35 +08:00
|
|
|
L.CanonicalDeclaration.FileURI = "file:///left.h"; // differs
|
|
|
|
R.CanonicalDeclaration.FileURI = "file:///right.h";
|
2018-03-12 22:49:09 +08:00
|
|
|
L.References = 1;
|
|
|
|
R.References = 2;
|
2018-06-23 00:11:35 +08:00
|
|
|
L.Signature = "()"; // present in left only
|
|
|
|
R.CompletionSnippetSuffix = "{$1:0}"; // present in right only
|
2018-08-31 21:55:01 +08:00
|
|
|
R.Documentation = "--doc--";
|
2018-07-05 14:20:41 +08:00
|
|
|
L.Origin = SymbolOrigin::Dynamic;
|
|
|
|
R.Origin = SymbolOrigin::Static;
|
2018-12-20 21:05:46 +08:00
|
|
|
R.Type = "expectedType";
|
2018-01-15 20:33:00 +08:00
|
|
|
|
2018-08-31 21:55:01 +08:00
|
|
|
Symbol M = mergeSymbol(L, R);
|
2018-01-15 20:33:00 +08:00
|
|
|
EXPECT_EQ(M.Name, "Foo");
|
2018-11-14 19:55:45 +08:00
|
|
|
EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:///left.h");
|
2018-03-12 22:49:09 +08:00
|
|
|
EXPECT_EQ(M.References, 3u);
|
2018-06-23 00:11:35 +08:00
|
|
|
EXPECT_EQ(M.Signature, "()");
|
|
|
|
EXPECT_EQ(M.CompletionSnippetSuffix, "{$1:0}");
|
2018-08-31 21:55:01 +08:00
|
|
|
EXPECT_EQ(M.Documentation, "--doc--");
|
2018-12-20 21:05:46 +08:00
|
|
|
EXPECT_EQ(M.Type, "expectedType");
|
2018-07-05 14:20:41 +08:00
|
|
|
EXPECT_EQ(M.Origin,
|
|
|
|
SymbolOrigin::Dynamic | SymbolOrigin::Static | SymbolOrigin::Merge);
|
2018-01-15 20:33:00 +08:00
|
|
|
}
|
|
|
|
|
2018-02-09 22:42:01 +08:00
|
|
|
TEST(MergeTest, PreferSymbolWithDefn) {
|
|
|
|
Symbol L, R;
|
|
|
|
|
|
|
|
L.ID = R.ID = SymbolID("hello");
|
|
|
|
L.CanonicalDeclaration.FileURI = "file:/left.h";
|
|
|
|
R.CanonicalDeclaration.FileURI = "file:/right.h";
|
2018-06-23 00:11:35 +08:00
|
|
|
L.Name = "left";
|
|
|
|
R.Name = "right";
|
2018-02-09 22:42:01 +08:00
|
|
|
|
2018-08-31 21:55:01 +08:00
|
|
|
Symbol M = mergeSymbol(L, R);
|
2018-11-14 19:55:45 +08:00
|
|
|
EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/left.h");
|
|
|
|
EXPECT_EQ(StringRef(M.Definition.FileURI), "");
|
2018-06-23 00:11:35 +08:00
|
|
|
EXPECT_EQ(M.Name, "left");
|
2018-02-09 22:42:01 +08:00
|
|
|
|
|
|
|
R.Definition.FileURI = "file:/right.cpp"; // Now right will be favored.
|
2018-08-31 21:55:01 +08:00
|
|
|
M = mergeSymbol(L, R);
|
2018-11-14 19:55:45 +08:00
|
|
|
EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/right.h");
|
|
|
|
EXPECT_EQ(StringRef(M.Definition.FileURI), "file:/right.cpp");
|
2018-06-23 00:11:35 +08:00
|
|
|
EXPECT_EQ(M.Name, "right");
|
2018-02-09 22:42:01 +08:00
|
|
|
}
|
|
|
|
|
2019-02-11 23:05:29 +08:00
|
|
|
TEST(MergeTest, PreferSymbolLocationInCodegenFile) {
|
|
|
|
Symbol L, R;
|
|
|
|
|
|
|
|
L.ID = R.ID = SymbolID("hello");
|
|
|
|
L.CanonicalDeclaration.FileURI = "file:/x.proto.h";
|
|
|
|
R.CanonicalDeclaration.FileURI = "file:/x.proto";
|
|
|
|
|
|
|
|
Symbol M = mergeSymbol(L, R);
|
|
|
|
EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/x.proto");
|
|
|
|
|
|
|
|
// Prefer L if both have codegen suffix.
|
|
|
|
L.CanonicalDeclaration.FileURI = "file:/y.proto";
|
|
|
|
M = mergeSymbol(L, R);
|
|
|
|
EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/y.proto");
|
|
|
|
}
|
|
|
|
|
[clangd] SymbolOccurrences -> Refs and cleanup
Summary:
A few things that I noticed while merging the SwapIndex patch:
- SymbolOccurrences and particularly SymbolOccurrenceSlab are unwieldy names,
and these names appear *a lot*. Ref, RefSlab, etc seem clear enough
and read/format much better.
- The asymmetry between SymbolSlab and RefSlab (build() vs freeze()) is
confusing and irritating, and doesn't even save much code.
Avoiding RefSlab::Builder was my idea, but it was a bad one; add it.
- DenseMap<SymbolID, ArrayRef<Ref>> seems like a reasonable compromise for
constructing MemIndex - and means many less wasted allocations than the
current DenseMap<SymbolID, vector<Ref*>> for FileIndex, and none for
slabs.
- RefSlab::find() is not actually used for anything, so we can throw
away the DenseMap and keep the representation much more compact.
- A few naming/consistency fixes: e.g. Slabs,Refs -> Symbols,Refs.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51605
llvm-svn: 341368
2018-09-04 22:39:56 +08:00
|
|
|
TEST(MergeIndexTest, Refs) {
|
[clangd] Cleanup: stop passing around list of supported URI schemes.
Summary:
Instead of passing around a list of supported URI schemes in clangd, we
expose an interface to convert a path to URI using any compatible scheme
that has been registered. It favors customized schemes and falls
back to "file" when no other scheme works.
Changes in this patch are:
- URI::create(AbsPath, URISchemes) -> URI::create(AbsPath). The new API finds a
compatible scheme from the registry.
- Remove URISchemes option everywhere (ClangdServer, SymbolCollecter, FileIndex etc).
- Unit tests will use "unittest" by default.
- Move "test" scheme from ClangdLSPServer to ClangdMain.cpp, and only
register the test scheme when lit-test or enable-lit-scheme is set.
(The new flag is added to make lit protocol.test work; I wonder if there
is alternative here.)
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D54800
llvm-svn: 347467
2018-11-22 23:02:05 +08:00
|
|
|
FileIndex Dyn;
|
|
|
|
FileIndex StaticIndex;
|
2018-10-04 22:20:22 +08:00
|
|
|
MergedIndex Merge(&Dyn, &StaticIndex);
|
2018-09-01 03:53:37 +08:00
|
|
|
|
|
|
|
const char *HeaderCode = "class Foo;";
|
|
|
|
auto HeaderSymbols = TestTU::withHeaderCode("class Foo;").headerSymbols();
|
|
|
|
auto Foo = findSymbol(HeaderSymbols, "Foo");
|
|
|
|
|
|
|
|
// Build dynamic index for test.cc.
|
|
|
|
Annotations Test1Code(R"(class $Foo[[Foo]];)");
|
|
|
|
TestTU Test;
|
|
|
|
Test.HeaderCode = HeaderCode;
|
|
|
|
Test.Code = Test1Code.code();
|
|
|
|
Test.Filename = "test.cc";
|
|
|
|
auto AST = Test.build();
|
2018-09-18 21:35:16 +08:00
|
|
|
Dyn.updateMain(Test.Filename, AST);
|
2018-09-01 03:53:37 +08:00
|
|
|
|
|
|
|
// Build static index for test.cc.
|
|
|
|
Test.HeaderCode = HeaderCode;
|
|
|
|
Test.Code = "// static\nclass Foo {};";
|
|
|
|
Test.Filename = "test.cc";
|
|
|
|
auto StaticAST = Test.build();
|
[clangd] SymbolOccurrences -> Refs and cleanup
Summary:
A few things that I noticed while merging the SwapIndex patch:
- SymbolOccurrences and particularly SymbolOccurrenceSlab are unwieldy names,
and these names appear *a lot*. Ref, RefSlab, etc seem clear enough
and read/format much better.
- The asymmetry between SymbolSlab and RefSlab (build() vs freeze()) is
confusing and irritating, and doesn't even save much code.
Avoiding RefSlab::Builder was my idea, but it was a bad one; add it.
- DenseMap<SymbolID, ArrayRef<Ref>> seems like a reasonable compromise for
constructing MemIndex - and means many less wasted allocations than the
current DenseMap<SymbolID, vector<Ref*>> for FileIndex, and none for
slabs.
- RefSlab::find() is not actually used for anything, so we can throw
away the DenseMap and keep the representation much more compact.
- A few naming/consistency fixes: e.g. Slabs,Refs -> Symbols,Refs.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51605
llvm-svn: 341368
2018-09-04 22:39:56 +08:00
|
|
|
// Add stale refs for test.cc.
|
2018-09-18 21:35:16 +08:00
|
|
|
StaticIndex.updateMain(Test.Filename, StaticAST);
|
2018-09-01 03:53:37 +08:00
|
|
|
|
[clangd] SymbolOccurrences -> Refs and cleanup
Summary:
A few things that I noticed while merging the SwapIndex patch:
- SymbolOccurrences and particularly SymbolOccurrenceSlab are unwieldy names,
and these names appear *a lot*. Ref, RefSlab, etc seem clear enough
and read/format much better.
- The asymmetry between SymbolSlab and RefSlab (build() vs freeze()) is
confusing and irritating, and doesn't even save much code.
Avoiding RefSlab::Builder was my idea, but it was a bad one; add it.
- DenseMap<SymbolID, ArrayRef<Ref>> seems like a reasonable compromise for
constructing MemIndex - and means many less wasted allocations than the
current DenseMap<SymbolID, vector<Ref*>> for FileIndex, and none for
slabs.
- RefSlab::find() is not actually used for anything, so we can throw
away the DenseMap and keep the representation much more compact.
- A few naming/consistency fixes: e.g. Slabs,Refs -> Symbols,Refs.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51605
llvm-svn: 341368
2018-09-04 22:39:56 +08:00
|
|
|
// Add refs for test2.cc
|
2018-09-01 03:53:37 +08:00
|
|
|
Annotations Test2Code(R"(class $Foo[[Foo]] {};)");
|
|
|
|
TestTU Test2;
|
|
|
|
Test2.HeaderCode = HeaderCode;
|
|
|
|
Test2.Code = Test2Code.code();
|
|
|
|
Test2.Filename = "test2.cc";
|
|
|
|
StaticAST = Test2.build();
|
2018-09-18 21:35:16 +08:00
|
|
|
StaticIndex.updateMain(Test2.Filename, StaticAST);
|
2018-09-01 03:53:37 +08:00
|
|
|
|
[clangd] SymbolOccurrences -> Refs and cleanup
Summary:
A few things that I noticed while merging the SwapIndex patch:
- SymbolOccurrences and particularly SymbolOccurrenceSlab are unwieldy names,
and these names appear *a lot*. Ref, RefSlab, etc seem clear enough
and read/format much better.
- The asymmetry between SymbolSlab and RefSlab (build() vs freeze()) is
confusing and irritating, and doesn't even save much code.
Avoiding RefSlab::Builder was my idea, but it was a bad one; add it.
- DenseMap<SymbolID, ArrayRef<Ref>> seems like a reasonable compromise for
constructing MemIndex - and means many less wasted allocations than the
current DenseMap<SymbolID, vector<Ref*>> for FileIndex, and none for
slabs.
- RefSlab::find() is not actually used for anything, so we can throw
away the DenseMap and keep the representation much more compact.
- A few naming/consistency fixes: e.g. Slabs,Refs -> Symbols,Refs.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51605
llvm-svn: 341368
2018-09-04 22:39:56 +08:00
|
|
|
RefsRequest Request;
|
2018-09-01 03:53:37 +08:00
|
|
|
Request.IDs = {Foo.ID};
|
[clangd] SymbolOccurrences -> Refs and cleanup
Summary:
A few things that I noticed while merging the SwapIndex patch:
- SymbolOccurrences and particularly SymbolOccurrenceSlab are unwieldy names,
and these names appear *a lot*. Ref, RefSlab, etc seem clear enough
and read/format much better.
- The asymmetry between SymbolSlab and RefSlab (build() vs freeze()) is
confusing and irritating, and doesn't even save much code.
Avoiding RefSlab::Builder was my idea, but it was a bad one; add it.
- DenseMap<SymbolID, ArrayRef<Ref>> seems like a reasonable compromise for
constructing MemIndex - and means many less wasted allocations than the
current DenseMap<SymbolID, vector<Ref*>> for FileIndex, and none for
slabs.
- RefSlab::find() is not actually used for anything, so we can throw
away the DenseMap and keep the representation much more compact.
- A few naming/consistency fixes: e.g. Slabs,Refs -> Symbols,Refs.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51605
llvm-svn: 341368
2018-09-04 22:39:56 +08:00
|
|
|
RefSlab::Builder Results;
|
2018-10-04 22:20:22 +08:00
|
|
|
Merge.refs(Request, [&](const Ref &O) { Results.insert(Foo.ID, O); });
|
[clangd] SymbolOccurrences -> Refs and cleanup
Summary:
A few things that I noticed while merging the SwapIndex patch:
- SymbolOccurrences and particularly SymbolOccurrenceSlab are unwieldy names,
and these names appear *a lot*. Ref, RefSlab, etc seem clear enough
and read/format much better.
- The asymmetry between SymbolSlab and RefSlab (build() vs freeze()) is
confusing and irritating, and doesn't even save much code.
Avoiding RefSlab::Builder was my idea, but it was a bad one; add it.
- DenseMap<SymbolID, ArrayRef<Ref>> seems like a reasonable compromise for
constructing MemIndex - and means many less wasted allocations than the
current DenseMap<SymbolID, vector<Ref*>> for FileIndex, and none for
slabs.
- RefSlab::find() is not actually used for anything, so we can throw
away the DenseMap and keep the representation much more compact.
- A few naming/consistency fixes: e.g. Slabs,Refs -> Symbols,Refs.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51605
llvm-svn: 341368
2018-09-04 22:39:56 +08:00
|
|
|
EXPECT_THAT(
|
|
|
|
std::move(Results).build(),
|
|
|
|
ElementsAre(Pair(
|
|
|
|
_, UnorderedElementsAre(AllOf(RefRange(Test1Code.range("Foo")),
|
|
|
|
FileURI("unittest:///test.cc")),
|
|
|
|
AllOf(RefRange(Test2Code.range("Foo")),
|
|
|
|
FileURI("unittest:///test2.cc"))))));
|
2019-01-15 02:11:09 +08:00
|
|
|
|
|
|
|
Request.Limit = 1;
|
|
|
|
RefSlab::Builder Results2;
|
|
|
|
Merge.refs(Request, [&](const Ref &O) { Results2.insert(Foo.ID, O); });
|
|
|
|
EXPECT_THAT(std::move(Results2).build(),
|
|
|
|
ElementsAre(Pair(
|
|
|
|
_, ElementsAre(AnyOf(FileURI("unittest:///test.cc"),
|
|
|
|
FileURI("unittest:///test2.cc"))))));
|
2018-09-01 03:53:37 +08:00
|
|
|
}
|
|
|
|
|
2019-10-07 18:53:56 +08:00
|
|
|
TEST(MergeIndexTest, NonDocumentation) {
|
|
|
|
Symbol L, R;
|
|
|
|
L.ID = R.ID = SymbolID("x");
|
|
|
|
L.Definition.FileURI = "file:/x.h";
|
|
|
|
R.Documentation = "Forward declarations because x.h is too big to include";
|
|
|
|
|
|
|
|
Symbol M = mergeSymbol(L, R);
|
|
|
|
EXPECT_EQ(M.Documentation, "");
|
|
|
|
}
|
|
|
|
|
2019-01-03 21:28:05 +08:00
|
|
|
MATCHER_P2(IncludeHeaderWithRef, IncludeHeader, References, "") {
|
[clangd] Support multiple #include headers in one symbol.
Summary:
Currently, a symbol can have only one #include header attached, which
might not work well if the symbol can be imported via different #includes depending
on where it's used. This patch stores multiple #include headers (with # references)
for each symbol, so that CodeCompletion can decide which include to insert.
In this patch, code completion simply picks the most popular include as the default inserted header. We also return all possible includes and their edits in the `CodeCompletion` results.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: mgrang, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D51291
llvm-svn: 341304
2018-09-03 18:18:21 +08:00
|
|
|
return (arg.IncludeHeader == IncludeHeader) && (arg.References == References);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MergeTest, MergeIncludesOnDifferentDefinitions) {
|
|
|
|
Symbol L, R;
|
|
|
|
L.Name = "left";
|
|
|
|
R.Name = "right";
|
|
|
|
L.ID = R.ID = SymbolID("hello");
|
|
|
|
L.IncludeHeaders.emplace_back("common", 1);
|
|
|
|
R.IncludeHeaders.emplace_back("common", 1);
|
|
|
|
R.IncludeHeaders.emplace_back("new", 1);
|
|
|
|
|
|
|
|
// Both have no definition.
|
|
|
|
Symbol M = mergeSymbol(L, R);
|
|
|
|
EXPECT_THAT(M.IncludeHeaders,
|
|
|
|
UnorderedElementsAre(IncludeHeaderWithRef("common", 2u),
|
|
|
|
IncludeHeaderWithRef("new", 1u)));
|
|
|
|
|
|
|
|
// Only merge references of the same includes but do not merge new #includes.
|
|
|
|
L.Definition.FileURI = "file:/left.h";
|
|
|
|
M = mergeSymbol(L, R);
|
|
|
|
EXPECT_THAT(M.IncludeHeaders,
|
|
|
|
UnorderedElementsAre(IncludeHeaderWithRef("common", 2u)));
|
|
|
|
|
|
|
|
// Definitions are the same.
|
|
|
|
R.Definition.FileURI = "file:/right.h";
|
|
|
|
M = mergeSymbol(L, R);
|
|
|
|
EXPECT_THAT(M.IncludeHeaders,
|
|
|
|
UnorderedElementsAre(IncludeHeaderWithRef("common", 2u),
|
|
|
|
IncludeHeaderWithRef("new", 1u)));
|
|
|
|
|
|
|
|
// Definitions are different.
|
|
|
|
R.Definition.FileURI = "file:/right.h";
|
|
|
|
M = mergeSymbol(L, R);
|
|
|
|
EXPECT_THAT(M.IncludeHeaders,
|
|
|
|
UnorderedElementsAre(IncludeHeaderWithRef("common", 2u),
|
|
|
|
IncludeHeaderWithRef("new", 1u)));
|
|
|
|
}
|
|
|
|
|
2017-12-14 19:25:49 +08:00
|
|
|
} // namespace
|
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|