Skip to content
Closed
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
18 changes: 9 additions & 9 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@

## Build & Test

Requires .NET SDK 8.0+. Use `dotnet` directly for building and testing — it's faster and
Requires .NET SDK 10.0+. Use `dotnet` directly for building and testing — it's faster and
requires no extra tooling. The `Invoke-Build` script requires the `InvokeBuild` and `platyPS`
PowerShell modules (platyPS is `#Requires`'d at the top, so the whole script fails without it),
and is mainly needed to assemble the full PowerShell module for release.

```powershell
# Build (run both; Hosting depends on the core library)
dotnet publish src/PowerShellEditorServices/PowerShellEditorServices.csproj -f netstandard2.0
dotnet publish src/PowerShellEditorServices.Hosting/PowerShellEditorServices.Hosting.csproj -f net8.0
dotnet publish src/PowerShellEditorServices.Hosting/PowerShellEditorServices.Hosting.csproj -f net10.0

# Run all unit tests
dotnet test test/PowerShellEditorServices.Test/ --framework net8.0
dotnet test test/PowerShellEditorServices.Test/ --framework net10.0

# Run a single test by name
dotnet test test/PowerShellEditorServices.Test/ --framework net8.0 --filter "FullyQualifiedName~CompletesCommandInFile"
dotnet test test/PowerShellEditorServices.Test/ --framework net10.0 --filter "FullyQualifiedName~CompletesCommandInFile"

# Run tests by trait category
dotnet test test/PowerShellEditorServices.Test/ --framework net8.0 --filter "Category=Completions"
dotnet test test/PowerShellEditorServices.Test/ --framework net10.0 --filter "Category=Completions"

# Run E2E tests
dotnet test test/PowerShellEditorServices.Test.E2E/ --framework net8.0
dotnet test test/PowerShellEditorServices.Test.E2E/ --framework net10.0
```

For assembling the full module or running the complete CI suite (including Windows PowerShell
Expand All @@ -48,11 +48,11 @@ Protocol (DAP)** server for PowerShell, consumed by VS Code and other editors.
- **`src/PowerShellEditorServices`** (`netstandard2.0`) — Core library containing all LSP/DAP
handlers, services, and the PowerShell execution engine. Namespace:
`Microsoft.PowerShell.EditorServices`.
- **`src/PowerShellEditorServices.Hosting`** (`net8.0`, `net462`) — Entry point layer that loads
- **`src/PowerShellEditorServices.Hosting`** (`net10.0`, `net462`) — Entry point layer that loads
PSES into a PowerShell process via `StartEditorServicesCommand`. Uses a custom
`AssemblyLoadContext` (`PsesLoadContext`) on .NET Core to isolate dependencies.
- **`module/PowerShellEditorServices/`** — The shipped PowerShell module. The build assembles
compiled binaries into `bin/Core/` (net8.0) and `bin/Desktop/` (net462). The module manifest
compiled binaries into `bin/Core/` (net10.0) and `bin/Desktop/` (net462). The module manifest
loads the appropriate DLL based on PowerShell edition.

### Key Services (registered in `PsesServiceCollectionExtensions`)
Expand Down Expand Up @@ -136,7 +136,7 @@ Because of that, treat any change to an existing `public` member as potentially
### Multi-targeting

The core library targets `netstandard2.0` for compatibility with both .NET Core and .NET
Framework. The hosting project and tests dual-target `net8.0` and `net462` (Windows PowerShell
Framework. The hosting project and tests dual-target `net10.0` and `net462` (Windows PowerShell
5.1). Non-Windows platforms skip `net462` targets.

## Pull Request Labels
Expand Down
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<PackageVersion Include="Microsoft.Extensions.Logging.Debug" Version="10.0.5" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.4.0" />
<PackageVersion Include="Microsoft.PowerShell.5.ReferenceAssemblies" Version="1.1.0" />
<PackageVersion Include="Microsoft.PowerShell.SDK" Version="7.4.14" />
<PackageVersion Include="Microsoft.PowerShell.SDK" Version="7.6.3" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="OmniSharp.Extensions.DebugAdapter.Client" Version="0.19.9" />
<PackageVersion Include="OmniSharp.Extensions.DebugAdapter.Server" Version="0.19.9" />
Expand Down
4 changes: 2 additions & 2 deletions PowerShellEditorServices.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ $script:BuildInfoPath = "src/PowerShellEditorServices.Hosting/BuildInfo.cs"

$script:NetFramework = @{
PS51 = 'net462'
PS74 = 'net8.0'
PS74 = 'net10.0'
Standard = 'netstandard2.0'
}

Expand All @@ -58,7 +58,7 @@ Task FindDotNet {

# Strip out semantic version metadata so it can be cast to `Version`
[Version]$existingVersion, $null = (dotnet --version) -split " " -split "-"
Assert ($existingVersion -ge [Version]("8.0")) ".NET SDK 8.0 or higher is required, please update it: https://aka.ms/dotnet-cli"
Assert ($existingVersion -ge [Version]("10.0")) ".NET SDK 10.0 or higher is required, please update it: https://aka.ms/dotnet-cli"

Write-Build DarkGreen "Using dotnet v$(dotnet --version) at path $((Get-Command dotnet).Source)"
}
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.416",
"version": "10.0.301",
"rollForward": "latestFeature",
"allowPrerelease": false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), PowerShellEditorServices.Common.props))\PowerShellEditorServices.Common.props" />

