Skip to content

Commit 441db22

Browse files
Restore concrete FileRange overloads on FileContext
#2306 widened the parameters of `FileContext.GetText` and `GetTextLines` from the concrete `FileRange` class to the `IFileRange` interface so that `$Context.CurrentFile.GetText($Context.SelectedRange)` would resolve (since `SelectedRange` is typed as `IFileRange`). That fixed the script-side call, but it dropped the old concrete-typed method slots from the assembly. Downstream modules that compile against PSES, most notably SeeminglyScience/EditorServicesCommandSuite, bind to the published metadata at build time. A precompiled caller of the old `GetText(FileRange)` signature would throw `MissingMethodException` at runtime even though it recompiles cleanly, so this was a binary-breaking change. Restore `GetText(FileRange)` and `GetTextLines(FileRange)` alongside the `IFileRange` overloads. Each casts to `IFileRange` and delegates to the widened implementation, so old binaries keep resolving and behavior is unchanged. The added tests declare their argument as the concrete `FileRange` so overload resolution actually exercises the compatibility shims. Drafted by Copilot (Claude Opus 4.8). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4835b11 commit 441db22

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

src/PowerShellEditorServices/Extensions/FileContext.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ public string GetText(IFileRange bufferRange)
112112
GetTextLines(bufferRange));
113113
}
114114

115+
/// <summary>
116+
/// Gets the file content in the specified range as a string.
117+
/// </summary>
118+
/// <param name="bufferRange">The buffer range for which content will be extracted.</param>
119+
/// <returns>A string with the specified range of content.</returns>
120+
/// <remarks>
121+
/// This overload preserves binary compatibility with callers compiled
122+
/// against the concrete <see cref="FileRange"/> parameter; it delegates
123+
/// to the <see cref="GetText(IFileRange)"/> overload.
124+
/// </remarks>
125+
public string GetText(FileRange bufferRange) => GetText((IFileRange)bufferRange);
126+
115127
/// <summary>
116128
/// Gets the complete file content as an array of strings.
117129
/// </summary>
@@ -125,6 +137,18 @@ public string GetText(IFileRange bufferRange)
125137
/// <returns>An array of strings, each representing a line in the file within the specified range.</returns>
126138
public string[] GetTextLines(IFileRange fileRange) => scriptFile.GetLinesInRange(fileRange.ToBufferRange());
127139

140+
/// <summary>
141+
/// Gets the file content in the specified range as an array of strings.
142+
/// </summary>
143+
/// <param name="fileRange">The buffer range for which content will be extracted.</param>
144+
/// <returns>An array of strings, each representing a line in the file within the specified range.</returns>
145+
/// <remarks>
146+
/// This overload preserves binary compatibility with callers compiled
147+
/// against the concrete <see cref="FileRange"/> parameter; it delegates
148+
/// to the <see cref="GetTextLines(IFileRange)"/> overload.
149+
/// </remarks>
150+
public string[] GetTextLines(FileRange fileRange) => GetTextLines((IFileRange)fileRange);
151+
128152
#endregion
129153

130154
#region Text Manipulation

test/PowerShellEditorServices.Test/Extensions/FileContextTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,36 @@ public void CanGetTextFromConstructedFileRange()
6464

6565
Assert.Equal("Line Three", editorContext.CurrentFile.GetText(range));
6666
}
67+
68+
// The concrete FileRange overloads exist to preserve binary compatibility
69+
// with callers compiled before GetText/GetTextLines were widened to IFileRange.
70+
// Declaring the variable as FileRange (not IFileRange) selects those overloads.
71+
[Fact]
72+
public void CanGetTextFromConcreteFileRange()
73+
{
74+
EditorContext editorContext = CreateEditorContext(
75+
"Line One\nLine Two\nLine Three",
76+
BufferRange.None);
77+
78+
FileRange range = new(
79+
new Microsoft.PowerShell.EditorServices.Extensions.FilePosition(3, 1),
80+
new Microsoft.PowerShell.EditorServices.Extensions.FilePosition(3, 11));
81+
82+
Assert.Equal("Line Three", editorContext.CurrentFile.GetText(range));
83+
}
84+
85+
[Fact]
86+
public void CanGetTextLinesFromConcreteFileRange()
87+
{
88+
EditorContext editorContext = CreateEditorContext(
89+
"Line One\nLine Two\nLine Three",
90+
BufferRange.None);
91+
92+
FileRange range = new(
93+
new Microsoft.PowerShell.EditorServices.Extensions.FilePosition(1, 1),
94+
new Microsoft.PowerShell.EditorServices.Extensions.FilePosition(2, 9));
95+
96+
Assert.Equal(new[] { "Line One", "Line Two" }, editorContext.CurrentFile.GetTextLines(range));
97+
}
6798
}
6899
}

0 commit comments

Comments
 (0)