clang API Documentation

FixItRewriter.h
Go to the documentation of this file.
00001 //===--- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This is a diagnostic client adaptor that performs rewrites as
00011 // suggested by code modification hints attached to diagnostics. It
00012 // then forwards any diagnostics to the adapted diagnostic client.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 #ifndef LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H
00016 #define LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H
00017 
00018 #include "clang/Basic/Diagnostic.h"
00019 #include "clang/Basic/SourceLocation.h"
00020 #include "clang/Edit/EditedSource.h"
00021 #include "clang/Rewrite/Core/Rewriter.h"
00022 
00023 namespace clang {
00024 
00025 class SourceManager;
00026 class FileEntry;
00027 
00028 class FixItOptions {
00029 public:
00030   FixItOptions() : FixWhatYouCan(false),
00031                    FixOnlyWarnings(false), Silent(false) { }
00032 
00033   virtual ~FixItOptions();
00034 
00035   /// \brief This file is about to be rewritten. Return the name of the file
00036   /// that is okay to write to.
00037   ///
00038   /// \param fd out parameter for file descriptor. After the call it may be set
00039   /// to an open file descriptor for the returned filename, or it will be -1
00040   /// otherwise.
00041   ///
00042   virtual std::string RewriteFilename(const std::string &Filename, int &fd) = 0;
00043 
00044   /// \brief Whether to abort fixing a file when not all errors could be fixed.
00045   bool FixWhatYouCan;
00046 
00047   /// \brief Whether to only fix warnings and not errors.
00048   bool FixOnlyWarnings;
00049 
00050   /// \brief If true, only pass the diagnostic to the actual diagnostic consumer
00051   /// if it is an error or a fixit was applied as part of the diagnostic.
00052   /// It basically silences warnings without accompanying fixits.
00053   bool Silent;
00054 };
00055 
00056 class FixItRewriter : public DiagnosticConsumer {
00057   /// \brief The diagnostics machinery.
00058   DiagnosticsEngine &Diags;
00059 
00060   edit::EditedSource Editor;
00061 
00062   /// \brief The rewriter used to perform the various code
00063   /// modifications.
00064   Rewriter Rewrite;
00065 
00066   /// \brief The diagnostic client that performs the actual formatting
00067   /// of error messages.
00068   DiagnosticConsumer *Client;
00069   std::unique_ptr<DiagnosticConsumer> Owner;
00070 
00071   /// \brief Turn an input path into an output path. NULL implies overwriting
00072   /// the original.
00073   FixItOptions *FixItOpts;
00074 
00075   /// \brief The number of rewriter failures.
00076   unsigned NumFailures;
00077 
00078   /// \brief Whether the previous diagnostic was not passed to the consumer.
00079   bool PrevDiagSilenced;
00080 
00081 public:
00082   typedef Rewriter::buffer_iterator iterator;
00083 
00084   /// \brief Initialize a new fix-it rewriter.
00085   FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
00086                 const LangOptions &LangOpts, FixItOptions *FixItOpts);
00087 
00088   /// \brief Destroy the fix-it rewriter.
00089   ~FixItRewriter();
00090 
00091   /// \brief Check whether there are modifications for a given file.
00092   bool IsModified(FileID ID) const {
00093     return Rewrite.getRewriteBufferFor(ID) != nullptr;
00094   }
00095 
00096   // Iteration over files with changes.
00097   iterator buffer_begin() { return Rewrite.buffer_begin(); }
00098   iterator buffer_end() { return Rewrite.buffer_end(); }
00099 
00100   /// \brief Write a single modified source file.
00101   ///
00102   /// \returns true if there was an error, false otherwise.
00103   bool WriteFixedFile(FileID ID, raw_ostream &OS);
00104 
00105   /// \brief Write the modified source files.
00106   ///
00107   /// \returns true if there was an error, false otherwise.
00108   bool WriteFixedFiles(
00109      std::vector<std::pair<std::string, std::string> > *RewrittenFiles=nullptr);
00110 
00111   /// IncludeInDiagnosticCounts - This method (whose default implementation
00112   /// returns true) indicates whether the diagnostics handled by this
00113   /// DiagnosticConsumer should be included in the number of diagnostics
00114   /// reported by DiagnosticsEngine.
00115   bool IncludeInDiagnosticCounts() const override;
00116 
00117   /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
00118   /// capturing it to a log as needed.
00119   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
00120                         const Diagnostic &Info) override;
00121 
00122   /// \brief Emit a diagnostic via the adapted diagnostic client.
00123   void Diag(SourceLocation Loc, unsigned DiagID);
00124 };
00125 
00126 }
00127 
00128 #endif