using namespace clang::tooling;
void HeaderOverride::recordReplacements(
- llvm::StringRef TransformID, const clang::tooling::Replacements &Replaces) {
- HeaderChangeDoc.TransformID = TransformID;
- HeaderChangeDoc.Replacements.resize(Replaces.size());
+ const clang::tooling::Replacements &Replaces) {
+ MigratorDoc.Replacements.resize(Replaces.size());
std::copy(Replaces.begin(), Replaces.end(),
- HeaderChangeDoc.Replacements.begin());
+ MigratorDoc.Replacements.begin());
}
SourceOverrides::SourceOverrides(llvm::StringRef MainFileName,
bool TrackChanges)
: MainFileName(MainFileName), TrackChanges(TrackChanges) {}
-void SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces,
- llvm::StringRef TransformName) {
+void
+SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces) {
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
new DiagnosticOptions());
DiagnosticsEngine Diagnostics(
DiagOpts.getPtr());
FileManager Files((FileSystemOptions()));
SourceManager SM(Diagnostics, Files);
- applyReplacements(Replaces, SM, TransformName);
+ applyReplacements(Replaces, SM);
}
void SourceOverrides::applyReplacements(clang::tooling::Replacements &Replaces,
- clang::SourceManager &SM,
- llvm::StringRef TransformName) {
+ clang::SourceManager &SM) {
applyOverrides(SM);
Rewriter Rewrites(SM, LangOptions());
E = HeadersReplaces.end();
I != E; ++I) {
HeaderOverride &HeaderOv = Headers[I->getKey()];
- HeaderOv.recordReplacements(TransformName, I->getValue());
+ HeaderOv.recordReplacements(I->getValue());
}
if (TrackChanges)
/// \brief Constructors.
/// @{
HeaderOverride() {}
- HeaderOverride(llvm::StringRef HeaderFileName,
- llvm::StringRef SourceFileName) {
- HeaderChangeDoc.HeaderFileName = HeaderFileName;
- HeaderChangeDoc.SourceFileName = SourceFileName;
+ HeaderOverride(llvm::StringRef TargetFile,
+ llvm::StringRef MainSourceFile) {
+ MigratorDoc.TargetFile = TargetFile;
+ MigratorDoc.MainSourceFile= MainSourceFile;
}
/// @}
/// \brief Getter for FileName.
llvm::StringRef getFileName() const {
- return HeaderChangeDoc.HeaderFileName;
+ return MigratorDoc.TargetFile;
}
/// \brief Accessor for ContentOverride.
/// \brief Swaps the content of ContentOverride with \p S.
void swapContentOverride(std::string &S) { ContentOverride.swap(S); }
- /// \brief Getter for HeaderChangeDoc.
- const HeaderChangeDocument &getHeaderChangeDoc() const {
- return HeaderChangeDoc;
+ /// \brief Getter for MigratorDoc.
+ const MigratorDocument &getMigratorDoc() const {
+ return MigratorDoc;
}
/// \brief Stores the replacements made by a transform to the header this
/// object represents.
- void recordReplacements(llvm::StringRef TransformID,
- const clang::tooling::Replacements &Replaces);
+ void recordReplacements(const clang::tooling::Replacements &Replaces);
/// \brief Helper function to adjust the changed ranges.
void adjustChangedRanges(const clang::tooling::Replacements &Replaces) {
private:
std::string ContentOverride;
ChangedRanges Changes;
- HeaderChangeDocument HeaderChangeDoc;
+ MigratorDocument MigratorDoc;
};
/// \brief Container mapping header file names to override information.
///
/// \param Replaces The replacements to apply.
/// \param SM A user provided SourceManager to be used when applying rewrites.
- /// \param TransformName The name of the transform the replacements come from.
void applyReplacements(clang::tooling::Replacements &Replaces,
- clang::SourceManager &SM,
- llvm::StringRef TransformName);
- void applyReplacements(clang::tooling::Replacements &Replaces,
- llvm::StringRef TransformName);
+ clang::SourceManager &SM);
+ void applyReplacements(clang::tooling::Replacements &Replaces);
/// \brief Convenience function for applying this source's overrides to
/// the given SourceManager.
I != E; ++I)
if ((InIncludeList = fileHasPathPrefix(FilePath, *I)))
break;
+
// If file is not in the list of included paths then it is not necessary
// to check the excluded path list.
if (!InIncludeList)
reformatSingleFile(Header.getFileName(), Header.getChanges(), SM);
Replaces.insert(HeaderReplaces.begin(), HeaderReplaces.end());
}
- Overrides.applyReplacements(Replaces, SM, "reformatter");
+ Overrides.applyReplacements(Replaces, SM);
}
tooling::Replacements Reformatter::reformatSingleFile(
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file provides structs to store the migrator specific header
-/// replacements and the YAML traits for Replacements.
+/// \brief This file provides functionality to serialize replacements for a
+/// single file. It is used by the C++11 Migrator to store all the changes made
+/// by a single transform to a particular file resulting from migrating a
+/// translation unit of a particular main source file.
///
//===----------------------------------------------------------------------===//
/// \brief The top-level YAML document that contains the details for the
/// replacement.
-struct HeaderChangeDocument {
- std::string TransformID;
+struct MigratorDocument {
std::vector<clang::tooling::Replacement> Replacements;
- std::string HeaderFileName;
- std::string SourceFileName;
+ std::string TargetFile;
+ std::string MainSourceFile;
};
+// FIXME: Put the YAML support for Replacement into clang::tooling. NOTE: The
+// implementation below doesn't serialize the filename for Replacements.
+
LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement)
namespace llvm {
}
};
-/// \brief Specialized MappingTraits for HeaderChangeDocument to be converted
+/// \brief Specialized MappingTraits for MigratorDocument to be converted
/// to/from a YAML File.
template <>
-struct MappingTraits<HeaderChangeDocument> {
- static void mapping(IO &Io, HeaderChangeDocument &TD) {
- Io.mapRequired("TransformID", TD.TransformID);
+struct MappingTraits<MigratorDocument> {
+ static void mapping(IO &Io, MigratorDocument &TD) {
Io.mapRequired("Replacements", TD.Replacements);
- Io.mapRequired("HeaderFileName", TD.HeaderFileName);
- Io.mapRequired("SourceFileName", TD.SourceFileName);
+ Io.mapRequired("TargetFile", TD.TargetFile);
+ Io.mapRequired("MainSourceFile", TD.MainSourceFile);
}
};
} // end namespace yaml
void Transform::handleEndSource() {
if (!getReplacements().empty()) {
SourceOverrides &SO = Overrides->getOrCreate(CurrentSource);
- SO.applyReplacements(getReplacements(), getName());
+ SO.applyReplacements(getReplacements());
}
if (Options().EnableTiming)
continue;
}
llvm::yaml::Output YAML(ReplacementsFile);
- YAML << const_cast<HeaderChangeDocument &>(
- HeaderI->getValue().getHeaderChangeDoc());
+ YAML << const_cast<MigratorDocument &>(
+ HeaderI->getValue().getMigratorDoc());
} else {
// If -yaml-only was not specified, then change headers on disk.
// FIXME: This is transitional behaviour. Remove this functionality
---
-TransformID: "LoopConvert"
Replacements:
- Offset: 432
Length: 61
- Offset: 506
Length: 2
ReplacementText: "elem"
-HeaderFileName: "$(path)/common.h"
-SourceFileName: "$(path)/main.cpp"
+TargetFile: "$(path)/common.h"
+MainSourceFile: "$(path)/main.cpp"
...
strlen("std::vector<such_a_long_name_for_a_type>::const_iterator");
Replaces.insert(
Replacement(FileName, 0, ReplacementLength, "auto"));
- Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager(),
- "use-auto");
+ Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager());
EXPECT_TRUE(Overrides.isSourceOverriden());
std::string ExpectedContent = "auto long_type =\n"
FileName, Changes, VFHelper.getNewSourceManager());
SourceOverrides Overrides(FileName, /*TrackChanges=*/false);
- Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager(),
- "reformatter");
+ Overrides.applyReplacements(Replaces, VFHelper.getNewSourceManager());
std::string Expected, Result;
//
//===----------------------------------------------------------------------===//
//
-// Test for the Yaml files generated by transforms on header files.
+// Tests that change description files can be written and read.
//
//===----------------------------------------------------------------------===//
TEST(ReplacementsYamlTest, writeReadTest) {
using clang::tooling::Replacement;
- const std::string HeaderFileName = "/path/to/common.h";
- const std::string SourceFileName = "/path/to/source.cpp";
- const std::string TransformID = "loop-convert";
+ const std::string TargetFile = "/path/to/common.h";
+ const std::string MainSourceFile = "/path/to/source.cpp";
const unsigned int ReplacementOffset1 = 232;
const unsigned int ReplacementLength1 = 56;
const std::string ReplacementText1 = "(auto & elem : V)";
const unsigned int ReplacementLength2 = 2;
const std::string ReplacementText2 = "elem";
- HeaderChangeDocument HCD;
- HCD.TransformID = TransformID;
- HCD.Replacements.push_back(Replacement(HeaderFileName, ReplacementOffset1,
+ MigratorDocument Doc;
+ Doc.Replacements.push_back(Replacement(TargetFile, ReplacementOffset1,
ReplacementLength1, ReplacementText1));
- HCD.Replacements.push_back(Replacement(HeaderFileName, ReplacementOffset2,
+ Doc.Replacements.push_back(Replacement(TargetFile, ReplacementOffset2,
ReplacementLength2, ReplacementText2));
- HCD.HeaderFileName = HeaderFileName.c_str();
- HCD.SourceFileName = SourceFileName.c_str();
+ Doc.TargetFile = TargetFile.c_str();
+ Doc.MainSourceFile= MainSourceFile.c_str();
std::string YamlContent;
llvm::raw_string_ostream YamlContentStream(YamlContent);
// Write to the YAML file.
{
yaml::Output YAML(YamlContentStream);
- YAML << HCD;
+ YAML << Doc;
YamlContentStream.str();
ASSERT_NE(YamlContent.length(), 0u);
}
// Read from the YAML file and verify that what was written is exactly what
// we read back.
{
- HeaderChangeDocument HCDActual;
+ MigratorDocument DocActual;
yaml::Input YAML(YamlContent);
- YAML >> HCDActual;
+ YAML >> DocActual;
ASSERT_NO_ERROR(YAML.error());
- EXPECT_EQ(HeaderFileName, HCDActual.HeaderFileName);
- EXPECT_EQ(SourceFileName, HCDActual.SourceFileName);
- EXPECT_EQ(TransformID, HCDActual.TransformID);
- ASSERT_EQ(2u, HCDActual.Replacements.size());
+ EXPECT_EQ(TargetFile, DocActual.TargetFile);
+ EXPECT_EQ(MainSourceFile, DocActual.MainSourceFile);
+ ASSERT_EQ(2u, DocActual.Replacements.size());
- EXPECT_EQ(ReplacementOffset1, HCDActual.Replacements[0].getOffset());
- EXPECT_EQ(ReplacementLength1, HCDActual.Replacements[0].getLength());
+ EXPECT_EQ(ReplacementOffset1, DocActual.Replacements[0].getOffset());
+ EXPECT_EQ(ReplacementLength1, DocActual.Replacements[0].getLength());
EXPECT_EQ(ReplacementText1,
- HCDActual.Replacements[0].getReplacementText().str());
+ DocActual.Replacements[0].getReplacementText().str());
- EXPECT_EQ(ReplacementOffset2, HCDActual.Replacements[1].getOffset());
- EXPECT_EQ(ReplacementLength2, HCDActual.Replacements[1].getLength());
+ EXPECT_EQ(ReplacementOffset2, DocActual.Replacements[1].getOffset());
+ EXPECT_EQ(ReplacementLength2, DocActual.Replacements[1].getLength());
EXPECT_EQ(ReplacementText2,
- HCDActual.Replacements[1].getReplacementText().str());
+ DocActual.Replacements[1].getReplacementText().str());
}
}