[clang][Rewriter] Adjust end offset before RewriteBuffer::getMappedOffset() call (#187374)

Without this patch, only cases when a token length increased were
supported.
If a token length decreased, we returned a larger string than expected
(e.g. in the added tests, "xretur " would be returned instead of
"xretur")
This commit is contained in:
Aleksandr Platonov 2026-04-07 09:29:56 +03:00 committed by GitHub
parent a485f1c634
commit d55122e439
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 12 additions and 4 deletions

View file

@ -112,15 +112,15 @@ std::string Rewriter::getRewrittenText(CharSourceRange Range) const {
return std::string(Ptr, Ptr+EndOff-StartOff);
}
const RewriteBuffer &RB = I->second;
EndOff = RB.getMappedOffset(EndOff, true);
StartOff = RB.getMappedOffset(StartOff);
// Adjust the end offset to the end of the last token, instead of being the
// start of the last token.
if (Range.isTokenRange())
EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
const RewriteBuffer &RB = I->second;
EndOff = RB.getMappedOffset(EndOff, true);
StartOff = RB.getMappedOffset(StartOff);
// Advance the iterators to the right spot, yay for linear time algorithms.
RewriteBuffer::iterator Start = RB.begin();
std::advance(Start, StartOff);

View file

@ -48,6 +48,10 @@ TEST(Rewriter, GetRewrittenTextRangeTypes) {
// get char range ^~~ = "xret"
// get token range ^~~+++ = "xreturn"
// get source range ^~~+++ = "xreturn"
// remove "n"
// get char range ^~~ = "xret"
// get token range ^~~++ = "xretur"
// get source range ^~~++ = "xretur"
RangeTypeTest T(Code, 13, 16);
EXPECT_EQ(T.Rewrite.getRewrittenText(T.CRange), "ret");
EXPECT_EQ(T.Rewrite.getRewrittenText(T.TRange), "return");
@ -56,6 +60,10 @@ TEST(Rewriter, GetRewrittenTextRangeTypes) {
EXPECT_EQ(T.Rewrite.getRewrittenText(T.CRange), "xret");
EXPECT_EQ(T.Rewrite.getRewrittenText(T.TRange), "xreturn");
EXPECT_EQ(T.Rewrite.getRewrittenText(T.SRange), "xreturn");
T.Rewrite.RemoveText(T.makeLoc(18));
EXPECT_EQ(T.Rewrite.getRewrittenText(T.CRange), "xret");
EXPECT_EQ(T.Rewrite.getRewrittenText(T.TRange), "xretur");
EXPECT_EQ(T.Rewrite.getRewrittenText(T.SRange), "xretur");
}
TEST(Rewriter, ReplaceTextRangeTypes) {