[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