[clang] 2e7add8 - [clang-format] Add a option for the position of Java static import
via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 18 10:12:42 PDT 2020
Author: mydeveloperday
Date: 2020-09-18T18:12:21+01:00
New Revision: 2e7add812eb7bdd90bd0f0fc3b633515edd55f27
URL: https://github.com/llvm/llvm-project/commit/2e7add812eb7bdd90bd0f0fc3b633515edd55f27
DIFF: https://github.com/llvm/llvm-project/commit/2e7add812eb7bdd90bd0f0fc3b633515edd55f27.diff
LOG: [clang-format] Add a option for the position of Java static import
Some Java style guides and IDEs group Java static imports after
non-static imports. This patch allows clang-format to control
the location of static imports.
Patch by: @bc-lee
Reviewed By: MyDeveloperDay, JakeMerdichAMD
Differential Revision: https://reviews.llvm.org/D87201
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/unittests/Format/FormatTest.cpp
clang/unittests/Format/SortImportsTestJava.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 20e829135b33..0c3ed9f4ab84 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1964,10 +1964,12 @@ the configuration (without a prefix: ``Auto``).
**JavaImportGroups** (``std::vector<std::string>``)
A vector of prefixes ordered by the desired groups for Java imports.
- Each group is separated by a newline. Static imports will also follow the
- same grouping convention above all non-static imports. One group's prefix
- can be a subset of another - the longest prefix is always matched. Within
- a group, the imports are ordered lexicographically.
+ One group's prefix can be a subset of another - the longest prefix is
+ always matched. Within a group, the imports are ordered lexicographically.
+ Static imports are grouped separately and follow the same group rules.
+ By default, static imports are placed before non-static imports,
+ but this behavior is changed by another option,
+ ``SortJavaStaticImport``.
In the .clang-format configuration file, this can be configured like
in the following yaml example. This will result in imports being
@@ -2393,6 +2395,33 @@ the configuration (without a prefix: ``Auto``).
#include "b.h" vs. #include "a.h"
#include "a.h" #include "b.h"
+**SortJavaStaticImport** (``SortJavaStaticImportOptions``)
+ When sorting Java imports, by default static imports are placed before
+ non-static imports. If ``JavaStaticImportAfterImport`` is ``After``,
+ static imports are placed after non-static imports.
+
+ Possible values:
+
+ * ``SJSIO_Before`` (in configuration: ``Before``)
+ Static imports are placed before non-static imports.
+
+ .. code-block:: java
+
+ import static org.example.function1;
+
+ import org.example.ClassA;
+
+ * ``SJSIO_After`` (in configuration: ``After``)
+ Static imports are placed after non-static imports.
+
+ .. code-block:: java
+
+ import org.example.ClassA;
+
+ import static org.example.function1;
+
+
+
**SortUsingDeclarations** (``bool``)
If ``true``, clang-format will sort using declarations.
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index c6c182b7bdce..2840a6846018 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1618,10 +1618,12 @@ struct FormatStyle {
/// A vector of prefixes ordered by the desired groups for Java imports.
///
- /// Each group is separated by a newline. Static imports will also follow the
- /// same grouping convention above all non-static imports. One group's prefix
- /// can be a subset of another - the longest prefix is always matched. Within
- /// a group, the imports are ordered lexicographically.
+ /// One group's prefix can be a subset of another - the longest prefix is
+ /// always matched. Within a group, the imports are ordered lexicographically.
+ /// Static imports are grouped separately and follow the same group rules.
+ /// By default, static imports are placed before non-static imports,
+ /// but this behavior is changed by another option,
+ /// ``SortJavaStaticImport``.
///
/// In the .clang-format configuration file, this can be configured like
/// in the following yaml example. This will result in imports being
@@ -2016,6 +2018,29 @@ struct FormatStyle {
/// \endcode
bool SortIncludes;
+ /// Position for Java Static imports.
+ enum SortJavaStaticImportOptions {
+ /// Static imports are placed before non-static imports.
+ /// \code{.java}
+ /// import static org.example.function1;
+ ///
+ /// import org.example.ClassA;
+ /// \endcode
+ SJSIO_Before,
+ /// Static imports are placed after non-static imports.
+ /// \code{.java}
+ /// import org.example.ClassA;
+ ///
+ /// import static org.example.function1;
+ /// \endcode
+ SJSIO_After,
+ };
+
+ /// When sorting Java imports, by default static imports are placed before
+ /// non-static imports. If ``JavaStaticImportAfterImport`` is ``After``,
+ /// static imports are placed after non-static imports.
+ SortJavaStaticImportOptions SortJavaStaticImport;
+
/// If ``true``, clang-format will sort using declarations.
///
/// The order of using declarations is defined as follows:
@@ -2435,6 +2460,7 @@ struct FormatStyle {
R.PenaltyBreakTemplateDeclaration &&
PointerAlignment == R.PointerAlignment &&
RawStringFormats == R.RawStringFormats &&
+ SortJavaStaticImport == R.SortJavaStaticImport &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
SpaceAfterLogicalNot == R.SpaceAfterLogicalNot &&
SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 5dda2bda06b5..03188b46099d 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -377,6 +377,15 @@ struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> {
}
};
+template <>
+struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
+ static void enumeration(IO &IO,
+ FormatStyle::SortJavaStaticImportOptions &Value) {
+ IO.enumCase(Value, "Before", FormatStyle::SJSIO_Before);
+ IO.enumCase(Value, "After", FormatStyle::SJSIO_After);
+ }
+};
+
template <> struct MappingTraits<FormatStyle> {
static void mapping(IO &IO, FormatStyle &Style) {
// When reading, read the language first, we need it for getPredefinedStyle.
@@ -574,6 +583,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("RawStringFormats", Style.RawStringFormats);
IO.mapOptional("ReflowComments", Style.ReflowComments);
IO.mapOptional("SortIncludes", Style.SortIncludes);
+ IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
@@ -947,6 +957,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.DisableFormat = false;
LLVMStyle.SortIncludes = true;
+ LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
LLVMStyle.SortUsingDeclarations = true;
LLVMStyle.StatementMacros.push_back("Q_UNUSED");
LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
@@ -2312,12 +2323,16 @@ static void sortJavaImports(const FormatStyle &Style,
JavaImportGroups.push_back(
findJavaImportGroup(Style, Imports[i].Identifier));
}
+ bool StaticImportAfterNormalImport =
+ Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
// Negating IsStatic to push static imports above non-static imports.
- return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI],
- Imports[LHSI].Identifier) <
- std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI],
- Imports[RHSI].Identifier);
+ return std::make_tuple(!Imports[LHSI].IsStatic ^
+ StaticImportAfterNormalImport,
+ JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
+ std::make_tuple(!Imports[RHSI].IsStatic ^
+ StaticImportAfterNormalImport,
+ JavaImportGroups[RHSI], Imports[RHSI].Identifier);
});
// Deduplicate imports.
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index eae7b24fae7c..eb72a01d3d27 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -14328,6 +14328,12 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("BitFieldColonSpacing: After", BitFieldColonSpacing,
FormatStyle::BFCS_After);
+ Style.SortJavaStaticImport = FormatStyle::SJSIO_Before;
+ CHECK_PARSE("SortJavaStaticImport: After", SortJavaStaticImport,
+ FormatStyle::SJSIO_After);
+ CHECK_PARSE("SortJavaStaticImport: Before", SortJavaStaticImport,
+ FormatStyle::SJSIO_Before);
+
// FIXME: This is required because parsing a configuration simply overwrites
// the first N elements of the list instead of resetting it.
Style.ForEachMacros.clear();
diff --git a/clang/unittests/Format/SortImportsTestJava.cpp b/clang/unittests/Format/SortImportsTestJava.cpp
index 12869eeb54ef..4a3e18abd453 100644
--- a/clang/unittests/Format/SortImportsTestJava.cpp
+++ b/clang/unittests/Format/SortImportsTestJava.cpp
@@ -250,6 +250,62 @@ TEST_F(SortImportsTestJava, FormatPariallyOnShouldNotReorder) {
"import org.c;\n"));
}
+TEST_F(SortImportsTestJava, SortJavaStaticImport) {
+ FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
+ EXPECT_EQ("import static com.test.a;\n"
+ "\n"
+ "import static org.a;\n"
+ "\n"
+ "import static com.a;\n"
+ "\n"
+ "import com.test.b;\n"
+ "\n"
+ "import org.b;\n"
+ "\n"
+ "import com.b;\n",
+ sort("import static com.test.a;\n"
+ "import static org.a;\n"
+ "import static com.a;\n"
+ "import com.test.b;\n"
+ "import org.b;\n"
+ "import com.b;\n"));
+
+ FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_After;
+ EXPECT_EQ("import com.test.b;\n"
+ "import com.test.c;\n"
+ "\n"
+ "import org.b;\n"
+ "\n"
+ "import com.b;\n"
+ "\n"
+ "import static com.test.a;\n"
+ "\n"
+ "import static org.a;\n"
+ "\n"
+ "import static com.a;\n",
+ sort("import static com.test.a;\n"
+ "import static org.a;\n"
+ "import static com.a;\n"
+ "import com.test.b;\n"
+ "import org.b;\n"
+ "import com.b;\n"
+ "import com.test.c;\n"));
+}
+
+TEST_F(SortImportsTestJava, SortJavaStaticImportAsGroup) {
+ FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_After;
+
+ EXPECT_EQ("import com.test.a;\n"
+ "import com.test.b;\n"
+ "\n"
+ "import static org.a;\n"
+ "import static org.b;\n",
+ sort("import com.test.a;\n"
+ "import static org.a;\n"
+ "import com.test.b;\n"
+ "import static org.b;\n"));
+}
+
TEST_F(SortImportsTestJava, DeduplicateImports) {
EXPECT_EQ("import org.a;\n", sort("import org.a;\n"
"import org.a;\n"));
More information about the cfe-commits
mailing list