Skip to content

Commit

Permalink
Merge pull request #1814 from SeeminglyScience/fix-convertto-scriptex…
Browse files Browse the repository at this point in the history
…tent

Fix error when piping `IFilePosition` to `ConvertTo-ScriptExtent`
  • Loading branch information
andyleejordan authored Jun 2, 2022
2 parents 3e0ca95 + ec01a45 commit bff3b49
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,77 +8,63 @@ function ConvertTo-ScriptExtent {
[CmdletBinding()]
[OutputType([System.Management.Automation.Language.IScriptExtent])]
param(
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName='ByOffset')]
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'ByOffset')]
[Alias('StartOffset', 'Offset')]
[int]
$StartOffsetNumber,
[int] $StartOffsetNumber,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByOffset')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByOffset')]
[Alias('EndOffset')]
[int]
$EndOffsetNumber,
[int] $EndOffsetNumber,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByPosition')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByPosition')]
[Alias('StartLine', 'Line')]
[int]
$StartLineNumber,
[int] $StartLineNumber,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByPosition')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByPosition')]
[Alias('StartColumn', 'Column')]
[int]
$StartColumnNumber,
[int] $StartColumnNumber,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByPosition')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByPosition')]
[Alias('EndLine')]
[int]
$EndLineNumber,
[int] $EndLineNumber,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByPosition')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByPosition')]
[Alias('EndColumn')]
[int]
$EndColumnNumber,
[int] $EndColumnNumber,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByPosition')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByOffset')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByBuffer')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByPosition')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByOffset')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByBuffer')]
[Alias('File', 'FileName')]
[string]
$FilePath = $psEditor.GetEditorContext().CurrentFile.Path,
[string] $FilePath = $psEditor.GetEditorContext().CurrentFile.Path,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByBuffer')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByBuffer')]
[Alias('Start')]
[Microsoft.PowerShell.EditorServices.Extensions.IFilePosition, Microsoft.PowerShell.EditorServices]
$StartBuffer,
[Microsoft.PowerShell.EditorServices.Extensions.IFilePosition, Microsoft.PowerShell.EditorServices] $StartBuffer,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByBuffer')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ByBuffer')]
[Alias('End')]
[Microsoft.PowerShell.EditorServices.Extensions.IFilePosition, Microsoft.PowerShell.EditorServices]
$EndBuffer,

[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
ParameterSetName='ByExtent')]
[System.Management.Automation.Language.IScriptExtent]
$Extent
[Microsoft.PowerShell.EditorServices.Extensions.IFilePosition, Microsoft.PowerShell.EditorServices] $EndBuffer,

[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'ByExtent')]
[System.Management.Automation.Language.IScriptExtent] $Extent
)
begin {
$fileContext = $psEditor.GetEditorContext().CurrentFile
$emptyExtent = [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]::Empty
}

