Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang-tools-extra/clangd/FeatureModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,9 @@ using FeatureModuleRegistry = llvm::Registry<FeatureModule>;

} // namespace clangd
} // namespace clang

namespace llvm {
extern template class Registry<clang::clangd::FeatureModule>;
} // namespace llvm

#endif
5 changes: 5 additions & 0 deletions clang-tools-extra/clangd/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ add_unittest(ClangdUnitTests ClangdTests
DumpASTTests.cpp
ExpectedTypeTest.cpp
FeatureModulesTests.cpp
FeatureModulesRegistryTests.cpp
FileDistanceTests.cpp
FileIndexTests.cpp
FindSymbolsTests.cpp
Expand Down Expand Up @@ -154,6 +155,8 @@ target_include_directories(ClangdTests PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
)

add_subdirectory(feature-modules)

clang_target_link_libraries(ClangdTests
PRIVATE
clangAST
Expand Down Expand Up @@ -183,6 +186,8 @@ target_link_libraries(ClangdTests
clangTidy
clangTidyUtils
clangdSupport

${FEATURE_MODULES}
)

if (CLANGD_ENABLE_REMOTE)
Expand Down
66 changes: 66 additions & 0 deletions clang-tools-extra/clangd/unittests/FeatureModulesRegistryTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//===--- FeatureModulesRegistryTests.cpp ---------------------------------===//
//
// 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 "FeatureModule.h"
#include "feature-modules/ForceLinker.h" // IWYU pragma: keep
#include "refactor/Tweak.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using testing::ElementsAre;

namespace llvm {
raw_ostream &operator<<(raw_ostream &OS,
const clang::clangd::FeatureModuleRegistry::entry &E) {
OS << "(name = " << E.getName() << ", description = '" << E.getDesc() << "')";
return OS;
}

raw_ostream &operator<<(
raw_ostream &OS,
const iterator_range<Registry<clang::clangd::FeatureModule>::iterator>
&Rng) {
OS << "{ ";
bool First = true;
for (clang::clangd::FeatureModuleRegistry::entry E : Rng) {
if (First)
First = false;
else
OS << ", ";
OS << E;
}
OS << " }";
return OS;
}

raw_ostream &operator<<(raw_ostream &OS, const clang::clangd::Tweak &T) {
OS << "(id = " << T.id() << ", "
<< "title = " << T.title() << ")";
return OS;
}
} // namespace llvm

namespace clang::clangd {
namespace {

MATCHER_P(moduleName, Name, "") { return arg.getName() == Name; }
MATCHER_P(tweakID, ID, "") { return arg->id() == ID; }

TEST(FeatureModulesRegistryTest, DummyModule) {
EXPECT_THAT(FeatureModuleRegistry::entries(),
ElementsAre(moduleName("dummy")));
FeatureModuleSet Set = FeatureModuleSet::fromRegistry();
ASSERT_EQ(Set.end() - Set.begin(), 1u);
std::vector<std::unique_ptr<Tweak>> Tweaks;
Set.begin()->contributeTweaks(Tweaks);
EXPECT_THAT(Tweaks, ElementsAre(tweakID("DummyTweak")));
}

} // namespace
} // namespace clang::clangd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_subdirectory(dummy)
set(FEATURE_MODULES ${FEATURE_MODULES} PARENT_SCOPE)
20 changes: 20 additions & 0 deletions clang-tools-extra/clangd/unittests/feature-modules/ForceLinker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===- ForceLinker.h ----------------------------------------------*-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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTEST_FEATURE_MODULES_FORCE_LINKER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTEST_FEATURE_MODULES_FORCE_LINKER_H

#include "llvm/Support/Compiler.h"

namespace clang::clangd {
extern volatile int DummyFeatureModuleAnchorSource;
static int LLVM_ATTRIBUTE_UNUSED DummyFeatureModuleAnchorDestination =
DummyFeatureModuleAnchorSource;
} // namespace clang::clangd

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_llvm_library(dummyFeatureModule DummyFeatureModule.cpp)
set(FEATURE_MODULES ${FEATURE_MODULES} dummyFeatureModule PARENT_SCOPE)
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===--- DummyFeatureModule.cpp -------------------------------------------===//
//
// 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 "FeatureModule.h"
#include "refactor/Tweak.h"
#include "support/Logger.h"

namespace clang::clangd {

class Dummy final : public FeatureModule {
static constexpr const char *TweakID = "DummyTweak";
struct DummyTweak final : public Tweak {
const char *id() const override { return TweakID; }
bool prepare(const Selection &) override { return true; }
Expected<Effect> apply(const Selection &) override {
return error("not implemented");
}
std::string title() const override { return id(); }
llvm::StringLiteral kind() const override {
return llvm::StringLiteral("");
};
};

void contributeTweaks(std::vector<std::unique_ptr<Tweak>> &Out) override {
Out.emplace_back(new DummyTweak);
}
};

static FeatureModuleRegistry::Add<Dummy>
X("dummy", "Dummy feature module with dummy tweak");

// This anchor is used to force the linker to link in the generated object file
// and thus register the Dummy feature module.
volatile int DummyFeatureModuleAnchorSource = 0;

} // namespace clang::clangd