diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -939,6 +939,7 @@ GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; GoogleStyle.AlignOperands = false; GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; + GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All; 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 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3142,6 +3142,23 @@ // 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: + return (Left.NestingLevel == 0 && Line.Level == 0); + 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 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -458,9 +458,7 @@ // Arrow functions in object literals. verifyFormat("var x = {\n" - " y: (a) => {\n" - " return a;\n" - " }\n" + " y: (a) => { return a; },\n" "};"); verifyFormat("var x = {y: (a) => a};"); @@ -485,9 +483,7 @@ "};"); // Object literals can leave out labels. - verifyFormat("f({a}, () => {\n" - " g(); //\n" - "});"); + verifyFormat("f({a}, () => { g(); });"); // Keys can be quoted. verifyFormat("var x = {\n" @@ -1111,9 +1107,7 @@ } TEST_F(FormatTestJS, ArrowFunctions) { - verifyFormat("var x = (a) => {\n" - " return a;\n" - "};"); + verifyFormat("var x = (a) => { return a; };\n"); verifyFormat("var x = (a) => {\n" " function y() {\n" " return 42;\n" @@ -1121,6 +1115,7 @@ " return a;\n" "};"); verifyFormat("var x = (a: type): {some: type} => {\n" + " y;\n" " return a;\n" "};"); verifyFormat("var x = (a) => a;"); @@ -1147,10 +1142,36 @@ " // 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); + Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None; + verifyFormat("const arr = () => {\n" + " x;\n" + "};", + Style); + Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty; + verifyFormat("const arr = () => {\n" + " x;\n" + "};", + Style); + verifyFormat("const arr = () => {};", + Style); + Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Inline; + verifyFormat("const arr = () => {\n" + " x;\n" + "};", + Style); + verifyFormat("foo(() => {});", + Style); +} + TEST_F(FormatTestJS, ReturnStatements) { verifyFormat("function() {\n" " return [hello, world];\n" @@ -1711,10 +1732,12 @@ TEST_F(FormatTestJS, RemoveEmptyLinesInArrowFunctions) { verifyFormat("x = () => {\n" " foo();\n" + " bar();\n" "};\n", "x = () => {\n" "\n" " foo();\n" + " bar();\n" "\n" "};\n"); }