1f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//===--- Refactoring.cpp - Framework for clang refactoring tools ----------===//
2f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//
3f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//                     The LLVM Compiler Infrastructure
4f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//
5f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// This file is distributed under the University of Illinois Open Source
6f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// License. See LICENSE.TXT for details.
7f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//
8f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//===----------------------------------------------------------------------===//
9f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//
10f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//  Implements tools to support refactorings.
11f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//
12f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//===----------------------------------------------------------------------===//
13f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
1402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor#include "clang/Basic/DiagnosticOptions.h"
15f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Basic/FileManager.h"
16f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Basic/SourceManager.h"
17f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Frontend/TextDiagnosticPrinter.h"
18f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Lex/Lexer.h"
19305c613af6cfc40e519c75d9d2c84c6fa9a841c0Ted Kremenek#include "clang/Rewrite/Core/Rewriter.h"
20f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Tooling/Refactoring.h"
21d11344a728c7ffab17e5557506edfbcbae18d34eAriel J. Bernal#include "llvm/Support/FileSystem.h"
22d11344a728c7ffab17e5557506edfbcbae18d34eAriel J. Bernal#include "llvm/Support/Path.h"
23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/raw_os_ostream.h"
24f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
25f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimeknamespace clang {
26f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimeknamespace tooling {
27f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
28f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekstatic const char * const InvalidLocation = "";
29f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
30f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekReplacement::Replacement()
318a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  : FilePath(InvalidLocation) {}
32f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
338a99945769aa83270bda4ae4890f519800aa19ebDaniel JasperReplacement::Replacement(StringRef FilePath, unsigned Offset, unsigned Length,
348a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper                         StringRef ReplacementText)
358a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper    : FilePath(FilePath), ReplacementRange(Offset, Length),
368a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper      ReplacementText(ReplacementText) {}
37f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
38651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesReplacement::Replacement(const SourceManager &Sources, SourceLocation Start,
39cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko                         unsigned Length, StringRef ReplacementText) {
40f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  setFromSourceLocation(Sources, Start, Length, ReplacementText);
41f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
42f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
43651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesReplacement::Replacement(const SourceManager &Sources,
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         const CharSourceRange &Range,
45cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko                         StringRef ReplacementText) {
46f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  setFromSourceRange(Sources, Range, ReplacementText);
47f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
48f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
49f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekbool Replacement::isApplicable() const {
50f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  return FilePath != InvalidLocation;
51f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
52f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
53f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimekbool Replacement::apply(Rewriter &Rewrite) const {
54f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  SourceManager &SM = Rewrite.getSourceMgr();
55f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  const FileEntry *Entry = SM.getFileManager().getFile(FilePath);
566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Entry)
57f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    return false;
58f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  FileID ID;
59f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  // FIXME: Use SM.translateFile directly.
60f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  SourceLocation Location = SM.translateFileLineCol(Entry, 1, 1);
61f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  ID = Location.isValid() ?
62f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    SM.getFileID(Location) :
63f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    SM.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
64f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  // FIXME: We cannot check whether Offset + Length is in the file, as
65f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  // the remapping API is not public in the RewriteBuffer.
66f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  const SourceLocation Start =
67f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    SM.getLocForStartOfFile(ID).
688a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper    getLocWithOffset(ReplacementRange.getOffset());
69f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  // ReplaceText returns false on success.
70f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  // ReplaceText only fails if the source location is not a file location, in
71f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  // which case we already returned false earlier.
728a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  bool RewriteSucceeded = !Rewrite.ReplaceText(
738a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper      Start, ReplacementRange.getLength(), ReplacementText);
74f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  assert(RewriteSucceeded);
75f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  return RewriteSucceeded;
76f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
77f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
785d51e8894624d5a12ed2c4fd80c31112d3d70f80Manuel Klimekstd::string Replacement::toString() const {
795d51e8894624d5a12ed2c4fd80c31112d3d70f80Manuel Klimek  std::string result;
805d51e8894624d5a12ed2c4fd80c31112d3d70f80Manuel Klimek  llvm::raw_string_ostream stream(result);
818a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  stream << FilePath << ": " << ReplacementRange.getOffset() << ":+"
828a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper         << ReplacementRange.getLength() << ":\"" << ReplacementText << "\"";
835d51e8894624d5a12ed2c4fd80c31112d3d70f80Manuel Klimek  return result;
845d51e8894624d5a12ed2c4fd80c31112d3d70f80Manuel Klimek}
855d51e8894624d5a12ed2c4fd80c31112d3d70f80Manuel Klimek
8605e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vanebool operator<(const Replacement &LHS, const Replacement &RHS) {
8705e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane  if (LHS.getOffset() != RHS.getOffset())
8805e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane    return LHS.getOffset() < RHS.getOffset();
8905e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane  if (LHS.getLength() != RHS.getLength())
9005e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane    return LHS.getLength() < RHS.getLength();
9105e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane  if (LHS.getFilePath() != RHS.getFilePath())
9205e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane    return LHS.getFilePath() < RHS.getFilePath();
9305e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane  return LHS.getReplacementText() < RHS.getReplacementText();
94f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
95f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
9605e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vanebool operator==(const Replacement &LHS, const Replacement &RHS) {
9705e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane  return LHS.getOffset() == RHS.getOffset() &&
9805e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane         LHS.getLength() == RHS.getLength() &&
9905e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane         LHS.getFilePath() == RHS.getFilePath() &&
10005e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane         LHS.getReplacementText() == RHS.getReplacementText();
101d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane}
102d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Replacement::setFromSourceLocation(const SourceManager &Sources,
104f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek                                        SourceLocation Start, unsigned Length,
105cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko                                        StringRef ReplacementText) {
106f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  const std::pair<FileID, unsigned> DecomposedLocation =
107f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek      Sources.getDecomposedLoc(Start);
108f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  const FileEntry *Entry = Sources.getFileEntryForID(DecomposedLocation.first);
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (Entry) {
110d11344a728c7ffab17e5557506edfbcbae18d34eAriel J. Bernal    // Make FilePath absolute so replacements can be applied correctly when
11119b60a524c53ada17a31b5c9a96c7885ca48c825Ariel J. Bernal    // relative paths for files are used.
11219b60a524c53ada17a31b5c9a96c7885ca48c825Ariel J. Bernal    llvm::SmallString<256> FilePath(Entry->getName());
113ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    std::error_code EC = llvm::sys::fs::make_absolute(FilePath);
11419b60a524c53ada17a31b5c9a96c7885ca48c825Ariel J. Bernal    this->FilePath = EC ? FilePath.c_str() : Entry->getName();
115b71aa7af7f4f9140c7bbcccca30aeecc671d767fAriel J. Bernal  } else {
116d11344a728c7ffab17e5557506edfbcbae18d34eAriel J. Bernal    this->FilePath = InvalidLocation;
117b71aa7af7f4f9140c7bbcccca30aeecc671d767fAriel J. Bernal  }
1188a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  this->ReplacementRange = Range(DecomposedLocation.second, Length);
119f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  this->ReplacementText = ReplacementText;
120f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
121f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
122f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// FIXME: This should go into the Lexer, but we need to figure out how
123f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// to handle ranges for refactoring in general first - there is no obvious
124f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// good way how to integrate this into the Lexer yet.
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic int getRangeSize(const SourceManager &Sources,
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        const CharSourceRange &Range) {
127f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  SourceLocation SpellingBegin = Sources.getSpellingLoc(Range.getBegin());
128f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  SourceLocation SpellingEnd = Sources.getSpellingLoc(Range.getEnd());
129f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  std::pair<FileID, unsigned> Start = Sources.getDecomposedLoc(SpellingBegin);
130f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  std::pair<FileID, unsigned> End = Sources.getDecomposedLoc(SpellingEnd);
131f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  if (Start.first != End.first) return -1;
132f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  if (Range.isTokenRange())
133f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    End.second += Lexer::MeasureTokenLength(SpellingEnd, Sources,
134f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek                                            LangOptions());
135f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  return End.second - Start.second;
136f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
137f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Replacement::setFromSourceRange(const SourceManager &Sources,
139f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek                                     const CharSourceRange &Range,
140cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko                                     StringRef ReplacementText) {
141f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  setFromSourceLocation(Sources, Sources.getSpellingLoc(Range.getBegin()),
142f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek                        getRangeSize(Sources, Range), ReplacementText);
143f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
144f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
14576a2ea3d8a0c3f3a54f293e305ae16f654eab04fDavid Blaikiebool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite) {
146f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  bool Result = true;
147f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  for (Replacements::const_iterator I = Replaces.begin(),
148f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek                                    E = Replaces.end();
149f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek       I != E; ++I) {
150f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    if (I->isApplicable()) {
151f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek      Result = I->apply(Rewrite) && Result;
152f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    } else {
153f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek      Result = false;
154f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    }
155f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  }
156f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  return Result;
157f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
158f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
159b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane// FIXME: Remove this function when Replacements is implemented as std::vector
160b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane// instead of std::set.
161b58cfd93c49727c1d471ce71901502df824556c7Edwin Vanebool applyAllReplacements(const std::vector<Replacement> &Replaces,
162b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane                          Rewriter &Rewrite) {
163b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane  bool Result = true;
164b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane  for (std::vector<Replacement>::const_iterator I = Replaces.begin(),
165b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane                                                E = Replaces.end();
166b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane       I != E; ++I) {
167b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane    if (I->isApplicable()) {
168b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane      Result = I->apply(Rewrite) && Result;
169b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane    } else {
170b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane      Result = false;
171b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane    }
172b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane  }
173b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane  return Result;
174b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane}
175b58cfd93c49727c1d471ce71901502df824556c7Edwin Vane
17676a2ea3d8a0c3f3a54f293e305ae16f654eab04fDavid Blaikiestd::string applyAllReplacements(StringRef Code, const Replacements &Replaces) {
1778a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  FileManager Files((FileSystemOptions()));
1788a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  DiagnosticsEngine Diagnostics(
1798a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
1808a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper      new DiagnosticOptions);
1818a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  Diagnostics.setClient(new TextDiagnosticPrinter(
1828a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper      llvm::outs(), &Diagnostics.getDiagnosticOptions()));
1838a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  SourceManager SourceMgr(Diagnostics, Files);
1848a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  Rewriter Rewrite(SourceMgr, LangOptions());
1858a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(Code, "<stdin>");
1868a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  const clang::FileEntry *Entry =
1878a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper      Files.getVirtualFile("<stdin>", Buf->getBufferSize(), 0);
1888a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  SourceMgr.overrideFileContents(Entry, Buf);
1898a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  FileID ID =
1908a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper      SourceMgr.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User);
19176a2ea3d8a0c3f3a54f293e305ae16f654eab04fDavid Blaikie  for (Replacements::const_iterator I = Replaces.begin(), E = Replaces.end();
19276a2ea3d8a0c3f3a54f293e305ae16f654eab04fDavid Blaikie       I != E; ++I) {
1938a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper    Replacement Replace("<stdin>", I->getOffset(), I->getLength(),
1948a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper                        I->getReplacementText());
1958a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper    if (!Replace.apply(Rewrite))
1968a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper      return "";
1978a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  }
1988a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  std::string Result;
1998a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  llvm::raw_string_ostream OS(Result);
2008a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  Rewrite.getEditBuffer(ID).write(OS);
2018a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  OS.flush();
2028a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper  return Result;
2038a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper}
2048a99945769aa83270bda4ae4890f519800aa19ebDaniel Jasper
2056bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasperunsigned shiftedCodePosition(const Replacements &Replaces, unsigned Position) {
2066bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper  unsigned NewPosition = Position;
2076bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper  for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); I != E;
2086bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper       ++I) {
2096bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper    if (I->getOffset() >= Position)
2106bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper      break;
2116bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper    if (I->getOffset() + I->getLength() > Position)
2126bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper      NewPosition += I->getOffset() + I->getLength() - Position;
2136bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper    NewPosition += I->getReplacementText().size() - I->getLength();
2146bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper  }
2156bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper  return NewPosition;
2166bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper}
2176bd3b93200c6ae141d0f7444ffb4cacd52b183edDaniel Jasper
218a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane// FIXME: Remove this function when Replacements is implemented as std::vector
219a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane// instead of std::set.
220a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vaneunsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
221a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane                             unsigned Position) {
222a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane  unsigned NewPosition = Position;
223a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane  for (std::vector<Replacement>::const_iterator I = Replaces.begin(),
224a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane                                                E = Replaces.end();
225a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane       I != E; ++I) {
226a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane    if (I->getOffset() >= Position)
227a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane      break;
228a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane    if (I->getOffset() + I->getLength() > Position)
229a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane      NewPosition += I->getOffset() + I->getLength() - Position;
230a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane    NewPosition += I->getReplacementText().size() - I->getLength();
231a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane  }
232a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane  return NewPosition;
233a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane}
234a778cde0ddf4c47a63786fb1067f25c1fbfcf19dEdwin Vane
235d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vanevoid deduplicate(std::vector<Replacement> &Replaces,
236d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane                 std::vector<Range> &Conflicts) {
237d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  if (Replaces.empty())
238d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane    return;
239d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane
240d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  // Deduplicate
24105e4af0b92f8b1febeb5abafd1f128cb5c3e00a4Edwin Vane  std::sort(Replaces.begin(), Replaces.end());
242d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  std::vector<Replacement>::iterator End =
243d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane      std::unique(Replaces.begin(), Replaces.end());
244d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  Replaces.erase(End, Replaces.end());
245d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane
246d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  // Detect conflicts
247d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  Range ConflictRange(Replaces.front().getOffset(),
248d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane                      Replaces.front().getLength());
249d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  unsigned ConflictStart = 0;
250d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  unsigned ConflictLength = 1;
251d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  for (unsigned i = 1; i < Replaces.size(); ++i) {
252d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane    Range Current(Replaces[i].getOffset(), Replaces[i].getLength());
253d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane    if (ConflictRange.overlapsWith(Current)) {
254d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane      // Extend conflicted range
255d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane      ConflictRange = Range(ConflictRange.getOffset(),
25695f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane                            std::max(ConflictRange.getLength(),
25795f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane                                     Current.getOffset() + Current.getLength() -
25895f0766c1942c8cdc9f913a083ad2bfc4c0c27c9Edwin Vane                                         ConflictRange.getOffset()));
259d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane      ++ConflictLength;
260d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane    } else {
261d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane      if (ConflictLength > 1)
262d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane        Conflicts.push_back(Range(ConflictStart, ConflictLength));
263d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane      ConflictRange = Current;
264d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane      ConflictStart = i;
265d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane      ConflictLength = 1;
266d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane    }
267d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  }
268d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane
269d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane  if (ConflictLength > 1)
270d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane    Conflicts.push_back(Range(ConflictStart, ConflictLength));
271d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane}
272d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane
273d5692dbfeb97ed2e7ff11bca26059fa735e1b308Edwin Vane
274f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekRefactoringTool::RefactoringTool(const CompilationDatabase &Compilations,
275f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek                                 ArrayRef<std::string> SourcePaths)
276d088a5f966c31462280d5ace29febc6889834611Edwin Vane  : ClangTool(Compilations, SourcePaths) {}
277f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
278f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekReplacements &RefactoringTool::getReplacements() { return Replace; }
279f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
280d088a5f966c31462280d5ace29febc6889834611Edwin Vaneint RefactoringTool::runAndSave(FrontendActionFactory *ActionFactory) {
281d088a5f966c31462280d5ace29febc6889834611Edwin Vane  if (int Result = run(ActionFactory)) {
282d088a5f966c31462280d5ace29febc6889834611Edwin Vane    return Result;
283d088a5f966c31462280d5ace29febc6889834611Edwin Vane  }
284d088a5f966c31462280d5ace29febc6889834611Edwin Vane
285f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  LangOptions DefaultLangOptions;
28602c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
28702c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor  TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts);
288f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  DiagnosticsEngine Diagnostics(
289cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
29002c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor      &*DiagOpts, &DiagnosticPrinter, false);
291d088a5f966c31462280d5ace29febc6889834611Edwin Vane  SourceManager Sources(Diagnostics, getFiles());
292f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  Rewriter Rewrite(Sources, DefaultLangOptions);
293d088a5f966c31462280d5ace29febc6889834611Edwin Vane
294d088a5f966c31462280d5ace29febc6889834611Edwin Vane  if (!applyAllReplacements(Rewrite)) {
295f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek    llvm::errs() << "Skipped some replacements.\n";
296f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek  }
297d088a5f966c31462280d5ace29febc6889834611Edwin Vane
298d088a5f966c31462280d5ace29febc6889834611Edwin Vane  return saveRewrittenFiles(Rewrite);
299d088a5f966c31462280d5ace29febc6889834611Edwin Vane}
300d088a5f966c31462280d5ace29febc6889834611Edwin Vane
301d088a5f966c31462280d5ace29febc6889834611Edwin Vanebool RefactoringTool::applyAllReplacements(Rewriter &Rewrite) {
302d088a5f966c31462280d5ace29febc6889834611Edwin Vane  return tooling::applyAllReplacements(Replace, Rewrite);
303d088a5f966c31462280d5ace29febc6889834611Edwin Vane}
304d088a5f966c31462280d5ace29febc6889834611Edwin Vane
305d088a5f966c31462280d5ace29febc6889834611Edwin Vaneint RefactoringTool::saveRewrittenFiles(Rewriter &Rewrite) {
3066bf97fb15c09db9a0238ccb73be2dbf9cd77a7eeAlp Toker  return Rewrite.overwriteChangedFiles() ? 1 : 0;
307f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek}
308f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek
309f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} // end namespace tooling
310f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} // end namespace clang
311