FixItRewriter.h revision 61d679ab2831b161c857cf3f974312fbd4ef1efd
1558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor//===--- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ----*- C++ -*-===// 2558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// 3558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// The LLVM Compiler Infrastructure 4558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// 5558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// This file is distributed under the University of Illinois Open Source 6558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// License. See LICENSE.TXT for details. 7558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// 8558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor//===----------------------------------------------------------------------===// 9558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// 10558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// This is a diagnostic client adaptor that performs rewrites as 11558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// suggested by code modification hints attached to diagnostics. It 12558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// then forwards any diagnostics to the adapted diagnostic client. 13558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor// 14558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor//===----------------------------------------------------------------------===// 159b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#ifndef LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H 169b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#define LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H 17558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 18558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor#include "clang/Basic/Diagnostic.h" 19d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky#include "clang/Basic/SourceLocation.h" 20de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor#include "clang/Rewrite/Rewriter.h" 21558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 22558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregornamespace clang { 23558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 24558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregorclass SourceManager; 2526df2f09587ad6978ac8e357ca46b2731d591cc4Douglas Gregorclass FileEntry; 2626df2f09587ad6978ac8e357ca46b2731d591cc4Douglas Gregor 271450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewyckyclass FixItOptions { 28ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewyckypublic: 2961d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis FixItOptions() : FixWhatYouCan(false), 3061d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis FixOnlyWarnings(false), Silent(false) { } 3161d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis 321450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky virtual ~FixItOptions(); 33ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky 34ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky /// \brief This file is about to be rewritten. Return the name of the file 35ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky /// that is okay to write to. 36ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky virtual std::string RewriteFilename(const std::string &Filename) = 0; 371450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky 381450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky /// \brief Whether to abort fixing a file when not all errors could be fixed. 391450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky bool FixWhatYouCan; 4061d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis 4161d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// \brief Whether to only fix warnings and not errors. 4261d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool FixOnlyWarnings; 4361d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis 4461d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// \brief If true, only pass the diagnostic to the actual diagnostic consumer 4561d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// if it is an error or a fixit was applied as part of the diagnostic. 4661d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// It basically silences warnings without accompanying fixits. 4761d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool Silent; 4826df2f09587ad6978ac8e357ca46b2731d591cc4Douglas Gregor}; 49558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 5078ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikieclass FixItRewriter : public DiagnosticConsumer { 51de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor /// \brief The diagnostics machinery. 52d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diags; 53558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 54558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \brief The rewriter used to perform the various code 55558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// modifications. 56de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor Rewriter Rewrite; 57de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor 58de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor /// \brief The diagnostic client that performs the actual formatting 59de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor /// of error messages. 6078ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer *Client; 6161d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool OwnsClient; 62558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 63ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky /// \brief Turn an input path into an output path. NULL implies overwriting 64ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky /// the original. 651450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky FixItOptions *FixItOpts; 66ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky 67558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \brief The number of rewriter failures. 68558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor unsigned NumFailures; 69558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 7061d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// \brief Whether the previous diagnostic was not passed to the consumer. 7161d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool PrevDiagSilenced; 7261d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis 73558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregorpublic: 74d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky typedef Rewriter::buffer_iterator iterator; 75d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky 76558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \brief Initialize a new fix-it rewriter. 77d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr, 781450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky const LangOptions &LangOpts, FixItOptions *FixItOpts); 79558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 80558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \brief Destroy the fix-it rewriter. 81558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor ~FixItRewriter(); 82558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 83d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// \brief Check whether there are modifications for a given file. 84d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky bool IsModified(FileID ID) const { 85d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky return Rewrite.getRewriteBufferFor(ID) != NULL; 86d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky } 87d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky 88d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky // Iteration over files with changes. 89d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky iterator buffer_begin() { return Rewrite.buffer_begin(); } 90d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky iterator buffer_end() { return Rewrite.buffer_end(); } 91d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky 92d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// \brief Write a single modified source file. 93d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// 94d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// \returns true if there was an error, false otherwise. 958cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner bool WriteFixedFile(FileID ID, raw_ostream &OS); 96d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky 97d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// \brief Write the modified source files. 98558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// 99558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \returns true if there was an error, false otherwise. 10061d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool WriteFixedFiles( 10161d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis std::vector<std::pair<std::string, std::string> > *RewrittenFiles = 0); 102558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 103558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// IncludeInDiagnosticCounts - This method (whose default implementation 104d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// returns true) indicates whether the diagnostics handled by this 10578ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie /// DiagnosticConsumer should be included in the number of diagnostics 106d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie /// reported by DiagnosticsEngine. 107558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor virtual bool IncludeInDiagnosticCounts() const; 108558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 109558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 110558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// capturing it to a log as needed. 111d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 11240847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie const Diagnostic &Info); 113558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 114de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor /// \brief Emit a diagnostic via the adapted diagnostic client. 11533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis void Diag(SourceLocation Loc, unsigned DiagID); 116aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor 117aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; 118558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor}; 119558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 120558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor} 121558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 1229b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#endif // LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H 123