<PropertyGroup>
<TargetFrameworks>net8.0;net462</TargetFrameworks>
<TargetFrameworks>net10.0;net462</TargetFrameworks>
<AssemblyName>Microsoft.PowerShell.EditorServices.Hosting</AssemblyName>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ internal class ReferencesCodeLensProvider : ICodeLensProvider
/// </summary>
private readonly IDocumentSymbolProvider _symbolProvider;
private readonly SymbolsService _symbolsService;
private readonly WorkspaceService _workspaceService;

public static string Id => nameof(ReferencesCodeLensProvider);

Expand All @@ -38,11 +37,9 @@ internal class ReferencesCodeLensProvider : ICodeLensProvider
/// <summary>
/// Construct a new ReferencesCodeLensProvider for a given EditorSession.
/// </summary>
/// <param name="workspaceService"></param>
/// <param name="symbolsService"></param>
public ReferencesCodeLensProvider(WorkspaceService workspaceService, SymbolsService symbolsService)
public ReferencesCodeLensProvider(SymbolsService symbolsService)
{
_workspaceService = workspaceService;
_symbolsService = symbolsService;
// TODO: Pull this from components
_symbolProvider = new ScriptDocumentSymbolProvider();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ internal interface IPowerShellDebugContext

DebuggerStopEventArgs LastStopEventArgs { get; }

public bool IsDebuggingRemoteRunspace { get; set; }
bool IsDebuggingRemoteRunspace { get; set; }

public event Action<object, DebuggerStopEventArgs> DebuggerStopped;
event Action<object, DebuggerStopEventArgs> DebuggerStopped;

public event Action<object, DebuggerResumingEventArgs> DebuggerResuming;
event Action<object, DebuggerResumingEventArgs> DebuggerResuming;

public event Action<object, BreakpointUpdatedEventArgs> BreakpointUpdated;
event Action<object, BreakpointUpdatedEventArgs> BreakpointUpdated;

void Continue();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,7 @@ public void SetDebugResuming(DebuggerResumeAction debuggerResumeAction)
// then this came over LSP and we need to set it.
_psesHost.SetExit();

if (LastStopEventArgs is not null)
{
LastStopEventArgs.ResumeAction = debuggerResumeAction;
}
LastStopEventArgs?.ResumeAction = debuggerResumeAction;

// We need to tell whatever is happening right now in the debug prompt to wrap up so we
// can continue. However, if the host was initialized with the console REPL disabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ internal abstract class SynchronousTask<TResult> : ISynchronousTask
private readonly CancellationToken _taskRequesterCancellationToken;

private bool _executionCanceled;

private TResult _result;

private ExceptionDispatchInfo _exceptionInfo;

protected SynchronousTask(
Expand Down Expand Up @@ -57,8 +54,10 @@ public TResult Result

_exceptionInfo?.Throw();

return _result;
return field;
}

private set;
}

public bool IsCanceled => _executionCanceled || _taskRequesterCancellationToken.IsCancellationRequested;
Expand Down Expand Up @@ -123,7 +122,7 @@ private void SetException(Exception e)

private void SetResult(TResult result)
{
_result = result;
Result = result;
_taskCompletionSource.SetResult(result);
}
}
Expand Down
10 changes: 4 additions & 6 deletions src/PowerShellEditorServices/Services/Symbols/ReferenceTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ internal sealed class ReferenceTable

private readonly ConcurrentDictionary<string, ConcurrentBag<SymbolReference>> _symbolReferences = new(StringComparer.OrdinalIgnoreCase);

private bool _isInited;

public ReferenceTable(ScriptFile parent) => _parent = parent;

/// <summary>
Expand All @@ -32,15 +30,15 @@ internal sealed class ReferenceTable
public void TagAsChanged()
{
_symbolReferences.Clear();
_isInited = false;
IsInitialized = false;
}

