[clang] 02656f2 - clang-format: [JS] options for arrow functions.
Martin Probst via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 27 07:27:35 PST 2020
Author: Martin Probst
Date: 2020-01-27T16:27:25+01:00
New Revision: 02656f29abda4eedd22e3b2b30bf2f422983514e
URL: https://github.com/llvm/llvm-project/commit/02656f29abda4eedd22e3b2b30bf2f422983514e
DIFF: https://github.com/llvm/llvm-project/commit/02656f29abda4eedd22e3b2b30bf2f422983514e.diff
LOG: clang-format: [JS] options for arrow functions.
Summary:
clang-format currently always wraps the body of non-empty arrow
functions:
const x = () => {
z();
};
This change implements support for the `AllowShortLambdasOnASingleLine`
style options, controlling the indent style for arrow function bodies
that have one or fewer statements. SLS_All puts all on a single line,
SLS_Inline only arrow functions used in an inline position.
const x = () => { z(); };
Multi-statement arrow functions continue to be wrapped. Function
expressions (`a = function() {}`) and function/method declarations are
unaffected as well.
Reviewers: krasimir
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73335
Added:
Modified:
clang/lib/Format/Format.cpp
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTestJS.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index a962e32f66b0..bc9551756bee 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -939,6 +939,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
GoogleStyle.AlignOperands = false;
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ // TODO: still under discussion whether to switch to SLS_All.
+ GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
GoogleStyle.BreakBeforeTernaryOperators = false;
// taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 723dc5c7ba88..8f9a29ab2f29 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3144,6 +3144,26 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// JavaScript top-level enum key/value pairs are put on separate lines
// instead of bin-packing.
return true;
+ if (Right.is(tok::r_brace) && Left.is(tok::l_brace) && Left.Previous &&
+ Left.Previous->is(TT_JsFatArrow)) {
+ // JS arrow function (=> {...}).
+ switch (Style.AllowShortLambdasOnASingleLine) {
+ case FormatStyle::SLS_All:
+ return false;
+ case FormatStyle::SLS_None:
+ return true;
+ case FormatStyle::SLS_Empty:
+ return !Left.Children.empty();
+ case FormatStyle::SLS_Inline:
+ // allow one-lining inline (e.g. in function call args) and empty arrow
+ // functions.
+ return (Left.NestingLevel == 0 && Line.Level == 0) &&
+ !Left.Children.empty();
+ default:
+ break;
+ }
+ }
+
if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
!Left.Children.empty())
// Support AllowShortFunctionsOnASingleLine for JavaScript.
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index ef3c6361355a..3c104b7aadbe 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -459,8 +459,9 @@ TEST_F(FormatTestJS, ContainerLiterals) {
// Arrow functions in object literals.
verifyFormat("var x = {\n"
" y: (a) => {\n"
+ " x();\n"
" return a;\n"
- " }\n"
+ " },\n"
"};");
verifyFormat("var x = {y: (a) => a};");
@@ -486,7 +487,8 @@ TEST_F(FormatTestJS, ContainerLiterals) {
// Object literals can leave out labels.
verifyFormat("f({a}, () => {\n"
- " g(); //\n"
+ " x;\n"
+ " g();\n"
"});");
// Keys can be quoted.
@@ -1112,8 +1114,9 @@ TEST_F(FormatTestJS, MultipleFunctionLiterals) {
TEST_F(FormatTestJS, ArrowFunctions) {
verifyFormat("var x = (a) => {\n"
+ " x;\n"
" return a;\n"
- "};");
+ "};\n");
verifyFormat("var x = (a) => {\n"
" function y() {\n"
" return 42;\n"
@@ -1121,6 +1124,7 @@ TEST_F(FormatTestJS, ArrowFunctions) {
" return a;\n"
"};");
verifyFormat("var x = (a: type): {some: type} => {\n"
+ " y;\n"
" return a;\n"
"};");
verifyFormat("var x = (a) => a;");
@@ -1147,10 +1151,41 @@ TEST_F(FormatTestJS, ArrowFunctions) {
" // break\n"
" );");
verifyFormat("const f = (x: string|null): string|null => {\n"
+ " y;\n"
" return x;\n"
"}\n");
}
+TEST_F(FormatTestJS, ArrowFunctionStyle) {
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
+ Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
+ verifyFormat("const arr = () => { x; };", Style);
+ verifyFormat("const arrInlineAll = () => {};", Style);
+ Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None;
+ verifyFormat("const arr = () => {\n"
+ " x;\n"
+ "};",
+ Style);
+ verifyFormat("const arrInlineNone = () => {\n"
+ "};",
+ Style);
+ Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
+ verifyFormat("const arr = () => {\n"
+ " x;\n"
+ "};",
+ Style);
+ verifyFormat("const arrInlineEmpty = () => {};",
+ Style);
+ Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Inline;
+ verifyFormat("const arr = () => {\n"
+ " x;\n"
+ "};",
+ Style);
+ verifyFormat("foo(() => {});",
+ Style);
+ verifyFormat("const arrInlineInline = () => {};", Style);
+}
+
TEST_F(FormatTestJS, ReturnStatements) {
verifyFormat("function() {\n"
" return [hello, world];\n"
@@ -1711,10 +1746,12 @@ TEST_F(FormatTestJS, TypeInterfaceLineWrapping) {
TEST_F(FormatTestJS, RemoveEmptyLinesInArrowFunctions) {
verifyFormat("x = () => {\n"
" foo();\n"
+ " bar();\n"
"};\n",
"x = () => {\n"
"\n"
" foo();\n"
+ " bar();\n"
"\n"
"};\n");
}
@@ -1791,6 +1828,10 @@ TEST_F(FormatTestJS, Modules) {
"];");
verifyFormat("export default [];");
verifyFormat("export default () => {};");
+ verifyFormat("export default () => {\n"
+ " x;\n"
+ " x;\n"
+ "};");
verifyFormat("export interface Foo {\n"
" foo: number;\n"
"}\n"
More information about the cfe-commits
mailing list