FileURI("unittest:///root/B.cc")}));
}
-TEST_F(BackgroundIndexTest, RelationsMultiFile) {
- MockFS FS;
- FS.Files[testPath("root/Base.h")] = "class Base {};";
- FS.Files[testPath("root/A.cc")] = R"cpp(
- #include "Base.h"
- class A : public Base {};
- )cpp";
- FS.Files[testPath("root/B.cc")] = R"cpp(
- #include "Base.h"
- class B : public Base {};
- )cpp";
-
- llvm::StringMap<std::string> Storage;
- size_t CacheHits = 0;
- MemoryShardStorage MSS(Storage, CacheHits);
- OverlayCDB CDB(/*Base=*/nullptr);
- BackgroundIndex Index(FS, CDB, [&](llvm::StringRef) { return &MSS; },
- /*Opts=*/{});
-
- tooling::CompileCommand Cmd;
- Cmd.Filename = testPath("root/A.cc");
- Cmd.Directory = testPath("root");
- Cmd.CommandLine = {"clang++", Cmd.Filename};
- CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
- ASSERT_TRUE(Index.blockUntilIdleForTest());
-
- Cmd.Filename = testPath("root/B.cc");
- Cmd.CommandLine = {"clang++", Cmd.Filename};
- CDB.setCompileCommand(testPath("root/B.cc"), Cmd);
- ASSERT_TRUE(Index.blockUntilIdleForTest());
-
- auto HeaderShard = MSS.loadShard(testPath("root/Base.h"));
- EXPECT_NE(HeaderShard, nullptr);
- SymbolID Base = findSymbol(*HeaderShard->Symbols, "Base").ID;
-
- RelationsRequest Req;
- Req.Subjects.insert(Base);
- Req.Predicate = RelationKind::BaseOf;
- uint32_t Results = 0;
- Index.relations(Req, [&](const SymbolID &, const Symbol &) { ++Results; });
- EXPECT_EQ(Results, 2u);
-}
-
TEST_F(BackgroundIndexTest, MainFileRefs) {
MockFS FS;
FS.Files[testPath("root/A.h")] = R"cpp(
TestFS.cpp
TestIndex.cpp
TestTU.cpp
+ TestWorkspace.cpp
TypeHierarchyTests.cpp
TweakTests.cpp
TweakTesting.cpp
#include "SyncAPI.h"
#include "TestFS.h"
#include "TestTU.h"
+#include "TestWorkspace.h"
#include "URI.h"
#include "index/CanonicalIncludes.h"
#include "index/FileIndex.h"
EXPECT_EQ(Results, 1u);
}
+TEST(FileIndexTest, RelationsMultiFile) {
+ TestWorkspace Workspace;
+ Workspace.addSource("Base.h", "class Base {};");
+ Workspace.addMainFile("A.cpp", R"cpp(
+ #include "Base.h"
+ class A : public Base {};
+ )cpp");
+ Workspace.addMainFile("B.cpp", R"cpp(
+ #include "Base.h"
+ class B : public Base {};
+ )cpp");
+
+ auto Index = Workspace.index();
+ FuzzyFindRequest FFReq;
+ FFReq.Query = "Base";
+ FFReq.AnyScope = true;
+ SymbolID Base;
+ Index->fuzzyFind(FFReq, [&](const Symbol &S) { Base = S.ID; });
+
+ RelationsRequest Req;
+ Req.Subjects.insert(Base);
+ Req.Predicate = RelationKind::BaseOf;
+ uint32_t Results = 0;
+ Index->relations(Req, [&](const SymbolID &, const Symbol &) { ++Results; });
+ EXPECT_EQ(Results, 2u);
+}
+
TEST(FileIndexTest, ReferencesInMainFileWithPreamble) {
TestTU TU;
TU.HeaderCode = "class Foo{};";
}
}
-std::shared_ptr<const PreambleData> TestTU::preamble() const {
+std::shared_ptr<const PreambleData>
+TestTU::preamble(PreambleParsedCallback PreambleCallback) const {
MockFS FS;
auto Inputs = inputs(FS);
IgnoreDiagnostics Diags;
auto ModuleCacheDeleter = llvm::make_scope_exit(
std::bind(deleteModuleCache, CI->getHeaderSearchOpts().ModuleCachePath));
return clang::clangd::buildPreamble(testPath(Filename), *CI, Inputs,
- /*StoreInMemory=*/true,
- /*PreambleCallback=*/nullptr);
+ /*StoreInMemory=*/true, PreambleCallback);
}
ParsedAST TestTU::build() const {
// By default, build() will report Error diagnostics as GTest errors.
// Suppress this behavior by adding an 'error-ok' comment to the code.
ParsedAST build() const;
- std::shared_ptr<const PreambleData> preamble() const;
+ std::shared_ptr<const PreambleData>
+ preamble(PreambleParsedCallback PreambleCallback = nullptr) const;
ParseInputs inputs(MockFS &FS) const;
SymbolSlab headerSymbols() const;
RefSlab headerRefs() const;
--- /dev/null
+//===--- TestWorkspace.cpp - Utility for writing multi-file tests -*- C++-*===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestWorkspace.h"
+
+namespace clang {
+namespace clangd {
+
+std::unique_ptr<SymbolIndex> TestWorkspace::index() {
+ auto Index = std::make_unique<FileIndex>();
+ for (const auto &Input : Inputs) {
+ if (!Input.second.IsMainFile)
+ continue;
+ TU.Code = Input.second.Code;
+ TU.Filename = Input.first().str();
+ TU.preamble([&](ASTContext &Ctx, std::shared_ptr<clang::Preprocessor> PP,
+ const CanonicalIncludes &CanonIncludes) {
+ Index->updatePreamble(testPath(Input.first()), "null", Ctx, PP,
+ CanonIncludes);
+ });
+ ParsedAST MainAST = TU.build();
+ Index->updateMain(testPath(Input.first()), MainAST);
+ }
+ return Index;
+}
+
+Optional<ParsedAST> TestWorkspace::openFile(llvm::StringRef Filename) {
+ auto It = Inputs.find(Filename);
+ if (It == Inputs.end()) {
+ ADD_FAILURE() << "Accessing non-existing file: " << Filename;
+ return llvm::None;
+ }
+ TU.Code = It->second.Code;
+ TU.Filename = It->first().str();
+ return TU.build();
+}
+
+void TestWorkspace::addInput(llvm::StringRef Filename,
+ const SourceFile &Input) {
+ Inputs.insert(std::make_pair(Filename, Input));
+ TU.AdditionalFiles.insert(std::make_pair(Filename, Input.Code));
+}
+} // namespace clangd
+} // namespace clang
\ No newline at end of file
--- /dev/null
+//===--- TestWorkspace.h - Utility for writing multi-file tests --*- C++-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// TestWorkspace builds on TestTU to provide a way to write tests involving
+// several related files with inclusion relationships between them.
+//
+// The tests can exercise both index and AST based operations.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTWORKSPACE_H
+#define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTWORKSPACE_H
+
+#include "TestFS.h"
+#include "TestTU.h"
+#include "index/FileIndex.h"
+#include "index/Index.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace clangd {
+
+class TestWorkspace {
+public:
+ // The difference between addSource() and addMainFile() is that only main
+ // files will be indexed.
+ void addSource(llvm::StringRef Filename, llvm::StringRef Code) {
+ addInput(Filename.str(), {Code.str(), /*IsMainFile=*/false});
+ }
+ void addMainFile(llvm::StringRef Filename, llvm::StringRef Code) {
+ addInput(Filename.str(), {Code.str(), /*IsMainFile=*/true});
+ }
+
+ std::unique_ptr<SymbolIndex> index();
+
+ Optional<ParsedAST> openFile(llvm::StringRef Filename);
+
+private:
+ struct SourceFile {
+ std::string Code;
+ bool IsMainFile = false;
+ };
+ llvm::StringMap<SourceFile> Inputs;
+ TestTU TU;
+
+ void addInput(llvm::StringRef Filename, const SourceFile &Input);
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTWORKSPACE_H
"TestFS.cpp",
"TestIndex.cpp",
"TestTU.cpp",
+ "TestWorkspace.cpp",
"TweakTesting.cpp",
"TweakTests.cpp",
"TypeHierarchyTests.cpp",