From: Martin Probst Date: Tue, 7 Feb 2017 14:05:30 +0000 (+0000) Subject: clang-format: [JS] handle parenthesized class expressions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae1b99494b1c2c8de6b6333a168bcb16022ed559;p=clang clang-format: [JS] handle parenthesized class expressions. Summary: In JavaScript, classes are expressions, so they can appear e.g. in argument lists. var C = foo(class { bar() { return 1; } }; Reviewers: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D29635 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@294302 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index 66da1feee9..5ffada8ae7 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -1381,6 +1381,12 @@ void UnwrappedLineParser::parseParens() { if (FormatTok->Tok.is(tok::l_brace)) parseBracedList(); break; + case tok::kw_class: + if (Style.Language == FormatStyle::LK_JavaScript) + parseRecord(/*ParseAsExpr=*/true); + else + nextToken(); + break; case tok::identifier: if (Style.Language == FormatStyle::LK_JavaScript && (FormatTok->is(Keywords.kw_function) || @@ -1819,7 +1825,7 @@ void UnwrappedLineParser::parseJavaEnumBody() { addUnwrappedLine(); } -void UnwrappedLineParser::parseRecord() { +void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { const FormatToken &InitialToken = *FormatTok; nextToken(); @@ -1863,11 +1869,15 @@ void UnwrappedLineParser::parseRecord() { } } if (FormatTok->Tok.is(tok::l_brace)) { - if (ShouldBreakBeforeBrace(Style, InitialToken)) - addUnwrappedLine(); + if (ParseAsExpr) { + parseChildBlock(); + } else { + if (ShouldBreakBeforeBrace(Style, InitialToken)) + addUnwrappedLine(); - parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true, - /*MunchSemi=*/false); + parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true, + /*MunchSemi=*/false); + } } // There is no addUnwrappedLine() here so that we fall through to parsing a // structural element afterwards. Thus, in "class A {} n, m;", diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index b03009511d..c34e5b9ec7 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -100,7 +100,10 @@ private: void parseAccessSpecifier(); bool parseEnum(); void parseJavaEnumBody(); - void parseRecord(); + // Parses a record (aka class) as a top level element. If ParseAsExpr is true, + // parses the record as a child block, i.e. if the class declaration is an + // expression. + void parseRecord(bool ParseAsExpr = false); void parseObjCProtocolList(); void parseObjCUntilAtEnd(); void parseObjCInterfaceOrImplementation(); @@ -162,7 +165,7 @@ private: const FormatStyle &Style; const AdditionalKeywords &Keywords; - + llvm::Regex CommentPragmasRegex; FormatTokenSource *Tokens; diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 70bccb9f49..b64d13ad50 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -1109,6 +1109,10 @@ TEST_F(FormatTestJS, ClassDeclarations) { verifyFormat("class C {\n static x(): string {\n return 'asd';\n }\n}"); verifyFormat("class C extends P implements I {}"); verifyFormat("class C extends p.P implements i.I {}"); + verifyFormat( + "x(class {\n" + " a(): A {}\n" + "});"); verifyFormat("class Test {\n" " aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaa):\n" " aaaaaaaaaaaaaaaaaaaaaa {}\n"