diff --git a/.editorconfig b/.editorconfig index 48f4d1c5a..1cb572ef7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -39,7 +39,7 @@ dotnet_diagnostic.CS0649.severity = error # CS1570: Parameter has no matching param tag in the XML comment dotnet_diagnostic.CS1570.severity = silent # CS1574: XML comment has cref attribute that could not be resolved. -dotnet_diagnostic.CS1574.severity = suggestion +dotnet_diagnostic.CS1574.severity = silent # CS1591: Missing XML comment for publicly visible type or member dotnet_diagnostic.CS1591.severity = silent # CS1998: This async method lacks 'await' operators and will run synchronously diff --git a/PowerShellEditorServices.build.ps1 b/PowerShellEditorServices.build.ps1 index 34a1e7590..bf37c108b 100644 --- a/PowerShellEditorServices.build.ps1 +++ b/PowerShellEditorServices.build.ps1 @@ -203,7 +203,7 @@ Task TestE2E Build, SetupHelpForTests, { Set-Location .\test\PowerShellEditorServices.Test.E2E\ $env:PWSH_EXE_NAME = if ($IsCoreCLR) { "pwsh" } else { "powershell" } - Invoke-BuildExec { & dotnet $script:dotnetTestArgs $script:NetRuntime.PS72 } + Invoke-BuildExec { & dotnet $script:dotnetTestArgs $script:NetRuntime.PS73 } if (!$script:IsNix) { if (-not [Security.Principal.WindowsIdentity]::GetCurrent().Owner.IsWellKnown("BuiltInAdministratorsSid")) { @@ -214,7 +214,7 @@ Task TestE2E Build, SetupHelpForTests, { try { Write-Host "Running end-to-end tests in Constrained Language Mode." [System.Environment]::SetEnvironmentVariable("__PSLockdownPolicy", "0x80000007", [System.EnvironmentVariableTarget]::Machine); - Invoke-BuildExec { & dotnet $script:dotnetTestArgs $script:NetRuntime.PS72 } + Invoke-BuildExec { & dotnet $script:dotnetTestArgs $script:NetRuntime.PS73 } } finally { [System.Environment]::SetEnvironmentVariable("__PSLockdownPolicy", $null, [System.EnvironmentVariableTarget]::Machine); } diff --git a/src/PowerShellEditorServices/Extensions/EditorContext.cs b/src/PowerShellEditorServices/Extensions/EditorContext.cs index fef641a28..f2ab42e8c 100644 --- a/src/PowerShellEditorServices/Extensions/EditorContext.cs +++ b/src/PowerShellEditorServices/Extensions/EditorContext.cs @@ -86,26 +86,15 @@ public void SetSelection( /// /// The starting position of the selection. /// The ending position of the selection. - public void SetSelection( - FilePosition startPosition, - FilePosition endPosition) - { - SetSelection( - new FileRange( - startPosition, - endPosition)); - } + public void SetSelection(FilePosition startPosition, FilePosition endPosition) => SetSelection(new FileRange(startPosition, endPosition)); /// /// Sets a selection in the host editor's active buffer. /// /// The range of the selection. - public void SetSelection(FileRange selectionRange) - { - editorOperations - .SetSelectionAsync(selectionRange.ToBufferRange()) - .Wait(); - } + #pragma warning disable VSTHRD002 + public void SetSelection(FileRange selectionRange) => editorOperations.SetSelectionAsync(selectionRange.ToBufferRange()).Wait(); + #pragma warning restore VSTHRD002 #endregion } diff --git a/src/PowerShellEditorServices/Extensions/EditorFileRanges.cs b/src/PowerShellEditorServices/Extensions/EditorFileRanges.cs index ed6ae9de5..901307a73 100644 --- a/src/PowerShellEditorServices/Extensions/EditorFileRanges.cs +++ b/src/PowerShellEditorServices/Extensions/EditorFileRanges.cs @@ -274,7 +274,7 @@ public interface ILspCurrentFileContext : IFileContext ILspFileRange SelectionRange { get; } } - internal struct OmnisharpLspPosition : ILspFilePosition, IEquatable + internal readonly struct OmnisharpLspPosition : ILspFilePosition, IEquatable { private readonly Position _position; @@ -287,7 +287,7 @@ internal struct OmnisharpLspPosition : ILspFilePosition, IEquatable _position == other._position; } - internal struct OmnisharpLspRange : ILspFileRange, IEquatable + internal readonly struct OmnisharpLspRange : ILspFileRange, IEquatable { private readonly Range _range; @@ -300,7 +300,7 @@ internal struct OmnisharpLspRange : ILspFileRange, IEquatable public bool Equals(OmnisharpLspRange other) => _range == other._range; } - internal struct BufferFilePosition : IFilePosition, IEquatable + internal readonly struct BufferFilePosition : IFilePosition, IEquatable { private readonly BufferPosition _position; @@ -317,7 +317,7 @@ public bool Equals(BufferFilePosition other) } } - internal struct BufferFileRange : IFileRange, IEquatable + internal readonly struct BufferFileRange : IFileRange, IEquatable { private readonly BufferRange _range; diff --git a/src/PowerShellEditorServices/Extensions/EditorObject.cs b/src/PowerShellEditorServices/Extensions/EditorObject.cs index cfbd97254..17006baf2 100644 --- a/src/PowerShellEditorServices/Extensions/EditorObject.cs +++ b/src/PowerShellEditorServices/Extensions/EditorObject.cs @@ -115,7 +115,9 @@ internal EditorObject( /// at the time this method is invoked. /// /// A instance of the EditorContext class. + #pragma warning disable VSTHRD002, VSTHRD104 public EditorContext GetEditorContext() => _editorOperations.GetEditorContextAsync().Result; + #pragma warning restore VSTHRD002, VSTHRD104 internal void SetAsStaticInstance() { diff --git a/src/PowerShellEditorServices/Extensions/EditorWindow.cs b/src/PowerShellEditorServices/Extensions/EditorWindow.cs index ac986308a..428c192ea 100644 --- a/src/PowerShellEditorServices/Extensions/EditorWindow.cs +++ b/src/PowerShellEditorServices/Extensions/EditorWindow.cs @@ -39,6 +39,7 @@ internal EditorWindow(IEditorOperations editorOperations) #endregion #region Public Methods + #pragma warning disable VSTHRD002 // These are public APIs that use async internal methods. /// /// Shows an informational message to the user. @@ -71,6 +72,7 @@ internal EditorWindow(IEditorOperations editorOperations) /// A timeout in milliseconds for how long the message should remain visible. public void SetStatusBarMessage(string message, int timeout) => editorOperations.SetStatusBarMessageAsync(message, timeout).Wait(); + #pragma warning restore VSTHRD002 #endregion } } diff --git a/src/PowerShellEditorServices/Extensions/EditorWorkspace.cs b/src/PowerShellEditorServices/Extensions/EditorWorkspace.cs index 18f001d56..aa5802564 100644 --- a/src/PowerShellEditorServices/Extensions/EditorWorkspace.cs +++ b/src/PowerShellEditorServices/Extensions/EditorWorkspace.cs @@ -31,6 +31,7 @@ public sealed class EditorWorkspace #endregion #region Public Methods + #pragma warning disable VSTHRD002 // These are public APIs that use async internal methods. /// /// Creates a new file in the editor @@ -53,6 +54,7 @@ public sealed class EditorWorkspace /// Determines wether the file is opened as a preview or as a durable editor. public void OpenFile(string filePath, bool preview) => editorOperations.OpenFileAsync(filePath, preview).Wait(); + #pragma warning restore VSTHRD002 #endregion } } diff --git a/src/PowerShellEditorServices/Extensions/FileContext.cs b/src/PowerShellEditorServices/Extensions/FileContext.cs index ddd84029d..770cc33f7 100644 --- a/src/PowerShellEditorServices/Extensions/FileContext.cs +++ b/src/PowerShellEditorServices/Extensions/FileContext.cs @@ -209,12 +209,14 @@ public void InsertText( /// /// The text string to insert. /// The buffer range which will be replaced by the string. + #pragma warning disable VSTHRD002 public void InsertText(string textToInsert, IFileRange insertRange) { editorOperations .InsertTextAsync(scriptFile.DocumentUri.ToString(), textToInsert, insertRange.ToBufferRange()) .Wait(); } + #pragma warning restore VSTHRD002 #endregion @@ -232,6 +234,7 @@ public void InsertText(string textToInsert, IFileRange insertRange) /// the path where the file should be saved, /// including the file name with extension as the leaf /// + #pragma warning disable VSTHRD002 public void SaveAs(string newFilePath) { // Do some validation here so that we can provide a helpful error if the path won't work @@ -244,8 +247,9 @@ public void SaveAs(string newFilePath) throw new IOException(string.Format("The file '{0}' already exists", absolutePath)); } - editorOperations.SaveFileAsync(scriptFile.FilePath, newFilePath); + editorOperations.SaveFileAsync(scriptFile.FilePath, newFilePath).Wait(); } + #pragma warning restore VSTHRD002 #endregion } diff --git a/src/PowerShellEditorServices/Hosting/EditorServicesServerFactory.cs b/src/PowerShellEditorServices/Hosting/EditorServicesServerFactory.cs index 2ff417029..be599b27f 100644 --- a/src/PowerShellEditorServices/Hosting/EditorServicesServerFactory.cs +++ b/src/PowerShellEditorServices/Hosting/EditorServicesServerFactory.cs @@ -83,7 +83,7 @@ public static EditorServicesServerFactory Create(string logPath, int minimumLogL /// The protocol transport input stream. /// The protocol transport output stream. /// The host details configuration for Editor Services - /// instantation. + /// instantiation. /// A new, unstarted language server instance. public PsesLanguageServer CreateLanguageServer( Stream inputStream, diff --git a/src/PowerShellEditorServices/Logging/LoggerExtensions.cs b/src/PowerShellEditorServices/Logging/LoggerExtensions.cs index a580c7802..94c821e42 100644 --- a/src/PowerShellEditorServices/Logging/LoggerExtensions.cs +++ b/src/PowerShellEditorServices/Logging/LoggerExtensions.cs @@ -9,6 +9,7 @@ namespace Microsoft.PowerShell.EditorServices.Logging { internal static class LoggerExtensions { + // TODO: These need to be fixed (and used consistently). public static void LogException( this ILogger logger, string message, diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs b/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs index 4c9ef8735..7ea6ad435 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs @@ -559,19 +559,6 @@ public StackFrameDetails[] GetStackFrames() } } - internal StackFrameDetails[] GetStackFrames(CancellationToken cancellationToken) - { - debugInfoHandle.Wait(cancellationToken); - try - { - return stackFrameDetails; - } - finally - { - debugInfoHandle.Release(); - } - } - internal async Task GetStackFramesAsync() { await debugInfoHandle.WaitAsync().ConfigureAwait(false); diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/Debugging/InvalidPowerShellExpressionException.cs b/src/PowerShellEditorServices/Services/DebugAdapter/Debugging/InvalidPowerShellExpressionException.cs index 38c95f1ae..e04478639 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/Debugging/InvalidPowerShellExpressionException.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/Debugging/InvalidPowerShellExpressionException.cs @@ -14,9 +14,10 @@ public class InvalidPowerShellExpressionException : Exception /// Initializes a new instance of the SetVariableExpressionException class. /// /// Message indicating why the expression is invalid. - public InvalidPowerShellExpressionException(string message) - : base(message) - { - } + public InvalidPowerShellExpressionException(string message) : base(message) { } + + public InvalidPowerShellExpressionException() { } + + public InvalidPowerShellExpressionException(string message, Exception innerException) : base(message, innerException) { } } } diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/StackTraceHandler.cs b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/StackTraceHandler.cs index fb3b5e17e..f53e094e7 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/StackTraceHandler.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/StackTraceHandler.cs @@ -19,20 +19,19 @@ internal class StackTraceHandler : IStackTraceHandler public StackTraceHandler(DebugService debugService) => _debugService = debugService; - public Task Handle(StackTraceArguments request, CancellationToken cancellationToken) + public async Task Handle(StackTraceArguments request, CancellationToken cancellationToken) { - StackFrameDetails[] stackFrameDetails = - _debugService.GetStackFrames(cancellationToken); + StackFrameDetails[] stackFrameDetails = await _debugService.GetStackFramesAsync(cancellationToken).ConfigureAwait(false); // Handle a rare race condition where the adapter requests stack frames before they've // begun building. - if (stackFrameDetails == null) + if (stackFrameDetails is null) { - return Task.FromResult(new StackTraceResponse + return new StackTraceResponse { StackFrames = Array.Empty(), TotalFrames = 0 - }); + }; } List newStackFrames = new(); @@ -52,19 +51,14 @@ public Task Handle(StackTraceArguments request, Cancellation { // Create the new StackFrame object with an ID that can // be referenced back to the current list of stack frames - //newStackFrames.Add( - // StackFrame.Create( - // stackFrameDetails[i], - // i)); - newStackFrames.Add( - LspDebugUtils.CreateStackFrame(stackFrameDetails[i], id: i)); + newStackFrames.Add(LspDebugUtils.CreateStackFrame(stackFrameDetails[i], id: i)); } - return Task.FromResult(new StackTraceResponse + return new StackTraceResponse { StackFrames = newStackFrames, TotalFrames = newStackFrames.Count - }); + }; } } } diff --git a/src/PowerShellEditorServices/Services/PowerShell/Debugging/DscBreakpointCapability.cs b/src/PowerShellEditorServices/Services/PowerShell/Debugging/DscBreakpointCapability.cs index 3f6f05b24..644eec763 100644 --- a/src/PowerShellEditorServices/Services/PowerShell/Debugging/DscBreakpointCapability.cs +++ b/src/PowerShellEditorServices/Services/PowerShell/Debugging/DscBreakpointCapability.cs @@ -97,7 +97,7 @@ public static Task GetDscCapabilityAsync( return Task.FromResult(null); } - Func getDscBreakpointCapabilityFunc = (pwsh, _) => + DscBreakpointCapability getDscBreakpointCapabilityFunc(SMA.PowerShell pwsh, CancellationToken _) { PSInvocationSettings invocationSettings = new() { @@ -159,7 +159,7 @@ public static Task GetDscCapabilityAsync( logger.LogTrace($"DSC resources found: {resourcePaths.Count}"); return capability; - }; + } return psesHost.ExecuteDelegateAsync( nameof(getDscBreakpointCapabilityFunc), diff --git a/src/PowerShellEditorServices/Services/PowerShell/Handlers/GetVersionHandler.cs b/src/PowerShellEditorServices/Services/PowerShell/Handlers/GetVersionHandler.cs index 025f92f5a..f6aaf1779 100644 --- a/src/PowerShellEditorServices/Services/PowerShell/Handlers/GetVersionHandler.cs +++ b/src/PowerShellEditorServices/Services/PowerShell/Handlers/GetVersionHandler.cs @@ -10,15 +10,15 @@ namespace Microsoft.PowerShell.EditorServices.Handlers { internal class GetVersionHandler : IGetVersionHandler { - public async Task Handle(GetVersionParams request, CancellationToken cancellationToken) + public Task Handle(GetVersionParams request, CancellationToken cancellationToken) { - return new PowerShellVersion + return Task.FromResult(new PowerShellVersion { Version = VersionUtils.PSVersionString, Edition = VersionUtils.PSEdition, Commit = VersionUtils.GitCommitId, Architecture = VersionUtils.Architecture - }; + }); } } } diff --git a/src/PowerShellEditorServices/Services/PowerShell/Handlers/PSHostProcessAndRunspaceHandlers.cs b/src/PowerShellEditorServices/Services/PowerShell/Handlers/PSHostProcessAndRunspaceHandlers.cs index ed0b37b04..fcf58cce3 100644 --- a/src/PowerShellEditorServices/Services/PowerShell/Handlers/PSHostProcessAndRunspaceHandlers.cs +++ b/src/PowerShellEditorServices/Services/PowerShell/Handlers/PSHostProcessAndRunspaceHandlers.cs @@ -62,10 +62,7 @@ public async Task Handle(GetRunspaceParams request, Cancella { IEnumerable runspaces = null; - if (request.ProcessId == null) - { - request.ProcessId = "current"; - } + request.ProcessId ??= "current"; // If the processId is a valid int, we need to run Get-Runspace within that process // otherwise just use the current runspace. diff --git a/src/PowerShellEditorServices/Services/PowerShell/Utility/CommandHelpers.cs b/src/PowerShellEditorServices/Services/PowerShell/Utility/CommandHelpers.cs index da4a89a34..7750aa042 100644 --- a/src/PowerShellEditorServices/Services/PowerShell/Utility/CommandHelpers.cs +++ b/src/PowerShellEditorServices/Services/PowerShell/Utility/CommandHelpers.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Management.Automation; using System.Threading; using System.Threading.Tasks; @@ -241,7 +242,7 @@ public static async Task GetAliasesAsync( .AddParameter("CommandType", CommandTypes.Alias), cancellationToken).ConfigureAwait(false); - foreach (AliasInfo aliasInfo in aliases) + foreach (AliasInfo aliasInfo in aliases.Cast()) { // TODO: When we move to netstandard2.1, we can use another overload which generates // static delegates and thus reduces allocations. diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs index 895c804ec..2861fe27f 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs @@ -35,16 +35,7 @@ public PsesCodeActionHandler(ILoggerFactory factory, AnalysisService analysisSer CodeActionKinds = new CodeActionKind[] { CodeActionKind.QuickFix } }; - // TODO: Either fix or ignore "method lacks 'await'" warning. - public override async Task Handle(CodeAction request, CancellationToken cancellationToken) - { - // TODO: How on earth do we handle a CodeAction? This is new... - if (cancellationToken.IsCancellationRequested) - { - _logger.LogDebug("CodeAction request canceled for: {Title}", request.Title); - } - return request; - } + public override Task Handle(CodeAction request, CancellationToken cancellationToken) => Task.FromResult(request); public override async Task Handle(CodeActionParams request, CancellationToken cancellationToken) { diff --git a/src/PowerShellEditorServices/Services/TextDocument/TokenOperations.cs b/src/PowerShellEditorServices/Services/TextDocument/TokenOperations.cs index d1a3ca5e5..4299993f7 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/TokenOperations.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/TokenOperations.cs @@ -136,7 +136,7 @@ internal static FoldingReferenceList FoldableReferences(Token[] tokens) refList.SafeAdd(CreateFoldingReference(blockStartToken, blockNextLine - 1, FoldingRangeKind.Comment)); blockStartToken = token; } - if (blockStartToken == null) { blockStartToken = token; } + blockStartToken ??= token; blockNextLine = thisLine + 1; } diff --git a/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs b/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs index 7f9a43049..3efe4edcf 100644 --- a/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs +++ b/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs @@ -39,6 +39,7 @@ public override async Task> Handle(WorkspaceSymbolP foreach (ScriptFile scriptFile in _workspaceService.GetOpenedFiles()) { + _logger.LogDebug($"Handling workspace symbols request for: {request.Query}"); IEnumerable foundSymbols = _symbolsService.FindSymbolsInFile(scriptFile); // TODO: Need to compute a relative path that is based on common path for all workspace files @@ -89,7 +90,7 @@ public override async Task> Handle(WorkspaceSymbolP }); } } - _logger.LogWarning("Logging in a handler works now."); + return new Container(symbols); } diff --git a/src/PowerShellEditorServices/Services/Workspace/RemoteFileManagerService.cs b/src/PowerShellEditorServices/Services/Workspace/RemoteFileManagerService.cs index 1229951de..0a7ed4c74 100644 --- a/src/PowerShellEditorServices/Services/Workspace/RemoteFileManagerService.cs +++ b/src/PowerShellEditorServices/Services/Workspace/RemoteFileManagerService.cs @@ -528,24 +528,22 @@ private void HandleRunspaceChanged(object sender, RunspaceChangedEventArgs e) } // Close any remote files that were opened - if (ShouldTearDownRemoteFiles(e)) + if (ShouldTearDownRemoteFiles(e) + && filesPerComputer.TryGetValue(e.PreviousRunspace.SessionDetails.ComputerName, out RemotePathMappings remotePathMappings)) { - if (filesPerComputer.TryGetValue(e.PreviousRunspace.SessionDetails.ComputerName, out RemotePathMappings remotePathMappings)) + List fileCloseTasks = new(); + foreach (string remotePath in remotePathMappings.OpenedPaths) { - List fileCloseTasks = new(); - foreach (string remotePath in remotePathMappings.OpenedPaths) - { - fileCloseTasks.Add(editorOperations?.CloseFileAsync(remotePath)); - } + fileCloseTasks.Add(editorOperations?.CloseFileAsync(remotePath)); + } - try - { - Task.WaitAll(fileCloseTasks.ToArray()); - } - catch (Exception ex) - { - logger.LogError(ex, "Unable to close all files in closed runspace"); - } + try + { + Task.WaitAll(fileCloseTasks.ToArray()); + } + catch (Exception ex) + { + logger.LogError(ex, "Unable to close all files in closed runspace"); } } diff --git a/src/PowerShellEditorServices/Utility/IScriptExtentExtensions.cs b/src/PowerShellEditorServices/Utility/IScriptExtentExtensions.cs deleted file mode 100644 index 29f78dc98..000000000 --- a/src/PowerShellEditorServices/Utility/IScriptExtentExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System.Management.Automation.Language; -using OmniSharp.Extensions.LanguageServer.Protocol.Models; - -namespace Microsoft.PowerShell.EditorServices.Utility -{ - internal static class IScriptExtentExtensions - { - public static Range ToRange(this IScriptExtent scriptExtent) - { - return new Range - { - Start = new Position - { - Line = scriptExtent.StartLineNumber - 1, - Character = scriptExtent.StartColumnNumber - 1 - }, - End = new Position - { - Line = scriptExtent.EndLineNumber - 1, - Character = scriptExtent.EndColumnNumber - 1 - } - }; - } - } -} diff --git a/src/PowerShellEditorServices/Utility/PSCommandExtensions.cs b/src/PowerShellEditorServices/Utility/PSCommandExtensions.cs index 6a9390af1..b16129af9 100644 --- a/src/PowerShellEditorServices/Utility/PSCommandExtensions.cs +++ b/src/PowerShellEditorServices/Utility/PSCommandExtensions.cs @@ -4,48 +4,14 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq.Expressions; using System.Management.Automation; using System.Management.Automation.Runspaces; -using System.Reflection; using System.Text; namespace Microsoft.PowerShell.EditorServices.Utility { internal static class PSCommandHelpers { - private static readonly Func s_commandCtor; - - static PSCommandHelpers() - { - ConstructorInfo ctor = typeof(Command).GetConstructor( - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, - binder: null, - new[] { typeof(CommandInfo) }, - modifiers: null); - - ParameterExpression commandInfo = Expression.Parameter(typeof(CommandInfo), nameof(commandInfo)); - - s_commandCtor = Expression.Lambda>( - Expression.New(ctor, commandInfo), - new[] { commandInfo }) - .Compile(); - } - - /// - /// PowerShell's missing an API for us to AddCommand using a CommandInfo. - /// An issue was filed here: https://github.com/PowerShell/PowerShell/issues/12295 - /// This works around this by creating a `Command` and passing it into PSCommand.AddCommand(Command command) - /// - /// - /// - /// - public static PSCommand AddCommand(this PSCommand command, CommandInfo commandInfo) - { - Command rsCommand = s_commandCtor(commandInfo); - return command.AddCommand(rsCommand); - } - public static PSCommand AddOutputCommand(this PSCommand psCommand) { return psCommand.MergePipelineResults() diff --git a/src/PowerShellEditorServices/Utility/PathUtils.cs b/src/PowerShellEditorServices/Utility/PathUtils.cs index 066bf5917..112e8b465 100644 --- a/src/PowerShellEditorServices/Utility/PathUtils.cs +++ b/src/PowerShellEditorServices/Utility/PathUtils.cs @@ -10,26 +10,6 @@ namespace Microsoft.PowerShell.EditorServices.Utility { internal static class PathUtils { - /// - /// The default path separator used by the base implementation of the providers. - /// - /// Porting note: IO.Path.DirectorySeparatorChar is correct for all platforms. On Windows, - /// it is '\', and on Linux, it is '/', as expected. - /// - /// - internal static readonly char DefaultPathSeparator = Path.DirectorySeparatorChar; - - /// - /// The alternate path separator used by the base implementation of the providers. - /// - /// Porting note: we do not use .NET's AlternatePathSeparatorChar here because it correctly - /// states that both the default and alternate are '/' on Linux. However, for PowerShell to - /// be "slash agnostic", we need to use the assumption that a '\' is the alternate path - /// separator on Linux. - /// - /// - internal static readonly char AlternatePathSeparator = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? '/' : '\\'; - /// /// The value to be used when comparing paths. Will be /// for case sensitive file systems and @@ -39,13 +19,6 @@ internal static class PathUtils ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; - /// - /// Converts all alternate path separators to the current platform's main path separators. - /// - /// The path to normalize. - /// The normalized path. - public static string NormalizePathSeparators(string path) => string.IsNullOrWhiteSpace(path) ? path : path.Replace(AlternatePathSeparator, DefaultPathSeparator); - /// /// Determines whether two specified strings represent the same path. /// @@ -67,8 +40,8 @@ internal static bool IsPathEqual(string left, string right) return false; } - left = Path.GetFullPath(left).TrimEnd(DefaultPathSeparator); - right = Path.GetFullPath(right).TrimEnd(DefaultPathSeparator); + left = Path.GetFullPath(left).TrimEnd(Path.DirectorySeparatorChar); + right = Path.GetFullPath(right).TrimEnd(Path.DirectorySeparatorChar); return left.Equals(right, PathComparison); } diff --git a/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs b/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs index d990ebe09..fd4854f04 100644 --- a/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs +++ b/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs @@ -151,7 +151,7 @@ function CanSendWorkspaceSymbolRequest { .Returning>(CancellationToken.None).ConfigureAwait(true); SymbolInformation symbol = Assert.Single(symbols); - Assert.Equal("CanSendWorkspaceSymbolRequest { }", symbol.Name); + Assert.Equal("function CanSendWorkspaceSymbolRequest ()", symbol.Name); } [SkippableFact] @@ -518,7 +518,7 @@ await PsesLanguageClient }) .Returning(CancellationToken.None).ConfigureAwait(true); - Assert.Collection(documentHighlights, + Assert.Collection(documentHighlights.OrderBy(i => i.Range.Start.Line), documentHighlight1 => { Range range = documentHighlight1.Range; @@ -868,8 +868,8 @@ function CanSendReferencesCodeLensRequest { Range range = codeLens.Range; Assert.Equal(1, range.Start.Line); Assert.Equal(9, range.Start.Character); - Assert.Equal(3, range.End.Line); - Assert.Equal(1, range.End.Character); + Assert.Equal(1, range.End.Line); + Assert.Equal(41, range.End.Character); CodeLens codeLensResolveResult = await PsesLanguageClient .SendRequest("codeLens/resolve", codeLens) @@ -910,26 +910,26 @@ class ChildClass : MyBaseClass, System.IDisposable { }) .Returning(CancellationToken.None).ConfigureAwait(true); - Assert.Collection(codeLenses, + Assert.Collection(codeLenses.OrderBy(i => i.Range.Start.Line), codeLens => { Range range = codeLens.Range; Assert.Equal(5, range.Start.Line); Assert.Equal(6, range.Start.Character); - Assert.Equal(7, range.End.Line); - Assert.Equal(1, range.End.Character); + Assert.Equal(5, range.End.Line); + Assert.Equal(17, range.End.Character); }, codeLens => { Range range = codeLens.Range; Assert.Equal(9, range.Start.Line); Assert.Equal(6, range.Start.Character); - Assert.Equal(11, range.End.Line); - Assert.Equal(1, range.End.Character); + Assert.Equal(9, range.End.Line); + Assert.Equal(16, range.End.Character); } ); - CodeLens baseClassCodeLens = codeLenses.First(); + CodeLens baseClassCodeLens = codeLenses.OrderBy(i => i.Range.Start.Line).First(); CodeLens codeLensResolveResult = await PsesLanguageClient .SendRequest("codeLens/resolve", baseClassCodeLens) .Returning(CancellationToken.None).ConfigureAwait(true); @@ -972,8 +972,8 @@ enum MyEnum { Range range = codeLens.Range; Assert.Equal(5, range.Start.Line); Assert.Equal(5, range.Start.Character); - Assert.Equal(9, range.End.Line); - Assert.Equal(1, range.End.Character); + Assert.Equal(5, range.End.Line); + Assert.Equal(11, range.End.Character); CodeLens codeLensResolveResult = await PsesLanguageClient .SendRequest("codeLens/resolve", codeLens) @@ -1146,7 +1146,7 @@ public async Task CanSendHoverRequestAsync() Assert.True(hover.Contents.HasMarkedStrings); Assert.Collection(hover.Contents.MarkedStrings, - str1 => Assert.Equal("function Write-Host", str1.Value), + str1 => Assert.Equal("Write-Host", str1.Value), str2 => { Assert.Equal("markdown", str2.Language); @@ -1157,7 +1157,7 @@ public async Task CanSendHoverRequestAsync() [Fact] public async Task CanSendSignatureHelpRequestAsync() { - string filePath = NewTestFile("Get-Date "); + string filePath = NewTestFile("Get-Date -"); SignatureHelp signatureHelp = await PsesLanguageClient .SendRequest( @@ -1171,7 +1171,7 @@ public async Task CanSendSignatureHelpRequestAsync() Position = new Position { Line = 0, - Character = 9 + Character = 10 } }) .Returning(CancellationToken.None).ConfigureAwait(true); diff --git a/test/PowerShellEditorServices.Test/Language/TokenOperationsTests.cs b/test/PowerShellEditorServices.Test/Language/TokenOperationsTests.cs index 325384d05..a47d765e1 100644 --- a/test/PowerShellEditorServices.Test/Language/TokenOperationsTests.cs +++ b/test/PowerShellEditorServices.Test/Language/TokenOperationsTests.cs @@ -174,7 +174,7 @@ public void LanguageServiceFindsFoldablRegionsWithLF() // Remove and CR characters string testString = allInOneScript.Replace("\r", ""); // Ensure that there are no CR characters in the string - Assert.True(testString.IndexOf("\r\n") == -1, "CRLF should not be present in the test string"); + Assert.False(testString.Contains("\r\n"), "CRLF should not be present in the test string"); FoldingReference[] result = GetRegions(testString); AssertFoldingReferenceArrays(expectedAllInOneScriptFolds, result); } diff --git a/test/PowerShellEditorServices.Test/PsesHostFactory.cs b/test/PowerShellEditorServices.Test/PsesHostFactory.cs index 8d535b260..b2d4ceb7c 100644 --- a/test/PowerShellEditorServices.Test/PsesHostFactory.cs +++ b/test/PowerShellEditorServices.Test/PsesHostFactory.cs @@ -61,8 +61,9 @@ public static PsesInternalHost Create(ILoggerFactory loggerFactory, bool loadPro PsesInternalHost psesHost = new(loggerFactory, null, testHostDetails); - // NOTE: Because this is used by constructors it can't use await. + #pragma warning disable VSTHRD002 // Because this is used by constructors it can't use await. if (psesHost.TryStartAsync(new HostStartOptions { LoadProfiles = loadProfiles }, CancellationToken.None).GetAwaiter().GetResult()) + #pragma warning restore VSTHRD002 { return psesHost; }