[clang] [clang-format] Enable sorting includes although formatting disabled (PR #113771)

Martin Lambertsen via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 29 11:22:43 PDT 2024


https://github.com/marlamb updated https://github.com/llvm/llvm-project/pull/113771

>From 965392797976b860d3ad62ad1be8acc7fc8fde3b Mon Sep 17 00:00:00 2001
From: Martin Lambertsen <github at lambertsen.one>
Date: Sat, 26 Oct 2024 21:41:37 +0200
Subject: [PATCH] [clang-format] Enable sorting includes although formatting
 disabled

Projects exist, which do not want to use an automated formatting, but
could benefit from sorting the includes, especially to include the main
headers first in order to improve the self-consistency of headers.

While this was possible with `clang-format` for some time, it was
disabled with commit `61dc0f2b593da149a4c0cea67819cd7bdbdd50b8`. The
main reason was that it is confusing for users.

This commit enables sorting the includes more explicitly, to allow the
feature without confusing users.
---
 clang/include/clang/Format/Format.h |  9 +++++++++
 clang/lib/Format/Format.cpp         | 21 +++++++++++++++++++--
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index c9b72e65cb236d..3150161875cff8 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2656,6 +2656,14 @@ struct FormatStyle {
   /// \version 12
   EmptyLineBeforeAccessModifierStyle EmptyLineBeforeAccessModifier;
 
+  enum EnableSortIncludesOptions : int8_t {
+    ESI_IfFormatEnabled,
+    ESI_Always,
+    ESI_Never,
+  };
+
+  EnableSortIncludesOptions EnableSortIncludes;
+
   /// If ``true``, clang-format detects whether function calls and
   /// definitions are formatted with one parameter per line.
   ///
@@ -5203,6 +5211,7 @@ struct FormatStyle {
            DisableFormat == R.DisableFormat &&
            EmptyLineAfterAccessModifier == R.EmptyLineAfterAccessModifier &&
            EmptyLineBeforeAccessModifier == R.EmptyLineBeforeAccessModifier &&
+           EnableSortIncludes == R.EnableSortIncludes &&
            ExperimentalAutoDetectBinPacking ==
                R.ExperimentalAutoDetectBinPacking &&
            FixNamespaceComments == R.FixNamespaceComments &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 0cf4cdbeab31f3..f675d108e52df4 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -361,6 +361,16 @@ struct ScalarEnumerationTraits<
   }
 };
 
+template <>
+struct ScalarEnumerationTraits<FormatStyle::EnableSortIncludesOptions> {
+  static void enumeration(IO &IO,
+                          FormatStyle::EnableSortIncludesOptions &Value) {
+    IO.enumCase(Value, "Always", FormatStyle::ESI_Always);
+    IO.enumCase(Value, "IfFormatEnabled", FormatStyle::ESI_IfFormatEnabled);
+    IO.enumCase(Value, "Never", FormatStyle::ESI_Never);
+  }
+};
+
 template <>
 struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> {
   static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) {
@@ -1024,6 +1034,7 @@ template <> struct MappingTraits<FormatStyle> {
                    Style.EmptyLineAfterAccessModifier);
     IO.mapOptional("EmptyLineBeforeAccessModifier",
                    Style.EmptyLineBeforeAccessModifier);
+    IO.mapOptional("EnableSortIncludes", Style.EnableSortIncludes);
     IO.mapOptional("ExperimentalAutoDetectBinPacking",
                    Style.ExperimentalAutoDetectBinPacking);
     IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
@@ -1531,6 +1542,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   LLVMStyle.DisableFormat = false;
   LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
   LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
+  LLVMStyle.EnableSortIncludes = FormatStyle::ESI_Always;
   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
   LLVMStyle.FixNamespaceComments = true;
   LLVMStyle.ForEachMacros.push_back("foreach");
@@ -1837,6 +1849,7 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
         FormatStyle::SIS_WithoutElse;
     ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
     ChromiumStyle.ContinuationIndentWidth = 8;
+    ChromiumStyle.EnableSortIncludes = FormatStyle::ESI_Always;
     ChromiumStyle.IndentWidth = 4;
     // See styleguide for import groups:
     // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order
@@ -1980,7 +1993,7 @@ FormatStyle getClangFormatStyle() {
 FormatStyle getNoStyle() {
   FormatStyle NoStyle = getLLVMStyle();
   NoStyle.DisableFormat = true;
-  NoStyle.SortIncludes = FormatStyle::SI_Never;
+  NoStyle.EnableSortIncludes = FormatStyle::ESI_Never;
   NoStyle.SortUsingDeclarations = FormatStyle::SUD_Never;
   return NoStyle;
 }
@@ -3494,8 +3507,12 @@ tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
                                    ArrayRef<tooling::Range> Ranges,
                                    StringRef FileName, unsigned *Cursor) {
   tooling::Replacements Replaces;
-  if (!Style.SortIncludes || Style.DisableFormat)
+  if (Style.SortIncludes == FormatStyle::SI_Never ||
+      Style.EnableSortIncludes == FormatStyle::ESI_Never ||
+      (Style.DisableFormat &&
+       Style.EnableSortIncludes == FormatStyle::ESI_IfFormatEnabled)) {
     return Replaces;
+  }
   if (isLikelyXml(Code))
     return Replaces;
   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript &&



More information about the cfe-commits mailing list