2017-12-14 19:25:49 +08:00
|
|
|
//===-- IndexTests.cpp -------------------------------*- C++ -*-----------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
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 "gmock/gmock.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"
|
2017-12-14 19:25:49 +08:00
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
[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
|
|
|
using testing::AllOf;
|
|
|
|
using testing::ElementsAre;
|
2017-12-24 03:38:03 +08:00
|
|
|
using testing::Pointee;
|
2018-08-20 22:39:32 +08:00
|
|
|
using testing::UnorderedElementsAre;
|
[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
|
|
|
using namespace llvm;
|
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; }
|
2018-09-01 03:53:37 +08:00
|
|
|
MATCHER_P(OccurrenceRange, Range, "") {
|
|
|
|
return std::tie(arg.Location.Start.Line, arg.Location.Start.Column,
|
|
|
|
arg.Location.End.Line, arg.Location.End.Column) ==
|
|
|
|
std::tie(Range.start.line, Range.start.character, Range.end.line,
|
|
|
|
Range.end.character);
|
|
|
|
}
|
|
|
|
MATCHER_P(FileURI, F, "") { return arg.Location.FileURI == F; }
|
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));
|
|
|
|
}
|
|
|
|
|
[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
|
|
|
|
[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
|
|
|
SwapIndex S(make_unique<MemIndex>(SymbolSlab(), MemIndex::OccurrenceMap(),
|
|
|
|
std::move(Token)));
|
|
|
|
EXPECT_FALSE(WeakToken.expired()); // Current MemIndex keeps it alive.
|
|
|
|
S.reset(make_unique<MemIndex>()); // Now the MemIndex is destroyed.
|
|
|
|
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";
|
|
|
|
MemIndex I(Symbols, MemIndex::OccurrenceMap());
|
|
|
|
EXPECT_THAT(match(I, Req), ElementsAre("2"));
|
2017-12-14 19:25:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MemIndexTest, MemIndexLimitedNumMatches) {
|
[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(generateNumSymbols(0, 100), SymbolOccurrenceSlab());
|
2017-12-14 19:25:49 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "5";
|
|
|
|
Req.MaxCandidateCount = 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);
|
2017-12-14 19:25:49 +08:00
|
|
|
EXPECT_EQ(Matches.size(), Req.MaxCandidateCount);
|
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"}),
|
[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
|
|
|
SymbolOccurrenceSlab());
|
2018-01-18 16:35:04 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "lol";
|
|
|
|
Req.MaxCandidateCount = 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) {
|
[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(generateSymbols({"a::y1", "b::y2", "y3"}),
|
|
|
|
SymbolOccurrenceSlab());
|
2017-12-19 19:37:40 +08:00
|
|
|
FuzzyFindRequest Req;
|
|
|
|
Req.Query = "y";
|
[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) {
|
[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(generateSymbols({"a::y1", "b::y2", "y3"}),
|
|
|
|
SymbolOccurrenceSlab());
|
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(
|
|
|
|
generateSymbols({"a::y1", "a::y2", "a::x", "b::y2", "y3"}),
|
|
|
|
SymbolOccurrenceSlab());
|
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(
|
|
|
|
generateSymbols({"a::y1", "a::y2", "a::x", "b::y3", "y3"}),
|
|
|
|
SymbolOccurrenceSlab());
|
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) {
|
[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(generateSymbols({"a::y1", "a::b::y2"}),
|
|
|
|
SymbolOccurrenceSlab());
|
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) {
|
[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(generateSymbols({"ns::ABC", "ns::abc"}),
|
|
|
|
SymbolOccurrenceSlab());
|
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) {
|
[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(generateSymbols({"ns::abc", "ns::xyz"}),
|
|
|
|
SymbolOccurrenceSlab());
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MergeIndexTest, Lookup) {
|
[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(generateSymbols({"ns::A", "ns::B"}),
|
|
|
|
SymbolOccurrenceSlab()),
|
|
|
|
J = MemIndex::build(generateSymbols({"ns::B", "ns::C"}),
|
|
|
|
SymbolOccurrenceSlab());
|
|
|
|
auto M = mergeIndex(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")}),
|
|
|
|
UnorderedElementsAre("ns::A", "ns::B"));
|
|
|
|
EXPECT_THAT(lookup(*M, {SymbolID("ns::A"), SymbolID("ns::C")}),
|
|
|
|
UnorderedElementsAre("ns::A", "ns::C"));
|
|
|
|
EXPECT_THAT(lookup(*M, SymbolID("ns::D")), UnorderedElementsAre());
|
|
|
|
EXPECT_THAT(lookup(*M, {}), UnorderedElementsAre());
|
2018-03-14 17:48:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MergeIndexTest, FuzzyFind) {
|
[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(generateSymbols({"ns::A", "ns::B"}),
|
|
|
|
SymbolOccurrenceSlab()),
|
|
|
|
J = MemIndex::build(generateSymbols({"ns::B", "ns::C"}),
|
|
|
|
SymbolOccurrenceSlab());
|
2018-01-15 20:33:00 +08:00
|
|
|
FuzzyFindRequest Req;
|
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(*mergeIndex(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-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-02-07 00:10:35 +08:00
|
|
|
EXPECT_EQ(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-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-02-09 22:42:01 +08:00
|
|
|
EXPECT_EQ(M.CanonicalDeclaration.FileURI, "file:/left.h");
|
|
|
|
EXPECT_EQ(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-02-09 22:42:01 +08:00
|
|
|
EXPECT_EQ(M.CanonicalDeclaration.FileURI, "file:/right.h");
|
|
|
|
EXPECT_EQ(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
|
|
|
}
|
|
|
|
|
2018-09-01 03:53:37 +08:00
|
|
|
TEST(MergeIndexTest, FindOccurrences) {
|
|
|
|
FileIndex Dyn({"unittest"});
|
|
|
|
FileIndex StaticIndex({"unittest"});
|
|
|
|
auto MergedIndex = mergeIndex(&Dyn, &StaticIndex);
|
|
|
|
|
|
|
|
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();
|
|
|
|
Dyn.update(Test.Filename, &AST.getASTContext(), AST.getPreprocessorPtr(),
|
|
|
|
AST.getLocalTopLevelDecls());
|
|
|
|
|
|
|
|
// Build static index for test.cc.
|
|
|
|
Test.HeaderCode = HeaderCode;
|
|
|
|
Test.Code = "// static\nclass Foo {};";
|
|
|
|
Test.Filename = "test.cc";
|
|
|
|
auto StaticAST = Test.build();
|
|
|
|
// Add stale occurrences for test.cc.
|
|
|
|
StaticIndex.update(Test.Filename, &StaticAST.getASTContext(),
|
|
|
|
StaticAST.getPreprocessorPtr(),
|
|
|
|
StaticAST.getLocalTopLevelDecls());
|
|
|
|
|
|
|
|
// Add occcurrences for test2.cc
|
|
|
|
Annotations Test2Code(R"(class $Foo[[Foo]] {};)");
|
|
|
|
TestTU Test2;
|
|
|
|
Test2.HeaderCode = HeaderCode;
|
|
|
|
Test2.Code = Test2Code.code();
|
|
|
|
Test2.Filename = "test2.cc";
|
|
|
|
StaticAST = Test2.build();
|
|
|
|
StaticIndex.update(Test2.Filename, &StaticAST.getASTContext(),
|
|
|
|
StaticAST.getPreprocessorPtr(),
|
|
|
|
StaticAST.getLocalTopLevelDecls());
|
|
|
|
|
|
|
|
OccurrencesRequest Request;
|
|
|
|
Request.IDs = {Foo.ID};
|
|
|
|
Request.Filter = AllOccurrenceKinds;
|
|
|
|
std::vector<SymbolOccurrence> Results;
|
|
|
|
MergedIndex->findOccurrences(
|
|
|
|
Request, [&](const SymbolOccurrence &O) { Results.push_back(O); });
|
|
|
|
|
|
|
|
EXPECT_THAT(Results, UnorderedElementsAre(
|
|
|
|
AllOf(OccurrenceRange(Test1Code.range("Foo")),
|
|
|
|
FileURI("unittest:///test.cc")),
|
|
|
|
AllOf(OccurrenceRange(Test2Code.range("Foo")),
|
|
|
|
FileURI("unittest:///test2.cc"))));
|
|
|
|
}
|
|
|
|
|
[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
|
|
|
MATCHER_P2(IncludeHeaderWithRef, IncludeHeader, References, "") {
|
|
|
|
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
|