Skip to content

Commit e45a772

Browse files
Copilotbergmeister
andauthored
Handle empty formatter replacements in ranges
Co-authored-by: bergmeister <9250262+bergmeister@users.noreply.github.com>
1 parent e021fce commit e45a772

2 files changed

Lines changed: 76 additions & 3 deletions

File tree

‎Engine/ScriptAnalyzer.cs‎

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,12 +1733,34 @@ private static EditableText Fix(
17331733
var columnDelta = 0;
17341734
if (correction.EndLineNumber == range.End.Line)
17351735
{
1736-
var replacementEndColumn = correction.Lines.Last().TrimEnd('\r').Length
1737-
+ (correction.Lines.Length == 1 ? correction.StartColumnNumber : 1);
1736+
var replacementEndColumn = correction.Lines.Length == 0
1737+
? correction.StartColumnNumber
1738+
: correction.Lines.Last().TrimEnd('\r').Length
1739+
+ (correction.Lines.Length == 1 ? correction.StartColumnNumber : 1);
17381740
columnDelta = replacementEndColumn - correction.EndColumnNumber;
17391741
}
17401742

1741-
range = new Range(range.Start, range.End.Shift(lineDelta, columnDelta));
1743+
var endLine = range.End.Line + lineDelta;
1744+
if (correction.Lines.Length == 0 && endLine < range.Start.Line)
1745+
{
1746+
if (text.LineCount == 0)
1747+
{
1748+
range = null;
1749+
}
1750+
else
1751+
{
1752+
endLine = Math.Min(Math.Max(endLine, 1), text.LineCount);
1753+
var endColumn = Math.Min(
1754+
Math.Max(range.End.Column + columnDelta, 1),
1755+
text.Lines[endLine - 1].Length + 1);
1756+
var end = new Position(endLine, endColumn);
1757+
range = new Range(end, end);
1758+
}
1759+
}
1760+
else
1761+
{
1762+
range = new Range(range.Start, range.End.Shift(lineDelta, columnDelta));
1763+
}
17421764
}
17431765
}
17441766

‎Tests/Engine/InvokeFormatter.tests.ps1‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,57 @@ function foo {
8282
Invoke-Formatter -ScriptDefinition $def -Range @(3, 1, 4, 1) | Should -Be $expected
8383
}
8484

85+
It "Should track the range when an edit deletes its last line" {
86+
$text = New-Object -TypeName "Microsoft.Windows.PowerShell.ScriptAnalyzer.EditableText" -ArgumentList "first`n`nlast"
87+
$correctionType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent" -as [type]
88+
$correction = [Activator]::CreateInstance(
89+
$correctionType,
90+
[object[]]@(2, 2, 1, 1, [string[]]@(), $null, $null))
91+
$correctionsType = [System.Collections.Generic.List``1].MakeGenericType($correctionType)
92+
$corrections = [Activator]::CreateInstance($correctionsType)
93+
$corrections.Add($correction)
94+
$range = New-Object -TypeName "Microsoft.Windows.PowerShell.ScriptAnalyzer.Range" -ArgumentList 1, 1, 2, 1
95+
$arguments = [object[]]@(
96+
$text.PSObject.BaseObject,
97+
$corrections.PSObject.BaseObject,
98+
0,
99+
$range.PSObject.BaseObject)
100+
$fixMethod = ("Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer" -as [type]).GetMethod(
101+
'Fix',
102+
[Reflection.BindingFlags]'NonPublic, Static')
103+
104+
$fixMethod.Invoke($null, $arguments) | Out-Null
105+
106+
$text.ToString() | Should -Be "first`nlast"
107+
$arguments[3].End.Line | Should -Be 1
108+
}
109+
110+
It "Should collapse the range when an edit deletes all selected lines" {
111+
$text = New-Object -TypeName "Microsoft.Windows.PowerShell.ScriptAnalyzer.EditableText" -ArgumentList "first`nlast"
112+
$correctionType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent" -as [type]
113+
$correction = [Activator]::CreateInstance(
114+
$correctionType,
115+
[object[]]@(2, 2, 1, 5, [string[]]@(), $null, $null))
116+
$correctionsType = [System.Collections.Generic.List``1].MakeGenericType($correctionType)
117+
$corrections = [Activator]::CreateInstance($correctionsType)
118+
$corrections.Add($correction)
119+
$range = New-Object -TypeName "Microsoft.Windows.PowerShell.ScriptAnalyzer.Range" -ArgumentList 2, 1, 2, 5
120+
$arguments = [object[]]@(
121+
$text.PSObject.BaseObject,
122+
$corrections.PSObject.BaseObject,
123+
0,
124+
$range.PSObject.BaseObject)
125+
$fixMethod = ("Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer" -as [type]).GetMethod(
126+
'Fix',
127+
[Reflection.BindingFlags]'NonPublic, Static')
128+
129+
$fixMethod.Invoke($null, $arguments) | Out-Null
130+
131+
$text.ToString() | Should -Be "first"
132+
$arguments[3].Start.Line | Should -Be 1
133+
$arguments[3].End.Line | Should -Be 1
134+
}
135+
85136
It "Should apply all corrections when earlier fixes expand the selected line" {
86137
$def = "if(`$a){'x'}`nif(`$b){'y'}"
87138
$expected = "if(`$a){'x'}`nif (`$b) { 'y' }"

0 commit comments

Comments
 (0)