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