Skip to content

Commit 45cdba0

Browse files
authored
Fix Indentation of mulitline command with backticks after comment line (#1318)
* try increase indentation after comment * make line after comment in multi line command with line continuation indent correctly and add tests. TODO: make it work for more than 1 line as well * Make it work for continued lines as well. Question: what if line continuations and pipelines are mixed? * tweak c# style and add more test cases * rename indices for better readability to address PR feedback
1 parent b34eec7 commit 45cdba0

File tree

2 files changed

+69
-13
lines changed

2 files changed

+69
-13
lines changed

Rules/UseConsistentIndentation.cs

+18-13
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
131131
var indentationLevel = 0;
132132
var onNewLine = true;
133133
var pipelineAsts = ast.FindAll(testAst => testAst is PipelineAst && (testAst as PipelineAst).PipelineElements.Count > 1, true);
134-
for (int k = 0; k < tokens.Length; k++)
134+
for (int tokenIndex = 0; tokenIndex < tokens.Length; tokenIndex++)
135135
{
136-
var token = tokens[k];
136+
var token = tokens[tokenIndex];
137137

138138
if (token.Kind == TokenKind.EndOfInput)
139139
{
@@ -151,8 +151,8 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
151151
break;
152152

153153
case TokenKind.Pipe:
154-
bool pipelineIsFollowedByNewlineOrLineContinuation = k < tokens.Length - 1 && k > 0 &&
155-
(tokens[k + 1].Kind == TokenKind.NewLine || tokens[k + 1].Kind == TokenKind.LineContinuation);
154+
bool pipelineIsFollowedByNewlineOrLineContinuation = tokenIndex < tokens.Length - 1 && tokenIndex > 0 &&
155+
(tokens[tokenIndex + 1].Kind == TokenKind.NewLine || tokens[tokenIndex + 1].Kind == TokenKind.LineContinuation);
156156
if (!pipelineIsFollowedByNewlineOrLineContinuation)
157157
{
158158
break;
@@ -164,7 +164,7 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
164164
}
165165
if (pipelineIndentationStyle == PipelineIndentationStyle.IncreaseIndentationForFirstPipeline)
166166
{
167-
bool isFirstPipeInPipeline = pipelineAsts.Any(pipelineAst => PositionIsEqual(((PipelineAst)pipelineAst).PipelineElements[0].Extent.EndScriptPosition, tokens[k - 1].Extent.EndScriptPosition));
167+
bool isFirstPipeInPipeline = pipelineAsts.Any(pipelineAst => PositionIsEqual(((PipelineAst)pipelineAst).PipelineElements[0].Extent.EndScriptPosition, tokens[tokenIndex - 1].Extent.EndScriptPosition));
168168
if (isFirstPipeInPipeline)
169169
{
170170
AddViolation(token, indentationLevel++, diagnosticRecords, ref onNewLine);
@@ -191,19 +191,24 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
191191
var tempIndentationLevel = indentationLevel;
192192

193193
// Check if the preceding character is an escape character
194-
if (k > 0 && tokens[k - 1].Kind == TokenKind.LineContinuation)
194+
if (tokenIndex > 0 && tokens[tokenIndex - 1].Kind == TokenKind.LineContinuation)
195195
{
196196
++tempIndentationLevel;
197197
}
198-
else
198+
199+
// check for comments in between multi-line commands with line continuation
200+
if (tokenIndex > 2 && tokens[tokenIndex - 1].Kind == TokenKind.NewLine
201+
&& tokens[tokenIndex - 2].Kind == TokenKind.Comment)
199202
{
200-
// Ignore comments
201-
// Since the previous token is a newline token we start
202-
// looking for comments at the token before the newline token.
203-
int j = k - 2;
204-
while (j > 0 && tokens[j].Kind == TokenKind.Comment)
203+
int searchForPrecedingLineContinuationIndex = tokenIndex - 2;
204+
while (searchForPrecedingLineContinuationIndex > 0 && tokens[searchForPrecedingLineContinuationIndex].Kind == TokenKind.Comment)
205+
{
206+
searchForPrecedingLineContinuationIndex--;
207+
}
208+
209+
if (searchForPrecedingLineContinuationIndex >= 0 && tokens[searchForPrecedingLineContinuationIndex].Kind == TokenKind.LineContinuation)
205210
{
206-
--j;
211+
tempIndentationLevel++;
207212
}
208213
}
209214

Tests/Rules/UseConsistentIndentation.tests.ps1

+51
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,25 @@ $testRootDirectory = Split-Path -Parent $directory
33

44
Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1")
55

6+
67
Describe "UseConsistentIndentation" {
8+
BeforeAll {
9+
function Invoke-FormatterAssertion {
10+
param(
11+
[string] $ScriptDefinition,
12+
[string] $ExcpectedScriptDefinition,
13+
[int] $NumberOfExpectedWarnings,
14+
[hashtable] $Settings
15+
)
16+
17+
# Unit test just using this rule only
18+
$violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings
19+
$violations.Count | Should -Be $NumberOfExpectedWarnings -Because $ScriptDefinition
20+
Invoke-Formatter -ScriptDefinition $scriptDefinition -Settings $settings | Should -Be $expected -Because $ScriptDefinition
21+
# Integration test with all default formatting rules
22+
Invoke-Formatter -ScriptDefinition $scriptDefinition | Should -Be $expected -Because $ScriptDefinition
23+
}
24+
}
725
BeforeEach {
826
$indentationUnit = ' '
927
$indentationSize = 4
@@ -107,6 +125,39 @@ function foo {
107125
}
108126

109127
Context "When a multi-line command is given" {
128+
129+
It "When a comment is in the middle of a multi-line statement with preceding and succeeding line continuations" {
130+
$scriptDefinition = @'
131+
foo `
132+
# comment
133+
-bar `
134+
-baz
135+
'@
136+
$expected = @'
137+
foo `
138+
# comment
139+
-bar `
140+
-baz
141+
'@
142+
Invoke-FormatterAssertion $scriptDefinition $expected 3 $settings
143+
}
144+
145+
It "When a comment is in the middle of a multi-line statement with preceding pipeline and succeeding line continuation " {
146+
$scriptDefinition = @'
147+
foo |
148+
# comment
149+
bar `
150+
-baz
151+
'@
152+
$expected = @'
153+
foo |
154+
# comment
155+
bar `
156+
-baz
157+
'@
158+
Invoke-FormatterAssertion $scriptDefinition $expected 3 $settings
159+
}
160+
110161
It "Should find a violation if a pipleline element is not indented correctly" {
111162
$def = @'
112163
get-process |

0 commit comments

Comments
 (0)