Skip to content

Commit 0e5eb9f

Browse files
Copilotbergmeister
andauthored
Handle multiple comments per line in indentation runs (#2249)
* Initial plan * Handle multiple comments per line in comment runs Co-authored-by: bergmeister <9250262+bergmeister@users.noreply.github.com> * Fix adjacent comment continuation indentation Co-authored-by: bergmeister <9250262+bergmeister@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bergmeister <9250262+bergmeister@users.noreply.github.com>
1 parent be6251d commit 0e5eb9f

2 files changed

Lines changed: 96 additions & 19 deletions

File tree

‎Rules/UseConsistentIndentation.cs‎

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,14 @@ private static int GetCommentRunIndentationOffset(
387387
int firstCommentIndex = tokenIndex;
388388
int currentLine = tokens[tokenIndex].Extent.StartLineNumber;
389389
int precedingIndex = tokenIndex - 1;
390+
while (precedingIndex >= 0 &&
391+
tokens[precedingIndex].Kind == TokenKind.Comment &&
392+
tokens[precedingIndex].Extent.StartLineNumber == currentLine)
393+
{
394+
firstCommentIndex = precedingIndex;
395+
precedingIndex--;
396+
}
397+
390398
while (precedingIndex >= 0 &&
391399
(tokens[precedingIndex].Kind == TokenKind.NewLine ||
392400
tokens[precedingIndex].Kind == TokenKind.LineContinuation))
@@ -395,37 +403,67 @@ private static int GetCommentRunIndentationOffset(
395403
if (precedingIndex < 0 ||
396404
tokens[precedingIndex].Kind != TokenKind.Comment ||
397405
HasCodeAfterCommentOnSameLine(tokens, precedingIndex) ||
398-
tokens[precedingIndex].Extent.EndLineNumber != currentLine - 1 ||
399-
(precedingIndex > 0 &&
400-
tokens[precedingIndex - 1].Kind != TokenKind.NewLine &&
401-
tokens[precedingIndex - 1].Kind != TokenKind.LineContinuation))
406+
tokens[precedingIndex].Extent.EndLineNumber != currentLine - 1)
402407
{
403408
break;
404409
}
405410

406-
firstCommentIndex = precedingIndex;
407-
currentLine = tokens[precedingIndex].Extent.StartLineNumber;
408-
precedingIndex--;
411+
int previousCommentLine = tokens[precedingIndex].Extent.StartLineNumber;
412+
int firstCommentOnPreviousLine = precedingIndex;
413+
int precedingCommentIndex = precedingIndex - 1;
414+
while (precedingCommentIndex >= 0 &&
415+
tokens[precedingCommentIndex].Kind == TokenKind.Comment &&
416+
tokens[precedingCommentIndex].Extent.StartLineNumber == previousCommentLine)
417+
{
418+
firstCommentOnPreviousLine = precedingCommentIndex;
419+
precedingCommentIndex--;
420+
}
421+
422+
if (precedingCommentIndex >= 0 &&
423+
tokens[precedingCommentIndex].Kind != TokenKind.NewLine &&
424+
tokens[precedingCommentIndex].Kind != TokenKind.LineContinuation)
425+
{
426+
break;
427+
}
428+
429+
firstCommentIndex = firstCommentOnPreviousLine;
430+
currentLine = previousCommentLine;
431+
precedingIndex = precedingCommentIndex;
409432
}
410433

411434
commentRunStartsAfterLineContinuation =
412435
firstCommentIndex > 0 &&
413436
tokens[firstCommentIndex - 1].Kind == TokenKind.LineContinuation;
414437
commentRunStartsAfterPipeline =
415438
PreviousLineEndedWithPipe(tokens, firstCommentIndex, tokens[firstCommentIndex]);
416-
int leastIndentedColumn = tokens[firstCommentIndex].Extent.StartColumnNumber;
417-
for (int nextCommentIndex = firstCommentIndex + 2;
418-
nextCommentIndex < tokens.Length &&
419-
(tokens[nextCommentIndex - 1].Kind == TokenKind.NewLine ||
420-
tokens[nextCommentIndex - 1].Kind == TokenKind.LineContinuation) &&
421-
tokens[nextCommentIndex].Kind == TokenKind.Comment &&
422-
!HasCodeAfterCommentOnSameLine(tokens, nextCommentIndex) &&
423-
tokens[nextCommentIndex].Extent.StartLineNumber == tokens[nextCommentIndex - 2].Extent.EndLineNumber + 1;
424-
nextCommentIndex += 2)
439+
int leastIndentedColumn = int.MaxValue;
440+
int nextCommentIndex = firstCommentIndex;
441+
while (nextCommentIndex < tokens.Length &&
442+
tokens[nextCommentIndex].Kind == TokenKind.Comment)
425443
{
426-
leastIndentedColumn = Math.Min(
427-
leastIndentedColumn,
428-
tokens[nextCommentIndex].Extent.StartColumnNumber);
444+
int currentCommentLine = tokens[nextCommentIndex].Extent.StartLineNumber;
445+
while (nextCommentIndex < tokens.Length &&
446+
tokens[nextCommentIndex].Kind == TokenKind.Comment &&
447+
tokens[nextCommentIndex].Extent.StartLineNumber == currentCommentLine)
448+
{
449+
leastIndentedColumn = Math.Min(
450+
leastIndentedColumn,
451+
tokens[nextCommentIndex].Extent.StartColumnNumber);
452+
nextCommentIndex++;
453+
}
454+
455+
if (nextCommentIndex + 1 >= tokens.Length ||
456+
(tokens[nextCommentIndex].Kind != TokenKind.NewLine &&
457+
tokens[nextCommentIndex].Kind != TokenKind.LineContinuation) ||
458+
tokens[nextCommentIndex + 1].Kind != TokenKind.Comment ||
459+
HasCodeAfterCommentOnSameLine(tokens, nextCommentIndex + 1) ||
460+
tokens[nextCommentIndex + 1].Extent.StartLineNumber !=
461+
tokens[nextCommentIndex - 1].Extent.EndLineNumber + 1)
462+
{
463+
break;
464+
}
465+
466+
nextCommentIndex++;
429467
}
430468

431469
return tokens[tokenIndex].Extent.StartColumnNumber -

‎Tests/Rules/UseConsistentIndentation.tests.ps1‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,19 @@ Write-Output `
268268
Should -Be $scriptDefinition
269269
}
270270

271+
It 'Should preserve indentation when a comment-only line contains multiple block comments' {
272+
$scriptDefinition = @'
273+
if ($a) {
274+
<# first #> <# second #>
275+
# nested
276+
}
277+
'@
278+
$settings.Rules.PSUseConsistentIndentation.PipelineIndentation = 'NoIndentation'
279+
280+
Invoke-Formatter -ScriptDefinition $scriptDefinition -Settings $settings |
281+
Should -Be $scriptDefinition
282+
}
283+
271284
It 'Should preserve continuation indentation before a block-comment-prefixed argument' {
272285
$scriptDefinition = @'
273286
Write-Output `
@@ -280,6 +293,32 @@ Write-Output `
280293
Should -Be $scriptDefinition
281294
}
282295

296+
It 'Should preserve continuation indentation after multiple inline block comments' {
297+
$scriptDefinition = @'
298+
Write-Output `
299+
<# first #> <# second #>
300+
-InputObject 'value'
301+
'@
302+
$settings.Rules.PSUseConsistentIndentation.PipelineIndentation = 'NoIndentation'
303+
304+
Invoke-Formatter -ScriptDefinition $scriptDefinition -Settings $settings |
305+
Should -Be $scriptDefinition
306+
}
307+
308+
It 'Should preserve indentation with many adjacent block comments' {
309+
$comments = (1..16 | ForEach-Object { "<# comment $_ #>" }) -join ' '
310+
$scriptDefinition = @(
311+
'if ($a) {'
312+
" $comments"
313+
' # nested'
314+
'}'
315+
) -join "`n"
316+
$settings.Rules.PSUseConsistentIndentation.PipelineIndentation = 'NoIndentation'
317+
318+
Invoke-Formatter -ScriptDefinition $scriptDefinition -Settings $settings |
319+
Should -Be $scriptDefinition
320+
}
321+
283322
It 'Should preserve indentation when the first comment is not the least-indented with <Kind> indentation' -TestCases @(
284323
@{ Kind = 'space'; Indentation = ' ' }
285324
@{ Kind = 'tab'; Indentation = "`t" }

0 commit comments

Comments
 (0)