From f5ca27cc3785b3a2bf9dd3c005f3aa6a2d14fb93 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Mon, 16 Oct 2017 18:28:26 +0000 Subject: [refactor] allow the use of refactoring diagnostics This commit allows the refactoring library to use its own set of refactoring-specific diagnostics to reports things like initiation errors. Differential Revision: https://reviews.llvm.org/D38772 llvm-svn: 315924 --- clang/tools/clang-refactor/ClangRefactor.cpp | 35 +++++++++++++++++++++------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'clang/tools/clang-refactor/ClangRefactor.cpp') diff --git a/clang/tools/clang-refactor/ClangRefactor.cpp b/clang/tools/clang-refactor/ClangRefactor.cpp index 8a5c8e6630d..ed9bf5ed28d 100644 --- a/clang/tools/clang-refactor/ClangRefactor.cpp +++ b/clang/tools/clang-refactor/ClangRefactor.cpp @@ -15,6 +15,7 @@ #include "TestSupport.h" #include "clang/Frontend/CommandLineSourceLoc.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Rewrite/Core/Rewriter.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Refactoring.h" @@ -65,7 +66,8 @@ public: /// logic into the refactoring operation. The test-specific consumer /// ensures that the individual results in a particular test group are /// identical. - virtual std::unique_ptr createCustomConsumer() { + virtual std::unique_ptr + createCustomConsumer() { return nullptr; } @@ -85,7 +87,8 @@ public: void print(raw_ostream &OS) override { TestSelections.dump(OS); } - std::unique_ptr createCustomConsumer() override { + std::unique_ptr + createCustomConsumer() override { return TestSelections.createConsumer(); } @@ -304,10 +307,20 @@ private: RefactoringActionCommandLineOptions Options; }; -class ClangRefactorConsumer : public RefactoringResultConsumer { +class ClangRefactorConsumer final : public ClangRefactorToolConsumerInterface { public: + ClangRefactorConsumer() {} + void handleError(llvm::Error Err) override { - llvm::errs() << llvm::toString(std::move(Err)) << "\n"; + Optional Diag = DiagnosticError::take(Err); + if (!Diag) { + llvm::errs() << llvm::toString(std::move(Err)) << "\n"; + return; + } + llvm::cantFail(std::move(Err)); // This is a success. + DiagnosticBuilder DB( + getDiags().Report(Diag->first, Diag->second.getDiagID())); + Diag->second.Emit(DB); } void handle(AtomicChanges Changes) override { @@ -468,8 +481,8 @@ public: return true; } - bool HasFailed = false; ClangRefactorConsumer Consumer; + bool HasFailed = false; if (foreachTranslationUnit(DB, Sources, [&](ASTContext &AST) { RefactoringRuleContext Context(AST.getSourceManager()); Context.setASTContext(AST); @@ -488,21 +501,27 @@ public: "The action must have at least one selection rule"); }; + std::unique_ptr CustomConsumer; + if (HasSelection) + CustomConsumer = Subcommand.getSelection()->createCustomConsumer(); + ClangRefactorToolConsumerInterface &ActiveConsumer = + CustomConsumer ? *CustomConsumer : Consumer; + ActiveConsumer.beginTU(AST); if (HasSelection) { assert(Subcommand.getSelection() && "Missing selection argument?"); if (opts::Verbose) Subcommand.getSelection()->print(llvm::outs()); - auto CustomConsumer = - Subcommand.getSelection()->createCustomConsumer(); if (Subcommand.getSelection()->forAllRanges( Context.getSources(), [&](SourceRange R) { Context.setSelectionRange(R); - InvokeRule(CustomConsumer ? *CustomConsumer : Consumer); + InvokeRule(ActiveConsumer); })) HasFailed = true; + ActiveConsumer.endTU(); return; } // FIXME (Alex L): Implement non-selection based invocation path. + ActiveConsumer.endTU(); })) return true; return HasFailed || applySourceChanges(Consumer.getSourceChanges()); -- cgit v1.2.3