ioeric updated this revision to Diff 79728.
ioeric added a comment.

- Make key customize-able.


https://reviews.llvm.org/D27054

Files:
  include/clang/Tooling/Refactoring/EditList.h
  lib/Tooling/CMakeLists.txt
  lib/Tooling/Refactoring/CMakeLists.txt
  lib/Tooling/Refactoring/EditList.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/RefactoringTest.cpp

Index: unittests/Tooling/RefactoringTest.cpp
===================================================================
--- unittests/Tooling/RefactoringTest.cpp
+++ unittests/Tooling/RefactoringTest.cpp
@@ -26,6 +26,7 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Refactoring/EditList.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/SmallString.h"
 #include "gtest/gtest.h"
@@ -102,10 +103,10 @@
 
 // Checks that an llvm::Error instance contains a ReplacementError with expected
 // error code, expected new replacement, and expected existing replacement.
-static bool checkReplacementError(
-    llvm::Error&& Error, replacement_error ExpectedErr,
-    llvm::Optional<Replacement> ExpectedExisting,
-    llvm::Optional<Replacement> ExpectedNew) {
+static bool checkReplacementError(llvm::Error &&Error,
+                                  replacement_error ExpectedErr,
+                                  llvm::Optional<Replacement> ExpectedExisting,
+                                  llvm::Optional<Replacement> ExpectedNew) {
   if (!Error) {
     llvm::errs() << "Error is a success.";
     return false;
@@ -1089,5 +1090,183 @@
   EXPECT_TRUE(FileToReplaces.empty());
 }
 
+class EditListTest : public ::testing::Test {
+  protected:
+    void setUp() {
+      DefaultFileID = Context.createInMemoryFile("input.cpp", DefaultCode);
+      DefaultLoc = Context.Sources.getLocForStartOfFile(DefaultFileID)
+                       .getLocWithOffset(20);
+      assert(DefaultLoc.isValid() && "Default location must be valid.");
+    }
+
+    RewriterTestContext Context;
+    std::string DefaultCode = std::string(100, 'a');
+    unsigned DefaultOffset = 20;
+    SourceLocation DefaultLoc;
+    FileID DefaultFileID;
+};
+
+TEST_F(EditListTest, EditListToYAML) {
+  setUp();
+  EditList Edit(Context.Sources, DefaultLoc);
+  llvm::Error Err = Edit.insertBefore(Context.Sources, DefaultLoc, "aa");
+  ASSERT_TRUE(!Err);
+  Err =
+      Edit.insertBefore(Context.Sources, DefaultLoc.getLocWithOffset(10), "bb");
+  ASSERT_TRUE(!Err);
+  Edit.addHeader("a.h");
+  Edit.removeHeader("b.h");
+  std::string YAMLString = Edit.toYAMLString();
+
+  // NOTE: If this test starts to fail for no obvious reason, check whitespace.
+  ASSERT_STREQ("---\n"
+               "Key:             'input.cpp:20'\n"
+               "FilePath:        input.cpp\n"
+               "Error:           ''\n"
+               "InsertedHeaders: [ a.h ]\n"
+               "RemovedHeaders:  [ b.h ]\n"
+               "Replacements:    \n" // Extra whitespace here!
+               "  - FilePath:        input.cpp\n"
+               "    Offset:          20\n"
+               "    Length:          0\n"
+               "    ReplacementText: aa\n"
+               "  - FilePath:        input.cpp\n"
+               "    Offset:          30\n"
+               "    Length:          0\n"
+               "    ReplacementText: bb\n"
+               "...\n",
+               YAMLString.c_str());
+}
+
+TEST_F(EditListTest, YAMLToEditList) {
+  setUp();
+  std::string YamlContent = "---\n"
+                            "Key:             'input.cpp:20'\n"
+                            "FilePath:        input.cpp\n"
+                            "Error:           'ok'\n"
+                            "InsertedHeaders: [ a.h ]\n"
+                            "RemovedHeaders:  [ b.h ]\n"
+                            "Replacements:    \n" // Extra whitespace here!
+                            "  - FilePath:        input.cpp\n"
+                            "    Offset:          20\n"
+                            "    Length:          0\n"
+                            "    ReplacementText: aa\n"
+                            "  - FilePath:        input.cpp\n"
+                            "    Offset:          30\n"
+                            "    Length:          0\n"
+                            "    ReplacementText: bb\n"
+                            "...\n";
+  EditList ExpectedEdit(Context.Sources, DefaultLoc);
+  llvm::Error Err =
+      ExpectedEdit.insertBefore(Context.Sources, DefaultLoc, "aa");
+  ASSERT_TRUE(!Err);
+  Err = ExpectedEdit.insertBefore(Context.Sources,
+                                  DefaultLoc.getLocWithOffset(10), "bb");
+  ASSERT_TRUE(!Err);
+
+  ExpectedEdit.addHeader("a.h");
+  ExpectedEdit.removeHeader("b.h");
+  ExpectedEdit.setError("ok");
+
+  EditList ActualEdit = EditList::convertFromYAML(YamlContent);
+  EXPECT_EQ(ExpectedEdit.getKey(), ActualEdit.getKey());
+  EXPECT_EQ(ExpectedEdit.getFilePath(), ActualEdit.getFilePath());
+  EXPECT_EQ(ExpectedEdit.getError(), ActualEdit.getError());
+  EXPECT_EQ(ExpectedEdit.getInsertedHeaders(), ActualEdit.getInsertedHeaders());
+  EXPECT_EQ(ExpectedEdit.getRemovedHeaders(), ActualEdit.getRemovedHeaders());
+  EXPECT_EQ(ExpectedEdit.getReplacements().size(),
+            ActualEdit.getReplacements().size());
+  EXPECT_EQ(2u, ActualEdit.getReplacements().size());
+  EXPECT_EQ(*ExpectedEdit.getReplacements().begin(),
+            *ActualEdit.getReplacements().begin());
+  EXPECT_EQ(*(++ExpectedEdit.getReplacements().begin()),
+            *(++ActualEdit.getReplacements().begin()));
+}
+
+TEST_F(EditListTest, CheckKeyAndKeyFile) {
+  setUp();
+  EditList Edit(Context.Sources, DefaultLoc);
+  EXPECT_EQ("input.cpp:20", Edit.getKey());
+  EXPECT_EQ("input.cpp", Edit.getFilePath());
+}
+
+TEST_F(EditListTest, InsertBefore) {
+  setUp();
+  EditList Edit(Context.Sources, DefaultLoc);
+  llvm::Error Err = Edit.insertBefore(Context.Sources, DefaultLoc, "aa");
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Edit.getReplacements().size(), 1u);
+  EXPECT_EQ(*Edit.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 0, "aa"));
+  Err = Edit.insertBefore(Context.Sources, DefaultLoc, "b");
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Edit.getReplacements().size(), 1u);
+  EXPECT_EQ(*Edit.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 0, "baa"));
+}
+
+TEST_F(EditListTest, InsertAfter) {
+  setUp();
+  EditList Edit(Context.Sources, DefaultLoc);
+  llvm::Error Err = Edit.insertAfter(Context.Sources, DefaultLoc, "aa");
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Edit.getReplacements().size(), 1u);
+  EXPECT_EQ(*Edit.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 0, "aa"));
+  Err = Edit.insertAfter(Context.Sources, DefaultLoc, "b");
+  ASSERT_TRUE(!Err);
+  EXPECT_EQ(Edit.getReplacements().size(), 1u);
+  EXPECT_EQ(*Edit.getReplacements().begin(),
+            Replacement(Context.Sources, DefaultLoc, 0, "aab"));
+}
+
+TEST_F(EditListTest, InsertBeforeWithInvalidLocation) {
+  setUp();
+  EditList Edit(Context.Sources, DefaultLoc);
+  llvm::Error Err = Edit.insertBefore(Context.Sources, DefaultLoc, "a");
+  ASSERT_TRUE(!Err);
+
+  // Invalid location.
+  Err = Edit.insertBefore(Context.Sources, SourceLocation(), "a");
+  ASSERT_TRUE((bool)Err);
+  EXPECT_TRUE(checkReplacementError(
+      std::move(Err), replacement_error::wrong_file_path,
+      Replacement(Context.Sources, DefaultLoc, 0, "a"),
+      Replacement(Context.Sources, SourceLocation(), 0, "a")));
+
+}
+
+TEST_F(EditListTest, InsertBeforeToWrongFile) {
+  setUp();
+  EditList Edit(Context.Sources, DefaultLoc);
+  llvm::Error Err = Edit.insertBefore(Context.Sources, DefaultLoc, "a");
+  ASSERT_TRUE(!Err);
+
+  // Inserting at a different file.
+  FileID NewID = Context.createInMemoryFile("extra.cpp", DefaultCode);
+  SourceLocation NewLoc = Context.Sources.getLocForStartOfFile(NewID);
+  Err = Edit.insertBefore(Context.Sources, NewLoc, "b");
+  ASSERT_TRUE((bool)Err);
+  EXPECT_TRUE(
+      checkReplacementError(std::move(Err), replacement_error::wrong_file_path,
+                            Replacement(Context.Sources, DefaultLoc, 0, "a"),
+                            Replacement(Context.Sources, NewLoc, 0, "b")));
+}
+
+TEST_F(EditListTest, InsertAfterWithInvalidLocation) {
+  setUp();
+  EditList Edit(Context.Sources, DefaultLoc);
+  llvm::Error Err = Edit.insertAfter(Context.Sources, DefaultLoc, "a");
+  ASSERT_TRUE(!Err);
+
+  // Invalid location.
+  Err = Edit.insertAfter(Context.Sources, SourceLocation(), "b");
+  ASSERT_TRUE((bool)Err);
+  EXPECT_TRUE(checkReplacementError(
+      std::move(Err), replacement_error::wrong_file_path,
+      Replacement(Context.Sources, DefaultLoc, 0, "a"),
+      Replacement(Context.Sources, SourceLocation(), 0, "b")));
+}
+
 } // end namespace tooling
 } // end namespace clang
