diff --git a/src/PowerShellEditorServices/Extensions/Api/EditorContextService.cs b/src/PowerShellEditorServices/Extensions/Api/EditorContextService.cs index 4440dede4..e9c3cab87 100644 --- a/src/PowerShellEditorServices/Extensions/Api/EditorContextService.cs +++ b/src/PowerShellEditorServices/Extensions/Api/EditorContextService.cs @@ -4,6 +4,7 @@ // using System; +using System.Threading; using System.Threading.Tasks; using Microsoft.PowerShell.EditorServices.Handlers; using OmniSharp.Extensions.LanguageServer.Protocol.Server; @@ -94,16 +95,18 @@ internal EditorContextService( public async Task GetCurrentLspFileContextAsync() { ClientEditorContext clientContext = - await _languageServer.SendRequest( + await _languageServer.SendRequest( "editor/getEditorContext", - new GetEditorContextRequest()).ConfigureAwait(false); + new GetEditorContextRequest()) + .Returning(CancellationToken.None) + .ConfigureAwait(false); return new LspCurrentFileContext(clientContext); } public Task OpenNewUntitledFileAsync() { - return _languageServer.SendRequest("editor/newFile", null); + return _languageServer.SendRequest("editor/newFile", null).ReturningVoid(CancellationToken.None); } public Task OpenFileAsync(Uri fileUri) => OpenFileAsync(fileUri, preview: false); @@ -114,12 +117,12 @@ public Task OpenFileAsync(Uri fileUri, bool preview) { FilePath = fileUri.LocalPath, Preview = preview, - }); + }).ReturningVoid(CancellationToken.None); } public Task CloseFileAsync(Uri fileUri) { - return _languageServer.SendRequest("editor/closeFile", fileUri.LocalPath); + return _languageServer.SendRequest("editor/closeFile", fileUri.LocalPath).ReturningVoid(CancellationToken.None); } public Task SaveFileAsync(Uri fileUri) => SaveFileAsync(fileUri, null); @@ -130,7 +133,7 @@ public Task SaveFileAsync(Uri oldFileUri, Uri newFileUri) { FilePath = oldFileUri.LocalPath, NewPath = newFileUri?.LocalPath, - }); + }).ReturningVoid(CancellationToken.None); } public Task SetSelectionAsync(ILspFileRange range) @@ -138,7 +141,7 @@ public Task SetSelectionAsync(ILspFileRange range) return _languageServer.SendRequest("editor/setSelection", new SetSelectionRequest { SelectionRange = range.ToOmnisharpRange() - }); + }).ReturningVoid(CancellationToken.None); } public Task InsertTextAsync(Uri fileUri, string text, ILspFileRange range) @@ -148,7 +151,7 @@ public Task InsertTextAsync(Uri fileUri, string text, ILspFileRange range) FilePath = fileUri.LocalPath, InsertText = text, InsertRange = range.ToOmnisharpRange(), - }); + }).ReturningVoid(CancellationToken.None); } } } diff --git a/src/PowerShellEditorServices/Extensions/Api/EditorUIService.cs b/src/PowerShellEditorServices/Extensions/Api/EditorUIService.cs index 3eaade2a1..0e58d7d64 100644 --- a/src/PowerShellEditorServices/Extensions/Api/EditorUIService.cs +++ b/src/PowerShellEditorServices/Extensions/Api/EditorUIService.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Microsoft.PowerShell.EditorServices.Services.PowerShellContext; using OmniSharp.Extensions.LanguageServer.Protocol.Server; @@ -112,12 +113,12 @@ public EditorUIService(ILanguageServer languageServer) public async Task PromptInputAsync(string message) { // The VSCode client currently doesn't use the Label field, so we ignore it - ShowInputPromptResponse response = await _languageServer.SendRequest( + ShowInputPromptResponse response = await _languageServer.SendRequest( "powerShell/showInputPrompt", new ShowInputPromptRequest { Name = message, - }); + }).Returning(CancellationToken.None); if (response.PromptCancelled) { @@ -134,7 +135,7 @@ public async Task> PromptMultipleSelectionAsync(string mes { ChoiceDetails[] choiceDetails = GetChoiceDetails(choices); - ShowChoicePromptResponse response = await _languageServer.SendRequest( + ShowChoicePromptResponse response = await _languageServer.SendRequest( "powerShell/showChoicePrompt", new ShowChoicePromptRequest { @@ -143,7 +144,7 @@ public async Task> PromptMultipleSelectionAsync(string mes Message = message, Choices = choiceDetails, DefaultChoices = defaultChoiceIndexes?.ToArray(), - }); + }).Returning(CancellationToken.None); if (response.PromptCancelled) { @@ -160,7 +161,7 @@ public async Task PromptSelectionAsync(string message, IReadOnlyList( + ShowChoicePromptResponse response = await _languageServer.SendRequest( "powerShell/showChoicePrompt", new ShowChoicePromptRequest { @@ -169,7 +170,7 @@ public async Task PromptSelectionAsync(string message, IReadOnlyList -1 ? new[] { defaultChoiceIndex } : null, - }); + }).Returning(CancellationToken.None); if (response.PromptCancelled) { diff --git a/src/PowerShellEditorServices/Extensions/Api/LanguageServerService.cs b/src/PowerShellEditorServices/Extensions/Api/LanguageServerService.cs index a50b600ad..0e7be9043 100644 --- a/src/PowerShellEditorServices/Extensions/Api/LanguageServerService.cs +++ b/src/PowerShellEditorServices/Extensions/Api/LanguageServerService.cs @@ -5,6 +5,7 @@ using MediatR; using OmniSharp.Extensions.LanguageServer.Protocol.Server; +using System.Threading; using System.Threading.Tasks; namespace Microsoft.PowerShell.EditorServices.Extensions.Services @@ -89,27 +90,27 @@ public void SendNotification(string method, object parameters) public Task SendRequestAsync(string method) { - return _languageServer.SendRequest(method); + return _languageServer.SendRequest(method).ReturningVoid(CancellationToken.None); } public Task SendRequestAsync(string method, T parameters) { - return _languageServer.SendRequest(method, parameters); + return _languageServer.SendRequest(method, parameters).ReturningVoid(CancellationToken.None); } public Task SendRequestAsync(string method) { - return _languageServer.SendRequest(method); + return _languageServer.SendRequest(method).Returning(CancellationToken.None); } public Task SendRequestAsync(string method, T parameters) { - return _languageServer.SendRequest(method, parameters); + return _languageServer.SendRequest(method, parameters).Returning(CancellationToken.None); } public Task SendRequestAsync(string method, object parameters) { - return _languageServer.SendRequest(method, parameters); + return _languageServer.SendRequest(method, parameters).Returning(CancellationToken.None); } } } diff --git a/src/PowerShellEditorServices/Extensions/EditorFileRanges.cs b/src/PowerShellEditorServices/Extensions/EditorFileRanges.cs index d91e8bdaf..2e73774f5 100644 --- a/src/PowerShellEditorServices/Extensions/EditorFileRanges.cs +++ b/src/PowerShellEditorServices/Extensions/EditorFileRanges.cs @@ -204,12 +204,12 @@ public interface ILspFilePosition /// /// The line index of the position within the file. /// - long Line { get; } + int Line { get; } /// /// The character offset from the line of the position. /// - long Character { get; } + int Character { get; } } /// @@ -260,9 +260,9 @@ public OmnisharpLspPosition(Position position) _position = position; } - public long Line => _position.Line; + public int Line => _position.Line; - public long Character => _position.Character; + public int Character => _position.Character; public bool Equals(OmnisharpLspPosition other) { @@ -350,15 +350,15 @@ public FilePosition(int line, int column) /// public class LspFilePosition : ILspFilePosition { - public LspFilePosition(long line, long column) + public LspFilePosition(int line, int column) { Line = line; Character = column; } - public long Line { get; } + public int Line { get; } - public long Character { get; } + public int Character { get; } } /// @@ -455,7 +455,7 @@ public static ILspFileRange ToLspRange(this IFileRange range) /// An equivalent 1-based file position. public static IFilePosition ToFilePosition(this ILspFilePosition position) { - return new FilePosition((int)position.Line + 1, (int)position.Character + 1); + return new FilePosition(position.Line + 1, position.Character + 1); } /// diff --git a/src/PowerShellEditorServices/PowerShellEditorServices.csproj b/src/PowerShellEditorServices/PowerShellEditorServices.csproj index 988f97ca0..159cf9b81 100644 --- a/src/PowerShellEditorServices/PowerShellEditorServices.csproj +++ b/src/PowerShellEditorServices/PowerShellEditorServices.csproj @@ -39,7 +39,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/src/PowerShellEditorServices/Server/PsesLanguageServer.cs b/src/PowerShellEditorServices/Server/PsesLanguageServer.cs index ca7786fe0..c62973992 100644 --- a/src/PowerShellEditorServices/Server/PsesLanguageServer.cs +++ b/src/PowerShellEditorServices/Server/PsesLanguageServer.cs @@ -92,7 +92,7 @@ public async Task StartAsync() .WithHandler() .WithHandler() .OnInitialize( - async (languageServer, request) => + async (languageServer, request, cancellationToken) => { var serviceProvider = languageServer.Services; var workspaceService = serviceProvider.GetService(); @@ -100,7 +100,17 @@ public async Task StartAsync() // Grab the workspace path from the parameters if (request.RootUri != null) { - workspaceService.WorkspacePath = workspaceService.ResolveFileUri(request.RootUri).LocalPath; + workspaceService.WorkspacePath = request.RootUri.GetFileSystemPath(); + } + else + { + // If RootUri isn't set, try to use the first WorkspaceFolder. + // TODO: Support multi-workspace. + foreach (var workspaceFolder in request.WorkspaceFolders) + { + workspaceService.WorkspacePath = workspaceFolder.Uri.GetFileSystemPath(); + break; + } } // Set the working directory of the PowerShell session to the workspace path diff --git a/src/PowerShellEditorServices/Services/Analysis/AnalysisService.cs b/src/PowerShellEditorServices/Services/Analysis/AnalysisService.cs index 33c9b4480..858441fa8 100644 --- a/src/PowerShellEditorServices/Services/Analysis/AnalysisService.cs +++ b/src/PowerShellEditorServices/Services/Analysis/AnalysisService.cs @@ -17,6 +17,7 @@ using Microsoft.PowerShell.EditorServices.Services.Analysis; using Microsoft.PowerShell.EditorServices.Services.Configuration; using Microsoft.PowerShell.EditorServices.Services.TextDocument; +using OmniSharp.Extensions.LanguageServer.Protocol; using OmniSharp.Extensions.LanguageServer.Protocol.Models; using OmniSharp.Extensions.LanguageServer.Protocol.Server; @@ -41,7 +42,7 @@ internal static string GetUniqueIdFromDiagnostic(Diagnostic diagnostic) var sb = new StringBuilder(256) .Append(diagnostic.Source ?? "?") .Append("_") - .Append(diagnostic.Code.IsString ? diagnostic.Code.String : diagnostic.Code.Long.ToString()) + .Append(diagnostic.Code?.IsString ?? true ? diagnostic.Code?.String : diagnostic.Code?.Long.ToString()) .Append("_") .Append(diagnostic.Severity?.ToString() ?? "?") .Append("_") @@ -421,7 +422,7 @@ private void PublishScriptDiagnostics(ScriptFile scriptFile, IReadOnlyList(diagnostics) }); } diff --git a/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs b/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs index 75244caff..50400ff55 100644 --- a/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs +++ b/src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs @@ -88,8 +88,8 @@ public CodeLens ResolveCodeLens(CodeLens codeLens, ScriptFile scriptFile) SymbolReference foundSymbol = _symbolsService.FindFunctionDefinitionAtLocation( scriptFile, - (int)codeLens.Range.Start.Line + 1, - (int)codeLens.Range.Start.Character + 1); + codeLens.Range.Start.Line + 1, + codeLens.Range.Start.Character + 1); List referencesResult = _symbolsService.FindReferencesOfSymbol( foundSymbol, diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/BreakpointHandlers.cs b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/BreakpointHandlers.cs index 02c6e9080..f50221c92 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/BreakpointHandlers.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/BreakpointHandlers.cs @@ -181,8 +181,8 @@ public async Task Handle(SetBreakpointsArguments request BreakpointDetails[] breakpointDetails = request.Breakpoints .Select((srcBreakpoint) => BreakpointDetails.Create( scriptFile.FilePath, - (int)srcBreakpoint.Line, - (int?)srcBreakpoint.Column, + srcBreakpoint.Line, + srcBreakpoint.Column, srcBreakpoint.Condition, srcBreakpoint.HitCondition, srcBreakpoint.LogMessage)) diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ConfigurationDoneHandler.cs b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ConfigurationDoneHandler.cs index f566b2c53..118f0a925 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ConfigurationDoneHandler.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/ConfigurationDoneHandler.cs @@ -46,7 +46,7 @@ public ConfigurationDoneHandler( _workspaceService = workspaceService; } - public async Task Handle(ConfigurationDoneArguments request, CancellationToken cancellationToken) + public Task Handle(ConfigurationDoneArguments request, CancellationToken cancellationToken) { _debugService.IsClientAttached = true; @@ -90,7 +90,7 @@ public async Task Handle(ConfigurationDoneArguments r } } - return new ConfigurationDoneResponse(); + return Task.FromResult(new ConfigurationDoneResponse()); } private async Task LaunchScriptAsync(string scriptToLaunch) diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs b/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs index 7b787d736..78e907acb 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/EditorOperationsService.cs @@ -8,6 +8,7 @@ using Microsoft.PowerShell.EditorServices.Services.TextDocument; using OmniSharp.Extensions.LanguageServer.Protocol.Models; using OmniSharp.Extensions.LanguageServer.Protocol.Server; +using System.Threading; using System.Threading.Tasks; namespace Microsoft.PowerShell.EditorServices.Services @@ -38,9 +39,11 @@ public async Task GetEditorContextAsync() }; ClientEditorContext clientContext = - await _languageServer.SendRequest( + await _languageServer.SendRequest( "editor/getEditorContext", - new GetEditorContextRequest()).ConfigureAwait(false); + new GetEditorContextRequest()) + .Returning(CancellationToken.None) + .ConfigureAwait(false); return this.ConvertClientEditorContext(clientContext); } @@ -70,7 +73,7 @@ public async Task InsertTextAsync(string filePath, string text, BufferRange inse Character = insertRange.End.Column - 1 } } - }).ConfigureAwait(false); + }).ReturningVoid(CancellationToken.None).ConfigureAwait(false); } public async Task SetSelectionAsync(BufferRange selectionRange) @@ -96,7 +99,7 @@ public async Task SetSelectionAsync(BufferRange selectionRange) Character = selectionRange.End.Column - 1 } } - }).ConfigureAwait(false); + }).ReturningVoid(CancellationToken.None).ConfigureAwait(false); } public EditorContext ConvertClientEditorContext( @@ -111,13 +114,13 @@ public EditorContext ConvertClientEditorContext( this, scriptFile, new BufferPosition( - (int) clientContext.CursorPosition.Line + 1, - (int) clientContext.CursorPosition.Character + 1), + clientContext.CursorPosition.Line + 1, + clientContext.CursorPosition.Character + 1), new BufferRange( - (int) clientContext.SelectionRange.Start.Line + 1, - (int) clientContext.SelectionRange.Start.Character + 1, - (int) clientContext.SelectionRange.End.Line + 1, - (int) clientContext.SelectionRange.End.Character + 1), + clientContext.SelectionRange.Start.Line + 1, + clientContext.SelectionRange.Start.Character + 1, + clientContext.SelectionRange.End.Line + 1, + clientContext.SelectionRange.End.Character + 1), clientContext.CurrentFileLanguage); } @@ -128,7 +131,9 @@ public async Task NewFileAsync() return; }; - await _languageServer.SendRequest("editor/newFile", null).ConfigureAwait(false); + await _languageServer.SendRequest("editor/newFile", null) + .ReturningVoid(CancellationToken.None) + .ConfigureAwait(false); } public async Task OpenFileAsync(string filePath) @@ -142,7 +147,7 @@ public async Task OpenFileAsync(string filePath) { FilePath = filePath, Preview = DefaultPreviewSetting - }).ConfigureAwait(false); + }).ReturningVoid(CancellationToken.None).ConfigureAwait(false); } public async Task OpenFileAsync(string filePath, bool preview) @@ -156,7 +161,7 @@ public async Task OpenFileAsync(string filePath, bool preview) { FilePath = filePath, Preview = preview - }).ConfigureAwait(false); + }).ReturningVoid(CancellationToken.None).ConfigureAwait(false); } public async Task CloseFileAsync(string filePath) @@ -166,7 +171,9 @@ public async Task CloseFileAsync(string filePath) return; }; - await _languageServer.SendRequest("editor/closeFile", filePath).ConfigureAwait(false); + await _languageServer.SendRequest("editor/closeFile", filePath) + .ReturningVoid(CancellationToken.None) + .ConfigureAwait(false); } public Task SaveFileAsync(string filePath) @@ -185,7 +192,7 @@ public async Task SaveFileAsync(string currentPath, string newSavePath) { FilePath = currentPath, NewPath = newSavePath - }).ConfigureAwait(false); + }).ReturningVoid(CancellationToken.None).ConfigureAwait(false); } public string GetWorkspacePath() @@ -205,7 +212,9 @@ public async Task ShowInformationMessageAsync(string message) return; }; - await _languageServer.SendRequest("editor/showInformationMessage", message).ConfigureAwait(false); + await _languageServer.SendRequest("editor/showInformationMessage", message) + .ReturningVoid(CancellationToken.None) + .ConfigureAwait(false); } public async Task ShowErrorMessageAsync(string message) @@ -215,7 +224,9 @@ public async Task ShowErrorMessageAsync(string message) return; }; - await _languageServer.SendRequest("editor/showErrorMessage", message).ConfigureAwait(false); + await _languageServer.SendRequest("editor/showErrorMessage", message) + .ReturningVoid(CancellationToken.None) + .ConfigureAwait(false); } public async Task ShowWarningMessageAsync(string message) @@ -225,7 +236,9 @@ public async Task ShowWarningMessageAsync(string message) return; }; - await _languageServer.SendRequest("editor/showWarningMessage", message).ConfigureAwait(false); + await _languageServer.SendRequest("editor/showWarningMessage", message) + .ReturningVoid(CancellationToken.None) + .ConfigureAwait(false); } public async Task SetStatusBarMessageAsync(string message, int? timeout) @@ -239,7 +252,7 @@ public async Task SetStatusBarMessageAsync(string message, int? timeout) { Message = message, Timeout = timeout - }).ConfigureAwait(false); + }).ReturningVoid(CancellationToken.None).ConfigureAwait(false); } public void ClearTerminal() diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetCommentHelpHandler.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetCommentHelpHandler.cs index c3b3134b4..46c497247 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetCommentHelpHandler.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetCommentHelpHandler.cs @@ -42,7 +42,7 @@ public async Task Handle(CommentHelpRequestParams requ return result; } - int triggerLine = (int) request.TriggerPosition.Line + 1; + int triggerLine = request.TriggerPosition.Line + 1; FunctionDefinitionAst functionDefinitionAst = _symbolsService.GetFunctionDefinitionForHelpComment( scriptFile, diff --git a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/PromptHandlers.cs b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/PromptHandlers.cs index 98d4905b5..0fbfa9636 100644 --- a/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/PromptHandlers.cs +++ b/src/PowerShellEditorServices/Services/PowerShellContext/Session/Host/PromptHandlers.cs @@ -34,7 +34,7 @@ protected override void ShowPrompt(PromptStyle promptStyle) { base.ShowPrompt(promptStyle); - _languageServer.SendRequest( + _languageServer.SendRequest( "powerShell/showChoicePrompt", new ShowChoicePromptRequest { @@ -44,6 +44,7 @@ protected override void ShowPrompt(PromptStyle promptStyle) Choices = this.Choices, DefaultChoices = this.DefaultChoices }) + .Returning(CancellationToken.None) .ContinueWith(HandlePromptResponse) .ConfigureAwait(false); } @@ -115,13 +116,14 @@ protected override void ShowFieldPrompt(FieldDetails fieldDetails) { base.ShowFieldPrompt(fieldDetails); - _languageServer.SendRequest( + _languageServer.SendRequest( "powerShell/showInputPrompt", new ShowInputPromptRequest { Name = fieldDetails.Name, Label = fieldDetails.Label - }).ContinueWith(HandlePromptResponse) + }).Returning(CancellationToken.None) + .ContinueWith(HandlePromptResponse) .ConfigureAwait(false); } diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs index 7e238e4f7..a054dbdf1 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs @@ -80,7 +80,7 @@ public async Task Handle(CodeActionParams request, // If there are any code fixes, send these commands first so they appear at top of "Code Fix" menu in the client UI. foreach (Diagnostic diagnostic in request.Context.Diagnostics) { - if (string.IsNullOrEmpty(diagnostic.Code.String)) + if (string.IsNullOrEmpty(diagnostic.Code?.String)) { _logger.LogWarning( $"textDocument/codeAction skipping diagnostic with empty Code field: {diagnostic.Source} {diagnostic.Message}"); @@ -118,13 +118,19 @@ public async Task Handle(CodeActionParams request, var ruleNamesProcessed = new HashSet(); foreach (Diagnostic diagnostic in request.Context.Diagnostics) { - if (!diagnostic.Code.IsString || string.IsNullOrEmpty(diagnostic.Code.String)) { continue; } + if ( + !diagnostic.Code.HasValue || + !diagnostic.Code.Value.IsString || + string.IsNullOrEmpty(diagnostic.Code?.String)) + { + continue; + } if (string.Equals(diagnostic.Source, "PSScriptAnalyzer", StringComparison.OrdinalIgnoreCase) && - !ruleNamesProcessed.Contains(diagnostic.Code.String)) + !ruleNamesProcessed.Contains(diagnostic.Code?.String)) { - ruleNamesProcessed.Add(diagnostic.Code.String); - var title = $"Show documentation for: {diagnostic.Code.String}"; + ruleNamesProcessed.Add(diagnostic.Code?.String); + var title = $"Show documentation for: {diagnostic.Code?.String}"; codeActions.Add(new CodeAction { Title = title, @@ -136,7 +142,7 @@ public async Task Handle(CodeActionParams request, { Title = title, Name = "PowerShell.ShowCodeActionDocumentation", - Arguments = JArray.FromObject(new[] { diagnostic.Code.String }) + Arguments = JArray.FromObject(new[] { diagnostic.Code?.String }) } }); } diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs index 5c6fa9324..f49a18695 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs @@ -63,8 +63,8 @@ public CompletionRegistrationOptions GetRegistrationOptions() public async Task Handle(CompletionParams request, CancellationToken cancellationToken) { - int cursorLine = (int) request.Position.Line + 1; - int cursorColumn = (int) request.Position.Character + 1; + int cursorLine = request.Position.Line + 1; + int cursorColumn = request.Position.Character + 1; ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs index b9173b949..6cbeaa9eb 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs @@ -50,8 +50,8 @@ public async Task Handle(DefinitionParams request, Canc SymbolReference foundSymbol = _symbolsService.FindSymbolAtLocation( scriptFile, - (int) request.Position.Line + 1, - (int) request.Position.Character + 1); + request.Position.Line + 1, + request.Position.Character + 1); List definitionLocations = new List(); if (foundSymbol != null) diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentHighlightHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentHighlightHandler.cs index 34b3da768..6a57948d3 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentHighlightHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/DocumentHighlightHandler.cs @@ -56,8 +56,8 @@ public Task Handle( IReadOnlyList symbolOccurrences = _symbolsService.FindOccurrencesInFile( scriptFile, - (int)request.Position.Line + 1, - (int)request.Position.Character + 1); + request.Position.Line + 1, + request.Position.Character + 1); if (symbolOccurrences == null) { diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs index e26bf4f17..060f9c6c9 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/FormattingHandlers.cs @@ -127,10 +127,10 @@ public async Task Handle(DocumentRangeFormattingParams reques Range range = request.Range; var rangeList = range == null ? null : new int[] { - (int)range.Start.Line + 1, - (int)range.Start.Character + 1, - (int)range.End.Line + 1, - (int)range.End.Character + 1 + range.Start.Line + 1, + range.Start.Character + 1, + range.End.Line + 1, + range.End.Character + 1 }; formattedScript = await _analysisService.FormatAsync( diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/HoverHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/HoverHandler.cs index 1c01ace54..2d3065906 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/HoverHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/HoverHandler.cs @@ -56,8 +56,8 @@ public async Task Handle(HoverParams request, CancellationToken cancellat SymbolDetails symbolDetails = await _symbolsService.FindSymbolDetailsAtLocationAsync( scriptFile, - (int) request.Position.Line + 1, - (int) request.Position.Character + 1).ConfigureAwait(false); + request.Position.Line + 1, + request.Position.Character + 1).ConfigureAwait(false); if (symbolDetails == null) { diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs index b2e46cffc..41147f805 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs @@ -46,8 +46,8 @@ public Task Handle(ReferenceParams request, CancellationToken SymbolReference foundSymbol = _symbolsService.FindSymbolAtLocation( scriptFile, - (int)request.Position.Line + 1, - (int)request.Position.Character + 1); + request.Position.Line + 1, + request.Position.Character + 1); List referencesResult = _symbolsService.FindReferencesOfSymbol( diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/SignatureHelpHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/SignatureHelpHandler.cs index 8b106a2f5..31ae18368 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/SignatureHelpHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/SignatureHelpHandler.cs @@ -61,8 +61,8 @@ public async Task Handle(SignatureHelpParams request, Cancellatio ParameterSetSignatures parameterSets = await _symbolsService.FindParameterSetsInFileAsync( scriptFile, - (int) request.Position.Line + 1, - (int) request.Position.Character + 1, + request.Position.Line + 1, + request.Position.Character + 1, _powerShellContextService).ConfigureAwait(false); if (parameterSets == null) diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/TextDocumentHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/TextDocumentHandler.cs index 73c779cac..c5b9f861e 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/TextDocumentHandler.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/TextDocumentHandler.cs @@ -143,7 +143,7 @@ TextDocumentSaveRegistrationOptions IRegistrationIMPORTANT: Not all documents have a backing file e.g. untitled: scheme documents. Consider using /// instead. /// - /// The file path at which the script resides. + /// The file URI at which the script resides. /// /// is not found. /// /// /// contains a null or empty string. /// - public ScriptFile GetFile(Uri fileUri) - { - Validate.IsNotNull(nameof(fileUri), fileUri); + public ScriptFile GetFile(Uri fileUri) => GetFile(DocumentUri.From(fileUri)); - // Resolve the full file path - Uri resolvedFileUri = ResolveFileUri(fileUri); + /// + /// Gets an open file in the workspace. If the file isn't open but exists on the filesystem, load and return it. + /// IMPORTANT: Not all documents have a backing file e.g. untitled: scheme documents. Consider using + /// instead. + /// + /// The document URI at which the script resides. + /// + /// is not found. + /// + /// + /// contains a null or empty string. + /// + public ScriptFile GetFile(DocumentUri documentUri) + { + Validate.IsNotNull(nameof(documentUri), documentUri); string keyName = VersionUtils.IsLinux - ? resolvedFileUri.OriginalString - : resolvedFileUri.OriginalString.ToLower(); + ? documentUri.ToString() + : documentUri.ToString().ToLower(); // Make sure the file isn't already loaded into the workspace if (!this.workspaceFiles.TryGetValue(keyName, out ScriptFile scriptFile)) { // This method allows FileNotFoundException to bubble up // if the file isn't found. - using (FileStream fileStream = new FileStream(resolvedFileUri.LocalPath, FileMode.Open, FileAccess.Read)) + using (FileStream fileStream = new FileStream(documentUri.GetFileSystemPath(), FileMode.Open, FileAccess.Read)) using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8)) { scriptFile = new ScriptFile( - resolvedFileUri, + documentUri.ToUri(), streamReader, this.powerShellVersion); this.workspaceFiles[keyName] = scriptFile; } - this.logger.LogDebug("Opened file on disk: " + resolvedFileUri.OriginalString); + this.logger.LogDebug("Opened file on disk: " + documentUri.ToString()); } return scriptFile; @@ -169,9 +181,17 @@ public bool TryGetFile(string filePath, out ScriptFile scriptFile) => /// /// The file uri at which the script resides. /// The out parameter that will contain the ScriptFile object. - public bool TryGetFile(Uri fileUri, out ScriptFile scriptFile) + public bool TryGetFile(Uri fileUri, out ScriptFile scriptFile) => + TryGetFile(DocumentUri.From(fileUri), out scriptFile); + + /// + /// Tries to get an open file in the workspace. Returns true if it succeeds, false otherwise. + /// + /// The file uri at which the script resides. + /// The out parameter that will contain the ScriptFile object. + public bool TryGetFile(DocumentUri documentUri, out ScriptFile scriptFile) { - switch (fileUri.Scheme) + switch (documentUri.Scheme) { // List supported schemes here case "file": @@ -185,7 +205,7 @@ public bool TryGetFile(Uri fileUri, out ScriptFile scriptFile) try { - scriptFile = GetFile(fileUri); + scriptFile = GetFile(documentUri); return true; } catch (Exception e) when ( @@ -197,7 +217,7 @@ e is IOException || e is SecurityException || e is UnauthorizedAccessException) { - this.logger.LogWarning($"Failed to get file for fileUri: '{fileUri.OriginalString}'", e); + this.logger.LogWarning($"Failed to get file for fileUri: '{documentUri.ToString()}'", e); scriptFile = null; return false; } @@ -233,29 +253,35 @@ e is SecurityException || /// The file Uri for which a buffer will be retrieved. /// The initial buffer contents if there is not an existing ScriptFile for this path. /// A ScriptFile instance for the specified path. - public ScriptFile GetFileBuffer(Uri fileUri, string initialBuffer) - { - Validate.IsNotNull(nameof(fileUri), fileUri); + public ScriptFile GetFileBuffer(Uri fileUri, string initialBuffer) => GetFileBuffer(DocumentUri.From(fileUri), initialBuffer); - // Resolve the full file path - Uri resolvedFileUri = ResolveFileUri(fileUri); + /// + /// Gets a new ScriptFile instance which is identified by the given file + /// path and initially contains the given buffer contents. + /// + /// The file Uri for which a buffer will be retrieved. + /// The initial buffer contents if there is not an existing ScriptFile for this path. + /// A ScriptFile instance for the specified path. + public ScriptFile GetFileBuffer(DocumentUri documentUri, string initialBuffer) + { + Validate.IsNotNull(nameof(documentUri), documentUri); string keyName = VersionUtils.IsLinux - ? resolvedFileUri.OriginalString - : resolvedFileUri.OriginalString.ToLower(); + ? documentUri.ToString() + : documentUri.ToString().ToLower(); // Make sure the file isn't already loaded into the workspace if (!this.workspaceFiles.TryGetValue(keyName, out ScriptFile scriptFile) && initialBuffer != null) { scriptFile = new ScriptFile( - resolvedFileUri, + documentUri.ToUri(), initialBuffer, this.powerShellVersion); this.workspaceFiles[keyName] = scriptFile; - this.logger.LogDebug("Opened file as in-memory buffer: " + resolvedFileUri.OriginalString); + this.logger.LogDebug("Opened file as in-memory buffer: " + documentUri.ToString()); } return scriptFile; diff --git a/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs b/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs index a4376d7b1..b7bb8f679 100644 --- a/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs +++ b/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs @@ -831,8 +831,8 @@ await LanguageClient.SendRequest( "Replace gci with Get-ChildItem", command.CodeAction.Title); Assert.Equal( - CodeActionKind.QuickFix.Kind, - command.CodeAction.Kind.Kind); + CodeActionKind.QuickFix, + command.CodeAction.Kind); Assert.Single(command.CodeAction.Edit.DocumentChanges); }, command => diff --git a/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj b/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj index b019aa149..055106f1c 100644 --- a/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj +++ b/test/PowerShellEditorServices.Test.E2E/PowerShellEditorServices.Test.E2E.csproj @@ -10,7 +10,7 @@ - + diff --git a/test/PowerShellEditorServices.Test/Services/Symbols/AstOperationsTests.cs b/test/PowerShellEditorServices.Test/Services/Symbols/AstOperationsTests.cs index 7f716aa27..35cf5e3fc 100644 --- a/test/PowerShellEditorServices.Test/Services/Symbols/AstOperationsTests.cs +++ b/test/PowerShellEditorServices.Test/Services/Symbols/AstOperationsTests.cs @@ -64,8 +64,8 @@ public void CanFindReferencesOfSymbolAtPostion(int lineNumber, int columnNumber, int positionsIndex = 0; foreach (SymbolReference reference in references) { - Assert.Equal((int)positions[positionsIndex].Line, reference.ScriptRegion.StartLineNumber); - Assert.Equal((int)positions[positionsIndex].Character, reference.ScriptRegion.StartColumnNumber); + Assert.Equal(positions[positionsIndex].Line, reference.ScriptRegion.StartLineNumber); + Assert.Equal(positions[positionsIndex].Character, reference.ScriptRegion.StartColumnNumber); positionsIndex++; }