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