[clang] 95b3947 - [clang-format] JSON formatting add new option for controlling newlines in json arrays
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 19 09:55:18 PDT 2022
Author: mydeveloperday
Date: 2022-09-19T17:54:39+01:00
New Revision: 95b39471110680f609cf56f5babf031a1c855d64
URL: https://github.com/llvm/llvm-project/commit/95b39471110680f609cf56f5babf031a1c855d64
DIFF: https://github.com/llvm/llvm-project/commit/95b39471110680f609cf56f5babf031a1c855d64.diff
LOG: [clang-format] JSON formatting add new option for controlling newlines in json arrays
Working in a mixed environment of both vscode/vim with a team configured prettier configuration, this can leave clang-format and prettier fighting each other over the formatting of arrays, both simple arrays of elements.
This review aims to add some "control knobs" to the Json formatting in clang-format to help align the two tools so they can be used interchangeably.
This will allow simply arrays `[1, 2, 3]` to remain on a single line but will break those arrays based on context within that array.
Happy to change the name of the option (this is the third name I tried)
Reviewed By: HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D133589
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTestJson.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 01ebbd72aae44..3be291578828d 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1698,6 +1698,23 @@ the configuration (without a prefix: ``Auto``).
@Mock
DataLoad loader;
+**BreakArrays** (``Boolean``) :versionbadge:`clang-format 16`
+ If ``true``, clang-format will always break after a Json array `[`
+ otherwise it will scan until the closing `]` to determine if it should add
+ newlines between elements (prettier compatible).
+
+ NOTE: This is currently only for formatting JSON.
+
+ .. code-block:: c++
+
+ true: false:
+ [ vs. [1, 2, 3, 4]
+ 1,
+ 2,
+ 3,
+ 4
+ ]
+
**BreakBeforeBinaryOperators** (``BinaryOperatorStyle``) :versionbadge:`clang-format 3.6`
The way to wrap binary operators.
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 818dbe0c89c78..c8b22f5ebde06 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -872,6 +872,23 @@ struct FormatStyle {
/// \version 3.7
bool BinPackParameters;
+ /// If ``true``, clang-format will always break after a Json array `[`
+ /// otherwise it will scan until the closing `]` to determine if it should add
+ /// newlines between elements (prettier compatible).
+ ///
+ /// NOTE: This is currently only for formatting JSON.
+ /// \code
+ /// true: false:
+ /// [ vs. [1, 2, 3, 4]
+ /// 1,
+ /// 2,
+ /// 3,
+ /// 4
+ /// ]
+ /// \endcode
+ /// \version 16
+ bool BreakArrays;
+
/// The style of wrapping parameters on the same line (bin-packed) or
/// on one line each.
enum BinPackStyle : int8_t {
@@ -3878,6 +3895,7 @@ struct FormatStyle {
AttributeMacros == R.AttributeMacros &&
BinPackArguments == R.BinPackArguments &&
BinPackParameters == R.BinPackParameters &&
+ BreakArrays == R.BreakArrays &&
BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 0327a7ccb22ea..58d5fc1f8c865 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -728,6 +728,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("BreakAfterJavaFieldAnnotations",
Style.BreakAfterJavaFieldAnnotations);
+ IO.mapOptional("BreakArrays", Style.BreakArrays);
IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
IO.mapOptional("ColumnLimit", Style.ColumnLimit);
IO.mapOptional("CommentPragmas", Style.CommentPragmas);
@@ -1249,6 +1250,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
LLVMStyle.ExperimentalAutoDetectBinPacking = false;
+ LLVMStyle.BreakArrays = true;
LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
LLVMStyle.FixNamespaceComments = true;
LLVMStyle.ForEachMacros.push_back("foreach");
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index e530120fa4454..21c2115e7b506 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4401,18 +4401,22 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// }
if (Left.is(TT_DictLiteral) && Left.is(tok::l_brace))
return true;
- // Always break after a JSON array opener.
- // [
- // ]
- if (Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&
- !Right.is(tok::r_square)) {
- return true;
+ // Always break after a JSON array opener based on BreakArrays.
+ if ((Left.is(TT_ArrayInitializerLSquare) && Left.is(tok::l_square) &&
+ Right.isNot(tok::r_square)) ||
+ Left.is(tok::comma)) {
+ if (Right.is(tok::l_brace))
+ return true;
+ // scan to the right if an we see an object or an array inside
+ // then break.
+ for (const auto *Tok = &Right; Tok; Tok = Tok->Next) {
+ if (Tok->isOneOf(tok::l_brace, tok::l_square))
+ return true;
+ if (Tok->isOneOf(tok::r_brace, tok::r_square))
+ break;
+ }
+ return Style.BreakArrays;
}
- // Always break after successive entries.
- // 1,
- // 2
- if (Left.is(tok::comma))
- return true;
}
// If the last token before a '}', ']', or ')' is a comma or a trailing
diff --git a/clang/unittests/Format/FormatTestJson.cpp b/clang/unittests/Format/FormatTestJson.cpp
index e213f6bcbe712..17fc3b77575c5 100644
--- a/clang/unittests/Format/FormatTestJson.cpp
+++ b/clang/unittests/Format/FormatTestJson.cpp
@@ -159,6 +159,27 @@ TEST_F(FormatTestJson, JsonArray) {
"]");
}
+TEST_F(FormatTestJson, JsonArrayOneLine) {
+ FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
+ Style.BreakArrays = false;
+ Style.SpacesInContainerLiterals = false;
+ verifyFormat("[]", Style);
+ verifyFormat("[1]", Style);
+ verifyFormat("[1, 2]", Style);
+ verifyFormat("[1, 2, 3]", Style);
+ verifyFormat("[1, 2, 3, 4]", Style);
+ verifyFormat("[1, 2, 3, 4, 5]", Style);
+
+ verifyFormat("[\n"
+ " 1,\n"
+ " 2,\n"
+ " {\n"
+ " A: 1\n"
+ " }\n"
+ "]",
+ Style);
+}
+
TEST_F(FormatTestJson, JsonNoStringSplit) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
Style.IndentWidth = 4;
More information about the cfe-commits
mailing list