aboutsummaryrefslogtreecommitdiff
path: root/clang-apply-replacements
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2017-01-03 14:36:13 +0000
committerAlexander Kornienko <alexfh@google.com>2017-01-03 14:36:13 +0000
commit6b97b9e1162fc98a8047e0b61cc659a2286a1c47 (patch)
tree7773af8e2280ec87aee830ee75515fc430a32b48 /clang-apply-replacements
parent7ee33c19aae558d5d7b37c83a6da9f7e2a304c53 (diff)
[clang-tidy] Add check name to YAML export (clang-tools-extra part)
Add a field indicating the associated check for every replacement to the YAML report generated with the '-export-fixes' option. Update clang-apply-replacements to handle the new format. Patch by Alpha Abdoulaye! Differential revision: https://reviews.llvm.org/D26137 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@290893 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-apply-replacements')
-rw-r--r--clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h21
-rw-r--r--clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp78
-rw-r--r--clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp19
3 files changed, 106 insertions, 12 deletions
diff --git a/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h b/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h
index 22393724..5e0ff48a 100644
--- a/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h
+++ b/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h
@@ -16,6 +16,7 @@
#ifndef LLVM_CLANG_APPLYREPLACEMENTS_H
#define LLVM_CLANG_APPLYREPLACEMENTS_H
+#include "clang/Tooling/Core/Diagnostic.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -43,6 +44,9 @@ typedef std::vector<clang::tooling::TranslationUnitReplacements> TUReplacements;
/// \brief Collection of TranslationUnitReplacement files.
typedef std::vector<std::string> TUReplacementFiles;
+/// \brief Collection of TranslationUniDiagnostics.
+typedef std::vector<clang::tooling::TranslationUnitDiagnostics> TUDiagnostics;
+
/// \brief Map mapping file name to Replacements targeting that file.
typedef llvm::DenseMap<const clang::FileEntry *,
std::vector<clang::tooling::Replacement>>
@@ -58,8 +62,8 @@ typedef llvm::DenseMap<const clang::FileEntry *,
/// \param[in] Directory Directory to begin search for serialized
/// TranslationUnitReplacements.
/// \param[out] TUs Collection of all found and deserialized
-/// TranslationUnitReplacements.
-/// \param[out] TURFiles Collection of all TranslationUnitReplacement files
+/// TranslationUnitReplacements or TranslationUnitDiagnostics.
+/// \param[out] TUFiles Collection of all TranslationUnitReplacement files
/// found in \c Directory.
/// \param[in] Diagnostics DiagnosticsEngine used for error output.
///
@@ -67,7 +71,11 @@ typedef llvm::DenseMap<const clang::FileEntry *,
/// directory structure.
std::error_code collectReplacementsFromDirectory(
const llvm::StringRef Directory, TUReplacements &TUs,
- TUReplacementFiles &TURFiles, clang::DiagnosticsEngine &Diagnostics);
+ TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics);
+
+std::error_code collectReplacementsFromDirectory(
+ const llvm::StringRef Directory, TUDiagnostics &TUs,
+ TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics);
/// \brief Deduplicate, check for conflicts, and apply all Replacements stored
/// in \c TUs. If conflicts occur, no Replacements are applied.
@@ -75,7 +83,8 @@ std::error_code collectReplacementsFromDirectory(
/// \post For all (key,value) in GroupedReplacements, value[i].getOffset() <=
/// value[i+1].getOffset().
///
-/// \param[in] TUs Collection of TranslationUnitReplacements to merge,
+/// \param[in] TUs Collection of TranslationUnitReplacements or
+/// TranslationUnitDiagnostics to merge,
/// deduplicate, and test for conflicts.
/// \param[out] GroupedReplacements Container grouping all Replacements by the
/// file they target.
@@ -88,6 +97,10 @@ bool mergeAndDeduplicate(const TUReplacements &TUs,
FileToReplacementsMap &GroupedReplacements,
clang::SourceManager &SM);
+bool mergeAndDeduplicate(const TUDiagnostics &TUs,
+ FileToReplacementsMap &GroupedReplacements,
+ clang::SourceManager &SM);
+
// FIXME: Remove this function after changing clang-apply-replacements to use
// Replacements class.
bool applyAllReplacements(const std::vector<tooling::Replacement> &Replaces,
diff --git a/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp b/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
index d2607b06..52234fed 100644
--- a/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
+++ b/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
@@ -20,6 +20,7 @@
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/DiagnosticsYaml.h"
#include "clang/Tooling/ReplacementsYaml.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/FileSystem.h"
@@ -37,7 +38,7 @@ namespace replace {
std::error_code collectReplacementsFromDirectory(
const llvm::StringRef Directory, TUReplacements &TUs,
- TUReplacementFiles &TURFiles, clang::DiagnosticsEngine &Diagnostics) {
+ TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) {
using namespace llvm::sys::fs;
using namespace llvm::sys::path;
@@ -54,7 +55,7 @@ std::error_code collectReplacementsFromDirectory(
if (extension(I->path()) != ".yaml")
continue;
- TURFiles.push_back(I->path());
+ TUFiles.push_back(I->path());
ErrorOr<std::unique_ptr<MemoryBuffer>> Out =
MemoryBuffer::getFile(I->path());
@@ -79,6 +80,51 @@ std::error_code collectReplacementsFromDirectory(
return ErrorCode;
}
+std::error_code
+collectReplacementsFromDirectory(const llvm::StringRef Directory,
+ TUDiagnostics &TUs, TUReplacementFiles &TUFiles,
+ clang::DiagnosticsEngine &Diagnostics) {
+ using namespace llvm::sys::fs;
+ using namespace llvm::sys::path;
+
+ std::error_code ErrorCode;
+
+ for (recursive_directory_iterator I(Directory, ErrorCode), E;
+ I != E && !ErrorCode; I.increment(ErrorCode)) {
+ if (filename(I->path())[0] == '.') {
+ // Indicate not to descend into directories beginning with '.'
+ I.no_push();
+ continue;
+ }
+
+ if (extension(I->path()) != ".yaml")
+ continue;
+
+ TUFiles.push_back(I->path());
+
+ ErrorOr<std::unique_ptr<MemoryBuffer>> Out =
+ MemoryBuffer::getFile(I->path());
+ if (std::error_code BufferError = Out.getError()) {
+ errs() << "Error reading " << I->path() << ": " << BufferError.message()
+ << "\n";
+ continue;
+ }
+
+ yaml::Input YIn(Out.get()->getBuffer(), nullptr, &eatDiagnostics);
+ tooling::TranslationUnitDiagnostics TU;
+ YIn >> TU;
+ if (YIn.error()) {
+ // File doesn't appear to be a header change description. Ignore it.
+ continue;
+ }
+
+ // Only keep files that properly parse.
+ TUs.push_back(TU);
+ }
+
+ return ErrorCode;
+}
+
/// \brief Dumps information for a sequence of conflicting Replacements.
///
/// \param[in] File FileEntry for the file the conflicting Replacements are
@@ -256,6 +302,34 @@ bool mergeAndDeduplicate(const TUReplacements &TUs,
return !deduplicateAndDetectConflicts(GroupedReplacements, SM);
}
+bool mergeAndDeduplicate(const TUDiagnostics &TUs,
+ FileToReplacementsMap &GroupedReplacements,
+ clang::SourceManager &SM) {
+
+ // Group all replacements by target file.
+ std::set<StringRef> Warned;
+ for (const auto &TU : TUs) {
+ for (const auto &D : TU.Diagnostics) {
+ for (const auto &Fix : D.Fix) {
+ for (const tooling::Replacement &R : Fix.second) {
+ // Use the file manager to deduplicate paths. FileEntries are
+ // automatically canonicalized.
+ const FileEntry *Entry = SM.getFileManager().getFile(R.getFilePath());
+ if (!Entry && Warned.insert(R.getFilePath()).second) {
+ errs() << "Described file '" << R.getFilePath()
+ << "' doesn't exist. Ignoring...\n";
+ continue;
+ }
+ GroupedReplacements[Entry].push_back(R);
+ }
+ }
+ }
+ }
+
+ // Ask clang to deduplicate and report conflicts.
+ return !deduplicateAndDetectConflicts(GroupedReplacements, SM);
+}
+
bool applyReplacements(const FileToReplacementsMap &GroupedReplacements,
clang::Rewriter &Rewrites) {
diff --git a/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp b/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
index 48c6903f..0881e677 100644
--- a/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
+++ b/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
@@ -66,7 +66,7 @@ static cl::opt<std::string>
cl::init("LLVM"), cl::cat(FormattingCategory));
namespace {
-// Helper object to remove the TUReplacement files (triggered by
+// Helper object to remove the TUReplacement and TUDiagnostic (triggered by
// "remove-change-desc-files" command line option) when exiting current scope.
class ScopedFileRemover {
public:
@@ -211,11 +211,16 @@ int main(int argc, char **argv) {
if (DoFormat)
FormatStyle = format::getStyle(FormatStyleOpt, FormatStyleConfig, "LLVM");
- TUReplacements TUs;
- TUReplacementFiles TURFiles;
+ TUReplacements TURs;
+ TUReplacementFiles TUFiles;
std::error_code ErrorCode =
- collectReplacementsFromDirectory(Directory, TUs, TURFiles, Diagnostics);
+ collectReplacementsFromDirectory(Directory, TURs, TUFiles, Diagnostics);
+
+ TUDiagnostics TUDs;
+ TUFiles.clear();
+ ErrorCode =
+ collectReplacementsFromDirectory(Directory, TUDs, TUFiles, Diagnostics);
if (ErrorCode) {
errs() << "Trouble iterating over directory '" << Directory
@@ -227,13 +232,15 @@ int main(int argc, char **argv) {
// command line option) when exiting main().
std::unique_ptr<ScopedFileRemover> Remover;
if (RemoveTUReplacementFiles)
- Remover.reset(new ScopedFileRemover(TURFiles, Diagnostics));
+ Remover.reset(new ScopedFileRemover(TUFiles, Diagnostics));
FileManager Files((FileSystemOptions()));
SourceManager SM(Diagnostics, Files);
FileToReplacementsMap GroupedReplacements;
- if (!mergeAndDeduplicate(TUs, GroupedReplacements, SM))
+ if (!mergeAndDeduplicate(TURs, GroupedReplacements, SM))
+ return 1;
+ if (!mergeAndDeduplicate(TUDs, GroupedReplacements, SM))
return 1;
Rewriter ReplacementsRewriter(SM, LangOptions());