diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 54626eb10..2eb49371a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,7 +2,7 @@ ## 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. @@ -10,19 +10,19 @@ 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 @@ -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`) @@ -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 diff --git a/Directory.Packages.props b/Directory.Packages.props index c76c2a7e3..79213e9c3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,7 +6,7 @@ - + diff --git a/PowerShellEditorServices.build.ps1 b/PowerShellEditorServices.build.ps1 index 62cb53369..bdfaf9d58 100644 --- a/PowerShellEditorServices.build.ps1 +++ b/PowerShellEditorServices.build.ps1 @@ -40,7 +40,7 @@ $script:BuildInfoPath = "src/PowerShellEditorServices.Hosting/BuildInfo.cs" $script:NetFramework = @{ PS51 = 'net462' - PS74 = 'net8.0' + PS74 = 'net10.0' Standard = 'netstandard2.0' } @@ -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)" } diff --git a/global.json b/global.json index 910363ade..7c8e277cf 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.416", + "version": "10.0.301", "rollForward": "latestFeature", "allowPrerelease": false } diff --git a/src/PowerShellEditorServices.Hosting/PowerShellEditorServices.Hosting.csproj b/src/PowerShellEditorServices.Hosting/PowerShellEditorServices.Hosting.csproj index a41911e14..bf6862c7e 100644 --- a/src/PowerShellEditorServices.Hosting/PowerShellEditorServices.Hosting.csproj +++ b/src/PowerShellEditorServices.Hosting/PowerShellEditorServices.Hosting.csproj @@ -3,7 +3,7 @@ Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), PowerShellEditorServices.Common.props))\PowerShellEditorServices.Common.props" /> - net8.0;net462 + net10.0;net462 Microsoft.PowerShell.EditorServices.Hosting diff --git a/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs b/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs index 0307163cc..5696b4736 100644 --- a/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs +++ b/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs @@ -25,7 +25,6 @@ internal class ReferencesCodeLensProvider : ICodeLensProvider /// private readonly IDocumentSymbolProvider _symbolProvider; private readonly SymbolsService _symbolsService; - private readonly WorkspaceService _workspaceService; public static string Id => nameof(ReferencesCodeLensProvider); @@ -38,11 +37,9 @@ internal class ReferencesCodeLensProvider : ICodeLensProvider /// /// Construct a new ReferencesCodeLensProvider for a given EditorSession. /// - /// /// - public ReferencesCodeLensProvider(WorkspaceService workspaceService, SymbolsService symbolsService) + public ReferencesCodeLensProvider(SymbolsService symbolsService) { - _workspaceService = workspaceService; _symbolsService = symbolsService; // TODO: Pull this from components _symbolProvider = new ScriptDocumentSymbolProvider(); diff --git a/src/PowerShellEditorServices/Services/PowerShell/Debugging/IPowerShellDebugContext.cs b/src/PowerShellEditorServices/Services/PowerShell/Debugging/IPowerShellDebugContext.cs index 506109b7d..9c3de43d6 100644 --- a/src/PowerShellEditorServices/Services/PowerShell/Debugging/IPowerShellDebugContext.cs +++ b/src/PowerShellEditorServices/Services/PowerShell/Debugging/IPowerShellDebugContext.cs @@ -13,13 +13,13 @@ internal interface IPowerShellDebugContext DebuggerStopEventArgs LastStopEventArgs { get; } - public bool IsDebuggingRemoteRunspace { get; set; } + bool IsDebuggingRemoteRunspace { get; set; } - public event Action DebuggerStopped; + event Action DebuggerStopped; - public event Action DebuggerResuming; + event Action DebuggerResuming; - public event Action BreakpointUpdated; + event Action BreakpointUpdated; void Continue(); diff --git a/src/PowerShellEditorServices/Services/PowerShell/Debugging/PowerShellDebugContext.cs b/src/PowerShellEditorServices/Services/PowerShell/Debugging/PowerShellDebugContext.cs index f88aa38d5..cb548fa6f 100644 --- a/src/PowerShellEditorServices/Services/PowerShell/Debugging/PowerShellDebugContext.cs +++ b/src/PowerShellEditorServices/Services/PowerShell/Debugging/PowerShellDebugContext.cs @@ -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, diff --git a/src/PowerShellEditorServices/Services/PowerShell/Execution/SynchronousTask.cs b/src/PowerShellEditorServices/Services/PowerShell/Execution/SynchronousTask.cs index fc7f97cd8..02017f1d7 100644 --- a/src/PowerShellEditorServices/Services/PowerShell/Execution/SynchronousTask.cs +++ b/src/PowerShellEditorServices/Services/PowerShell/Execution/SynchronousTask.cs @@ -25,9 +25,6 @@ internal abstract class SynchronousTask : ISynchronousTask private readonly CancellationToken _taskRequesterCancellationToken; private bool _executionCanceled; - - private TResult _result; - private ExceptionDispatchInfo _exceptionInfo; protected SynchronousTask( @@ -57,8 +54,10 @@ public TResult Result _exceptionInfo?.Throw(); - return _result; + return field; } + + private set; } public bool IsCanceled => _executionCanceled || _taskRequesterCancellationToken.IsCancellationRequested; @@ -123,7 +122,7 @@ private void SetException(Exception e) private void SetResult(TResult result) { - _result = result; + Result = result; _taskCompletionSource.SetResult(result); } } diff --git a/src/PowerShellEditorServices/Services/Symbols/ReferenceTable.cs b/src/PowerShellEditorServices/Services/Symbols/ReferenceTable.cs index 6cb8e52c4..b0dc8f7e7 100644 --- a/src/PowerShellEditorServices/Services/Symbols/ReferenceTable.cs +++ b/src/PowerShellEditorServices/Services/Symbols/ReferenceTable.cs @@ -22,8 +22,6 @@ internal sealed class ReferenceTable private readonly ConcurrentDictionary> _symbolReferences = new(StringComparer.OrdinalIgnoreCase); - private bool _isInited; - public ReferenceTable(ScriptFile parent) => _parent = parent; /// @@ -32,15 +30,15 @@ internal sealed class ReferenceTable public void TagAsChanged() { _symbolReferences.Clear(); - _isInited = false; + IsInitialized = false; } /// - /// 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. /// - private bool IsInitialized => !_symbolReferences.IsEmpty || _isInited; + private bool IsInitialized { get => !_symbolReferences.IsEmpty || field; set; } internal IEnumerable TryGetReferences(SymbolReference? symbol) { diff --git a/src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs b/src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs index 99f8bbbc8..827b4eee5 100644 --- a/src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs +++ b/src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs @@ -70,7 +70,7 @@ public SymbolsService( _codeLensProviders = new ConcurrentDictionary(); if (configurationService.CurrentSettings.EnableReferencesCodeLens) { - ReferencesCodeLensProvider referencesProvider = new(_workspaceService, this); + ReferencesCodeLensProvider referencesProvider = new(this); _ = _codeLensProviders.TryAdd(referencesProvider.ProviderId, referencesProvider); } @@ -495,7 +495,7 @@ void CloseUnopenedFiles() return; } - TryRegisterCodeLensProvider(new ReferencesCodeLensProvider(_workspaceService, this)); + TryRegisterCodeLensProvider(new ReferencesCodeLensProvider(this)); return; } diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs index bf5f99d0f..64ccb3156 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs @@ -90,7 +90,7 @@ public override async Task 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 @@ -184,7 +184,7 @@ public override async Task Handle(DocumentRangeFormattingPara return s_emptyTextEditContainer; } - return new TextEditContainer(new OmniSharp.Extensions.LanguageServer.Protocol.Models.TextEdit + return new TextEditContainer(new TextEdit { NewText = formattedScript, Range = editRange diff --git a/src/PowerShellEditorServices/Services/Workspace/RemoteFileManagerService.cs b/src/PowerShellEditorServices/Services/Workspace/RemoteFileManagerService.cs index 961338023..5b0ff6065 100644 --- a/src/PowerShellEditorServices/Services/Workspace/RemoteFileManagerService.cs +++ b/src/PowerShellEditorServices/Services/Workspace/RemoteFileManagerService.cs @@ -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) { diff --git a/src/PowerShellEditorServices/Utility/VersionUtils.cs b/src/PowerShellEditorServices/Utility/VersionUtils.cs index 0b8919294..1726943cf 100644 --- a/src/PowerShellEditorServices/Utility/VersionUtils.cs +++ b/src/PowerShellEditorServices/Utility/VersionUtils.cs @@ -48,9 +48,9 @@ internal static class VersionUtils public static bool IsPS7OrGreater { get; } = PSVersion.Major >= 7; /// - /// True if we are running in PowerShell 7.4, false otherwise. + /// True if we are running in PowerShell 7.4 or greater, false otherwise. /// - public static bool IsPS74 { get; } = PSVersion.Major == 7 && PSVersion.Minor == 4; + public static bool IsPS74OrGreater { get; } = PSVersion >= new Version(7, 4); /// /// True if we are running on Windows, false otherwise. diff --git a/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj b/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj index 82c0899f5..a5f9dcd90 100644 --- a/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj +++ b/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj @@ -3,7 +3,7 @@ Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), PowerShellEditorServices.Common.props))\PowerShellEditorServices.Common.props" /> - net8.0 + net10.0 false diff --git a/test/PowerShellEditorServices.Test.Shared/Completion/CompleteVariableInFile.cs b/test/PowerShellEditorServices.Test.Shared/Completion/CompleteVariableInFile.cs index 3dbfb80c9..21742733c 100644 --- a/test/PowerShellEditorServices.Test.Shared/Completion/CompleteVariableInFile.cs +++ b/test/PowerShellEditorServices.Test.Shared/Completion/CompleteVariableInFile.cs @@ -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", diff --git a/test/PowerShellEditorServices.Test/PowerShellEditorServices.Test.csproj b/test/PowerShellEditorServices.Test/PowerShellEditorServices.Test.csproj index 0566b8cf2..7a1fdd941 100644 --- a/test/PowerShellEditorServices.Test/PowerShellEditorServices.Test.csproj +++ b/test/PowerShellEditorServices.Test/PowerShellEditorServices.Test.csproj @@ -2,7 +2,7 @@ - net8.0;net462 + net10.0;net462 Microsoft.PowerShell.EditorServices.Test x64 @@ -17,12 +17,12 @@ - + - - + +