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 1/2] [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 2/2] 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

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to