Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -3952,6 +3952,12 @@
var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3];
f({a : 1, b : 2, c : 3}); f({a: 1, b: 2, c: 3});
+**SpacesInJavaScriptUnion** (``Boolean``) :versionbadge:`clang-format 14`
+ .. code-block:: c++
+
+ true: false:
+ let x: A | B; vs. let x: A|B;
+
**SpacesInLineCommentPrefix** (``SpacesInLineComment``) :versionbadge:`clang-format 14`
How many spaces are allowed at the start of a line comment. To disable the
maximum set it to ``-1``, apart from that the maximum takes precedence
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -323,6 +323,9 @@
- Option ``AfterOverloadedOperator`` has been added in ``SpaceBeforeParensOptions``
to allow space between overloaded operator and opening parentheses.
+- Option ``SpacesInJavaScriptUnion`` has been added to allow spaces around
+ JavaScript union and intersection type operators.
+
libclang
--------
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3614,6 +3614,15 @@
/// \version 14
SpacesInLineComment SpacesInLineCommentPrefix;
+ // If ``true``, spaces will be inserted before and after the ``|`` of
+ // a JavaScript/TypeScript union.
+ /// \code
+ /// true: false:
+ /// let x: A | B; vs. let x: A|B;
+ /// \endcode
+ /// \version 14
+ bool SpacesInJavaScriptUnion;
+
/// If ``true``, spaces will be inserted after ``(`` and before ``)``.
/// \code
/// true: false:
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -818,6 +818,7 @@
Style.SpacesInCStyleCastParentheses);
IO.mapOptional("SpacesInLineCommentPrefix",
Style.SpacesInLineCommentPrefix);
+ IO.mapOptional("SpacesInJavaScriptUnion", Style.SpacesInJavaScriptUnion);
IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
IO.mapOptional("SpaceBeforeSquareBrackets",
@@ -1221,6 +1222,7 @@
LLVMStyle.SpacesInContainerLiterals = true;
LLVMStyle.SpacesInCStyleCastParentheses = false;
LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
+ LLVMStyle.SpacesInJavaScriptUnion = false;
LLVMStyle.SpaceAfterCStyleCast = false;
LLVMStyle.SpaceAfterLogicalNot = false;
LLVMStyle.SpaceAfterTemplateKeyword = true;
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3517,8 +3517,13 @@
return true;
if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
return false;
- if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator))
+ if (Left.is(TT_JsTypeOperator) || Right.is(TT_JsTypeOperator)) {
+ if ((Left.is(TT_JsTypeOperator) && Right.isTypeOrIdentifier()) ||
+ (Left.isTypeOrIdentifier() || Left.is(TT_TemplateCloser)) &&
+ Right.is(TT_JsTypeOperator))
+ return Style.SpacesInJavaScriptUnion;
return false;
+ }
if ((Left.is(tok::l_brace) || Right.is(tok::r_brace)) &&
Line.First->isOneOf(Keywords.kw_import, tok::kw_export))
return false;
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -18789,6 +18789,7 @@
CHECK_PARSE_BOOL(SpaceInEmptyParentheses);
CHECK_PARSE_BOOL(SpacesInContainerLiterals);
CHECK_PARSE_BOOL(SpacesInCStyleCastParentheses);
+ CHECK_PARSE_BOOL(SpacesInJavaScriptUnion);
CHECK_PARSE_BOOL(SpaceAfterCStyleCast);
CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword);
CHECK_PARSE_BOOL(SpaceAfterLogicalNot);
Index: clang/unittests/Format/FormatTestJS.cpp
===================================================================
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1674,6 +1674,31 @@
verifyFormat("export type X = {\n"
" a: Foo|Bar;\n"
"};");
+
+ auto Style = getGoogleJSStyleWithColumns(60);
+ Style.SpacesInJavaScriptUnion = true;
+ verifyFormat("let x: A | B = A | B;", Style);
+ verifyFormat("let x?: A | B = A | B;", Style);
+ verifyFormat("let x: A & B | C = A & B;", Style);
+ verifyFormat("let x: Foo = new Foo();", Style);
+ verifyFormat("function(x: A | B): C & D {}", Style);
+ verifyFormat("function(x: A | B = A | B): C & D {}", Style);
+ verifyFormat("function x(path: number | string) {}", Style);
+ verifyFormat("function x(): string | number {}", Style);
+ verifyFormat("type Foo = Bar | Baz;", Style);
+ verifyFormat("type Foo = Bar | Baz;", Style);
+ verifyFormat("type Foo = (Bar | Baz);", Style);
+ verifyFormat("let x: Bar | Baz;", Style);
+ verifyFormat("let x: Bar | Baz;", Style);
+ verifyFormat("let x: (Foo | Bar)[];", Style);
+ verifyFormat("type X = {\n"
+ " a: Foo | Bar;\n"
+ "};",
+ Style);
+ verifyFormat("export type X = {\n"
+ " a: Foo | Bar;\n"
+ "};",
+ Style);
}
TEST_F(FormatTestJS, UnionIntersectionTypesInObjectType) {
@@ -1686,6 +1711,19 @@
" b: b|null,\n"
" }) {}\n"
"}");
+
+ auto Style = getGoogleJSStyleWithColumns(60);
+ Style.SpacesInJavaScriptUnion = true;
+ verifyFormat("let x: {x: number | null} = {x: number | null};", Style);
+ verifyFormat("let nested: {x: {y: number | null}};", Style);
+ verifyFormat("let mixed: {x: [number | null, {w: number}]};", Style);
+ verifyFormat("class X {\n"
+ " contructor(x: {\n"
+ " a: a | null,\n"
+ " b: b | null,\n"
+ " }) {}\n"
+ "}",
+ Style);
}
TEST_F(FormatTestJS, ClassDeclarations) {