Author: djasper Date: Mon Feb 20 08:51:16 2017 New Revision: 295663 URL: http://llvm.org/viewvc/llvm-project?rev=295663&view=rev Log: clang-format: [JS] Improve line-wrapping behavior of template strings.
Specifically, similar to other blocks, clang-format now wraps both after "${" and before the corresponding "}", if the contained expression spans multiple lines. Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/FormatToken.h cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTestJS.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=295663&r1=295662&r2=295663&view=diff ============================================================================== --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Mon Feb 20 08:51:16 2017 @@ -383,6 +383,8 @@ void ContinuationIndenter::addTokenOnCur Current.FakeLParens.size() > 0 && Current.FakeLParens.back() > prec::Unknown) State.Stack.back().NoLineBreak = true; + if (Previous.is(TT_TemplateString) && Previous.opensScope()) + State.Stack.back().NoLineBreak = true; if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign && Previous.opensScope() && Previous.isNot(TT_ObjCMethodExpr) && @@ -398,7 +400,7 @@ void ContinuationIndenter::addTokenOnCur State.Stack.back().NoLineBreak = true; if (Current.isMemberAccess() && Previous.is(tok::r_paren) && (Previous.MatchingParen && - (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) { + (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) // If there is a function call with long parameters, break before trailing // calls. This prevents things like: // EXPECT_CALL(SomeLongParameter).Times( @@ -406,7 +408,6 @@ void ContinuationIndenter::addTokenOnCur // We don't want to do this for short parameters as they can just be // indexes. State.Stack.back().NoLineBreak = true; - } // Don't allow the RHS of an operator to be split over multiple lines unless // there is a line-break right after the operator. @@ -618,7 +619,9 @@ unsigned ContinuationIndenter::addTokenO // If we break after { or the [ of an array initializer, we should also break // before the corresponding } or ]. if (PreviousNonComment && - (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare))) + (PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) || + (PreviousNonComment->is(TT_TemplateString) && + PreviousNonComment->opensScope()))) State.Stack.back().BreakBeforeClosingBrace = true; if (State.Stack.back().AvoidBinPacking) { @@ -666,6 +669,8 @@ unsigned ContinuationIndenter::getNewLin return State.Stack[State.Stack.size() - 2].LastSpace; return State.FirstIndent; } + if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope()) + return State.Stack[State.Stack.size() - 2].LastSpace; if (Current.is(tok::identifier) && Current.Next && Current.Next->is(TT_DictLiteral)) return State.Stack.back().Indent; @@ -840,6 +845,11 @@ unsigned ContinuationIndenter::moveState moveStatePastFakeLParens(State, Newline); moveStatePastScopeCloser(State); + if (Current.is(TT_TemplateString) && Current.opensScope()) + State.Stack.back().LastSpace = + (Current.IsMultiline ? Current.LastLineColumnWidth + : State.Column + Current.ColumnWidth) - + strlen("${"); moveStatePastScopeOpener(State, Newline); moveStatePastFakeRParens(State); Modified: cfe/trunk/lib/Format/FormatToken.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=295663&r1=295662&r2=295663&view=diff ============================================================================== --- cfe/trunk/lib/Format/FormatToken.h (original) +++ cfe/trunk/lib/Format/FormatToken.h Mon Feb 20 08:51:16 2017 @@ -455,6 +455,8 @@ struct FormatToken { /// \brief Returns \c true if this tokens starts a block-type list, i.e. a /// list that should be indented with a block indent. bool opensBlockOrBlockTypeList(const FormatStyle &Style) const { + if (is(TT_TemplateString) && opensScope()) + return true; return is(TT_ArrayInitializerLSquare) || (is(tok::l_brace) && (BlockKind == BK_Block || is(TT_DictLiteral) || @@ -463,6 +465,8 @@ struct FormatToken { /// \brief Same as opensBlockOrBlockTypeList, but for the closing token. bool closesBlockOrBlockTypeList(const FormatStyle &Style) const { + if (is(TT_TemplateString) && closesScope()) + return true; return MatchingParen && MatchingParen->opensBlockOrBlockTypeList(Style); } Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=295663&r1=295662&r2=295663&view=diff ============================================================================== --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Mon Feb 20 08:51:16 2017 @@ -2536,9 +2536,12 @@ bool TokenAnnotator::canBreakBefore(cons // https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#A.10 return false; if (Left.isOneOf(Keywords.kw_module, tok::kw_namespace) && - Right.isOneOf(tok::identifier, tok::string_literal)) { + Right.isOneOf(tok::identifier, tok::string_literal)) return false; // must not break in "module foo { ...}" - } + if (Right.is(TT_TemplateString) && Right.closesScope()) + return false; + if (Left.is(TT_TemplateString) && Left.opensScope()) + return true; } if (Left.is(tok::at)) Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=295663&r1=295662&r2=295663&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTestJS.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestJS.cpp Mon Feb 20 08:51:16 2017 @@ -1421,62 +1421,46 @@ TEST_F(FormatTestJS, TemplateStrings) { " aaaaaaaaaaaaa:${ aaaaaaa. aaaaa} aaaaaaaa`;"); verifyFormat("var x = someFunction(`${})`) //\n" " .oooooooooooooooooon();"); - verifyFormat("var x = someFunction(`${aaaa}${aaaaa( //\n" - " aaaaa)})`);"); + verifyFormat("var x = someFunction(`${aaaa}${\n" + " aaaaa( //\n" + " aaaaa)\n" + " })`);"); } TEST_F(FormatTestJS, TemplateStringMultiLineExpression) { - verifyFormat("var f = `aaaaaaaaaaaaaaaaaa: ${aaaaa + //\n" - " bbbb}`;", - "var f = `aaaaaaaaaaaaaaaaaa: ${aaaaa + //\n" - " bbbb}`;"); - verifyFormat("var f = `aaaaaaaaaaaaaaaaaa: ${ //\n" - " aaaaa + //\n" - " bbbb}`;", - "var f = `aaaaaaaaaaaaaaaaaa: ${ //\n" + verifyFormat("var f = `aaaaaaaaaaaaaaaaaa: ${\n" " aaaaa + //\n" + " bbbb\n" + " }`;", + "var f = `aaaaaaaaaaaaaaaaaa: ${aaaaa + //\n" " bbbb}`;"); verifyFormat("var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${aaaaa + //\n" - " bbbb}`;", + " aaaaaaaaaaaaaaaaaa: ${\n" + " aaaaa + //\n" + " bbbb\n" + " }`;", "var f = `\n" " aaaaaaaaaaaaaaaaaa: ${ aaaaa + //\n" " bbbb }`;"); verifyFormat("var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${ //\n" - " aaaaa + //\n" - " bbbb}`;", - "var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${ //\n" - " aaaaa + //\n" - " bbbb}` ;"); - verifyFormat("var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${someFunction(\n" - " aaaaa + //\n" - " bbbb)}`;", - "var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${ someFunction (\n" - " aaaaa + //\n" - " bbbb)}`;"); - verifyFormat("var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${ //\n" + " aaaaaaaaaaaaaaaaaa: ${\n" " someFunction(\n" " aaaaa + //\n" - " bbbb)}`;", + " bbbb)\n" + " }`;", "var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${ //\n" - " someFunction (\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction (\n" " aaaaa + //\n" " bbbb)}`;"); + + // It might be preferable to wrap before "someFunction". verifyFormat("var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${ //\n" - " someFunction({\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction({\n" " aaaa: aaaaa,\n" " bbbb: bbbbb,\n" " })}`;", "var f = `\n" - " aaaaaaaaaaaaaaaaaa: ${ //\n" - " someFunction ({\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction ({\n" " aaaa: aaaaa,\n" " bbbb: bbbbb,\n" " })}`;"); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits