[clang-tools-extra] r204909 - Output messages when clang-tidy applies fix-its.

Alexander Kornienko alexfh at google.com
Thu Mar 27 03:24:12 PDT 2014


Author: alexfh
Date: Thu Mar 27 05:24:11 2014
New Revision: 204909

URL: http://llvm.org/viewvc/llvm-project?rev=204909&view=rev
Log:
Output messages when clang-tidy applies fix-its.

Reviewers: djasper, klimek

Reviewed By: djasper

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D3192

Modified:
    clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
    clang-tools-extra/trunk/test/clang-tidy/fix.cpp

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp?rev=204909&r1=204908&r2=204909&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp Thu Mar 27 05:24:11 2014
@@ -25,6 +25,7 @@
 #include "clang/Frontend/ASTConsumers.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Lex/PPCallbacks.h"
@@ -38,6 +39,7 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
 #include <algorithm>
+#include <utility>
 #include <vector>
 
 using namespace clang::ast_matchers;
@@ -90,6 +92,84 @@ private:
   ClangTidyContext &Context;
 };
 
+class ErrorReporter {
+public:
+  ErrorReporter(bool ApplyFixes)
+      : Files(FileSystemOptions()), DiagOpts(new DiagnosticOptions()),
+        DiagPrinter(new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts)),
+        Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts,
+              DiagPrinter),
+        SourceMgr(Diags, Files), Rewrite(SourceMgr, LangOpts),
+        ApplyFixes(ApplyFixes) {
+    DiagOpts->ShowColors = llvm::sys::Process::StandardOutHasColors();
+    DiagPrinter->BeginSourceFile(LangOpts);
+  }
+
+  void reportDiagnostic(const ClangTidyMessage &Message,
+                        DiagnosticsEngine::Level Level,
+                        const tooling::Replacements *Fixes = nullptr) {
+    SourceLocation Loc = getLocation(Message.FilePath, Message.FileOffset);
+    // Contains a pair for each attempted fix: location and whether the fix was
+    // applied successfully.
+    SmallVector<std::pair<SourceLocation, bool>, 4> FixLocations;
+    {
+      DiagnosticBuilder Diag =
+          Diags.Report(Loc, Diags.getCustomDiagID(Level, "%0"))
+          << Message.Message;
+      if (Fixes != NULL) {
+        for (const tooling::Replacement &Fix : *Fixes) {
+          SourceLocation FixLoc =
+              getLocation(Fix.getFilePath(), Fix.getOffset());
+          SourceLocation FixEndLoc = FixLoc.getLocWithOffset(Fix.getLength());
+          Diag << FixItHint::CreateReplacement(SourceRange(FixLoc, FixEndLoc),
+                                               Fix.getReplacementText());
+          ++TotalFixes;
+          if (ApplyFixes) {
+            bool Success = Fix.isApplicable() && Fix.apply(Rewrite);
+            if (Success)
+              ++AppliedFixes;
+            FixLocations.push_back(std::make_pair(FixLoc, Success));
+          }
+        }
+      }
+    }
+    for (auto Fix : FixLocations) {
+      Diags.Report(Fix.first, Fix.second ? diag::note_fixit_applied
+                                         : diag::note_fixit_failed);
+    }
+  }
+
+  void Finish() {
+    // FIXME: Run clang-format on changes.
+    if (ApplyFixes && TotalFixes > 0) {
+      llvm::errs() << "clang-tidy applied " << AppliedFixes << " of "
+                   << TotalFixes << " suggested fixes.\n";
+      Rewrite.overwriteChangedFiles();
+    }
+  }
+
+private:
+  SourceLocation getLocation(StringRef FilePath, unsigned Offset) {
+    if (FilePath.empty())
+      return SourceLocation();
+
+    const FileEntry *File = SourceMgr.getFileManager().getFile(FilePath);
+    FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
+    return SourceMgr.getLocForStartOfFile(ID).getLocWithOffset(Offset);
+  }
+
+  FileManager Files;
+  LangOptions LangOpts; // FIXME: use langopts from each original file
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticConsumer *DiagPrinter;
+  DiagnosticsEngine Diags;
+  SourceManager SourceMgr;
+  Rewriter Rewrite;
+  bool ApplyFixes;
+  unsigned TotalFixes = 0;
+  unsigned AppliedFixes = 0;
+};
+
 } // namespace
 
 ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