/// <summary>
/// Prefer checking if the dictionary has contents to determine if initialized. The field
/// `_isInited` is to guard against re-scanning files with no command references, but will
/// Prefer checking if the dictionary has contents to determine if initialized. The backing
/// field is to guard against re-scanning files with no command references, but will
/// generally be less reliable of a check.
/// </summary>
private bool IsInitialized => !_symbolReferences.IsEmpty || _isInited;
private bool IsInitialized { get => !_symbolReferences.IsEmpty || field; set; }

internal IEnumerable<SymbolReference> TryGetReferences(SymbolReference? symbol)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public SymbolsService(
_codeLensProviders = new ConcurrentDictionary<string, ICodeLensProvider>();
if (configurationService.CurrentSettings.EnableReferencesCodeLens)
{
ReferencesCodeLensProvider referencesProvider = new(_workspaceService, this);
ReferencesCodeLensProvider referencesProvider = new(this);
_ = _codeLensProviders.TryAdd(referencesProvider.ProviderId, referencesProvider);
}

Expand Down Expand Up @@ -495,7 +495,7 @@ void CloseUnopenedFiles()
return;
}

TryRegisterCodeLensProvider(new ReferencesCodeLensProvider(_workspaceService, this));
TryRegisterCodeLensProvider(new ReferencesCodeLensProvider(this));
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public override async Task<TextEditContainer> Handle(DocumentFormattingParams re
return s_emptyTextEditContainer;
}

return new TextEditContainer(new OmniSharp.Extensions.LanguageServer.Protocol.Models.TextEdit
return new TextEditContainer(new TextEdit
{
NewText = formattedScript,
Range = editRange
Expand Down Expand Up @@ -184,7 +184,7 @@ public override async Task<TextEditContainer> Handle(DocumentRangeFormattingPara
return s_emptyTextEditContainer;
}

return new TextEditContainer(new OmniSharp.Extensions.LanguageServer.Protocol.Models.TextEdit
return new TextEditContainer(new TextEdit
{
NewText = formattedScript,
Range = editRange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -691,10 +691,7 @@ private void RemovePSEditFunction(IRunspaceInfo runspaceInfo)
}
try
{
if (runspaceInfo.Runspace.Events != null)
{
runspaceInfo.Runspace.Events.ReceivedEvents.PSEventReceived -= HandlePSEventReceivedAsync;
}
runspaceInfo.Runspace.Events?.ReceivedEvents.PSEventReceived -= HandlePSEventReceivedAsync;

if (runspaceInfo.Runspace.RunspaceStateInfo.State == RunspaceState.Opened)
{
Expand Down
4 changes: 2 additions & 2 deletions src/PowerShellEditorServices/Utility/VersionUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ internal static class VersionUtils
public static bool IsPS7OrGreater { get; } = PSVersion.Major >= 7;

/// <summary>
/// True if we are running in PowerShell 7.4, false otherwise.
/// True if we are running in PowerShell 7.4 or greater, false otherwise.
/// </summary>
public static bool IsPS74 { get; } = PSVersion.Major == 7 && PSVersion.Minor == 4;
public static bool IsPS74OrGreater { get; } = PSVersion >= new Version(7, 4);

/// <summary>
/// True if we are running on Windows, false otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), PowerShellEditorServices.Common.props))\PowerShellEditorServices.Common.props" />

<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ internal static class CompleteVariableInFile
public static readonly CompletionItem ExpectedCompletion = new()
{
Kind = CompletionItemKind.Variable,
// PowerShell 7.4 now lights up a type for the detail, otherwise it's the same as the
// label and therefore hidden.
Detail = Utility.VersionUtils.IsPS74 ? "[string]" : "",
// PowerShell 7.4 and greater light up a type for the detail, otherwise it's the same as
// the label and therefore hidden.
Detail = Utility.VersionUtils.IsPS74OrGreater ? "[string]" : "",
FilterText = "$testVar1",
InsertText = "$testVar1",
Label = "testVar1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), PowerShellEditorServices.Common.props))\PowerShellEditorServices.Common.props" />

<PropertyGroup>
<TargetFrameworks>net8.0;net462</TargetFrameworks>
<TargetFrameworks>net10.0;net462</TargetFrameworks>
<AssemblyName>Microsoft.PowerShell.EditorServices.Test</AssemblyName>
<TargetPlatform>x64</TargetPlatform>
</PropertyGroup>
Expand All @@ -17,12 +17,12 @@
</ItemGroup>

<!-- The Hosting assembly (and thus PsesLoadContext) only exists on .NET Core. -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'net10.0' ">
<ProjectReference Include="..\..\src\PowerShellEditorServices.Hosting\PowerShellEditorServices.Hosting.csproj" />
</ItemGroup>

<!-- PowerShell 7.4.x -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<!-- PowerShell 7.6.x -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net10.0' ">
<PackageReference Include="Microsoft.PowerShell.SDK" />
</ItemGroup>

Expand Down
Loading