diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 5b6727bf9e43..940fcc8ae2f1 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -886,6 +886,22 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() { return false; } +void UnwrappedLineParser::tryToParseJSFunction() { + nextToken(); + if (FormatTok->isNot(tok::l_paren)) + return; + nextToken(); + while (FormatTok->isNot(tok::l_brace)) { + // Err on the side of caution in order to avoid consuming the full file in + // case of incomplete code. + if (!FormatTok->isOneOf(tok::identifier, tok::comma, tok::r_paren, + tok::comment)) + return; + nextToken(); + } + parseChildBlock(); +} + bool UnwrappedLineParser::tryToParseBracedList() { if (FormatTok->BlockKind == BK_Unknown) calculateBraceTypes(); @@ -903,9 +919,11 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) { // FIXME: Once we have an expression parser in the UnwrappedLineParser, // replace this by using parseAssigmentExpression() inside. do { - // FIXME: When we start to support lambdas, we'll want to parse them away - // here, otherwise our bail-out scenarios below break. The better solution - // might be to just implement a more or less complete expression parser. + if (Style.Language == FormatStyle::LK_JavaScript && + FormatTok->TokenText == "function") { + tryToParseJSFunction(); + continue; + } switch (FormatTok->Tok.getKind()) { case tok::caret: nextToken(); diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 8f0c5a3ef41e..9eb560116295 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -100,6 +100,7 @@ private: void parseObjCProtocol(); bool tryToParseLambda(); bool tryToParseLambdaIntroducer(); + void tryToParseJSFunction(); void addUnwrappedLine(); bool eof() const; void nextToken(); diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index 606303a68a92..2dfd10faf1bd 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -101,6 +101,13 @@ TEST_F(FormatTestJS, GoogScopes) { TEST_F(FormatTestJS, Closures) { verifyFormat("doFoo(function() { return 1; });"); verifyFormat("var func = function() { return 1; };"); + verifyFormat("return {\n" + " body: {\n" + " setAttribute: function(key, val) { this[key] = val; },\n" + " getAttribute: function(key) { return this[key]; },\n" + " style: {direction: ''}\n" + " }\n" + "};"); } TEST_F(FormatTestJS, ReturnStatements) {