njames93 updated this revision to Diff 250053.
njames93 marked 6 inline comments as done.
njames93 added a comment.
- Extend tests
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76037/new/
https://reviews.llvm.org/D76037
Files:
clang-tools-extra/clang-apply-replacements/CMakeLists.txt
clang/include/clang/Tooling/ReplacementsYaml.h
clang/lib/Tooling/CMakeLists.txt
clang/lib/Tooling/Refactoring/CMakeLists.txt
clang/lib/Tooling/ReplacementsYaml.cpp
clang/unittests/Tooling/ReplacementsYamlTest.cpp
Index: clang/unittests/Tooling/ReplacementsYamlTest.cpp
===================================================================
--- clang/unittests/Tooling/ReplacementsYamlTest.cpp
+++ clang/unittests/Tooling/ReplacementsYamlTest.cpp
@@ -46,28 +46,34 @@
YamlContentStream.str().c_str());
}
-TEST(ReplacementsYamlTest, serializesNewLines) {
- TranslationUnitReplacements Doc;
+TEST(ReplacementsYamlTest, handlesEscaped) {
+ TranslationUnitReplacements Doc, NewDoc;
Doc.MainSourceFile = "/path/to/source.cpp";
- Doc.Replacements.emplace_back("/path/to/file1.h", 0, 0, "#include <utility>\n");
+ const StringRef FilePath = "/path/to/file1.h";
+ Doc.Replacements.emplace_back(FilePath, 0, 0, "#include <utility>\n");
+ Doc.Replacements.emplace_back(FilePath, 0, 0, "'\\ \a \b \f \n \r \t \v");
- std::string YamlContent;
- llvm::raw_string_ostream YamlContentStream(YamlContent);
+ SmallString<512> YamlContent;
+ llvm::raw_svector_ostream YamlContentStream(YamlContent);
yaml::Output YAML(YamlContentStream);
YAML << Doc;
+ yaml::Input IYAML(YamlContent);
+ IYAML >> NewDoc;
- // NOTE: If this test starts to fail for no obvious reason, check whitespace.
- ASSERT_STREQ("---\n"
- "MainSourceFile: '/path/to/source.cpp'\n"
- "Replacements:\n"
- " - FilePath: '/path/to/file1.h'\n"
- " Offset: 0\n"
- " Length: 0\n"
- " ReplacementText: '#include <utility>\n\n'\n"
- "...\n",
- YamlContentStream.str().c_str());
+ ASSERT_FALSE(IYAML.error());
+ ASSERT_EQ(Doc.MainSourceFile, NewDoc.MainSourceFile);
+ ASSERT_EQ(Doc.Replacements.size(), NewDoc.Replacements.size());
+ for (auto DocR = Doc.Replacements.begin(),
+ NewDocR = NewDoc.Replacements.begin(),
+ DocE = Doc.Replacements.end();
+ DocR != DocE; DocR++, NewDocR++) {
+ ASSERT_EQ(DocR->getFilePath(), NewDocR->getFilePath());
+ ASSERT_EQ(DocR->getLength(), NewDocR->getLength());
+ ASSERT_EQ(DocR->getOffset(), NewDocR->getOffset());
+ ASSERT_EQ(DocR->getReplacementText(), NewDocR->getReplacementText());
+ }
}
TEST(ReplacementsYamlTest, deserializesReplacements) {
@@ -120,3 +126,53 @@
ASSERT_EQ(10u, DocActual.Replacements[0].getLength());
ASSERT_EQ("replacement", DocActual.Replacements[0].getReplacementText());
}
+
+TEST(ReplacementsYamlTest, deserializesEscapedReplacements) {
+ StringRef YamlContent =
+ "---\n"
+ "MainSourceFile: /path/to/source.cpp\n"
+ "Replacements:\n"
+ " - FilePath: /path/to/file1.h\n"
+ " Offset: 232\n"
+ " Length: 56\n"
+ " ReplacementText: '\\\\ \\a \\b \\f \\n \\r \\t \\v'\n"
+ "...\n";
+ TranslationUnitReplacements DocActual;
+ yaml::Input YAML(YamlContent);
+ YAML >> DocActual;
+ ASSERT_FALSE(YAML.error());
+ ASSERT_EQ(1u, DocActual.Replacements.size());
+ ASSERT_EQ("/path/to/source.cpp", DocActual.MainSourceFile);
+ ASSERT_EQ("/path/to/file1.h", DocActual.Replacements[0].getFilePath());
+ ASSERT_EQ(232u, DocActual.Replacements[0].getOffset());
+ ASSERT_EQ(56u, DocActual.Replacements[0].getLength());
+ ASSERT_EQ("\\ \a \b \f \n \r \t \v",
+ DocActual.Replacements[0].getReplacementText());
+}
+
+TEST(ReplacementsYamlTest, serializesEscapingReplacements) {
+
+ TranslationUnitReplacements Doc;
+
+ Doc.MainSourceFile = "/path/to/source.cpp";
+ Doc.Replacements.emplace_back("/path/to/file1.h", 232, 56,
+ "\\ \a \b \f \n \r \t \v");
+
+ SmallString<256> YamlContent;
+ llvm::raw_svector_ostream YamlContentStream(YamlContent);
+
+ yaml::Output YAML(YamlContentStream);
+ YAML << Doc;
+
+ // NOTE: If this test starts to fail for no obvious reason, check whitespace.
+ ASSERT_EQ(
+ StringRef("---\n"
+ "MainSourceFile: '/path/to/source.cpp'\n"
+ "Replacements:\n"
+ " - FilePath: '/path/to/file1.h'\n"
+ " Offset: 232\n"
+ " Length: 56\n"
+ " ReplacementText: '\\\\ \\a \\b \\f \\n \\r \\t \\v'\n"
+ "...\n"),
+ YamlContentStream.str());
+}
Index: clang/lib/Tooling/ReplacementsYaml.cpp
===================================================================
--- /dev/null
+++ clang/lib/Tooling/ReplacementsYaml.cpp
@@ -0,0 +1,75 @@
+//===-- ReplacementsYaml.cpp -- Serialiazation for Replacements -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/ReplacementsYaml.h"
+
+namespace llvm {
+namespace yaml {
+
+namespace {
+struct Escapes {
+ char EscapeChar;
+ char WrittenChar;
+};
+} // namespace
+
+static constexpr Escapes EscapeChars[] = {
+ {'\\', '\\'}, {'\a', 'a'}, {'\b', 'b'}, {'\f', 'f'},
+ {'\n', 'n'}, {'\r', 'r'}, {'\t', 't'}, {'\v', 'v'}};
+
+std::string
+MappingTraits<clang::tooling::Replacement>::NormalizedReplacement::escape(
+ StringRef Str) {
+ std::string Res;
+ llvm::raw_string_ostream Builder(Res);
+ for (char C : Str) {
+ if (llvm::none_of(EscapeChars, [&](Escapes Escape) {
+ if (C == Escape.EscapeChar) {
+ Builder << '\\' << Escape.WrittenChar;
+ return true;
+ }
+ return false;
+ })) {
+ Builder << C;
+ }
+ }
+ return Res;
+}
+
+std::string
+MappingTraits<clang::tooling::Replacement>::NormalizedReplacement::unescape(
+ StringRef Str) {
+ std::string Res;
+ llvm::raw_string_ostream Builder(Res);
+ while (!Str.empty()) {
+ if (Str.consume_front("\\")) {
+ if (Str.empty()) {
+ Builder << '\\';
+ break;
+ }
+ char C = Str.front();
+ Str = Str.drop_front();
+ if (llvm::none_of(EscapeChars, [&](Escapes Escape) {
+ if (C == Escape.WrittenChar) {
+ Builder << Escape.EscapeChar;
+ return true;
+ }
+ return false;
+ })) {
+ Builder << '\\' << C;
+ }
+ continue;
+ }
+ Builder << Str.front();
+ Str = Str.drop_front();
+ }
+ return Res;
+}
+
+} // namespace yaml
+} // namespace llvm
Index: clang/lib/Tooling/Refactoring/CMakeLists.txt
===================================================================
--- clang/lib/Tooling/Refactoring/CMakeLists.txt
+++ clang/lib/Tooling/Refactoring/CMakeLists.txt
@@ -21,5 +21,6 @@
clangIndex
clangLex
clangRewrite
+ clangTooling
clangToolingCore
)
Index: clang/lib/Tooling/CMakeLists.txt
===================================================================
--- clang/lib/Tooling/CMakeLists.txt
+++ clang/lib/Tooling/CMakeLists.txt
@@ -25,6 +25,7 @@
JSONCompilationDatabase.cpp
Refactoring.cpp
RefactoringCallbacks.cpp
+ ReplacementsYaml.cpp
StandaloneExecution.cpp
Tooling.cpp
Index: clang/include/clang/Tooling/ReplacementsYaml.h
===================================================================
--- clang/include/clang/Tooling/ReplacementsYaml.h
+++ clang/include/clang/Tooling/ReplacementsYaml.h
@@ -35,17 +35,16 @@
NormalizedReplacement(const IO &, const clang::tooling::Replacement &R)
: FilePath(R.getFilePath()), Offset(R.getOffset()),
- Length(R.getLength()), ReplacementText(R.getReplacementText()) {
- size_t lineBreakPos = ReplacementText.find('\n');
- while (lineBreakPos != std::string::npos) {
- ReplacementText.replace(lineBreakPos, 1, "\n\n");
- lineBreakPos = ReplacementText.find('\n', lineBreakPos + 2);
- }
- }
+ Length(R.getLength()),
+ ReplacementText(escape(R.getReplacementText())) {}
+
+ std::string escape(StringRef Str);
+
+ std::string unescape(StringRef Str);
clang::tooling::Replacement denormalize(const IO &) {
return clang::tooling::Replacement(FilePath, Offset, Length,
- ReplacementText);
+ unescape(ReplacementText));
}
std::string FilePath;
Index: clang-tools-extra/clang-apply-replacements/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-apply-replacements/CMakeLists.txt
+++ clang-tools-extra/clang-apply-replacements/CMakeLists.txt
@@ -9,6 +9,7 @@
clangAST
clangBasic
clangRewrite
+ clangTooling
clangToolingCore
clangToolingRefactoring
)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits