r295663 - clang-format: [JS] Improve line-wrapping behavior of template strings.
Daniel Jasper via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 20 06:51:17 PST 2017
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"
" })}`;");
More information about the cfe-commits
mailing list