1243791Sdim//===--- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ----*- C++ -*-===//
2243791Sdim//
3243791Sdim//                     The LLVM Compiler Infrastructure
4243791Sdim//
5243791Sdim// This file is distributed under the University of Illinois Open Source
6243791Sdim// License. See LICENSE.TXT for details.
7243791Sdim//
8243791Sdim//===----------------------------------------------------------------------===//
9243791Sdim//
10243791Sdim// This is a diagnostic client adaptor that performs rewrites as
11243791Sdim// suggested by code modification hints attached to diagnostics. It
12243791Sdim// then forwards any diagnostics to the adapted diagnostic client.
13243791Sdim//
14243791Sdim//===----------------------------------------------------------------------===//
15243791Sdim#ifndef LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
16243791Sdim#define LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
17243791Sdim
18243791Sdim#include "clang/Basic/Diagnostic.h"
19243791Sdim#include "clang/Basic/SourceLocation.h"
20249423Sdim#include "clang/Edit/EditedSource.h"
21243791Sdim#include "clang/Rewrite/Core/Rewriter.h"
22243791Sdim
23243791Sdimnamespace clang {
24243791Sdim
25243791Sdimclass SourceManager;
26243791Sdimclass FileEntry;
27243791Sdim
28243791Sdimclass FixItOptions {
29243791Sdimpublic:
30243791Sdim  FixItOptions() : FixWhatYouCan(false),
31243791Sdim                   FixOnlyWarnings(false), Silent(false) { }
32243791Sdim
33243791Sdim  virtual ~FixItOptions();
34243791Sdim
35243791Sdim  /// \brief This file is about to be rewritten. Return the name of the file
36243791Sdim  /// that is okay to write to.
37243791Sdim  ///
38243791Sdim  /// \param fd out parameter for file descriptor. After the call it may be set
39243791Sdim  /// to an open file descriptor for the returned filename, or it will be -1
40243791Sdim  /// otherwise.
41243791Sdim  ///
42243791Sdim  virtual std::string RewriteFilename(const std::string &Filename, int &fd) = 0;
43243791Sdim
44243791Sdim  /// \brief Whether to abort fixing a file when not all errors could be fixed.
45243791Sdim  bool FixWhatYouCan;
46243791Sdim
47243791Sdim  /// \brief Whether to only fix warnings and not errors.
48243791Sdim  bool FixOnlyWarnings;
49243791Sdim
50243791Sdim  /// \brief If true, only pass the diagnostic to the actual diagnostic consumer
51243791Sdim  /// if it is an error or a fixit was applied as part of the diagnostic.
52243791Sdim  /// It basically silences warnings without accompanying fixits.
53243791Sdim  bool Silent;
54243791Sdim};
55243791Sdim
56243791Sdimclass FixItRewriter : public DiagnosticConsumer {
57243791Sdim  /// \brief The diagnostics machinery.
58243791Sdim  DiagnosticsEngine &Diags;
59243791Sdim
60243791Sdim  edit::EditedSource Editor;
61243791Sdim
62243791Sdim  /// \brief The rewriter used to perform the various code
63243791Sdim  /// modifications.
64243791Sdim  Rewriter Rewrite;
65243791Sdim
66243791Sdim  /// \brief The diagnostic client that performs the actual formatting
67243791Sdim  /// of error messages.
68243791Sdim  DiagnosticConsumer *Client;
69243791Sdim  bool OwnsClient;
70243791Sdim
71243791Sdim  /// \brief Turn an input path into an output path. NULL implies overwriting
72243791Sdim  /// the original.
73243791Sdim  FixItOptions *FixItOpts;
74243791Sdim
75243791Sdim  /// \brief The number of rewriter failures.
76243791Sdim  unsigned NumFailures;
77243791Sdim
78243791Sdim  /// \brief Whether the previous diagnostic was not passed to the consumer.
79243791Sdim  bool PrevDiagSilenced;
80243791Sdim
81243791Sdimpublic:
82243791Sdim  typedef Rewriter::buffer_iterator iterator;
83243791Sdim
84243791Sdim  /// \brief Initialize a new fix-it rewriter.
85243791Sdim  FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
86243791Sdim                const LangOptions &LangOpts, FixItOptions *FixItOpts);
87243791Sdim
88243791Sdim  /// \brief Destroy the fix-it rewriter.
89243791Sdim  ~FixItRewriter();
90243791Sdim
91243791Sdim  /// \brief Check whether there are modifications for a given file.
92243791Sdim  bool IsModified(FileID ID) const {
93243791Sdim    return Rewrite.getRewriteBufferFor(ID) != NULL;
94243791Sdim  }
95243791Sdim
96243791Sdim  // Iteration over files with changes.
97243791Sdim  iterator buffer_begin() { return Rewrite.buffer_begin(); }
98243791Sdim  iterator buffer_end() { return Rewrite.buffer_end(); }
99243791Sdim
100243791Sdim  /// \brief Write a single modified source file.
101243791Sdim  ///
102243791Sdim  /// \returns true if there was an error, false otherwise.
103243791Sdim  bool WriteFixedFile(FileID ID, raw_ostream &OS);
104243791Sdim
105243791Sdim  /// \brief Write the modified source files.
106243791Sdim  ///
107243791Sdim  /// \returns true if there was an error, false otherwise.
108243791Sdim  bool WriteFixedFiles(
109243791Sdim         std::vector<std::pair<std::string, std::string> > *RewrittenFiles = 0);
110243791Sdim
111243791Sdim  /// IncludeInDiagnosticCounts - This method (whose default implementation
112243791Sdim  /// returns true) indicates whether the diagnostics handled by this
113243791Sdim  /// DiagnosticConsumer should be included in the number of diagnostics
114243791Sdim  /// reported by DiagnosticsEngine.
115243791Sdim  virtual bool IncludeInDiagnosticCounts() const;
116243791Sdim
117243791Sdim  /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
118243791Sdim  /// capturing it to a log as needed.
119243791Sdim  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
120243791Sdim                                const Diagnostic &Info);
121243791Sdim
122243791Sdim  /// \brief Emit a diagnostic via the adapted diagnostic client.
123243791Sdim  void Diag(SourceLocation Loc, unsigned DiagID);
124243791Sdim};
125243791Sdim
126243791Sdim}
127243791Sdim
128243791Sdim#endif // LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
129