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_FIX_IT_REWRITER_H
     16 #define LLVM_CLANG_REWRITE_FIX_IT_REWRITER_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() : 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   /// \brief Whether to abort fixing a file when not all errors could be fixed.
     45   bool FixWhatYouCan;
     46 
     47   /// \brief Whether to only fix warnings and not errors.
     48   bool FixOnlyWarnings;
     49 
     50   /// \brief If true, only pass the diagnostic to the actual diagnostic consumer
     51   /// if it is an error or a fixit was applied as part of the diagnostic.
     52   /// It basically silences warnings without accompanying fixits.
     53   bool Silent;
     54 };
     55 
     56 class FixItRewriter : public DiagnosticConsumer {
     57   /// \brief The diagnostics machinery.
     58   DiagnosticsEngine &Diags;
     59 
     60   edit::EditedSource Editor;
     61 
     62   /// \brief The rewriter used to perform the various code
     63   /// modifications.
     64   Rewriter Rewrite;
     65 
     66   /// \brief The diagnostic client that performs the actual formatting
     67   /// of error messages.
     68   DiagnosticConsumer *Client;
     69   bool OwnsClient;
     70 
     71   /// \brief Turn an input path into an output path. NULL implies overwriting
     72   /// the original.
     73   FixItOptions *FixItOpts;
     74 
     75   /// \brief The number of rewriter failures.
     76   unsigned NumFailures;
     77 
     78   /// \brief Whether the previous diagnostic was not passed to the consumer.
     79   bool PrevDiagSilenced;
     80 
     81 public:
     82   typedef Rewriter::buffer_iterator iterator;
     83 
     84   /// \brief Initialize a new fix-it rewriter.
     85   FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
     86                 const LangOptions &LangOpts, FixItOptions *FixItOpts);
     87 
     88   /// \brief Destroy the fix-it rewriter.
     89   ~FixItRewriter();
     90 
     91   /// \brief Check whether there are modifications for a given file.
     92   bool IsModified(FileID ID) const {
     93     return Rewrite.getRewriteBufferFor(ID) != nullptr;
     94   }
     95 
     96   // Iteration over files with changes.
     97   iterator buffer_begin() { return Rewrite.buffer_begin(); }
     98   iterator buffer_end() { return Rewrite.buffer_end(); }
     99 
    100   /// \brief Write a single modified source file.
    101   ///
    102   /// \returns true if there was an error, false otherwise.
    103   bool WriteFixedFile(FileID ID, raw_ostream &OS);
    104 
    105   /// \brief Write the modified source files.
    106   ///
    107   /// \returns true if there was an error, false otherwise.
    108   bool WriteFixedFiles(
    109      std::vector<std::pair<std::string, std::string> > *RewrittenFiles=nullptr);
    110 
    111   /// IncludeInDiagnosticCounts - This method (whose default implementation
    112   /// returns true) indicates whether the diagnostics handled by this
    113   /// DiagnosticConsumer should be included in the number of diagnostics
    114   /// reported by DiagnosticsEngine.
    115   bool IncludeInDiagnosticCounts() const override;
    116 
    117   /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
    118   /// capturing it to a log as needed.
    119   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
    120                         const Diagnostic &Info) override;
    121 
    122   /// \brief Emit a diagnostic via the adapted diagnostic client.
    123   void Diag(SourceLocation Loc, unsigned DiagID);
    124 };
    125 
    126 }
    127 
    128 #endif // LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
    129