123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- //===- unittests/Rewrite/RewriteBufferTest.cpp - RewriteBuffer tests ------===//
- //
- // 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/Rewrite/Core/RewriteBuffer.h"
- #include "gtest/gtest.h"
- using namespace llvm;
- using namespace clang;
- namespace {
- #define EXPECT_OUTPUT(Buf, Output) EXPECT_EQ(Output, writeOutput(Buf))
- static std::string writeOutput(const RewriteBuffer &Buf) {
- std::string Result;
- raw_string_ostream OS(Result);
- Buf.write(OS);
- OS.flush();
- return Result;
- }
- static void tagRange(unsigned Offset, unsigned Len, StringRef tagName,
- RewriteBuffer &Buf) {
- std::string BeginTag;
- raw_string_ostream(BeginTag) << '<' << tagName << '>';
- std::string EndTag;
- raw_string_ostream(EndTag) << "</" << tagName << '>';
- Buf.InsertTextAfter(Offset, BeginTag);
- Buf.InsertTextBefore(Offset+Len, EndTag);
- }
- TEST(RewriteBuffer, TagRanges) {
- StringRef Input = "hello world";
- const char *Output = "<outer><inner>hello</inner></outer> ";
- RewriteBuffer Buf;
- Buf.Initialize(Input);
- StringRef RemoveStr = "world";
- size_t Pos = Input.find(RemoveStr);
- Buf.RemoveText(Pos, RemoveStr.size());
- StringRef TagStr = "hello";
- Pos = Input.find(TagStr);
- tagRange(Pos, TagStr.size(), "outer", Buf);
- tagRange(Pos, TagStr.size(), "inner", Buf);
- EXPECT_OUTPUT(Buf, Output);
- }
- TEST(RewriteBuffer, DISABLED_RemoveLineIfEmpty_XFAIL) {
- StringRef Input = "def\n"
- "ghi\n"
- "jkl\n";
- RewriteBuffer Buf;
- Buf.Initialize(Input);
- // Insert "abc\n" at the start.
- Buf.InsertText(0, "abc\n");
- EXPECT_OUTPUT(Buf, "abc\n"
- "def\n"
- "ghi\n"
- "jkl\n");
- // Remove "def\n".
- //
- // After the removal of "def", we have:
- //
- // "abc\n"
- // "\n"
- // "ghi\n"
- // "jkl\n"
- //
- // Because removeLineIfEmpty=true, RemoveText has to remove the "\n" left on
- // the line. This happens correctly for the rewrite buffer itself, so the
- // next check below passes.
- //
- // However, RemoveText's implementation incorrectly records the delta for
- // removing the "\n" using the rewrite buffer offset, 4, where it was
- // supposed to use the original input offset, 3. Interpreted as an original
- // input offset, 4 points to "g" not to "\n". Thus, any future modifications
- // at the original input's "g" will incorrectly see "g" as having become an
- // empty string and so will map to the next character, "h", in the rewrite
- // buffer.
- StringRef RemoveStr0 = "def";
- Buf.RemoveText(Input.find(RemoveStr0), RemoveStr0.size(),
- /*removeLineIfEmpty*/ true);
- EXPECT_OUTPUT(Buf, "abc\n"
- "ghi\n"
- "jkl\n");
- // Try to remove "ghi\n".
- //
- // As discussed above, the original input offset for "ghi\n" incorrectly
- // maps to the rewrite buffer offset for "hi\nj", so we end up with:
- //
- // "abc\n"
- // "gkl\n"
- //
- // To show that removeLineIfEmpty=true is the culprit, change true to false
- // and append a newline to RemoveStr0 above. The test then passes.
- StringRef RemoveStr1 = "ghi\n";
- Buf.RemoveText(Input.find(RemoveStr1), RemoveStr1.size());
- EXPECT_OUTPUT(Buf, "abc\n"
- "jkl\n");
- }
- } // anonymous namespace
|