From: Daniel Jasper Date: Thu, 8 May 2014 09:25:39 +0000 (+0000) Subject: clang-format: [JS] support closures in container literals. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a16d0b2f6727377e6d36cd4ca146b630b421c6e5;p=clang clang-format: [JS] support closures in container literals. Before: return {body: {setAttribute: function(key, val) {this[key] = val; } , getAttribute : function(key) { return this[key]; } , style : { direction: '' } } } ; After: return { body: { setAttribute: function(key, val) { this[key] = val; }, getAttribute: function(key) { return this[key]; }, style: {direction: ''} } }; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208292 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 5b6727bf9e..940fcc8ae2 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/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/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index 8f0c5a3ef4..9eb5601162 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/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/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 606303a68a..2dfd10faf1 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/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) {