Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions Rules/UseConsistentIndentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,10 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
}

bool lineHasPipelineBeforeToken = LineHasPipelineBeforeToken(tokens, tokenIndex, token);
AddViolation(token, tempIndentationLevel, diagnosticRecords, ref onNewLine, lineHasPipelineBeforeToken);
int commentIndentationOffset = token.Kind == TokenKind.Comment
? GetCommentRunIndentationOffset(tokens, tokenIndex)
: 0;
AddViolation(token, tempIndentationLevel, diagnosticRecords, ref onNewLine, lineHasPipelineBeforeToken, commentIndentationOffset);
}
break;
}
Expand Down Expand Up @@ -336,6 +339,31 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
return diagnosticRecords;
}

private static int GetCommentRunIndentationOffset(Token[] tokens, int tokenIndex)
{
int firstCommentIndex = tokenIndex;
int currentLine = tokens[tokenIndex].Extent.StartLineNumber;
int precedingIndex = tokenIndex - 1;
while (precedingIndex >= 0 && tokens[precedingIndex].Kind == TokenKind.NewLine)
{
precedingIndex--;
Comment on lines +347 to +349
if (precedingIndex < 0 ||
tokens[precedingIndex].Kind != TokenKind.Comment ||
tokens[precedingIndex].Extent.EndLineNumber != currentLine - 1 ||
(precedingIndex > 0 && tokens[precedingIndex - 1].Kind != TokenKind.NewLine))
{
break;
}

firstCommentIndex = precedingIndex;
currentLine = tokens[precedingIndex].Extent.StartLineNumber;
precedingIndex--;
}

return tokens[tokenIndex].Extent.StartColumnNumber -
tokens[firstCommentIndex].Extent.StartColumnNumber;
}

/// <summary>
/// Scans forward from the current opener to the end of the line.
/// Returns true if there is at least one unclosed opener when
Expand Down Expand Up @@ -612,12 +640,14 @@ private void AddViolation(
int expectedIndentationLevel,
List<DiagnosticRecord> diagnosticRecords,
ref bool onNewLine,
bool lineHasPipelineBeforeToken = false)
bool lineHasPipelineBeforeToken = false,
int indentationOffset = 0)
{
if (onNewLine)
{
onNewLine = false;
if (token.Extent.StartColumnNumber - 1 != GetIndentation(expectedIndentationLevel))
int expectedIndentation = Math.Max(0, GetIndentation(expectedIndentationLevel) + indentationOffset);
if (token.Extent.StartColumnNumber - 1 != expectedIndentation)
{
var fileName = token.Extent.File;
var extent = token.Extent;
Expand All @@ -640,14 +670,14 @@ private void AddViolation(
GetDiagnosticSeverity(),
fileName,
null,
GetSuggestedCorrections(token, expectedIndentationLevel, lineHasPipelineBeforeToken)));
GetSuggestedCorrections(token, expectedIndentation, lineHasPipelineBeforeToken)));
}
}
}

private List<CorrectionExtent> GetSuggestedCorrections(
Token token,
int indentationLevel,
int indentation,
bool lineHasPipelineBeforeToken = false)
{
// TODO Add another constructor for correction extent that takes extent
Expand All @@ -661,7 +691,7 @@ private List<CorrectionExtent> GetSuggestedCorrections(
token.Extent.EndLineNumber,
1,
token.Extent.EndColumnNumber,
GetIndentationString(indentationLevel) + optionalPipeline + token.Extent.Text,
new string(indentationChar, indentation) + optionalPipeline + token.Extent.Text,
token.Extent.File));
return corrections;
}
Expand All @@ -677,9 +707,5 @@ private int GetIndentation(int indentationLevel)
return indentationLevel * indentationLevelMultiplier;
}

private string GetIndentationString(int indentationLevel)
{
return new string(indentationChar, GetIndentation(indentationLevel));
}
}
}
52 changes: 51 additions & 1 deletion Tests/Rules/UseConsistentIndentation.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,58 @@ function foo {
}
}

Context "When a multi-line command is given" {
Context "When a commented-out code block is provided" {

It 'Should preserve relative indentation in commented-out code with <Kind> indentation' -TestCases @(
@{ Kind = 'space'; Indentation = ' ' }
@{ Kind = 'tab'; Indentation = "`t" }
) {
param([string] $Kind, [string] $Indentation)
$scriptDefinition = @(
'if ($a) {'
"$Indentation# if (`$b) {"
"$Indentation$Indentation# doThing"
"$Indentation# }"
"$($Indentation)Write-Output 'after'"
'}'
) -join "`n"
$settings.Rules.PSUseConsistentIndentation.Kind = $Kind
$settings.Rules.PSUseConsistentIndentation.PipelineIndentation = 'NoIndentation'

Invoke-Formatter -ScriptDefinition $scriptDefinition -Settings $settings |
Should -Be $scriptDefinition
}

It 'Should shift a commented-out code block without flattening it with <Kind> indentation' -TestCases @(
@{ Kind = 'space'; Indentation = ' ' }
@{ Kind = 'tab'; Indentation = "`t" }
) {
param([string] $Kind, [string] $Indentation)
$scriptDefinition = @(
'if ($a) {'
'# if ($b) {'
"$Indentation# doThing"
'# }'
"$($Indentation)Write-Output 'after'"
'}'
) -join "`n"
$expectedScriptDefinition = @(
'if ($a) {'
"$Indentation# if (`$b) {"
"$Indentation$Indentation# doThing"
"$Indentation# }"
"$($Indentation)Write-Output 'after'"
'}'
) -join "`n"
$settings.Rules.PSUseConsistentIndentation.Kind = $Kind
$settings.Rules.PSUseConsistentIndentation.PipelineIndentation = 'NoIndentation'

Invoke-Formatter -ScriptDefinition $scriptDefinition -Settings $settings |
Should -Be $expectedScriptDefinition
}
}

Context "When a multi-line command is given" {
It "When a comment is in the middle of a multi-line statement with preceding and succeeding line continuations" {
$scriptDefinition = @'
foo `
Expand Down
Loading