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" 2030660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "clang/Edit/EditedSource.h" 2130a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Rewrite/Core/Rewriter.h" 22558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 23558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregornamespace clang { 24558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 25558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregorclass SourceManager; 2626df2f09587ad6978ac8e357ca46b2731d591cc4Douglas Gregorclass FileEntry; 2726df2f09587ad6978ac8e357ca46b2731d591cc4Douglas Gregor 281450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewyckyclass FixItOptions { 29ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewyckypublic: 3061d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis FixItOptions() : FixWhatYouCan(false), 3161d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis FixOnlyWarnings(false), Silent(false) { } 3261d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis 331450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky virtual ~FixItOptions(); 34ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky 35ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky /// \brief This file is about to be rewritten. Return the name of the file 36ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky /// that is okay to write to. 37c8af9107fd1eb014d9124b753c38c4d06fa219f4Argyrios Kyrtzidis /// 38c8af9107fd1eb014d9124b753c38c4d06fa219f4Argyrios Kyrtzidis /// \param fd out parameter for file descriptor. After the call it may be set 39c8af9107fd1eb014d9124b753c38c4d06fa219f4Argyrios Kyrtzidis /// to an open file descriptor for the returned filename, or it will be -1 40c8af9107fd1eb014d9124b753c38c4d06fa219f4Argyrios Kyrtzidis /// otherwise. 41c8af9107fd1eb014d9124b753c38c4d06fa219f4Argyrios Kyrtzidis /// 42c8af9107fd1eb014d9124b753c38c4d06fa219f4Argyrios Kyrtzidis virtual std::string RewriteFilename(const std::string &Filename, int &fd) = 0; 431450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky 441450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky /// \brief Whether to abort fixing a file when not all errors could be fixed. 451450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky bool FixWhatYouCan; 4661d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis 4761d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// \brief Whether to only fix warnings and not errors. 4861d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool FixOnlyWarnings; 4961d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis 5061d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// \brief If true, only pass the diagnostic to the actual diagnostic consumer 5161d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// if it is an error or a fixit was applied as part of the diagnostic. 5261d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// It basically silences warnings without accompanying fixits. 5361d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool Silent; 5426df2f09587ad6978ac8e357ca46b2731d591cc4Douglas Gregor}; 55558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 5678ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikieclass FixItRewriter : public DiagnosticConsumer { 57de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor /// \brief The diagnostics machinery. 58d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diags; 59558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 6030660a898545416f0fea2d717f16f75640001e38Ted Kremenek edit::EditedSource Editor; 6130660a898545416f0fea2d717f16f75640001e38Ted Kremenek 62558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \brief The rewriter used to perform the various code 63558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// modifications. 64de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor Rewriter Rewrite; 65de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor 66de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor /// \brief The diagnostic client that performs the actual formatting 67de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor /// of error messages. 6878ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer *Client; 6961d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool OwnsClient; 70558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 71ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky /// \brief Turn an input path into an output path. NULL implies overwriting 72ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky /// the original. 731450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky FixItOptions *FixItOpts; 74ba5f6eced29937e4e4851a2c0980744768413d66Nick Lewycky 75558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \brief The number of rewriter failures. 76558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor unsigned NumFailures; 77558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 7861d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis /// \brief Whether the previous diagnostic was not passed to the consumer. 7961d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool PrevDiagSilenced; 8061d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis 81558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregorpublic: 82d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky typedef Rewriter::buffer_iterator iterator; 83d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky 84558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \brief Initialize a new fix-it rewriter. 85d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr, 861450f265fcc84a7ca64dd9f3b8d4492c5bd55e23Nick Lewycky const LangOptions &LangOpts, FixItOptions *FixItOpts); 87558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 88558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \brief Destroy the fix-it rewriter. 89558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor ~FixItRewriter(); 90558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 91d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// \brief Check whether there are modifications for a given file. 92d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky bool IsModified(FileID ID) const { 936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Rewrite.getRewriteBufferFor(ID) != nullptr; 94d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky } 95d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky 96d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky // Iteration over files with changes. 97d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky iterator buffer_begin() { return Rewrite.buffer_begin(); } 98d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky iterator buffer_end() { return Rewrite.buffer_end(); } 99d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky 100d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// \brief Write a single modified source file. 101d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// 102d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// \returns true if there was an error, false otherwise. 1038cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner bool WriteFixedFile(FileID ID, raw_ostream &OS); 104d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky 105d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// \brief Write the modified source files. 106558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// 107558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// \returns true if there was an error, false otherwise. 10861d679ab2831b161c857cf3f974312fbd4ef1efdArgyrios Kyrtzidis bool WriteFixedFiles( 1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::vector<std::pair<std::string, std::string> > *RewrittenFiles=nullptr); 110558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 111558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// IncludeInDiagnosticCounts - This method (whose default implementation 112d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky /// returns true) indicates whether the diagnostics handled by this 11378ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie /// DiagnosticConsumer should be included in the number of diagnostics 114d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie /// reported by DiagnosticsEngine. 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IncludeInDiagnosticCounts() const override; 116558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 117558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 118558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor /// capturing it to a log as needed. 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Diagnostic &Info) override; 121558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 122de4bf6a63219c5b9d3bce1fed3dfe075568098a0Douglas Gregor /// \brief Emit a diagnostic via the adapted diagnostic client. 12333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis void Diag(SourceLocation Loc, unsigned DiagID); 124558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor}; 125558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 126558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor} 127558cb56caf8906e0adbe643e3febbef0b7af1b9fDouglas Gregor 1289b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#endif // LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H 129