process {
# Already a InternalScriptExtent, FileScriptExtent or is empty.
$returnAsIs = $Extent -and
(0 -ne $Extent.StartOffset -or
0 -ne $Extent.EndOffset -or
$Extent -eq $emptyExtent)
($Extent.StartOffset -or $Extent.EndOffset -or $Extent -eq $emptyExtent)

if ($returnAsIs) { return $Extent }
if ($returnAsIs) {
return $Extent
}

if ($StartOffsetNumber) {
$startOffset = $StartOffsetNumber
$endOffset = $EndOffsetNumber
$endOffset = $EndOffsetNumber

# Allow creating a single position extent with just the offset parameter.
if (-not $EndOffsetNumber) {
Expand All @@ -92,8 +78,7 @@ function ConvertTo-ScriptExtent {
}

if ($StartBuffer) {
if (-not $EndBuffer)
{
if (-not $EndBuffer) {
$EndBuffer = $StartBuffer
}

Expand All @@ -105,12 +90,34 @@ function ConvertTo-ScriptExtent {
$EndBuffer.Column)
}

if (-not $StartColumnNumber) { $StartColumnNumber = 1 }
if (-not $StartLineNumber) { $StartLineNumber = 1 }
if (-not $EndLineNumber) { $EndLineNumber = 1 }
if (-not $EndColumnNumber) { $EndColumnNumber = 1 }
# Allow piping a single line and column to get a zero length script extent.
if ($PSBoundParameters.ContainsKey('StartColumnNumber') -and -not $PSBoundParameters.ContainsKey('EndColumnNumber')) {
$EndColumnNumber = $StartColumnNumber
}

if ($PSBoundParameters.ContainsKey('StartLineNumber') -and -not $PSBoundParameters.ContainsKey('EndLineNumber')) {
$EndLineNumber = $StartLineNumber
}

# Protect against zero as a value since lines and columns start at 1
if (-not $StartColumnNumber) {
$StartColumnNumber = 1
}

if (-not $StartLineNumber) {
$StartLineNumber = 1
}

if (-not $EndLineNumber) {
$EndLineNumber = 1
}

if (-not $EndColumnNumber) {
$EndColumnNumber = 1
}

return [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]::FromPositions(
$fileContext,
$StartLineNumber,
$StartColumnNumber,
$EndLineNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function Set-ScriptExtent {
)
begin {
$fileContext = $psEditor.GetEditorContext().CurrentFile
$extentList = [System.Collections.Generic.List[Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]]::new()
$extentList = [System.Collections.Generic.List[[Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]]]::new()
}
process {
if ($Extent -isnot [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]) {
Expand Down
36 changes: 31 additions & 5 deletions src/PowerShellEditorServices/Extensions/EditorFileRanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,23 @@ public class FileScriptPosition : IScriptPosition, IFilePosition

public static FileScriptPosition FromPosition(FileContext file, int lineNumber, int columnNumber)
{
if (file is null)
{
throw new ArgumentNullException(nameof(file));
}

int offset = 0;
int currLine = 1;
string fileText = file.Ast.Extent.Text;
while (offset < fileText.Length && currLine < lineNumber)
{
offset = fileText.IndexOf('\n', offset);
offset = fileText.IndexOf('\n', offset) + 1;
if (offset is 0)
{
// Line and column passed were not valid and the offset can not be determined.
return new FileScriptPosition(file, lineNumber, columnNumber, offset);
}

currLine++;
}

Expand All @@ -31,6 +42,11 @@ public static FileScriptPosition FromPosition(FileContext file, int lineNumber,

public static FileScriptPosition FromOffset(FileContext file, int offset)
{
if (file is null)
{
throw new ArgumentNullException(nameof(file));
}

int line = 1;
string fileText = file.Ast.Extent.Text;

Expand Down Expand Up @@ -59,7 +75,7 @@ public static FileScriptPosition FromOffset(FileContext file, int offset)
internal FileScriptPosition(FileContext file, int lineNumber, int columnNumber, int offset)
{
_file = file;
Line = file.GetTextLines()[lineNumber - 1];
Line = file?.GetTextLines()?[lineNumber - 1] ?? string.Empty;
ColumnNumber = columnNumber;
LineNumber = lineNumber;
Offset = offset;
Expand All @@ -79,7 +95,7 @@ internal FileScriptPosition(FileContext file, int lineNumber, int columnNumber,

int IFilePosition.Line => LineNumber;

public string GetFullScript() => _file.GetText();
public string GetFullScript() => _file?.GetText() ?? string.Empty;
}

public class FileScriptExtent : IScriptExtent, IFileRange
Expand All @@ -94,6 +110,11 @@ public static bool IsEmpty(FileScriptExtent extent)

public static FileScriptExtent FromOffsets(FileContext file, int startOffset, int endOffset)
{
if (file is null)
{
throw new ArgumentNullException(nameof(file));
}

return new FileScriptExtent(
file,
FileScriptPosition.FromOffset(file, startOffset),
Expand All @@ -102,6 +123,11 @@ public static FileScriptExtent FromOffsets(FileContext file, int startOffset, in

public static FileScriptExtent FromPositions(FileContext file, int startLine, int startColumn, int endLine, int endColumn)
{
if (file is null)
{
throw new ArgumentNullException(nameof(file));
}

return new FileScriptExtent(
file,
FileScriptPosition.FromPosition(file, startLine, startColumn),
Expand All @@ -127,7 +153,7 @@ public FileScriptExtent(FileContext file, FileScriptPosition start, FileScriptPo

public IScriptPosition EndScriptPosition => _end;

public string File => _file.Path;
public string File => _file?.Path ?? string.Empty;

public int StartColumnNumber => _start.ColumnNumber;

Expand All @@ -137,7 +163,7 @@ public FileScriptExtent(FileContext file, FileScriptPosition start, FileScriptPo

public IScriptPosition StartScriptPosition => _start;

public string Text => _file.GetText().Substring(_start.Offset, _end.Offset - _start.Offset);
public string Text => _file?.GetText()?.Substring(_start.Offset, _end.Offset - _start.Offset) ?? string.Empty;

IFilePosition IFileRange.Start => _start;

Expand Down

0 comments on commit bff3b49

Please sign in to comment.