diff --git a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp --- a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp @@ -10,6 +10,8 @@ #include "FindSymbols.h" #include "SyncAPI.h" #include "TestFS.h" +#include "TestTU.h" +#include "llvm/ADT/StringRef.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -42,43 +44,32 @@ return Field(&DocumentSymbol::children, ElementsAre(ChildrenM...)); } -ClangdServer::Options optsForTests() { - auto ServerOpts = ClangdServer::optsForTest(); - ServerOpts.WorkspaceRoot = testRoot(); - ServerOpts.BuildDynamicSymbolIndex = true; - return ServerOpts; -} - class WorkspaceSymbolsTest : public ::testing::Test { -public: - WorkspaceSymbolsTest() : Server(CDB, FS, optsForTests()) { - // Make sure the test root directory is created. - FS.Files[testPath("unused")] = ""; - CDB.ExtraClangFlags = {"-xc++"}; - } - protected: - MockFS FS; - MockCompilationDatabase CDB; - ClangdServer Server; int Limit = 0; + TestTU TU; std::vector getSymbols(llvm::StringRef Query) { - EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for preamble"; - auto SymbolInfos = runWorkspaceSymbols(Server, Query, Limit); + auto SymbolInfos = getWorkspaceSymbols(Query, Limit, TU.index().get(), + testPath(TU.Filename)); EXPECT_TRUE(bool(SymbolInfos)) << "workspaceSymbols returned an error"; return *SymbolInfos; } void addFile(llvm::StringRef FileName, llvm::StringRef Contents) { - Server.addDocument(testPath(FileName), Contents); + TU.AdditionalFiles[FileName] = Contents.str(); + } + + void setMainFile(llvm::StringRef FileName, llvm::StringRef Contents) { + TU.Code = Contents.str(); + TU.Filename = FileName.str(); } }; } // namespace TEST_F(WorkspaceSymbolsTest, Macros) { - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #define MACRO X )cpp"); @@ -90,7 +81,7 @@ } TEST_F(WorkspaceSymbolsTest, NoLocals) { - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( void test(int FirstParam, int SecondParam) { struct LocalClass {}; int local_var; @@ -106,7 +97,7 @@ int global_func(); struct GlobalStruct {};)cpp"); - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" )cpp"); EXPECT_THAT(getSymbols("global"), @@ -121,7 +112,7 @@ struct { int InUnnamed; } UnnamedStruct;)cpp"); - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" )cpp"); EXPECT_THAT(getSymbols("UnnamedStruct"), @@ -133,9 +124,9 @@ } TEST_F(WorkspaceSymbolsTest, InMainFile) { - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( int test() {} - static test2() {} + static void test2() {} )cpp"); EXPECT_THAT(getSymbols("test"), ElementsAre(QName("test"), QName("test2"))); } @@ -149,7 +140,7 @@ } } )cpp"); - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" )cpp"); EXPECT_THAT(getSymbols("a"), @@ -169,7 +160,7 @@ } TEST_F(WorkspaceSymbolsTest, AnonymousNamespace) { - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( namespace { void test() {} } @@ -186,7 +177,7 @@ int foo2() { } )cpp"); - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" #include "foo2.h" )cpp"); @@ -206,7 +197,7 @@ } } )cpp"); - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" )cpp"); EXPECT_THAT(getSymbols("::"), @@ -241,7 +232,7 @@ }; } )cpp"); - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" )cpp"); EXPECT_THAT(getSymbols("Red"), ElementsAre(QName("Red"))); @@ -263,7 +254,7 @@ namespace ns{} void func(); )cpp"); - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" )cpp"); EXPECT_THAT(getSymbols("::"), ElementsAre(QName("func"), QName("ns"))); @@ -274,7 +265,7 @@ int foo; int foo2; )cpp"); - addFile("foo.cpp", R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" )cpp"); // Foo is higher ranked because of exact name match. @@ -288,7 +279,8 @@ } TEST_F(WorkspaceSymbolsTest, TempSpecs) { - addFile("foo.h", R"cpp( + TU.ExtraArgs = {"-xc++"}; + setMainFile("foo.h", R"cpp( template class Foo {}; template class Foo {}; template <> class Foo {}; @@ -306,29 +298,28 @@ namespace { class DocumentSymbolsTest : public ::testing::Test { -public: - DocumentSymbolsTest() : Server(CDB, FS, optsForTests()) {} - protected: - MockFS FS; - MockCompilationDatabase CDB; - ClangdServer Server; + TestTU TU; - std::vector getSymbols(PathRef File) { - EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for preamble"; - auto SymbolInfos = runDocumentSymbols(Server, File); + std::vector getSymbols() { + auto AST = TU.build(); + auto SymbolInfos = getDocumentSymbols(AST); EXPECT_TRUE(bool(SymbolInfos)) << "documentSymbols returned an error"; return *SymbolInfos; } void addFile(llvm::StringRef FilePath, llvm::StringRef Contents) { - Server.addDocument(FilePath, Contents); + TU.AdditionalFiles[FilePath] = Contents.str(); + } + + void setMainFile(llvm::StringRef FileName, llvm::StringRef Contents) { + TU.Code = Contents.str(); + TU.Filename = FileName.str(); } }; } // namespace TEST_F(DocumentSymbolsTest, BasicSymbols) { - std::string FilePath = testPath("foo.cpp"); Annotations Main(R"( class Foo; class Foo { @@ -372,9 +363,9 @@ } // namespace foo )"); - addFile(FilePath, Main.code()); + setMainFile("foo.cpp", Main.code()); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), ElementsAreArray( {AllOf(WithName("Foo"), WithKind(SymbolKind::Class), Children()), AllOf(WithName("Foo"), WithKind(SymbolKind::Class), @@ -417,7 +408,6 @@ } TEST_F(DocumentSymbolsTest, DeclarationDefinition) { - std::string FilePath = testPath("foo.cpp"); Annotations Main(R"( class Foo { void $decl[[f]](); @@ -426,9 +416,9 @@ } )"); - addFile(FilePath, Main.code()); + setMainFile("foo.cpp", Main.code()); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), ElementsAre( AllOf(WithName("Foo"), WithKind(SymbolKind::Class), Children(AllOf(WithName("f"), WithKind(SymbolKind::Method), @@ -438,47 +428,43 @@ } TEST_F(DocumentSymbolsTest, Concepts) { - CDB.ExtraClangFlags = {"-std=c++20"}; - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, - "template concept C = requires(T t) { t.foo(); };"); + TU.ExtraArgs = {"-std=c++20"}; + setMainFile("foo.cpp", + "template concept C = requires(T t) { t.foo(); };"); - EXPECT_THAT(getSymbols(FilePath), ElementsAre(WithName("C"))); + EXPECT_THAT(getSymbols(), ElementsAre(WithName("C"))); } TEST_F(DocumentSymbolsTest, ExternSymbol) { - std::string FilePath = testPath("foo.cpp"); addFile(testPath("foo.h"), R"cpp( extern int var; )cpp"); - addFile(FilePath, R"cpp( + setMainFile("foo.cpp", R"cpp( #include "foo.h" )cpp"); - EXPECT_THAT(getSymbols(FilePath), IsEmpty()); + EXPECT_THAT(getSymbols(), IsEmpty()); } TEST_F(DocumentSymbolsTest, NoLocals) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, - R"cpp( + setMainFile("foo.cpp", + R"cpp( void test(int FirstParam, int SecondParam) { struct LocalClass {}; int local_var; })cpp"); - EXPECT_THAT(getSymbols(FilePath), ElementsAre(WithName("test"))); + EXPECT_THAT(getSymbols(), ElementsAre(WithName("test"))); } TEST_F(DocumentSymbolsTest, Unnamed) { - std::string FilePath = testPath("foo.h"); - addFile(FilePath, - R"cpp( + setMainFile("foo.cpp", + R"cpp( struct { int InUnnamed; } UnnamedStruct; )cpp"); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), ElementsAre( AllOf(WithName("(anonymous struct)"), WithKind(SymbolKind::Struct), Children(AllOf(WithName("InUnnamed"), @@ -492,21 +478,16 @@ int foo() { } )cpp"); - std::string FilePath = testPath("foo.h"); - addFile(FilePath, R"cpp( + setMainFile("foo.h", R"cpp( #include "bar.h" int test() { } )cpp"); - addFile(testPath("foo.cpp"), R"cpp( - #include "foo.h" - )cpp"); - EXPECT_THAT(getSymbols(FilePath), ElementsAre(WithName("test"))); + EXPECT_THAT(getSymbols(), ElementsAre(WithName("test"))); } TEST_F(DocumentSymbolsTest, Template) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"( + setMainFile("foo.cpp", R"( template struct Tmpl {T x = 0;}; template <> struct Tmpl { int y = 0; @@ -525,7 +506,7 @@ double varTmpl = 10.0; )"); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), ElementsAre( AllOf(WithName("Tmpl"), WithKind(SymbolKind::Struct), Children(AllOf(WithName("x"), WithKind(SymbolKind::Field)))), @@ -542,8 +523,7 @@ } TEST_F(DocumentSymbolsTest, Namespaces) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"cpp( + setMainFile("foo.cpp", R"cpp( namespace ans1 { int ai1; namespace ans2 { @@ -567,7 +547,7 @@ } )cpp"); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), ElementsAreArray<::testing::Matcher>( {AllOf(WithName("ans1"), Children(AllOf(WithName("ai1"), Children()), @@ -580,8 +560,7 @@ } TEST_F(DocumentSymbolsTest, Enums) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"( + setMainFile("foo.cpp", R"( enum { Red }; @@ -598,7 +577,7 @@ } )"); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), ElementsAre( AllOf(WithName("(anonymous enum)"), Children(WithName("Red"))), AllOf(WithName("Color"), Children(WithName("Green"))), @@ -608,7 +587,6 @@ } TEST_F(DocumentSymbolsTest, FromMacro) { - std::string FilePath = testPath("foo.cpp"); Annotations Main(R"( #define FF(name) \ class name##_Test {}; @@ -620,31 +598,29 @@ FF2(); )"); - addFile(FilePath, Main.code()); + setMainFile("foo.cpp", Main.code()); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), ElementsAre( AllOf(WithName("abc_Test"), SymNameRange(Main.range("expansion"))), AllOf(WithName("Test"), SymNameRange(Main.range("spelling"))))); } TEST_F(DocumentSymbolsTest, FuncTemplates) { - std::string FilePath = testPath("foo.cpp"); Annotations Source(R"cpp( template T foo() {} auto x = foo(); - auto y = foo() + auto y = foo(); )cpp"); - addFile(FilePath, Source.code()); + setMainFile("foo.cpp", Source.code()); // Make sure we only see the template declaration, not instantiations. - EXPECT_THAT(getSymbols(FilePath), + EXPECT_THAT(getSymbols(), ElementsAre(WithName("foo"), WithName("x"), WithName("y"))); } TEST_F(DocumentSymbolsTest, UsingDirectives) { - std::string FilePath = testPath("foo.cpp"); Annotations Source(R"cpp( namespace ns { int foo; @@ -655,16 +631,14 @@ using namespace ::ns; // check we don't loose qualifiers. using namespace ns_alias; // and namespace aliases. )cpp"); - addFile(FilePath, Source.code()); - EXPECT_THAT(getSymbols(FilePath), - ElementsAre(WithName("ns"), WithName("ns_alias"), - WithName("using namespace ::ns"), - WithName("using namespace ns_alias"))); + setMainFile("foo.cpp", Source.code()); + EXPECT_THAT(getSymbols(), ElementsAre(WithName("ns"), WithName("ns_alias"), + WithName("using namespace ::ns"), + WithName("using namespace ns_alias"))); } TEST_F(DocumentSymbolsTest, TempSpecs) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"cpp( + setMainFile("foo.cpp", R"cpp( template class Foo {}; template class Foo {}; template <> class Foo {}; @@ -672,7 +646,7 @@ )cpp"); // Foo is higher ranked because of exact name match. EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), UnorderedElementsAre( AllOf(WithName("Foo"), WithKind(SymbolKind::Class)), AllOf(WithName("Foo"), WithKind(SymbolKind::Class)), @@ -681,8 +655,7 @@ } TEST_F(DocumentSymbolsTest, Qualifiers) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"cpp( + setMainFile("foo.cpp", R"cpp( namespace foo { namespace bar { struct Cls; @@ -705,7 +678,7 @@ )cpp"); // All the qualifiers should be preserved exactly as written. - EXPECT_THAT(getSymbols(FilePath), + EXPECT_THAT(getSymbols(), UnorderedElementsAre( WithName("foo"), WithName("foo::bar::Cls"), WithName("foo::bar::func1"), WithName("::foo::bar::func2"), @@ -714,8 +687,7 @@ } TEST_F(DocumentSymbolsTest, QualifiersWithTemplateArgs) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"cpp( + setMainFile("foo.cpp", R"cpp( template class Foo; template <> @@ -738,7 +710,7 @@ int Foo_type::method3() { return 30; } )cpp"); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(), UnorderedElementsAre(WithName("Foo"), WithName("Foo"), WithName("int_type"), WithName("Foo::method1"), diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.h b/clang-tools-extra/clangd/unittests/SyncAPI.h --- a/clang-tools-extra/clangd/unittests/SyncAPI.h +++ b/clang-tools-extra/clangd/unittests/SyncAPI.h @@ -46,12 +46,6 @@ std::string runDumpAST(ClangdServer &Server, PathRef File); -llvm::Expected> -runWorkspaceSymbols(ClangdServer &Server, StringRef Query, int Limit); - -Expected> runDocumentSymbols(ClangdServer &Server, - PathRef File); - SymbolSlab runFuzzyFind(const SymbolIndex &Index, StringRef Query); SymbolSlab runFuzzyFind(const SymbolIndex &Index, const FuzzyFindRequest &Req); RefSlab getRefs(const SymbolIndex &Index, SymbolID ID); diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.cpp b/clang-tools-extra/clangd/unittests/SyncAPI.cpp --- a/clang-tools-extra/clangd/unittests/SyncAPI.cpp +++ b/clang-tools-extra/clangd/unittests/SyncAPI.cpp @@ -111,20 +111,6 @@ return std::move(*Result); } -llvm::Expected> -runWorkspaceSymbols(ClangdServer &Server, llvm::StringRef Query, int Limit) { - llvm::Optional>> Result; - Server.workspaceSymbols(Query, Limit, capture(Result)); - return std::move(*Result); -} - -llvm::Expected> -runDocumentSymbols(ClangdServer &Server, PathRef File) { - llvm::Optional>> Result; - Server.documentSymbols(File, capture(Result)); - return std::move(*Result); -} - SymbolSlab runFuzzyFind(const SymbolIndex &Index, llvm::StringRef Query) { FuzzyFindRequest Req; Req.Query = std::string(Query);