@@ -252,59 +332,15 @@ void runClangTidy(StringRef EnableChecks
   Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(Context)));
 }
 
-static SourceLocation getLocation(SourceManager &SourceMgr, StringRef FilePath,
-                                  unsigned Offset) {
-  if (FilePath.empty())
-    return SourceLocation();
-
-  const FileEntry *File = SourceMgr.getFileManager().getFile(FilePath);
-  FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
-  return SourceMgr.getLocForStartOfFile(ID).getLocWithOffset(Offset);
-}
-
-static void reportDiagnostic(const ClangTidyMessage &Message,
-                             SourceManager &SourceMgr,
-                             DiagnosticsEngine::Level Level,
-                             DiagnosticsEngine &Diags,
-                             const tooling::Replacements *Fixes = NULL) {
-  SourceLocation Loc =
-      getLocation(SourceMgr, Message.FilePath, Message.FileOffset);
-  DiagnosticBuilder Diag = Diags.Report(Loc, Diags.getCustomDiagID(Level, "%0"))
-                           << Message.Message;
-  if (Fixes != NULL) {
-    for (const tooling::Replacement &Fix : *Fixes) {
-      SourceLocation FixLoc =
-          getLocation(SourceMgr, Fix.getFilePath(), Fix.getOffset());
-      Diag << FixItHint::CreateReplacement(
-                  SourceRange(FixLoc, FixLoc.getLocWithOffset(Fix.getLength())),
-                  Fix.getReplacementText());
-    }
-  }
-}
-
 void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix) {
-  FileManager Files((FileSystemOptions()));
-  LangOptions LangOpts; // FIXME: use langopts from each original file
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
-  DiagOpts->ShowColors = llvm::sys::Process::StandardOutHasColors();
-  DiagnosticConsumer *DiagPrinter =
-      new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts);
-  DiagnosticsEngine Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-                          &*DiagOpts, DiagPrinter);
-  DiagPrinter->BeginSourceFile(LangOpts);
-  SourceManager SourceMgr(Diags, Files);
-  Rewriter Rewrite(SourceMgr, LangOpts);
+  ErrorReporter Reporter(Fix);
   for (const ClangTidyError &Error : Errors) {
-    reportDiagnostic(Error.Message, SourceMgr, DiagnosticsEngine::Warning, Diags,
-                     &Error.Fix);
+    Reporter.reportDiagnostic(Error.Message, DiagnosticsEngine::Warning,
+                              &Error.Fix);
     for (const ClangTidyMessage &Note : Error.Notes)
-      reportDiagnostic(Note, SourceMgr, DiagnosticsEngine::Note, Diags);
-
-    tooling::applyAllReplacements(Error.Fix, Rewrite);
+      Reporter.reportDiagnostic(Note, DiagnosticsEngine::Note);
   }
-  // FIXME: Run clang-format on changes.
-  if (Fix)
-    Rewrite.overwriteChangedFiles();
+  Reporter.Finish();
 }
 
 } // namespace tidy

Modified: clang-tools-extra/trunk/test/clang-tidy/fix.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/fix.cpp?rev=204909&r1=204908&r2=204909&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/fix.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/fix.cpp Thu Mar 27 05:24:11 2014
@@ -1,10 +1,14 @@
 // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: clang-tidy %t.cpp -fix --
+// RUN: clang-tidy %t.cpp -fix -- > %t.msg 2>&1
 // RUN: FileCheck -input-file=%t.cpp %s
+// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MESSAGES %s
 
 namespace i {
 }
 // CHECK: } // namespace i
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
 
 class A { A(int i); };
 // CHECK: class A { explicit A(int i); };
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-MESSAGES: clang-tidy applied 2 of 2 suggested fixes.





More information about the cfe-commits mailing list