https://github.com/nataliakokoromyti updated https://github.com/llvm/llvm-project/pull/177326
>From e281c4373cbb56cdd226a8bf7f9af681564d5c08 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Thu, 22 Jan 2026 01:35:54 -0800 Subject: [PATCH 01/21] [clang-format] java import sorting should ignore imports in comments and text blocks --- clang/lib/Format/Format.cpp | 30 ++++++++++++++++++- .../unittests/Format/SortImportsTestJava.cpp | 26 ++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f0e9aff2fd21a..58dfae897ed0f 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3757,6 +3757,8 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, SmallVector<StringRef> AssociatedCommentLines; bool FormattingOff = false; + bool InBlockComment = false; + bool InTextBlock = false; for (;;) { auto Pos = Code.find('\n', SearchFrom); @@ -3769,7 +3771,33 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, else if (isClangFormatOn(Trimmed)) FormattingOff = false; - if (ImportRegex.match(Line, &Matches)) { + // Track block comments (/* ... */) + // Check if we're starting a block comment on this line + bool IsBlockComment = false; + if (Trimmed.starts_with("/*")) { + IsBlockComment = true; + if (!Trimmed.contains("*/")) + InBlockComment = true; + } + // Check if we're ending a block comment that started on a previous line + if (InBlockComment && Trimmed.contains("*/")) { + InBlockComment = false; + IsBlockComment = true; + } + // If we're in a multi-line block comment (not the first or last line) + if (InBlockComment && !Trimmed.starts_with("/*")) + IsBlockComment = true; + + // Track Java text blocks (""" ... """) + size_t Count = 0; + size_t StartPos = 0; + while ((StartPos = Trimmed.find("\"\"\"", StartPos)) != StringRef::npos) { + ++Count; + StartPos += 3; + } + if (Count % 2 == 1) + InTextBlock = !InTextBlock; + if (!IsBlockComment && !InTextBlock && ImportRegex.match(Line, &Matches)) { if (FormattingOff) { // If at least one import line has formatting turned off, turn off // formatting entirely. diff --git a/clang/unittests/Format/SortImportsTestJava.cpp b/clang/unittests/Format/SortImportsTestJava.cpp index 26674c75e97b1..9af9d8860fe73 100644 --- a/clang/unittests/Format/SortImportsTestJava.cpp +++ b/clang/unittests/Format/SortImportsTestJava.cpp @@ -349,6 +349,32 @@ TEST_F(SortImportsTestJava, NoReplacementsForValidImportsWindows) { sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty()); } +TEST_F(SortImportsTestJava, DoNotSortImportsInBlockComment) { + EXPECT_EQ("/* import org.d;\n" + "import org.c;\n" + "import org.b; */\n" + "import org.a;", + sort("/* import org.d;\n" + "import org.c;\n" + "import org.b; */\n" + "import org.a;")); +} + +TEST_F(SortImportsTestJava, DoNotSortImportsInTextBlock) { + EXPECT_EQ("String code = \"\"\"\n" + " import org.c;\n" + " \\\"\"\"\n" + " import org.b;\n" + "\\\\\"\"\";\n" + "import org.a;", + sort("String code = \"\"\"\n" + " import org.c;\n" + " \\\"\"\"\n" + " import org.b;\n" + "\\\\\"\"\";\n" + "import org.a;")); +} + } // end namespace } // end namespace format } // end namespace clang >From bd865fcd182a9e45053713485760f6b616b41b25 Mon Sep 17 00:00:00 2001 From: Natalia Kokoromyti <[email protected]> Date: Sun, 25 Jan 2026 02:07:27 -0800 Subject: [PATCH 02/21] fix --- clang/lib/Format/Format.cpp | 39 ++++++++----------- .../unittests/Format/SortImportsTestJava.cpp | 30 +++++++------- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 58dfae897ed0f..40ce229b9844f 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3743,6 +3743,10 @@ namespace { const char JavaImportRegexPattern[] = "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"; +const char JavaTypeDeclRegexPattern[] = + "^[\t ]*(public|private|protected|static|final|abstract|sealed|strictfp)?" + "[\t ]*(class|interface|enum|record|@interface)[\t ]+"; + } // anonymous namespace tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, @@ -3752,13 +3756,12 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, unsigned Prev = 0; unsigned SearchFrom = 0; llvm::Regex ImportRegex(JavaImportRegexPattern); + llvm::Regex TypeDeclRegex(JavaTypeDeclRegexPattern); SmallVector<StringRef, 4> Matches; SmallVector<JavaImportDirective, 16> ImportsInBlock; SmallVector<StringRef> AssociatedCommentLines; bool FormattingOff = false; - bool InBlockComment = false; - bool InTextBlock = false; for (;;) { auto Pos = Code.find('\n', SearchFrom); @@ -3771,33 +3774,23 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, else if (isClangFormatOn(Trimmed)) FormattingOff = false; - // Track block comments (/* ... */) - // Check if we're starting a block comment on this line + // Track block comments (/* ... */). bool IsBlockComment = false; if (Trimmed.starts_with("/*")) { IsBlockComment = true; - if (!Trimmed.contains("*/")) - InBlockComment = true; - } - // Check if we're ending a block comment that started on a previous line - if (InBlockComment && Trimmed.contains("*/")) { - InBlockComment = false; - IsBlockComment = true; + // Only skip multi-line comments if we haven't started collecting imports yet. + // Comments between imports should be associated with the import below. + if (ImportsInBlock.empty()) { + Pos = Code.find("*/", SearchFrom + 2); + } } - // If we're in a multi-line block comment (not the first or last line) - if (InBlockComment && !Trimmed.starts_with("/*")) - IsBlockComment = true; - // Track Java text blocks (""" ... """) - size_t Count = 0; - size_t StartPos = 0; - while ((StartPos = Trimmed.find("\"\"\"", StartPos)) != StringRef::npos) { - ++Count; - StartPos += 3; + // Check if we've encountered a type declaration - we're past imports. + if (!IsBlockComment && TypeDeclRegex.match(Trimmed)) { + break; } - if (Count % 2 == 1) - InTextBlock = !InTextBlock; - if (!IsBlockComment && !InTextBlock && ImportRegex.match(Line, &Matches)) { + + if (!IsBlockComment && ImportRegex.match(Line, &Matches)) { if (FormattingOff) { // If at least one import line has formatting turned off, turn off // formatting entirely. diff --git a/clang/unittests/Format/SortImportsTestJava.cpp b/clang/unittests/Format/SortImportsTestJava.cpp index 9af9d8860fe73..1b2b0654cfdae 100644 --- a/clang/unittests/Format/SortImportsTestJava.cpp +++ b/clang/unittests/Format/SortImportsTestJava.cpp @@ -360,19 +360,23 @@ TEST_F(SortImportsTestJava, DoNotSortImportsInBlockComment) { "import org.a;")); } -TEST_F(SortImportsTestJava, DoNotSortImportsInTextBlock) { - EXPECT_EQ("String code = \"\"\"\n" - " import org.c;\n" - " \\\"\"\"\n" - " import org.b;\n" - "\\\\\"\"\";\n" - "import org.a;", - sort("String code = \"\"\"\n" - " import org.c;\n" - " \\\"\"\"\n" - " import org.b;\n" - "\\\\\"\"\";\n" - "import org.a;")); +TEST_F(SortImportsTestJava, StopAtClassDeclaration) { + EXPECT_EQ("import org.a;\n" + "\n" + "class Foo {\n" + " String code = \"\"\"\n" + " import org.c;\n" + " import org.b;\n" + " \"\"\";\n" + "}", + sort("import org.a;\n" + "\n" + "class Foo {\n" + " String code = \"\"\"\n" + " import org.c;\n" + " import org.b;\n" + " \"\"\";\n" + "}")); } } // end namespace >From ee14636f8f69aa1e73f160fa584a13cccda9076b Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 26 Jan 2026 00:27:08 -0800 Subject: [PATCH 03/21] fix format --- clang/lib/Format/Format.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 40ce229b9844f..07580f7f3311e 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3778,17 +3778,14 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, bool IsBlockComment = false; if (Trimmed.starts_with("/*")) { IsBlockComment = true; - // Only skip multi-line comments if we haven't started collecting imports yet. - // Comments between imports should be associated with the import below. - if (ImportsInBlock.empty()) { + // Skip block comments before imports start. + if (ImportsInBlock.empty()) Pos = Code.find("*/", SearchFrom + 2); - } } - // Check if we've encountered a type declaration - we're past imports. - if (!IsBlockComment && TypeDeclRegex.match(Trimmed)) { + // Check if we've encountered a type declaration. + if (!IsBlockComment && TypeDeclRegex.match(Trimmed)) break; - } if (!IsBlockComment && ImportRegex.match(Line, &Matches)) { if (FormattingOff) { >From d3ceb2220c68629af2457b03c7286127c709889c Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 26 Jan 2026 00:43:41 -0800 Subject: [PATCH 04/21] simplify regexpattern --- clang/lib/Format/Format.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 07580f7f3311e..dbae8d36b620d 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3744,7 +3744,7 @@ const char JavaImportRegexPattern[] = "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"; const char JavaTypeDeclRegexPattern[] = - "^[\t ]*(public|private|protected|static|final|abstract|sealed|strictfp)?" + "^[\t ]*(public|private|protected|static|final|abstract)*" "[\t ]*(class|interface|enum|record|@interface)[\t ]+"; } // anonymous namespace >From 0446edfe571fba5912fdc04ded62791ff8d78dde Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 2 Feb 2026 02:23:13 -0800 Subject: [PATCH 05/21] rm JavaTypeDeclRegexPattern + handle trimmed.empty() at top --- clang/lib/Format/Format.cpp | 41 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index dbae8d36b620d..1879b7c9ee60a 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3743,9 +3743,7 @@ namespace { const char JavaImportRegexPattern[] = "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"; -const char JavaTypeDeclRegexPattern[] = - "^[\t ]*(public|private|protected|static|final|abstract)*" - "[\t ]*(class|interface|enum|record|@interface)[\t ]+"; +const char JavaPackageRegexPattern[] = "^[\t ]*package[\t ]+[^;]+;"; } // anonymous namespace @@ -3756,7 +3754,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, unsigned Prev = 0; unsigned SearchFrom = 0; llvm::Regex ImportRegex(JavaImportRegexPattern); - llvm::Regex TypeDeclRegex(JavaTypeDeclRegexPattern); + llvm::Regex PackageRegex(JavaPackageRegexPattern); SmallVector<StringRef, 4> Matches; SmallVector<JavaImportDirective, 16> ImportsInBlock; SmallVector<StringRef> AssociatedCommentLines; @@ -3774,20 +3772,22 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, else if (isClangFormatOn(Trimmed)) FormattingOff = false; - // Track block comments (/* ... */). - bool IsBlockComment = false; - if (Trimmed.starts_with("/*")) { - IsBlockComment = true; - // Skip block comments before imports start. - if (ImportsInBlock.empty()) - Pos = Code.find("*/", SearchFrom + 2); - } - - // Check if we've encountered a type declaration. - if (!IsBlockComment && TypeDeclRegex.match(Trimmed)) - break; - - if (!IsBlockComment && ImportRegex.match(Line, &Matches)) { + if (Trimmed.empty()) { + // Skip empty lines. + } else if (Trimmed.starts_with("//")) { + if (!ImportsInBlock.empty()) + AssociatedCommentLines.push_back(Line); + } else if (Trimmed.starts_with("/*")) { + auto EndPos = Code.find("*/", SearchFrom + 2); + if (EndPos != StringRef::npos) { + Line = Code.substr(Prev, EndPos + 2 - Prev); + Pos = EndPos + 1; + } + if (!ImportsInBlock.empty()) + AssociatedCommentLines.push_back(Line); + } else if (PackageRegex.match(Trimmed)) { + // Skip package declarations. + } else if (ImportRegex.match(Trimmed, &Matches)) { if (FormattingOff) { // If at least one import line has formatting turned off, turn off // formatting entirely. @@ -3801,9 +3801,8 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, ImportsInBlock.push_back( {Identifier, Line, Prev, AssociatedCommentLines, IsStatic}); AssociatedCommentLines.clear(); - } else if (!Trimmed.empty() && !ImportsInBlock.empty()) { - // Associating comments within the imports with the nearest import below - AssociatedCommentLines.push_back(Line); + } else { + break; } Prev = Pos + 1; if (Pos == StringRef::npos || Pos + 1 == Code.size()) >From a775a5c401d57208464b356a6e871abf9e6f6cb3 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Sat, 7 Feb 2026 15:11:01 -0800 Subject: [PATCH 06/21] fix regex Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 1879b7c9ee60a..a4ae7bb797119 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3740,10 +3740,10 @@ static void sortJavaImports(const FormatStyle &Style, namespace { -const char JavaImportRegexPattern[] = - "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"; +constexpr StringRef JavaImportRegexPattern( +"^import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"); -const char JavaPackageRegexPattern[] = "^[\t ]*package[\t ]+[^;]+;"; +constexpr StringRef JavaPackageRegexPattern("^package[\t ]+"); } // anonymous namespace >From ddca59c48fccc497b5b4df901a630606d94176a1 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Sat, 7 Feb 2026 15:33:32 -0800 Subject: [PATCH 07/21] fix formatting --- clang/lib/Format/Format.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index a4ae7bb797119..387711d6af712 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3740,8 +3740,8 @@ static void sortJavaImports(const FormatStyle &Style, namespace { -constexpr StringRef JavaImportRegexPattern( -"^import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"); +constexpr StringRef + JavaImportRegexPattern("^import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"); constexpr StringRef JavaPackageRegexPattern("^package[\t ]+"); >From 0d1ac13b1d764bfcb0cff9f645c27ee2e75119ef Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Sat, 7 Feb 2026 15:49:32 -0800 Subject: [PATCH 08/21] fix formatting --- clang/lib/Format/Format.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 387711d6af712..352e7c2723f1f 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3740,7 +3740,7 @@ static void sortJavaImports(const FormatStyle &Style, namespace { -constexpr StringRef +constexpr StringRef JavaImportRegexPattern("^import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"); constexpr StringRef JavaPackageRegexPattern("^package[\t ]+"); >From 5f93956bed006ab283b674d22395d6fe6e32cb0f Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Sat, 7 Feb 2026 16:04:58 -0800 Subject: [PATCH 09/21] move trimmed.empty() to top --- clang/lib/Format/Format.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 352e7c2723f1f..a71da41ed5938 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3766,15 +3766,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, StringRef Line = Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); - StringRef Trimmed = Line.trim(); - if (isClangFormatOff(Trimmed)) - FormattingOff = true; - else if (isClangFormatOn(Trimmed)) - FormattingOff = false; - - if (Trimmed.empty()) { - // Skip empty lines. - } else if (Trimmed.starts_with("//")) { + StringRef Trimmed = Line.trim();`r`n if (Trimmed.empty()) {`r`n // Skip empty lines.`r`n } else if (isClangFormatOff(Trimmed)) {`r`n FormattingOff = true;`r`n } else if (isClangFormatOn(Trimmed)) {`r`n FormattingOff = false;`r`n } else if (Trimmed.starts_with("//")) { if (!ImportsInBlock.empty()) AssociatedCommentLines.push_back(Line); } else if (Trimmed.starts_with("/*")) { >From 8b4fbe9019be18989750d8a1d359f91c71ce7fb4 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Sat, 7 Feb 2026 16:05:00 -0800 Subject: [PATCH 10/21] fix newline --- clang/lib/Format/Format.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index a71da41ed5938..b9fa503d00c24 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3766,7 +3766,14 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, StringRef Line = Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); - StringRef Trimmed = Line.trim();`r`n if (Trimmed.empty()) {`r`n // Skip empty lines.`r`n } else if (isClangFormatOff(Trimmed)) {`r`n FormattingOff = true;`r`n } else if (isClangFormatOn(Trimmed)) {`r`n FormattingOff = false;`r`n } else if (Trimmed.starts_with("//")) { + StringRef Trimmed = Line.trim(); + if (Trimmed.empty()) { + // Skip empty lines. + } else if (isClangFormatOff(Trimmed)) { + FormattingOff = true; + } else if (isClangFormatOn(Trimmed)) { + FormattingOff = false; + } else if (Trimmed.starts_with("//")) { if (!ImportsInBlock.empty()) AssociatedCommentLines.push_back(Line); } else if (Trimmed.starts_with("/*")) { >From 5c3449e9780d8f41de71d3f9dbfad2549ac81b5a Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:18:32 -0800 Subject: [PATCH 11/21] keep original comment Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index b9fa503d00c24..ef5f2ef3455b7 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3774,7 +3774,8 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, } else if (isClangFormatOn(Trimmed)) { FormattingOff = false; } else if (Trimmed.starts_with("//")) { - if (!ImportsInBlock.empty()) + // Associating comments within the imports with the nearest import below. + if (HasImport) AssociatedCommentLines.push_back(Line); } else if (Trimmed.starts_with("/*")) { auto EndPos = Code.find("*/", SearchFrom + 2); >From cb0b54fda6da289fca5c2d33ad82cae702d3a09d Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:19:03 -0800 Subject: [PATCH 12/21] set HasImport Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ef5f2ef3455b7..cd4736fb8f8bc 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3800,6 +3800,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, IsStatic = true; ImportsInBlock.push_back( {Identifier, Line, Prev, AssociatedCommentLines, IsStatic}); + HasImport = true; AssociatedCommentLines.clear(); } else { break; >From 6474762cc073aa45146cfeb1bf78a0d4c7f9a7be Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:28:47 -0800 Subject: [PATCH 13/21] rm SearchFrom + HasImport decl Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index cd4736fb8f8bc..d770cf31e6a53 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3752,7 +3752,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, StringRef FileName, tooling::Replacements &Replaces) { unsigned Prev = 0; - unsigned SearchFrom = 0; + bool HasImport = false; llvm::Regex ImportRegex(JavaImportRegexPattern); llvm::Regex PackageRegex(JavaPackageRegexPattern); SmallVector<StringRef, 4> Matches; >From c98d19c83c9f6f31ef5930b97c974fda5a0b7082 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:29:11 -0800 Subject: [PATCH 14/21] Update clang/lib/Format/Format.cpp Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index d770cf31e6a53..f0edfc76d8265 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3810,7 +3810,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, break; SearchFrom = Pos + 1; } - if (!ImportsInBlock.empty()) + if (HasImport) sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces); return Replaces; } >From c5692e56491192d0d0df331bb97fdc73298428df Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:29:23 -0800 Subject: [PATCH 15/21] Update clang/lib/Format/Format.cpp Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f0edfc76d8265..ea61b7b0e3ac4 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3778,15 +3778,15 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, if (HasImport) AssociatedCommentLines.push_back(Line); } else if (Trimmed.starts_with("/*")) { - auto EndPos = Code.find("*/", SearchFrom + 2); - if (EndPos != StringRef::npos) { - Line = Code.substr(Prev, EndPos + 2 - Prev); - Pos = EndPos + 1; - } - if (!ImportsInBlock.empty()) + Pos = Code.find("*/", Pos + 2); + if (Pos != StringRef::npos) + Pos = Code.find('\n', Pos + 2); + if (HasImport) { + // Extend `Line` for a multiline comment to include all lines the + // comment spans. + Line = GetLine(); AssociatedCommentLines.push_back(Line); - } else if (PackageRegex.match(Trimmed)) { - // Skip package declarations. + } } else if (ImportRegex.match(Trimmed, &Matches)) { if (FormattingOff) { // If at least one import line has formatting turned off, turn off >From 483eb72f4e57a125bc1c14ef610e7e874107cdfd Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:29:35 -0800 Subject: [PATCH 16/21] Update clang/lib/Format/Format.cpp Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ea61b7b0e3ac4..16178b0d8dbda 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3767,8 +3767,8 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); StringRef Trimmed = Line.trim(); - if (Trimmed.empty()) { - // Skip empty lines. + if (Trimmed.empty() || PackageRegex.match(Trimmed)) { + // Skip empty line and package statement. } else if (isClangFormatOff(Trimmed)) { FormattingOff = true; } else if (isClangFormatOn(Trimmed)) { >From 22de9b38893050a78ac3ba1aaaee623ed02cbbb5 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:29:45 -0800 Subject: [PATCH 17/21] Update clang/lib/Format/Format.cpp Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 16178b0d8dbda..fbcf0421c94ce 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3803,6 +3803,8 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, HasImport = true; AssociatedCommentLines.clear(); } else { + // `Trimmed` is neither empty, nor a comment or a package/import + // statement. break; } Prev = Pos + 1; >From 6894468478f4c976ca0698abe67fe906371073cb Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:29:56 -0800 Subject: [PATCH 18/21] Update clang/unittests/Format/SortImportsTestJava.cpp Co-authored-by: owenca <[email protected]> --- clang/unittests/Format/SortImportsTestJava.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/clang/unittests/Format/SortImportsTestJava.cpp b/clang/unittests/Format/SortImportsTestJava.cpp index 1b2b0654cfdae..68838cd90961d 100644 --- a/clang/unittests/Format/SortImportsTestJava.cpp +++ b/clang/unittests/Format/SortImportsTestJava.cpp @@ -350,14 +350,11 @@ TEST_F(SortImportsTestJava, NoReplacementsForValidImportsWindows) { } TEST_F(SortImportsTestJava, DoNotSortImportsInBlockComment) { - EXPECT_EQ("/* import org.d;\n" - "import org.c;\n" - "import org.b; */\n" - "import org.a;", - sort("/* import org.d;\n" - "import org.c;\n" - "import org.b; */\n" - "import org.a;")); + constexpr StringRef Code("/* import org.d;\n" + "import org.c;\n" + "import org.b; */\n" + "import org.a;"); + EXPECT_EQ(Code, sort(Code)); } TEST_F(SortImportsTestJava, StopAtClassDeclaration) { >From 23f28e75d862698066ec44e50e0a454dfd9750d1 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:30:17 -0800 Subject: [PATCH 19/21] Update clang/lib/Format/Format.cpp Co-authored-by: owenca <[email protected]> --- clang/lib/Format/Format.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index fbcf0421c94ce..4ccf4f865e1eb 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3810,7 +3810,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, Prev = Pos + 1; if (Pos == StringRef::npos || Pos + 1 == Code.size()) break; - SearchFrom = Pos + 1; + Prev = Pos + 1; } if (HasImport) sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces); >From 8b6dca095837fa950d867b07cc2e8961307e1943 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:41:35 -0800 Subject: [PATCH 20/21] rm SearchFrom usage everywhere --- clang/lib/Format/Format.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 4ccf4f865e1eb..ed3a8e45c2c19 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3762,7 +3762,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, bool FormattingOff = false; for (;;) { - auto Pos = Code.find('\n', SearchFrom); + auto Pos = Code.find('\n', Prev); StringRef Line = Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); @@ -3778,13 +3778,14 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, if (HasImport) AssociatedCommentLines.push_back(Line); } else if (Trimmed.starts_with("/*")) { - Pos = Code.find("*/", Pos + 2); - if (Pos != StringRef::npos) - Pos = Code.find('\n', Pos + 2); + const auto EndPos = Code.find("*/", Prev + 2); + Pos = EndPos != StringRef::npos ? Code.find('\n', EndPos + 2) + : StringRef::npos; if (HasImport) { // Extend `Line` for a multiline comment to include all lines the // comment spans. - Line = GetLine(); + Line = + Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); AssociatedCommentLines.push_back(Line); } } else if (ImportRegex.match(Trimmed, &Matches)) { @@ -3807,7 +3808,6 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, // statement. break; } - Prev = Pos + 1; if (Pos == StringRef::npos || Pos + 1 == Code.size()) break; Prev = Pos + 1; >From 3ade17fbaae4929b78935fbf9357529393cdc628 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <[email protected]> Date: Mon, 9 Feb 2026 23:54:12 -0800 Subject: [PATCH 21/21] small refactor --- clang/lib/Format/Format.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ed3a8e45c2c19..51e880fb69169 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3759,12 +3759,13 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, SmallVector<JavaImportDirective, 16> ImportsInBlock; SmallVector<StringRef> AssociatedCommentLines; - bool FormattingOff = false; - - for (;;) { + for (bool FormattingOff = false;;) { auto Pos = Code.find('\n', Prev); - StringRef Line = - Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); + auto GetLine = [&] { + return Code.substr(Prev, + (Pos != StringRef::npos ? Pos : Code.size()) - Prev); + }; + StringRef Line = GetLine(); StringRef Trimmed = Line.trim(); if (Trimmed.empty() || PackageRegex.match(Trimmed)) { @@ -3784,8 +3785,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, if (HasImport) { // Extend `Line` for a multiline comment to include all lines the // comment spans. - Line = - Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); + Line = GetLine(); AssociatedCommentLines.push_back(Line); } } else if (ImportRegex.match(Trimmed, &Matches)) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
