1 //===- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This is a diagnostic client adaptor that performs rewrites as 11 // suggested by code modification hints attached to diagnostics. It 12 // then forwards any diagnostics to the adapted diagnostic client. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H 17 #define LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H 18 19 #include "clang/Basic/Diagnostic.h" 20 #include "clang/Basic/LLVM.h" 21 #include "clang/Basic/SourceLocation.h" 22 #include "clang/Edit/EditedSource.h" 23 #include "clang/Rewrite/Core/Rewriter.h" 24 #include <memory> 25 #include <string> 26 #include <utility> 27 #include <vector> 28 29 namespace clang { 30 31 class LangOptions; 32 class SourceManager; 33 34 class FixItOptions { 35 public: 36 FixItOptions() = default; 37 virtual ~FixItOptions(); 38 39 /// This file is about to be rewritten. Return the name of the file 40 /// that is okay to write to. 41 /// 42 /// \param fd out parameter for file descriptor. After the call it may be set 43 /// to an open file descriptor for the returned filename, or it will be -1 44 /// otherwise. 45 virtual std::string RewriteFilename(const std::string &Filename, int &fd) = 0; 46 47 /// True if files should be updated in place. RewriteFilename is only called 48 /// if this is false. 49 bool InPlace = false; 50 51 /// Whether to abort fixing a file when not all errors could be fixed. 52 bool FixWhatYouCan = false; 53 54 /// Whether to only fix warnings and not errors. 55 bool FixOnlyWarnings = false; 56 57 /// If true, only pass the diagnostic to the actual diagnostic consumer 58 /// if it is an error or a fixit was applied as part of the diagnostic. 59 /// It basically silences warnings without accompanying fixits. 60 bool Silent = false; 61 }; 62 63 class FixItRewriter : public DiagnosticConsumer { 64 /// The diagnostics machinery. 65 DiagnosticsEngine &Diags; 66 67 edit::EditedSource Editor; 68 69 /// The rewriter used to perform the various code 70 /// modifications. 71 Rewriter Rewrite; 72 73 /// The diagnostic client that performs the actual formatting 74 /// of error messages. 75 DiagnosticConsumer *Client; 76 std::unique_ptr<DiagnosticConsumer> Owner; 77 78 /// Turn an input path into an output path. NULL implies overwriting 79 /// the original. 80 FixItOptions *FixItOpts; 81 82 /// The number of rewriter failures. 83 unsigned NumFailures = 0; 84 85 /// Whether the previous diagnostic was not passed to the consumer. 86 bool PrevDiagSilenced = false; 87 88 public: 89 /// Initialize a new fix-it rewriter. 90 FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr, 91 const LangOptions &LangOpts, FixItOptions *FixItOpts); 92 93 /// Destroy the fix-it rewriter. 94 ~FixItRewriter() override; 95 96 /// Check whether there are modifications for a given file. IsModified(FileID ID)97 bool IsModified(FileID ID) const { 98 return Rewrite.getRewriteBufferFor(ID) != nullptr; 99 } 100 101 using iterator = Rewriter::buffer_iterator; 102 103 // Iteration over files with changes. buffer_begin()104 iterator buffer_begin() { return Rewrite.buffer_begin(); } buffer_end()105 iterator buffer_end() { return Rewrite.buffer_end(); } 106 107 /// Write a single modified source file. 108 /// 109 /// \returns true if there was an error, false otherwise. 110 bool WriteFixedFile(FileID ID, raw_ostream &OS); 111 112 /// Write the modified source files. 113 /// 114 /// \returns true if there was an error, false otherwise. 115 bool WriteFixedFiles( 116 std::vector<std::pair<std::string, std::string>> *RewrittenFiles = nullptr); 117 118 /// IncludeInDiagnosticCounts - This method (whose default implementation 119 /// returns true) indicates whether the diagnostics handled by this 120 /// DiagnosticConsumer should be included in the number of diagnostics 121 /// reported by DiagnosticsEngine. 122 bool IncludeInDiagnosticCounts() const override; 123 124 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 125 /// capturing it to a log as needed. 126 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 127 const Diagnostic &Info) override; 128 129 /// Emit a diagnostic via the adapted diagnostic client. 130 void Diag(SourceLocation Loc, unsigned DiagID); 131 }; 132 133 } // namespace clang 134 135 #endif // LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H 136