Index: unittests/Tooling/CMakeLists.txt
===================================================================
--- unittests/Tooling/CMakeLists.txt
+++ unittests/Tooling/CMakeLists.txt
@@ -38,4 +38,5 @@
   clangRewrite
   clangTooling
   clangToolingCore
+  clangToolingRefactor
   )
Index: lib/Tooling/Refactoring/EditList.cpp
===================================================================
--- /dev/null
+++ lib/Tooling/Refactoring/EditList.cpp
@@ -0,0 +1,192 @@
+//===--- EditList.cpp - EditList implementation -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactoring/EditList.h"
+#include "clang/Tooling/ReplacementsYaml.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <string>
+
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::EditList)
+
+namespace {
+/// \brief Helper to (de)serialize an EditList since we don't have direct
+/// access to its data members.
+/// Data members of a normalized editlist can be directly mapped from/to YAML
+/// string.
+struct NormalizedEditList {
+  NormalizedEditList() = default;
+
+  NormalizedEditList(const llvm::yaml::IO &) {}
+
+  // This converts EditList's internal implementation of the replacements set
+  // to a vector of replacements.
+  NormalizedEditList(const llvm::yaml::IO &, const clang::tooling::EditList &E)
+      : Key(E.getKey()), FilePath(E.getFilePath()), Error(E.getError()),
+        InsertedHeaders(E.getInsertedHeaders()),
+        RemovedHeaders(E.getRemovedHeaders()) {
+    std::copy(E.getReplacements().begin(), E.getReplacements().end(),
+              std::back_inserter(Replaces));
+  }
+
+  // This is not expected to be called but needed for template instantiation.
+  clang::tooling::EditList denormalize(const llvm::yaml::IO &) {
+    llvm_unreachable("Do not convert YAML to EditList directly with '>>'. "
+                     "Use EditList::convertFromYAML instead.");
+  }
+  std::string Key;
+  std::string FilePath;
+  std::string Error;
+  std::vector<std::string> InsertedHeaders;
+  std::vector<std::string> RemovedHeaders;
+  std::vector<clang::tooling::Replacement> Replaces;
+};
+} // anonymous namespace
+
+namespace llvm {
+namespace yaml {
+
+/// \brief Specialized MappingTraits to describe how an EditList is
+/// (de)serialized.
+template <> struct MappingTraits<NormalizedEditList> {
+  static void mapping(IO &Io, NormalizedEditList &Doc) {
+    Io.mapRequired("Key", Doc.Key);
+    Io.mapRequired("FilePath", Doc.FilePath);
+    Io.mapRequired("Error", Doc.Error);
+    Io.mapRequired("InsertedHeaders", Doc.InsertedHeaders);
+    Io.mapRequired("RemovedHeaders", Doc.RemovedHeaders);
+    Io.mapRequired("Replacements", Doc.Replaces);
+  }
+};
+
+/// \brief Specialized MappingTraits to describe how an EditList is
+/// (de)serialized.
+template <> struct MappingTraits<clang::tooling::EditList> {
+  static void mapping(IO &Io,
+                      clang::tooling::EditList &Doc) {
+    MappingNormalization<NormalizedEditList, clang::tooling::EditList>
+    Keys(Io, Doc);
+    Io.mapRequired("Key", Keys->Key);
+    Io.mapRequired("FilePath", Keys->FilePath);
+    Io.mapRequired("Error", Keys->Error);
+    Io.mapRequired("InsertedHeaders", Keys->InsertedHeaders);
+    Io.mapRequired("RemovedHeaders", Keys->RemovedHeaders);
+    Io.mapRequired("Replacements", Keys->Replaces);
+  }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+namespace clang {
+namespace tooling {
+
+EditList::EditList(const SourceManager &SM, SourceLocation KeyPosition) {
+  const FullSourceLoc FullKeyPosition(KeyPosition, SM);
+  std::pair<FileID, unsigned> FileIDAndOffset =
+      FullKeyPosition.getSpellingLoc().getDecomposedLoc();
+  const FileEntry *FE = SM.getFileEntryForID(FileIDAndOffset.first);
+  assert(FE && "Cannot create EditList with invalid location.");
+  FilePath = FE->getName();
+  Key = FilePath + ":" + std::to_string(FileIDAndOffset.second);
+}
+
+EditList::EditList(std::string Key, std::string FilePath, std::string Error,
+                   std::vector<std::string> InsertedHeaders,
+                   std::vector<std::string> RemovedHeaders,
+                   clang::tooling::Replacements Replaces)
+    : Key(std::move(Key)), FilePath(std::move(FilePath)),
+      Error(std::move(Error)), InsertedHeaders(std::move(InsertedHeaders)),
+      RemovedHeaders(std::move(RemovedHeaders)), Replaces(std::move(Replaces)) {
+}
+
+std::string EditList::toYAMLString() {
+  std::string YamlContent;
+  llvm::raw_string_ostream YamlContentStream(YamlContent);
+
+  llvm::yaml::Output YAML(YamlContentStream);
+  YAML << *this;
+  YamlContentStream.flush();
+  return YamlContent;
+}
+
+EditList EditList::convertFromYAML(llvm::StringRef YAMLContent) {
+  NormalizedEditList NE;
+  llvm::yaml::Input YAML(YAMLContent);
+  YAML >> NE;
+  EditList E(NE.Key, NE.FilePath, NE.Error, NE.InsertedHeaders,
+             NE.RemovedHeaders, tooling::Replacements());
+  for (const auto &R : NE.Replaces) {
+    llvm::Error Err = E.addReplacement(R);
+    if (Err)
+      llvm_unreachable(
+          "Failed to add replacement when Converting YAML to EditList.");
+    llvm::consumeError(std::move(Err));
+  }
+  return E;
+}
+
+llvm::Error EditList::addReplacement(const Replacement &R) {
+  return Replaces.add(R);
+}
+
+void EditList::mergeReplacements(const Replacements &Rs) {
+  Replaces = Replaces.merge(Rs);
+}
+
+llvm::Error EditList::insertBefore(const SourceManager &SM, SourceLocation Loc,
+                                   llvm::StringRef Text) {
+  if (Text.empty()) return llvm::Error::success();
+  Replacement R(SM, Loc, 0, Text);
+  llvm::Error Err = Replaces.add(R);
+  if (Err) {
+    return llvm::handleErrors(
+        std::move(Err), [&](const ReplacementError &RE) -> llvm::Error {
+          if (RE.get() != replacement_error::insert_conflict)
+            return llvm::make_error<ReplacementError>(RE);
+          unsigned NewOffset =
+              Replaces.getShiftedCodePosition(R.getOffset()) -
+              RE.getExistingReplacement()->getReplacementText().size();
+          Replacement NewR(R.getFilePath(), NewOffset, 0, Text);
+          mergeReplacements(Replacements(NewR));
+          return llvm::Error::success();
+        });
+  }
+  return llvm::Error::success();
+}
+
+llvm::Error EditList::insertAfter(const SourceManager &SM, SourceLocation Loc,
+                                  llvm::StringRef Text) {
+  if (Text.empty()) return llvm::Error::success();
+  Replacement R(SM, Loc, 0, Text);
+  llvm::Error Err = Replaces.add(R);
+  if (Err) {
+    return llvm::handleErrors(
+        std::move(Err), [&](const ReplacementError &RE) -> llvm::Error {
+          if (RE.get() != replacement_error::insert_conflict)
+            return llvm::make_error<ReplacementError>(RE);
+          unsigned NewOffset = Replaces.getShiftedCodePosition(R.getOffset());
+          Replacement NewR(R.getFilePath(), NewOffset, 0, Text);
+          mergeReplacements(Replacements(NewR));
+          return llvm::Error::success();
+        });
+  }
+  return llvm::Error::success();
+}
+
+void EditList::addHeader(llvm::StringRef Header) {
+  InsertedHeaders.push_back(Header);
+}
+
+void EditList::removeHeader(llvm::StringRef Header) {
+  RemovedHeaders.push_back(Header);
+}
+
+} // end namespace tooling
+} // end namespace clang
Index: lib/Tooling/Refactoring/CMakeLists.txt
===================================================================
--- /dev/null
+++ lib/Tooling/Refactoring/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(LLVM_LINK_COMPONENTS
+  Option
+  Support
+  )
+
+add_clang_library(clangToolingRefactor
+  EditList.cpp
+
+  LINK_LIBS
+  clangBasic
+  clangToolingCore
+  )
Index: lib/Tooling/CMakeLists.txt
===================================================================
--- lib/Tooling/CMakeLists.txt
+++ lib/Tooling/CMakeLists.txt
@@ -4,6 +4,7 @@
   )
 
 add_subdirectory(Core)
+add_subdirectory(Refactoring)
 
 add_clang_library(clangTooling
   ArgumentsAdjusters.cpp
Index: include/clang/Tooling/Refactoring/EditList.h
===================================================================
--- /dev/null
+++ include/clang/Tooling/Refactoring/EditList.h
@@ -0,0 +1,134 @@
+//===--- EditList.h - Refactoring edits -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines EditList which is used to create a set of source eidts,
+//  e.g. replacements and header insertions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_EDITLIST_H
+#define LLVM_CLANG_TOOLING_REFACTOR_EDITLIST_H
+
+#include "clang/Basic/SourceManager.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace tooling {
+
+/// \brief An edit list is used to create and group a set of source edits, e.g.
+/// replacements or header insertions. Edits in an EditList should be related,
+/// e.g. replacements for the same type reference and the corresponding header
+/// insertion/deletion.
+///
+/// An EditList is uniquely identified by a key and will either be fully applied
+/// or not applied at all.
+///
+/// Calling setError on an EditList stores the error message and marks it as
+/// bad, i.e. none of its source edits will be applied.
+class EditList {
+public:
+  /// \brief Creates an edit list around \p KeyPosition with the key being a
+  /// concatenation of the file name and the offset of \p KeyPosition.
+  /// \p KeyPosition should be the location of the key syntactical element that
+  /// is being changed, e.g. the call to a refactored method.
+  EditList(const SourceManager &SM, SourceLocation KeyPosition);
+
+  /// \brief Creates an edit list for \p FilePath with a customized key.
+  EditList(llvm::StringRef FilePath, llvm::StringRef Key)
+      : Key(Key), FilePath(FilePath) {}
+
+  /// \brief Returns the edit as a YAML string.
+  std::string toYAMLString();
+
+  /// \brief Converts a YAML-encoded edit to EditList.
+  static EditList convertFromYAML(llvm::StringRef YAMLContent);
+
+  /// \brief Returns the key of this edit, which is a concatenation of the file
+  /// name and offset of the key position.
+  std::string getKey() const { return Key; }
+
+  /// \brief Returns the path of the file containing this edit.
+  std::string getFilePath() const { return FilePath; }
+
+  /// \brief If this edit could not be created successfully, e.g. because of
+  /// conflicts among replacements, use this to set an error description.
+  /// Thereby, places that cannot be fixed automatically can be gathered when
+  /// applying edits.
+  void setError(llvm::StringRef Error) { this->Error = Error; }
+
+  /// \brief Returns whether an error has been set on this list.
+  bool hasError() const { return !Error.empty(); }
+
+  /// \brief Returns the error message or an empty string if it does not exist.
+  std::string getError() const { return Error; }
+
+  /// \brief Adds a replacement \p R to the edit.
+  /// \returns An llvm::Error carrying ReplacementError on error.
+  llvm::Error addReplacement(const Replacement &R);
+
+  /// \brief Merges `Rs` into the existing replacements with `Rs` referring to
+  /// the code after all existing replacements are applied. This enables
+  /// conflict resolving.
+  void mergeReplacements(const clang::tooling::Replacements &Rs);
+
+  /// \brief Adds a replacement that inserts \p Text at \p Loc. If this
+  /// insertion conflicts with an existing insertion (at the same position),
+  /// this will be inserted before the existing insertion. If the conflicting
+  /// replacement is not an insertion, an error is returned.
+  ///
+  /// \returns An llvm::Error carrying ReplacementError on error.
+  llvm::Error insertBefore(const SourceManager &SM, SourceLocation Loc,
+                           llvm::StringRef Text);
+
+  /// \brief Same as `InsertBefore` except this inserts after the conflicting
+  /// insertion.
+  llvm::Error insertAfter(const SourceManager &SM, clang::SourceLocation Loc,
+                          llvm::StringRef Text);
+
+  /// \brief Adds a header into the file that contains the key position.
+  /// Header can be in angle brackets or double quotation marks. By default
+  /// (header is not quoted), header will be surrounded with double quotes.
+  void addHeader(llvm::StringRef Header);
+
+  /// \brief Removes a header from the file that contains the key position.
+  void removeHeader(llvm::StringRef Header);
+
+  /// \brief Returns a const reference to existing replacements.
+  const Replacements &getReplacements() const { return Replaces; }
+
+  llvm::ArrayRef<std::string> getInsertedHeaders() const {
+    return InsertedHeaders;
+  }
+  llvm::ArrayRef<std::string> getRemovedHeaders() const {
+    return RemovedHeaders;
+  }
+
+private:
+  EditList() {}
+
+  EditList(std::string Key, std::string FilePath, std::string Error,
+           std::vector<std::string> InsertedHeaders,
+           std::vector<std::string> RemovedHeaders,
+           clang::tooling::Replacements Replaces);
+
+  // This uniquely identifies an EditList.
+  std::string Key;
+  std::string FilePath;
+  std::string Error;
+  std::vector<std::string> InsertedHeaders;
+  std::vector<std::string> RemovedHeaders;
+  tooling::Replacements Replaces;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_EDITLIST_H
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to