@@ -278,6 +278,14 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
278
278
// double z);
279
279
// In the above example, we need to take special care to ensure that
280
280
// '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";
281
289
// Special handling is required for 'nested' ternary operators.
282
290
SmallVector<unsigned , 16 > ScopeStack;
283
291
@@ -298,16 +306,20 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
298
306
ScopeStack.push_back (i);
299
307
300
308
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;
301
313
302
- if (Changes[i].NewlinesBefore > 0 && !InsideNestedScope ) {
314
+ if (Changes[i].NewlinesBefore > 0 && !SkipMatchCheck ) {
303
315
Shift = 0 ;
304
316
FoundMatchOnLine = false ;
305
317
}
306
318
307
319
// If this is the first matching token to be aligned, remember by how many
308
320
// spaces it has to be shifted, so the rest of the changes on the line are
309
321
// shifted by the same amount
310
- if (!FoundMatchOnLine && !InsideNestedScope && Matches (Changes[i])) {
322
+ if (!FoundMatchOnLine && !SkipMatchCheck && Matches (Changes[i])) {
311
323
FoundMatchOnLine = true ;
312
324
Shift = Column - Changes[i].StartOfTokenColumn ;
313
325
Changes[i].Spaces += Shift;
@@ -317,15 +329,41 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
317
329
// as mentioned in the ScopeStack comment.
318
330
if (InsideNestedScope && Changes[i].NewlinesBefore > 0 ) {
319
331
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 ())
326
361
Changes[i].Spaces += Shift;
327
362
}
328
363
364
+ if (ContinuedStringLiteral)
365
+ Changes[i].Spaces += Shift;
366
+
329
367
assert (Shift >= 0 );
330
368
Changes[i].StartOfTokenColumn += Shift;
331
369
if (i + 1 != Changes.size ())
@@ -434,7 +472,10 @@ static unsigned AlignTokens(
434
472
AlignCurrentSequence ();
435
473
436
474
// 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 ;
438
479
LineIsComment = true ;
439
480
}
440
481
0 commit comments