diff --git a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h --- a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h +++ b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h @@ -38,6 +38,8 @@ // includes. class TransformerClangTidyCheck : public ClangTidyCheck { public: + TransformerClangTidyCheck(StringRef Name, ClangTidyContext *Context); + // \p MakeRule generates the rewrite rule to be used by the check, based on // the given language and clang-tidy options. It can return \c None to handle // cases where the options disable the check. @@ -68,8 +70,11 @@ /// the overridden method. void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + /// Set the rule that this check implements. + void setRule(transformer::RewriteRule R); + private: - Optional Rule; + transformer::RewriteRule Rule; IncludeInserter Inserter; }; diff --git a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp --- a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp @@ -21,6 +21,18 @@ } #endif +static void verifyRule(const RewriteRule &Rule) { + assert(llvm::all_of(Rule.Cases, hasExplanation) && + "clang-tidy checks must have an explanation by default;" + " explicitly provide an empty explanation if none is desired"); +} + +TransformerClangTidyCheck::TransformerClangTidyCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + Inserter( + Options.getLocalOrGlobal("IncludeStyle", IncludeSorter::IS_LLVM)) {} + // This constructor cannot dispatch to the simpler one (below), because, in // order to get meaningful results from `getLangOpts` and `Options`, we need the // `ClangTidyCheck()` constructor to have been called. If we were to dispatch, @@ -31,24 +43,21 @@ const OptionsView &)> MakeRule, StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), Rule(MakeRule(getLangOpts(), Options)), - Inserter( - Options.getLocalOrGlobal("IncludeStyle", IncludeSorter::IS_LLVM)) { - if (Rule) - assert(llvm::all_of(Rule->Cases, hasExplanation) && - "clang-tidy checks must have an explanation by default;" - " explicitly provide an empty explanation if none is desired"); + : TransformerClangTidyCheck(Name, Context) { + if (Optional R = MakeRule(getLangOpts(), Options)) + setRule(std::move(*R)); } TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R, StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), Rule(std::move(R)), - Inserter( - Options.getLocalOrGlobal("IncludeStyle", IncludeSorter::IS_LLVM)) { - assert(llvm::all_of(Rule->Cases, hasExplanation) && - "clang-tidy checks must have an explanation by default;" - " explicitly provide an empty explanation if none is desired"); + : TransformerClangTidyCheck(Name, Context) { + setRule(std::move(R)); +} + +void TransformerClangTidyCheck::setRule(transformer::RewriteRule R) { + verifyRule(R); + Rule = std::move(R); } void TransformerClangTidyCheck::registerPPCallbacks( @@ -58,8 +67,8 @@ void TransformerClangTidyCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { - if (Rule) - for (auto &Matcher : transformer::detail::buildMatchers(*Rule)) + if (!Rule.Cases.empty()) + for (auto &Matcher : transformer::detail::buildMatchers(Rule)) Finder->addDynamicMatcher(Matcher, this); } @@ -68,8 +77,7 @@ if (Result.Context->getDiagnostics().hasErrorOccurred()) return; - assert(Rule && "check() should not fire if Rule is None"); - RewriteRule::Case Case = transformer::detail::findSelectedCase(Result, *Rule); + RewriteRule::Case Case = transformer::detail::findSelectedCase(Result, Rule); Expected> Edits = Case.Edits(Result); if (!Edits) { llvm::errs() << "Rewrite failed: " << llvm::toString(Edits.takeError())