@@ -278,6 +278,14 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
278278 // double z);
279279 // In the above example, we need to take special care to ensure that
280280 // 'double z' is indented along with it's owning function 'b'.
281+ // The same holds for calling a function:
282+ // double a = foo(x);
283+ // int b = bar(foo(y),
284+ // foor(z));
285+ // Similar for broken string literals:
286+ // double x = 3.14;
287+ // auto s = "Hello"
288+ // "World";
281289 // Special handling is required for 'nested' ternary operators.
282290 SmallVector<unsigned , 16 > ScopeStack;
283291
@@ -298,16 +306,20 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
298306 ScopeStack.push_back (i);
299307
300308 bool InsideNestedScope = ScopeStack.size () != 0 ;
309+ bool ContinuedStringLiteral = i > Start &&
310+ Changes[i].Tok ->is (tok::string_literal) &&
311+ Changes[i - 1 ].Tok ->is (tok::string_literal);
312+ bool SkipMatchCheck = InsideNestedScope || ContinuedStringLiteral;
301313
302- if (Changes[i].NewlinesBefore > 0 && !InsideNestedScope ) {
314+ if (Changes[i].NewlinesBefore > 0 && !SkipMatchCheck ) {
303315 Shift = 0 ;
304316 FoundMatchOnLine = false ;
305317 }
306318
307319 // If this is the first matching token to be aligned, remember by how many
308320 // spaces it has to be shifted, so the rest of the changes on the line are
309321 // shifted by the same amount
310- if (!FoundMatchOnLine && !InsideNestedScope && Matches (Changes[i])) {
322+ if (!FoundMatchOnLine && !SkipMatchCheck && Matches (Changes[i])) {
311323 FoundMatchOnLine = true ;
312324 Shift = Column - Changes[i].StartOfTokenColumn ;
313325 Changes[i].Spaces += Shift;
@@ -317,15 +329,41 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
317329 // as mentioned in the ScopeStack comment.
318330 if (InsideNestedScope && Changes[i].NewlinesBefore > 0 ) {
319331 unsigned ScopeStart = ScopeStack.back ();
320- if (Changes[ScopeStart - 1 ].Tok ->is (TT_FunctionDeclarationName) ||
321- (ScopeStart > Start + 1 &&
322- Changes[ScopeStart - 2 ].Tok ->is (TT_FunctionDeclarationName)) ||
323- Changes[i].Tok ->is (TT_ConditionalExpr) ||
324- (Changes[i].Tok ->Previous &&
325- Changes[i].Tok ->Previous ->is (TT_ConditionalExpr)))
332+ auto ShouldShiftBeAdded = [&] {
333+ // Function declaration
334+ if (Changes[ScopeStart - 1 ].Tok ->is (TT_FunctionDeclarationName))
335+ return true ;
336+
337+ // Continued function declaration
338+ if (ScopeStart > Start + 1 &&
339+ Changes[ScopeStart - 2 ].Tok ->is (TT_FunctionDeclarationName))
340+ return true ;
341+
342+ // Continued function call
343+ if (ScopeStart > Start + 1 &&
344+ Changes[ScopeStart - 2 ].Tok ->is (tok::identifier) &&
345+ Changes[ScopeStart - 1 ].Tok ->is (tok::l_paren))
346+ return true ;
347+
348+ // Ternary operator
349+ if (Changes[i].Tok ->is (TT_ConditionalExpr))
350+ return true ;
351+
352+ // Continued ternary operator
353+ if (Changes[i].Tok ->Previous &&
354+ Changes[i].Tok ->Previous ->is (TT_ConditionalExpr))
355+ return true ;
356+
357+ return false ;
358+ };
359+
360+ if (ShouldShiftBeAdded ())
326361 Changes[i].Spaces += Shift;
327362 }
328363
364+ if (ContinuedStringLiteral)
365+ Changes[i].Spaces += Shift;
366+
329367 assert (Shift >= 0 );
330368 Changes[i].StartOfTokenColumn += Shift;
331369 if (i + 1 != Changes.size ())
@@ -434,7 +472,10 @@ static unsigned AlignTokens(
434472 AlignCurrentSequence ();
435473
436474 // A new line starts, re-initialize line status tracking bools.
437- FoundMatchOnLine = false ;
475+ // Keep the match state if a string literal is continued on this line.
476+ if (i == 0 || !Changes[i].Tok ->is (tok::string_literal) ||
477+ !Changes[i - 1 ].Tok ->is (tok::string_literal))
478+ FoundMatchOnLine = false ;
438479 LineIsComment = true ;
439480 }
440481
0 commit comments