forked from OSchip/llvm-project
Fix calculation of shifted cursor/code positions. Specifically support
the case where a specific range is replaced by new text. Previously, the calculation would shift any position from within a replaced region to the first character after the region. This is undersirable, e.g. for clang-format's include sorting. llvm-svn: 253859
This commit is contained in:
parent
2f8d345adc
commit
3fed94525c
|
@ -143,34 +143,32 @@ void Replacement::setFromSourceRange(const SourceManager &Sources,
|
|||
ReplacementText);
|
||||
}
|
||||
|
||||
unsigned shiftedCodePosition(const Replacements &Replaces, unsigned Position) {
|
||||
unsigned NewPosition = Position;
|
||||
for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); I != E;
|
||||
++I) {
|
||||
if (I->getOffset() >= Position)
|
||||
break;
|
||||
if (I->getOffset() + I->getLength() > Position)
|
||||
NewPosition += I->getOffset() + I->getLength() - Position;
|
||||
NewPosition += I->getReplacementText().size() - I->getLength();
|
||||
template <typename T>
|
||||
unsigned shiftedCodePositionInternal(const T &Replaces, unsigned Position) {
|
||||
unsigned Offset = 0;
|
||||
for (const auto& R : Replaces) {
|
||||
if (R.getOffset() + R.getLength() <= Position) {
|
||||
Offset += R.getReplacementText().size() - R.getLength();
|
||||
continue;
|
||||
}
|
||||
if (R.getOffset() < Position &&
|
||||
R.getOffset() + R.getReplacementText().size() <= Position) {
|
||||
Position = R.getOffset() + R.getReplacementText().size() - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NewPosition;
|
||||
return Position + Offset;
|
||||
}
|
||||
|
||||
unsigned shiftedCodePosition(const Replacements &Replaces, unsigned Position) {
|
||||
return shiftedCodePositionInternal(Replaces, Position);
|
||||
}
|
||||
|
||||
// FIXME: Remove this function when Replacements is implemented as std::vector
|
||||
// instead of std::set.
|
||||
unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
|
||||
unsigned Position) {
|
||||
unsigned NewPosition = Position;
|
||||
for (std::vector<Replacement>::const_iterator I = Replaces.begin(),
|
||||
E = Replaces.end();
|
||||
I != E; ++I) {
|
||||
if (I->getOffset() >= Position)
|
||||
break;
|
||||
if (I->getOffset() + I->getLength() > Position)
|
||||
NewPosition += I->getOffset() + I->getLength() - Position;
|
||||
NewPosition += I->getReplacementText().size() - I->getLength();
|
||||
}
|
||||
return NewPosition;
|
||||
return shiftedCodePositionInternal(Replaces, Position);
|
||||
}
|
||||
|
||||
void deduplicate(std::vector<Replacement> &Replaces,
|
||||
|
|
|
@ -176,8 +176,8 @@ TEST(ShiftedCodePositionTest, FindsNewCodePosition) {
|
|||
EXPECT_EQ(1u, shiftedCodePosition(Replaces, 2)); // i|t i;
|
||||
EXPECT_EQ(2u, shiftedCodePosition(Replaces, 3)); // in| i;
|
||||
EXPECT_EQ(3u, shiftedCodePosition(Replaces, 4)); // int| i;
|
||||
EXPECT_EQ(4u, shiftedCodePosition(Replaces, 5)); // int | i;
|
||||
EXPECT_EQ(4u, shiftedCodePosition(Replaces, 6)); // int |i;
|
||||
EXPECT_EQ(3u, shiftedCodePosition(Replaces, 5)); // int | i;
|
||||
EXPECT_EQ(3u, shiftedCodePosition(Replaces, 6)); // int |i;
|
||||
EXPECT_EQ(4u, shiftedCodePosition(Replaces, 7)); // int |;
|
||||
EXPECT_EQ(5u, shiftedCodePosition(Replaces, 8)); // int i|
|
||||
}
|
||||
|
@ -195,8 +195,8 @@ TEST(ShiftedCodePositionTest, VectorFindsNewCodePositionWithInserts) {
|
|||
EXPECT_EQ(1u, shiftedCodePosition(Replaces, 2)); // i|t i;
|
||||
EXPECT_EQ(2u, shiftedCodePosition(Replaces, 3)); // in| i;
|
||||
EXPECT_EQ(3u, shiftedCodePosition(Replaces, 4)); // int| i;
|
||||
EXPECT_EQ(4u, shiftedCodePosition(Replaces, 5)); // int | i;
|
||||
EXPECT_EQ(4u, shiftedCodePosition(Replaces, 6)); // int |i;
|
||||
EXPECT_EQ(3u, shiftedCodePosition(Replaces, 5)); // int | i;
|
||||
EXPECT_EQ(3u, shiftedCodePosition(Replaces, 6)); // int |i;
|
||||
EXPECT_EQ(4u, shiftedCodePosition(Replaces, 7)); // int |;
|
||||
EXPECT_EQ(5u, shiftedCodePosition(Replaces, 8)); // int i|
|
||||
}
|
||||
|
@ -205,8 +205,17 @@ TEST(ShiftedCodePositionTest, FindsNewCodePositionWithInserts) {
|
|||
Replacements Replaces;
|
||||
Replaces.insert(Replacement("", 4, 0, "\"\n\""));
|
||||
// Assume '"12345678"' is turned into '"1234"\n"5678"'.
|
||||
EXPECT_EQ(4u, shiftedCodePosition(Replaces, 4)); // "123|5678"
|
||||
EXPECT_EQ(8u, shiftedCodePosition(Replaces, 5)); // "1234|678"
|
||||
EXPECT_EQ(3u, shiftedCodePosition(Replaces, 3)); // "123|5678"
|
||||
EXPECT_EQ(7u, shiftedCodePosition(Replaces, 4)); // "1234|678"
|
||||
EXPECT_EQ(8u, shiftedCodePosition(Replaces, 5)); // "12345|78"
|
||||
}
|
||||
|
||||
TEST(ShiftedCodePositionTest, FindsNewCodePositionInReplacedText) {
|
||||
Replacements Replaces;
|
||||
// Replace the first four characters with "abcd".
|
||||
Replaces.insert(Replacement("", 0, 4, "abcd"));
|
||||
for (unsigned i = 0; i < 3; ++i)
|
||||
EXPECT_EQ(i, shiftedCodePosition(Replaces, i));
|
||||
}
|
||||
|
||||
class FlushRewrittenFilesTest : public ::testing::Test {
|
||||
|
|
Loading…
Reference in New Issue