diff options
| author | Martin Probst <martin@probst.io> | 2017-02-07 16:33:13 +0000 |
|---|---|---|
| committer | Martin Probst <martin@probst.io> | 2017-02-07 16:33:13 +0000 |
| commit | 8e3eba037359409054c047c80b32e98ed150e55b (patch) | |
| tree | d0b507d06efc6a0d2a8edf2f347291b044f93182 | |
| parent | f86708dbf57eba32d46a32b4d5e23ec6649d4a72 (diff) | |
| download | bcm5719-llvm-8e3eba037359409054c047c80b32e98ed150e55b.tar.gz bcm5719-llvm-8e3eba037359409054c047c80b32e98ed150e55b.zip | |
clang-format: [JS] correcly format object literal methods.
Summary:
In JavaScript, object literals can contain methods:
var x = {
a() { return 1; },
};
Previously, clang-format always parsed nested {} inside a braced list as
further braced lists. Special case this logic for JavaScript to try
parsing as a braced list, but fall back to parsing as a child block.
Reviewers: djasper
Subscribers: klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D29656
llvm-svn: 294315
| -rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 25 | ||||
| -rw-r--r-- | clang/unittests/Format/FormatTestJS.cpp | 12 |
3 files changed, 30 insertions, 8 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index bfb74f0b962..940b5cc57e5 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2648,6 +2648,7 @@ void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { << " T=" << getTokenTypeName(Tok->Type) << " S=" << Tok->SpacesRequiredBefore << " B=" << Tok->BlockParameterCount + << " BK=" << Tok->BlockKind << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName() << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind << " FakeLParens="; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 5ffada8ae7c..5b6d0b73e40 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -335,8 +335,11 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { case tok::l_brace: if (Style.Language == FormatStyle::LK_JavaScript && PrevTok && PrevTok->is(tok::colon)) - // In TypeScript's TypeMemberLists, there can be semicolons between the - // individual members. + // A colon indicates this code is in a type, or a braced list following + // a label in an object literal ({a: {b: 1}}). + // The code below could be confused by semicolons between the individual + // members in a type member list, which would normally trigger BK_Block. + // In both cases, this must be parsed as an inline braced init. Tok->BlockKind = BK_BracedInit; else Tok->BlockKind = BK_Unknown; @@ -1298,6 +1301,12 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) { continue; } } + if (FormatTok->is(tok::l_brace)) { + // Could be a method inside of a braced list `{a() { return 1; }}`. + if (tryToParseBracedList()) + continue; + parseChildBlock(); + } } switch (FormatTok->Tok.getKind()) { case tok::caret: @@ -1309,12 +1318,6 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) { case tok::l_square: tryToParseLambda(); break; - case tok::l_brace: - // Assume there are no blocks inside a braced init list apart - // from the ones we explicitly parse out (like lambdas). - FormatTok->BlockKind = BK_BracedInit; - parseBracedList(); - break; case tok::l_paren: parseParens(); // JavaScript can just have free standing methods and getters/setters in @@ -1325,6 +1328,12 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) { break; } break; + case tok::l_brace: + // Assume there are no blocks inside a braced init list apart + // from the ones we explicitly parse out (like lambdas). + FormatTok->BlockKind = BK_BracedInit; + parseBracedList(); + break; case tok::r_brace: nextToken(); return !HasError; diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index 61acce3a977..4038e512590 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -240,6 +240,18 @@ TEST_F(FormatTestJS, ContainerLiterals) { "};"); verifyFormat("var x = {y: (a) => a};"); + // Methods in object literals. + verifyFormat("var x = {\n" + " y(a: string): number {\n" + " return a;\n" + " }\n" + "};"); + verifyFormat("var x = {\n" + " y(a: string) {\n" + " return a;\n" + " }\n" + "};"); + // Computed keys. verifyFormat("var x = {[a]: 1, b: 2, [c]: 3};"); verifyFormat("var x = {\n" |

