clang-format: [JS] Indent expressions in ${} relative to their surrounding

This only affects expressions inside ${} scopes of template strings.
Here, we want to indent relative to the surrounding template string and
not the surrounding expression. Otherwise, this can create quite a mess.

Before:
  var f = `
    aaaaaaaaaaaaaaaaaa: ${someFunction(
      aaaaa +  //
      bbbb)}`;

After:
  var f = `
    aaaaaaaaaaaaaaaaaa: ${someFunction(
                              aaaaa +  //
                              bbbb)}`;

llvm-svn: 293636
This commit is contained in:
Daniel Jasper 2017-01-31 14:39:33 +00:00
parent 8813d5d221
commit 3f11941d8a
2 changed files with 70 additions and 2 deletions

View File

@ -985,12 +985,23 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
// int> v);
// FIXME: We likely want to do this for more combinations of brackets.
// Verify that it is wanted for ObjC, too.
if (Current.Tok.getKind() == tok::less &&
Current.ParentBracket == tok::l_paren) {
if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
NewIndent = std::max(NewIndent, State.Stack.back().Indent);
LastSpace = std::max(LastSpace, State.Stack.back().Indent);
}
// JavaScript template strings are special as we always want to indent
// nested expressions relative to the ${}. Otherwise, this can create quite
// a mess.
if (Current.is(TT_TemplateString)) {
unsigned Column = Current.IsMultiline
? Current.LastLineColumnWidth
: State.Column + Current.ColumnWidth;
NewIndent = Column;
LastSpace = Column;
NestedBlockIndent = Column;
}
AvoidBinPacking =
(State.Line->MustBeDeclaration && !Style.BinPackParameters) ||
(!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||

View File

@ -1401,6 +1401,63 @@ TEST_F(FormatTestJS, TemplateStrings) {
" aaaaaaaaaaaaa:${ aaaaaaa. aaaaa} aaaaaaaa`;");
}
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"
" aaaaa + //\n"
" bbbb}`;");
verifyFormat("var f = `\n"
" aaaaaaaaaaaaaaaaaa: ${aaaaa + //\n"
" bbbb}`;",
"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"
" someFunction(\n"
" aaaaa + //\n"
" bbbb)}`;",
"var f = `\n"
" aaaaaaaaaaaaaaaaaa: ${ //\n"
" someFunction (\n"
" aaaaa + //\n"
" bbbb)}`;");
verifyFormat("var f = `\n"
" aaaaaaaaaaaaaaaaaa: ${ //\n"
" someFunction({\n"
" aaaa: aaaaa,\n"
" bbbb: bbbbb,\n"
" })}`;",
"var f = `\n"
" aaaaaaaaaaaaaaaaaa: ${ //\n"
" someFunction ({\n"
" aaaa: aaaaa,\n"
" bbbb: bbbbb,\n"
" })}`;");
}
TEST_F(FormatTestJS, TemplateStringASI) {
verifyFormat("var x = `hello${world}`;", "var x = `hello${\n"
" world\n"