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