Skip to content

Commit 7092b4c

Browse files
Copilotbergmeister
andauthored
Preserve comment-run indentation
Co-authored-by: bergmeister <9250262+bergmeister@users.noreply.github.com>
1 parent 6f2826a commit 7092b4c

2 files changed

Lines changed: 101 additions & 6 deletions

File tree

‎Rules/UseConsistentIndentation.cs‎

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,10 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
298298
}
299299

300300
bool lineHasPipelineBeforeToken = LineHasPipelineBeforeToken(tokens, tokenIndex, token);
301-
AddViolation(token, tempIndentationLevel, diagnosticRecords, ref onNewLine, lineHasPipelineBeforeToken);
301+
int commentIndentationOffset = token.Kind == TokenKind.Comment
302+
? GetCommentRunIndentationOffset(tokens, tokenIndex)
303+
: 0;
304+
AddViolation(token, tempIndentationLevel, diagnosticRecords, ref onNewLine, lineHasPipelineBeforeToken, commentIndentationOffset);
302305
}
303306
break;
304307
}
@@ -336,6 +339,30 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
336339
return diagnosticRecords;
337340
}
338341

342+
private static int GetCommentRunIndentationOffset(Token[] tokens, int tokenIndex)
343+
{
344+
int firstCommentIndex = tokenIndex;
345+
int currentLine = tokens[tokenIndex].Extent.StartLineNumber;
346+
int precedingIndex = tokenIndex - 1;
347+
while (precedingIndex >= 0 && tokens[precedingIndex].Kind == TokenKind.NewLine)
348+
{
349+
precedingIndex--;
350+
if (precedingIndex < 0 ||
351+
tokens[precedingIndex].Kind != TokenKind.Comment ||
352+
tokens[precedingIndex].Extent.EndLineNumber != currentLine - 1)
353+
{
354+
break;
355+
}
356+
357+
firstCommentIndex = precedingIndex;
358+
currentLine = tokens[precedingIndex].Extent.StartLineNumber;
359+
precedingIndex--;
360+
}
361+
362+
return tokens[tokenIndex].Extent.StartColumnNumber -
363+
tokens[firstCommentIndex].Extent.StartColumnNumber;
364+
}
365+
339366
/// <summary>
340367
/// Scans forward from the current opener to the end of the line.
341368
/// Returns true if there is at least one unclosed opener when
@@ -612,12 +639,14 @@ private void AddViolation(
612639
int expectedIndentationLevel,
613640
List<DiagnosticRecord> diagnosticRecords,
614641
ref bool onNewLine,
615-
bool lineHasPipelineBeforeToken = false)
642+
bool lineHasPipelineBeforeToken = false,
643+
int indentationOffset = 0)
616644
{
617645
if (onNewLine)
618646
{
619647
onNewLine = false;
620-
if (token.Extent.StartColumnNumber - 1 != GetIndentation(expectedIndentationLevel))
648+
int expectedIndentation = Math.Max(0, GetIndentation(expectedIndentationLevel) + indentationOffset);
649+
if (token.Extent.StartColumnNumber - 1 != expectedIndentation)
621650
{
622651
var fileName = token.Extent.File;
623652
var extent = token.Extent;
@@ -640,14 +669,14 @@ private void AddViolation(
640669
GetDiagnosticSeverity(),
641670
fileName,
642671
null,
643-
GetSuggestedCorrections(token, expectedIndentationLevel, lineHasPipelineBeforeToken)));
672+
GetSuggestedCorrections(token, expectedIndentation, lineHasPipelineBeforeToken)));
644673
}
645674
}
646675
}
647676

648677
private List<CorrectionExtent> GetSuggestedCorrections(
649678
Token token,
650-
int indentationLevel,
679+
int indentation,
651680
bool lineHasPipelineBeforeToken = false)
652681
{
653682
// TODO Add another constructor for correction extent that takes extent
@@ -661,7 +690,7 @@ private List<CorrectionExtent> GetSuggestedCorrections(
661690
token.Extent.EndLineNumber,
662691
1,
663692
token.Extent.EndColumnNumber,
664-
GetIndentationString(indentationLevel) + optionalPipeline + token.Extent.Text,
693+
new string(indentationChar, indentation) + optionalPipeline + token.Extent.Text,
665694
token.Extent.File));
666695
return corrections;
667696
}

‎Tests/Rules/UseConsistentIndentation.tests.ps1‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,72 @@ function foo {
206206

207207
Context "When a multi-line command is given" {
208208

209+
It 'Should preserve relative indentation in commented-out code with <Kind> indentation' -TestCases @(
210+
@{ Kind = 'space'; Indentation = ' ' }
211+
@{ Kind = 'tab'; Indentation = "`t" }
212+
) {
213+
param([string] $Kind, [string] $Indentation)
214+
$scriptDefinition = @(
215+
'if ($a) {'
216+
"$Indentation# if (`$b) {"
217+
"$Indentation$Indentation# doThing"
218+
"$Indentation# }"
219+
"$($Indentation)Write-Output 'after'"
220+
'}'
221+
) -join "`n"
222+
$settings = @{
223+
IncludeRules = @('PSUseConsistentIndentation')
224+
Rules = @{
225+
PSUseConsistentIndentation = @{
226+
Enable = $true
227+
IndentationSize = 4
228+
PipelineIndentation = 'NoIndentation'
229+
Kind = $Kind
230+
}
231+
}
232+
}
233+
234+
Invoke-Formatter -ScriptDefinition $scriptDefinition -Settings $settings |
235+
Should -Be $scriptDefinition
236+
}
237+
238+
It 'Should shift a commented-out code block without flattening it with <Kind> indentation' -TestCases @(
239+
@{ Kind = 'space'; Indentation = ' ' }
240+
@{ Kind = 'tab'; Indentation = "`t" }
241+
) {
242+
param([string] $Kind, [string] $Indentation)
243+
$scriptDefinition = @(
244+
'if ($a) {'
245+
'# if ($b) {'
246+
"$Indentation# doThing"
247+
'# }'
248+
"$($Indentation)Write-Output 'after'"
249+
'}'
250+
) -join "`n"
251+
$expectedScriptDefinition = @(
252+
'if ($a) {'
253+
"$Indentation# if (`$b) {"
254+
"$Indentation$Indentation# doThing"
255+
"$Indentation# }"
256+
"$($Indentation)Write-Output 'after'"
257+
'}'
258+
) -join "`n"
259+
$settings = @{
260+
IncludeRules = @('PSUseConsistentIndentation')
261+
Rules = @{
262+
PSUseConsistentIndentation = @{
263+
Enable = $true
264+
IndentationSize = 4
265+
PipelineIndentation = 'NoIndentation'
266+
Kind = $Kind
267+
}
268+
}
269+
}
270+
271+
Invoke-Formatter -ScriptDefinition $scriptDefinition -Settings $settings |
272+
Should -Be $expectedScriptDefinition
273+
}
274+
209275
It "When a comment is in the middle of a multi-line statement with preceding and succeeding line continuations" {
210276
$scriptDefinition = @'
211277
foo `

0 commit comments

Comments
 (0)