ymandel updated this revision to Diff 200536.
ymandel added a comment.

Renamed TransformerTidy to TransformerClangTidyCheck; classes and files.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61386/new/

https://reviews.llvm.org/D61386

Files:
  clang-tools-extra/clang-tidy/utils/CMakeLists.txt
  clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h
  clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
  clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp

Index: clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
@@ -0,0 +1,63 @@
+//===---- TransformerClangTidyCheckTest.cpp - clang-tidy ------------------===//
+//
+// 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 "../clang-tidy/utils/TransformerClangTidyCheck.h"
+#include "ClangTidyTest.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Refactoring/Stencil.h"
+#include "clang/Tooling/Refactoring/Transformer.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+namespace {
+// Invert the code of an if-statement, while maintaining its semantics.
+tooling::RewriteRule invertIf() {
+  using namespace ::clang::ast_matchers;
+  using tooling::change;
+  using tooling::stencil::cat;
+  using tooling::stencil::node;
+  using tooling::stencil::sNode;
+
+  StringRef C = "C", T = "T", E = "E";
+  return tooling::makeRule(
+      ifStmt(hasCondition(expr().bind(C)), hasThen(stmt().bind(T)),
+             hasElse(stmt().bind(E))),
+      change<Stmt>(cat("if(!(", node(C), ")) ", sNode(E), " else ", sNode(T))));
+}
+
+class IfInverterCheck : public TransformerClangTidyCheck {
+public:
+  IfInverterCheck(StringRef Name, ClangTidyContext *Context)
+      : TransformerClangTidyCheck(invertIf(), Name, Context) {}
+};
+
+// Basic test of using a rewrite rule as a ClangTidy.
+TEST(TransformerClangTidyCheckTest, Basic) {
+  const std::string Input = R"cc(
+    void log(const char* msg);
+    void foo() {
+      if (10 > 1.0)
+        log("oh no!");
+      else
+        log("ok");
+    }
+  )cc";
+  const std::string Expected = R"(
+    void log(const char* msg);
+    void foo() {
+      if(!(10 > 1.0)) log("ok"); else log("oh no!");
+    }
+  )";
+  EXPECT_EQ(Expected, test::runCheckOnCode<IfInverterCheck>(Input));
+}
+} // namespace
+} // namespace utils
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
===================================================================
--- clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
+++ clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
@@ -17,6 +17,7 @@
   OverlappingReplacementsTest.cpp
   UsingInserterTest.cpp
   ReadabilityModuleTest.cpp
+  TransformerClangTidyCheckTest.cpp
   )
 
 target_link_libraries(ClangTidyTests
@@ -36,4 +37,5 @@
   clangTidyUtils
   clangTooling
   clangToolingCore
+  clangToolingRefactor
   )
Index: clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h
@@ -0,0 +1,49 @@
+//===---------- TransformerClangTidyCheck.h - clang-tidy ------------------===//
+//
+// 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_CLANG_TIDY_TRANSFORMER_CLANG_TIDY_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_TRANSFORMER_CLANG_TIDY_CHECK_H
+
+#include "../ClangTidy.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Refactoring/Transformer.h"
+#include <deque>
+#include <vector>
+
+namespace clang {
+namespace tidy {
+namespace utils {
+
+// A base class for defining a ClangTidy check based on a `RewriteRule`.
+//
+// For example, given a rule `MyCheckAsRewriteRule`, one can define a tidy check
+// as follows:
+//
+// class MyCheck : public TransformerClangTidyCheck {
+//  public:
+//   MyCheck(StringRef Name, ClangTidyContext *Context)
+//       : TransformerClangTidyCheck(MyCheckAsRewriteRule, Name, Context) {}
+// };
+class TransformerClangTidyCheck : public ClangTidyCheck {
+public:
+  TransformerClangTidyCheck(tooling::RewriteRule R, StringRef Name,
+                            ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context), Rule(std::move(R)) {}
+
+  void registerMatchers(ast_matchers::MatchFinder *Finder) final;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
+
+private:
+  tooling::RewriteRule Rule;
+};
+
+} // namespace utils
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_TRANSFORMER_CLANG_TIDY_CHECK_H
Index: clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
@@ -0,0 +1,62 @@
+//===---------- TransformerClangTidyCheck.cpp - clang-tidy ----------------===//
+//
+// 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 "TransformerClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+
+void TransformerClangTidyCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
+  Finder->addDynamicMatcher(tooling::detail::buildMatcher(Rule), this);
+}
+
+void TransformerClangTidyCheck::check(
+    const ast_matchers::MatchFinder::MatchResult &Result) {
+  if (Result.Context->getDiagnostics().hasErrorOccurred())
+    return;
+
+  // Verify the existence and validity of the AST node that roots this rule.
+  const ast_matchers::BoundNodes::IDToNodeMap &NodesMap = Result.Nodes.getMap();
+  auto Root = NodesMap.find(tooling::RewriteRule::RootId);
+  assert(Root != NodesMap.end() && "Transformation failed: missing root node.");
+  SourceLocation RootLoc = Result.SourceManager->getExpansionLoc(
+      Root->second.getSourceRange().getBegin());
+  assert(RootLoc.isValid() && "Invalid location for Root node of match.");
+
+  tooling::RewriteRule::Case Case =
+      tooling::detail::findSelectedCase(Result, Rule);
+  Expected<SmallVector<tooling::detail::Transformation, 1>> Transformations =
+      tooling::detail::translateEdits(Result, Case.Edits);
+  if (!Transformations) {
+    llvm::errs() << "Rewrite failed: "
+                 << llvm::toString(Transformations.takeError()) << "\n";
+    return;
+  }
+
+  // No rewrite applied, but no error encountered either.
+  if (Transformations->empty())
+    return;
+
+  StringRef Message = "no explanation";
+  if (Case.Explanation) {
+    if (Expected<std::string> E = Case.Explanation(Result))
+      Message = *E;
+    else
+      llvm::errs() << "Error in explanation: " << llvm::toString(E.takeError())
+                   << "\n";
+  }
+  DiagnosticBuilder Diag = diag(RootLoc, Message);
+  for (const auto &T : *Transformations) {
+    Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
+  }
+}
+
+} // namespace utils
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/utils/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/utils/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/utils/CMakeLists.txt
@@ -13,6 +13,7 @@
   LexerUtils.cpp
   NamespaceAliaser.cpp
   OptionsUtils.cpp
+  TransformerClangTidyCheck.cpp
   TypeTraits.cpp
   UsingInserter.cpp
 
@@ -22,4 +23,5 @@
   clangBasic
   clangLex
   clangTidy
+  clangToolingRefactor
   )
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to