Skip to content

Commit

Permalink
std::function-ize ClangTidyCheckFactories.
Browse files Browse the repository at this point in the history
Reviewers: djasper

Reviewed By: djasper

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D5289

llvm-svn: 217492
  • Loading branch information
alexfh committed Sep 10, 2014
1 parent 936e053 commit d3fdcf8
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 63 deletions.
8 changes: 4 additions & 4 deletions clang-tools-extra/clang-tidy/ClangTidyModule.cpp
Expand Up @@ -16,16 +16,16 @@
namespace clang {
namespace tidy {

void ClangTidyCheckFactories::addCheckFactory(
StringRef Name, std::unique_ptr<CheckFactoryBase> Factory) {
Factories[Name] = std::move(Factory);
void ClangTidyCheckFactories::registerCheckFactory(
StringRef Name, std::function<ClangTidyCheck *()> Factory) {
Factories[Name] = Factory;
}

void ClangTidyCheckFactories::createChecks(
GlobList &Filter, std::vector<std::unique_ptr<ClangTidyCheck>> &Checks) {
for (const auto &Factory : Factories) {
if (Filter.contains(Factory.first)) {
ClangTidyCheck *Check = Factory.second->createCheck();
ClangTidyCheck *Check = Factory.second();
Check->setName(Factory.first);
Checks.emplace_back(Check);
}
Expand Down
101 changes: 42 additions & 59 deletions clang-tools-extra/clang-tidy/ClangTidyModule.h
Expand Up @@ -11,79 +11,51 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_MODULE_H

#include "ClangTidy.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <functional>
#include <map>
#include <string>
#include <utility>

namespace clang {
namespace tidy {

/// \brief A factory, that can instantiate a specific clang-tidy check for
/// processing a translation unit.
///
/// In order to register your check with the \c ClangTidyModule, create a
/// subclass of \c CheckFactoryBase and implement \c createCheck(). Then, use
/// this subclass in \c ClangTidyModule::addCheckFactories().
class CheckFactoryBase {
public:
virtual ~CheckFactoryBase() {}
virtual ClangTidyCheck *createCheck() = 0;
};

/// \brief A subclass of \c CheckFactoryBase that should be used for all
/// \c ClangTidyChecks that don't require constructor parameters.
///
/// For example, if have a clang-tidy check like:
/// \code
/// class MyTidyCheck : public ClangTidyCheck {
/// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
/// ..
/// }
/// };
/// \endcode
/// you can register it with:
/// \code
/// class MyModule : public ClangTidyModule {
/// void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
/// CheckFactories.addCheckFactory(
/// "myproject-my-check", new ClangTidyCheckFactory<MyTidyCheck>());
/// }
/// };
/// \endcode
template <typename T> class ClangTidyCheckFactory : public CheckFactoryBase {
public:
ClangTidyCheck *createCheck() override { return new T; }
};

class ClangTidyCheckFactories;

/// \brief A clang-tidy module groups a number of \c ClangTidyChecks and gives
/// them a prefixed name.
class ClangTidyModule {
public:
virtual ~ClangTidyModule() {}

/// \brief Implement this function in order to register all \c CheckFactories
/// belonging to this module.
virtual void addCheckFactories(ClangTidyCheckFactories &CheckFactories) = 0;
};

/// \brief A collection of \c ClangTidyCheckFactory instances.
///
/// All clang-tidy modules register their check factories with an instance of
/// this object.
class ClangTidyCheckFactories {
public:
/// \brief Register \p Factory with the name \p Name.
void addCheckFactory(StringRef Name,
std::unique_ptr<CheckFactoryBase> Factory);
/// \brief Registers check \p Factory with name \p Name.
///
/// For all checks that have default constructors, use \c registerCheck.
void registerCheckFactory(StringRef Name,
std::function<ClangTidyCheck *()> Factory);

/// \brief Registers the \c CheckType with the name \p Name by adding a
/// corresponding \c ClangTidyCheckFactory.
/// \brief Registers the \c CheckType with the name \p Name.
///
/// This method should be used for all \c ClangTidyChecks that don't require
/// constructor parameters.
///
/// For example, if have a clang-tidy check like:
/// \code
/// class MyTidyCheck : public ClangTidyCheck {
/// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
/// ..
/// }
/// };
/// \endcode
/// you can register it with:
/// \code
/// class MyModule : public ClangTidyModule {
/// void addCheckFactories(ClangTidyCheckFactories &Factories) override {
/// Factories.registerCheck<MyTidyCheck>("myproject-my-check");
/// }
/// };
/// \endcode
template<typename CheckType>
void registerCheck(StringRef Name) {
addCheckFactory(Name,
llvm::make_unique<ClangTidyCheckFactory<CheckType>>());
registerCheckFactory(Name, []() { return new CheckType(); });
}

/// \brief Create instances of all checks matching \p CheckRegexString and
Expand All @@ -93,7 +65,7 @@ class ClangTidyCheckFactories {
void createChecks(GlobList &Filter,
std::vector<std::unique_ptr<ClangTidyCheck>> &Checks);

typedef std::map<std::string, std::unique_ptr<CheckFactoryBase>> FactoryMap;
typedef std::map<std::string, std::function<ClangTidyCheck *()>> FactoryMap;
FactoryMap::const_iterator begin() const { return Factories.begin(); }
FactoryMap::const_iterator end() const { return Factories.end(); }
bool empty() const { return Factories.empty(); }
Expand All @@ -102,6 +74,17 @@ class ClangTidyCheckFactories {
FactoryMap Factories;
};

/// \brief A clang-tidy module groups a number of \c ClangTidyChecks and gives
/// them a prefixed name.
class ClangTidyModule {
public:
virtual ~ClangTidyModule() {}

/// \brief Implement this function in order to register all \c CheckFactories
/// belonging to this module.
virtual void addCheckFactories(ClangTidyCheckFactories &CheckFactories) = 0;
};

} // end namespace tidy
} // end namespace clang

Expand Down

0 comments on commit d3fdcf8

Please sign in to comment.