[clang-format] Do not update cursor pos if no includes replacement (#77456)

Fix https://github.com/llvm/llvm-project/issues/77450.

---------

Signed-off-by: NorthBlue333 <north333@free.fr>
Co-authored-by: Owen Pan <owenpiano@gmail.com>
This commit is contained in:
NorthBlue333
2024-04-26 05:34:49 +02:00
committed by GitHub
parent 59bfc31068
commit 2de0bedfeb
2 changed files with 122 additions and 3 deletions

View File

@@ -3116,6 +3116,7 @@ static void sortCppIncludes(const FormatStyle &Style,
return;
}
const auto OldCursor = Cursor ? *Cursor : 0;
std::string result;
for (unsigned Index : Indices) {
if (!result.empty()) {
@@ -3139,6 +3140,8 @@ static void sortCppIncludes(const FormatStyle &Style,
// the entire range of blocks. Otherwise, no replacement is generated.
if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
IncludesBeginOffset, IncludesBlockSize)))) {
if (Cursor)
*Cursor = OldCursor;
return;
}

View File

@@ -6,19 +6,19 @@
//
//===----------------------------------------------------------------------===//
#include "FormatTestUtils.h"
#include "FormatTestBase.h"
#include "clang/Format/Format.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Debug.h"
#include "gtest/gtest.h"
#define DEBUG_TYPE "format-test"
#define DEBUG_TYPE "sort-includes-test"
namespace clang {
namespace format {
namespace {
class SortIncludesTest : public ::testing::Test {
class SortIncludesTest : public test::FormatTestBase {
protected:
std::vector<tooling::Range> GetCodeRange(StringRef Code) {
return std::vector<tooling::Range>(1, tooling::Range(0, Code.size()));
@@ -821,6 +821,122 @@ TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionWithRegrouping) {
EXPECT_EQ(27u, newCursor(Code, 28)); // Start of last line
}
TEST_F(SortIncludesTest,
CalculatesCorrectCursorPositionWhenNoReplacementsWithRegroupingAndCRLF) {
Style.IncludeBlocks = Style.IBS_Regroup;
FmtStyle.LineEnding = FormatStyle::LE_CRLF;
Style.IncludeCategories = {
{"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}};
std::string Code = "#include \"a\"\r\n" // Start of line: 0
"\r\n" // Start of line: 14
"#include \"b\"\r\n" // Start of line: 16
"\r\n" // Start of line: 30
"#include \"c\"\r\n" // Start of line: 32
"\r\n" // Start of line: 46
"int i;"; // Start of line: 48
verifyNoChange(Code);
EXPECT_EQ(0u, newCursor(Code, 0));
EXPECT_EQ(14u, newCursor(Code, 14));
EXPECT_EQ(16u, newCursor(Code, 16));
EXPECT_EQ(30u, newCursor(Code, 30));
EXPECT_EQ(32u, newCursor(Code, 32));
EXPECT_EQ(46u, newCursor(Code, 46));
EXPECT_EQ(48u, newCursor(Code, 48));
}
TEST_F(
SortIncludesTest,
CalculatesCorrectCursorPositionWhenRemoveLinesReplacementsWithRegroupingAndCRLF) {
Style.IncludeBlocks = Style.IBS_Regroup;
FmtStyle.LineEnding = FormatStyle::LE_CRLF;
Style.IncludeCategories = {{".*", 0, 0, false}};
std::string Code = "#include \"a\"\r\n" // Start of line: 0
"\r\n" // Start of line: 14
"#include \"b\"\r\n" // Start of line: 16
"\r\n" // Start of line: 30
"#include \"c\"\r\n" // Start of line: 32
"\r\n" // Start of line: 46
"int i;"; // Start of line: 48
std::string Expected = "#include \"a\"\r\n" // Start of line: 0
"#include \"b\"\r\n" // Start of line: 14
"#include \"c\"\r\n" // Start of line: 28
"\r\n" // Start of line: 42
"int i;"; // Start of line: 44
EXPECT_EQ(Expected, sort(Code));
EXPECT_EQ(0u, newCursor(Code, 0));
EXPECT_EQ(
14u,
newCursor(Code, 14)); // cursor on empty line in include block is ignored
EXPECT_EQ(14u, newCursor(Code, 16));
EXPECT_EQ(
30u,
newCursor(Code, 30)); // cursor on empty line in include block is ignored
EXPECT_EQ(28u, newCursor(Code, 32));
EXPECT_EQ(42u, newCursor(Code, 46));
EXPECT_EQ(44u, newCursor(Code, 48));
}
// FIXME: the tests below should pass.
#if 0
TEST_F(
SortIncludesTest,
CalculatesCorrectCursorPositionWhenNewLineReplacementsWithRegroupingAndCRLF) {
Style.IncludeBlocks = Style.IBS_Regroup;
FmtStyle.LineEnding = FormatStyle::LE_CRLF;
Style.IncludeCategories = {
{"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}};
std::string Code = "#include \"a\"\r\n" // Start of line: 0
"#include \"b\"\r\n" // Start of line: 14
"#include \"c\"\r\n" // Start of line: 28
"\r\n" // Start of line: 42
"int i;"; // Start of line: 44
std::string Expected = "#include \"a\"\r\n" // Start of line: 0
"\r\n" // Start of line: 14
"#include \"b\"\r\n" // Start of line: 16
"\r\n" // Start of line: 30
"#include \"c\"\r\n" // Start of line: 32
"\r\n" // Start of line: 46
"int i;"; // Start of line: 48
EXPECT_EQ(Expected, sort(Code));
EXPECT_EQ(0u, newCursor(Code, 0));
EXPECT_EQ(15u, newCursor(Code, 16));
EXPECT_EQ(30u, newCursor(Code, 32));
EXPECT_EQ(44u, newCursor(Code, 46));
EXPECT_EQ(46u, newCursor(Code, 48));
}
TEST_F(
SortIncludesTest,
CalculatesCorrectCursorPositionWhenNoNewLineReplacementsWithRegroupingAndCRLF) {
Style.IncludeBlocks = Style.IBS_Regroup;
FmtStyle.LineEnding = FormatStyle::LE_CRLF;
Style.IncludeCategories = {
{"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}};
std::string Code = "#include \"a\"\r\n" // Start of line: 0
"\r\n" // Start of line: 14
"#include \"c\"\r\n" // Start of line: 16
"\r\n" // Start of line: 30
"#include \"b\"\r\n" // Start of line: 32
"\r\n" // Start of line: 46
"int i;"; // Start of line: 48
std::string Expected = "#include \"a\"\r\n" // Start of line: 0
"\r\n" // Start of line: 14
"#include \"b\"\r\n" // Start of line: 16
"\r\n" // Start of line: 30
"#include \"c\"\r\n" // Start of line: 32
"\r\n" // Start of line: 46
"int i;"; // Start of line: 48
EXPECT_EQ(Expected, sort(Code));
EXPECT_EQ(0u, newCursor(Code, 0));
EXPECT_EQ(14u, newCursor(Code, 14));
EXPECT_EQ(30u, newCursor(Code, 32));
EXPECT_EQ(30u, newCursor(Code, 30));
EXPECT_EQ(15u, newCursor(Code, 15));
EXPECT_EQ(44u, newCursor(Code, 46));
EXPECT_EQ(46u, newCursor(Code, 48));
}
#endif
TEST_F(SortIncludesTest, DeduplicateIncludes) {
EXPECT_EQ("#include <a>\n"
"#include <b>\n"