public override Task <CodeLensContainer> Handle(CodeLensParams request, CancellationToken cancellationToken) { ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); CodeLens[] codeLensResults = ProvideCodeLenses(scriptFile); return(Task.FromResult(new CodeLensContainer(codeLensResults))); }
public Task <DocumentHighlightContainer> Handle( DocumentHighlightParams request, CancellationToken cancellationToken) { ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); IReadOnlyList <SymbolReference> symbolOccurrences = _symbolsService.FindOccurrencesInFile( scriptFile, (int)request.Position.Line + 1, (int)request.Position.Character + 1); if (symbolOccurrences == null) { return(Task.FromResult(s_emptyHighlightContainer)); } var highlights = new DocumentHighlight[symbolOccurrences.Count]; for (int i = 0; i < symbolOccurrences.Count; i++) { highlights[i] = new DocumentHighlight { Kind = DocumentHighlightKind.Write, // TODO: Which symbol types are writable? Range = symbolOccurrences[i].ScriptRegion.ToRange() }; } return(Task.FromResult(new DocumentHighlightContainer(highlights))); }
public async Task <LocationOrLocationLinks> Handle(DefinitionParams request, CancellationToken cancellationToken) { ScriptFile scriptFile = _workspaceService.GetFile( request.TextDocument.Uri.ToString()); SymbolReference foundSymbol = _symbolsService.FindSymbolAtLocation( scriptFile, (int)request.Position.Line + 1, (int)request.Position.Character + 1); List <LocationOrLocationLink> definitionLocations = new List <LocationOrLocationLink>(); if (foundSymbol != null) { SymbolReference foundDefinition = await _symbolsService.GetDefinitionOfSymbolAsync( scriptFile, foundSymbol); if (foundDefinition != null) { definitionLocations.Add( new LocationOrLocationLink( new Location { Uri = PathUtils.ToUri(foundDefinition.FilePath), Range = GetRangeFromScriptRegion(foundDefinition.ScriptRegion) })); } } return(new LocationOrLocationLinks(definitionLocations)); }
public async Task <Hover> Handle(HoverParams request, CancellationToken cancellationToken) { ScriptFile scriptFile = _workspaceService.GetFile( request.TextDocument.Uri.ToString()); SymbolDetails symbolDetails = await _symbolsService.FindSymbolDetailsAtLocationAsync( scriptFile, (int)request.Position.Line + 1, (int)request.Position.Character + 1); List <MarkedString> symbolInfo = new List <MarkedString>(); Range symbolRange = null; if (symbolDetails != null) { symbolInfo.Add(new MarkedString("PowerShell", symbolDetails.DisplayString)); if (!string.IsNullOrEmpty(symbolDetails.Documentation)) { symbolInfo.Add(new MarkedString("markdown", symbolDetails.Documentation)); } symbolRange = GetRangeFromScriptRegion(symbolDetails.SymbolReference.ScriptRegion); } return(new Hover { Contents = new MarkedStringsOrMarkupContent(symbolInfo), Range = symbolRange }); }
public async Task <CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken) { int cursorLine = (int)request.Position.Line + 1; int cursorColumn = (int)request.Position.Character + 1; ScriptFile scriptFile = _workspaceService.GetFile( request.TextDocument.Uri.ToString()); CompletionResults completionResults = await GetCompletionsInFileAsync( scriptFile, cursorLine, cursorColumn); CompletionItem[] completionItems = s_emptyCompletionResult; if (completionResults != null) { completionItems = new CompletionItem[completionResults.Completions.Length]; for (int i = 0; i < completionItems.Length; i++) { completionItems[i] = CreateCompletionItem(completionResults.Completions[i], completionResults.ReplacedRange, i + 1); } } return(new CompletionList(completionItems)); }
public override async Task <LocationOrLocationLinks> Handle(DefinitionParams request, CancellationToken cancellationToken) { ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); SymbolReference foundSymbol = SymbolsService.FindSymbolAtLocation( scriptFile, request.Position.Line + 1, request.Position.Character + 1); List <LocationOrLocationLink> definitionLocations = new List <LocationOrLocationLink>(); if (foundSymbol != null) { SymbolReference foundDefinition = await _symbolsService.GetDefinitionOfSymbolAsync( scriptFile, foundSymbol).ConfigureAwait(false); if (foundDefinition != null) { definitionLocations.Add( new LocationOrLocationLink( new Location { Uri = DocumentUri.From(foundDefinition.FilePath), Range = GetRangeFromScriptRegion(foundDefinition.ScriptRegion) })); } } return(new LocationOrLocationLinks(definitionLocations)); }
public override Task <LocationContainer> Handle(ReferenceParams request, CancellationToken cancellationToken) { ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); SymbolReference foundSymbol = _symbolsService.FindSymbolAtLocation( scriptFile, request.Position.Line + 1, request.Position.Character + 1); List <SymbolReference> referencesResult = _symbolsService.FindReferencesOfSymbol( foundSymbol, _workspaceService.ExpandScriptReferences(scriptFile), _workspaceService); var locations = new List <Location>(); if (referencesResult != null) { foreach (SymbolReference foundReference in referencesResult) { locations.Add(new Location { Uri = DocumentUri.From(foundReference.FilePath), Range = GetRangeFromScriptRegion(foundReference.ScriptRegion) }); } } return(Task.FromResult(new LocationContainer(locations))); }
public Task <Unit> Handle(DidChangeTextDocumentParams notification, CancellationToken token) { ScriptFile changedFile = _workspaceService.GetFile(notification.TextDocument.Uri.ToString()); // A text change notification can batch multiple change requests foreach (TextDocumentContentChangeEvent textChange in notification.ContentChanges) { changedFile.ApplyChange( GetFileChangeDetails( textChange.Range, textChange.Text)); } // TODO: Get all recently edited files in the workspace _analysisService.RunScriptDiagnosticsAsync(new ScriptFile[] { changedFile }); return(Unit.Task); }
public async Task <TextEditContainer> Handle(DocumentFormattingParams request, CancellationToken cancellationToken) { var scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); var pssaSettings = _configurationService.CurrentSettings.CodeFormatting.GetPSSASettingsHashtable( (int)request.Options.TabSize, request.Options.InsertSpaces, _logger); // TODO raise an error event in case format returns null string formattedScript; Range editRange; var extent = scriptFile.ScriptAst.Extent; // todo create an extension for converting range to script extent editRange = new Range { Start = new Position { Line = extent.StartLineNumber - 1, Character = extent.StartColumnNumber - 1 }, End = new Position { Line = extent.EndLineNumber - 1, Character = extent.EndColumnNumber - 1 } }; formattedScript = await _analysisService.FormatAsync( scriptFile.Contents, pssaSettings, null).ConfigureAwait(false); formattedScript = formattedScript ?? scriptFile.Contents; return(new TextEditContainer(new TextEdit { NewText = formattedScript, Range = editRange })); }
protected override Task Tokenize(SemanticTokensBuilder builder, ITextDocumentIdentifierParams identifier, CancellationToken cancellationToken) { ScriptFile file = _workspaceService.GetFile(identifier.TextDocument.Uri); foreach (Token token in file.ScriptTokens) { PushToken(token, builder); } return(Task.CompletedTask); }
public Task <Unit> Handle(DidChangeTextDocumentParams notification, CancellationToken token) { ScriptFile changedFile = _workspaceService.GetFile(notification.TextDocument.Uri); // A text change notification can batch multiple change requests foreach (TextDocumentContentChangeEvent textChange in notification.ContentChanges) { changedFile.ApplyChange( GetFileChangeDetails( textChange.Range, textChange.Text)); } #pragma warning disable CS4014 // Kick off script diagnostics without blocking the response // TODO: Get all recently edited files in the workspace _analysisService.RunScriptDiagnosticsAsync(new ScriptFile[] { changedFile }); #pragma warning restore CS4014 return(Unit.Task); }
private async Task LaunchScriptAsync(string scriptToLaunch) { // Is this an untitled script? if (ScriptFile.IsUntitledPath(scriptToLaunch)) { ScriptFile untitledScript = _workspaceService.GetFile(scriptToLaunch); if (BreakpointApiUtils.SupportsBreakpointApis) { // Parse untitled files with their `Untitled:` URI as the file name which will cache the URI & contents within the PowerShell parser. // By doing this, we light up the ability to debug Untitled files with breakpoints. // This is only possible via the direct usage of the breakpoint APIs in PowerShell because // Set-PSBreakpoint validates that paths are actually on the filesystem. ScriptBlockAst ast = Parser.ParseInput(untitledScript.Contents, untitledScript.DocumentUri, out Token[] tokens, out ParseError[] errors);
public override async Task <CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken) { int cursorLine = request.Position.Line + 1; int cursorColumn = request.Position.Character + 1; ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); IEnumerable <CompletionItem> completionResults = await GetCompletionsInFileAsync( scriptFile, cursorLine, cursorColumn, cancellationToken).ConfigureAwait(false); return(new CompletionList(completionResults)); }
public async Task <CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken) { int cursorLine = request.Position.Line + 1; int cursorColumn = request.Position.Character + 1; ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); try { await _completionLock.WaitAsync(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { _logger.LogDebug("Completion request canceled for file: {0}", request.TextDocument.Uri); return(Array.Empty <CompletionItem>()); } try { if (cancellationToken.IsCancellationRequested) { _logger.LogDebug("Completion request canceled for file: {0}", request.TextDocument.Uri); return(Array.Empty <CompletionItem>()); } CompletionResults completionResults = await GetCompletionsInFileAsync( scriptFile, cursorLine, cursorColumn).ConfigureAwait(false); if (completionResults == null) { return(Array.Empty <CompletionItem>()); } CompletionItem[] completionItems = new CompletionItem[completionResults.Completions.Length]; for (int i = 0; i < completionItems.Length; i++) { completionItems[i] = CreateCompletionItem(completionResults.Completions[i], completionResults.ReplacedRange, i + 1); } return(completionItems); } finally { _completionLock.Release(); } }
public async Task <SignatureHelp> Handle(SignatureHelpParams request, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { _logger.LogDebug("SignatureHelp request canceled for file: {0}", request.TextDocument.Uri); return(new SignatureHelp()); } ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); ParameterSetSignatures parameterSets = await _symbolsService.FindParameterSetsInFileAsync( scriptFile, (int)request.Position.Line + 1, (int)request.Position.Character + 1, _powerShellContextService).ConfigureAwait(false); if (parameterSets == null) { return(new SignatureHelp()); } var signatures = new SignatureInformation[parameterSets.Signatures.Length]; for (int i = 0; i < signatures.Length; i++) { var parameters = new List <ParameterInformation>(); foreach (ParameterInfo param in parameterSets.Signatures[i].Parameters) { parameters.Add(CreateParameterInfo(param)); } signatures[i] = new SignatureInformation { Label = parameterSets.CommandName + " " + parameterSets.Signatures[i].SignatureText, Documentation = null, Parameters = parameters, }; } return(new SignatureHelp { Signatures = signatures, ActiveParameter = null, ActiveSignature = 0 }); }
private async Task LaunchScriptAsync(string scriptToLaunch) { // Is this an untitled script? if (ScriptFile.IsUntitledPath(scriptToLaunch)) { ScriptFile untitledScript = _workspaceService.GetFile(scriptToLaunch); await _powerShellContextService .ExecuteScriptStringAsync(untitledScript.Contents, true, true); } else { await _powerShellContextService .ExecuteScriptWithArgsAsync(scriptToLaunch, _debugStateService.Arguments, writeInputToHost : true); } _jsonRpcServer.SendNotification(EventNames.Terminated); }
public async Task <SignatureHelp> Handle(SignatureHelpParams request, CancellationToken cancellationToken) { ScriptFile scriptFile = _workspaceService.GetFile( request.TextDocument.Uri.ToString()); ParameterSetSignatures parameterSets = await _symbolsService.FindParameterSetsInFileAsync( scriptFile, (int)request.Position.Line + 1, (int)request.Position.Character + 1, _powerShellContextService); SignatureInformation[] signatures = s_emptySignatureResult; if (parameterSets != null) { signatures = new SignatureInformation[parameterSets.Signatures.Length]; for (int i = 0; i < signatures.Length; i++) { var parameters = new ParameterInformation[parameterSets.Signatures[i].Parameters.Count()]; int j = 0; foreach (ParameterInfo param in parameterSets.Signatures[i].Parameters) { parameters[j] = CreateParameterInfo(param); j++; } signatures[i] = new SignatureInformation { Label = parameterSets.CommandName + " " + parameterSets.Signatures[i].SignatureText, Documentation = null, Parameters = parameters, }; } } return(new SignatureHelp { Signatures = signatures, ActiveParameter = null, ActiveSignature = 0 }); }
public Task <SymbolInformationOrDocumentSymbolContainer> Handle(DocumentSymbolParams request, CancellationToken cancellationToken) { ScriptFile scriptFile = _workspaceService.GetFile( request.TextDocument.Uri.ToString()); IEnumerable <SymbolReference> foundSymbols = this.ProvideDocumentSymbols(scriptFile); SymbolInformationOrDocumentSymbol[] symbols = null; string containerName = Path.GetFileNameWithoutExtension(scriptFile.FilePath); if (foundSymbols != null) { symbols = foundSymbols .Select(r => { return(new SymbolInformationOrDocumentSymbol(new SymbolInformation { ContainerName = containerName, Kind = GetSymbolKind(r.SymbolType), Location = new Location { Uri = PathUtils.ToUri(r.FilePath), Range = GetRangeFromScriptRegion(r.ScriptRegion) }, Name = GetDecoratedSymbolName(r) })); }) .ToArray(); } else { symbols = new SymbolInformationOrDocumentSymbol[0]; } return(Task.FromResult(new SymbolInformationOrDocumentSymbolContainer(symbols))); }
public override async Task <Hover> Handle(HoverParams request, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { _logger.LogDebug("Hover request canceled for file: {0}", request.TextDocument.Uri); return(null); } ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri); SymbolDetails symbolDetails = await _symbolsService.FindSymbolDetailsAtLocationAsync( scriptFile, request.Position.Line + 1, request.Position.Character + 1).ConfigureAwait(false); if (symbolDetails == null) { return(null); } List <MarkedString> symbolInfo = new List <MarkedString>(); symbolInfo.Add(new MarkedString("PowerShell", symbolDetails.DisplayString)); if (!string.IsNullOrEmpty(symbolDetails.Documentation)) { symbolInfo.Add(new MarkedString("markdown", symbolDetails.Documentation)); } Range symbolRange = GetRangeFromScriptRegion(symbolDetails.SymbolReference.ScriptRegion); return(new Hover { Contents = new MarkedStringsOrMarkupContent(symbolInfo), Range = symbolRange }); }
public async Task <CommandOrCodeActionContainer> Handle(CodeActionParams request, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(Array.Empty <CommandOrCodeAction>()); } // On Windows, VSCode still gives us file URIs like "file:///c%3a/...", so we need to escape them IReadOnlyDictionary <string, MarkerCorrection> corrections = await _analysisService.GetMostRecentCodeActionsForFileAsync( _workspaceService.GetFile(request.TextDocument.Uri)).ConfigureAwait(false); if (corrections == null) { return(Array.Empty <CommandOrCodeAction>()); } var codeActions = new List <CommandOrCodeAction>(); // 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)) { _logger.LogWarning( $"textDocument/codeAction skipping diagnostic with empty Code field: {diagnostic.Source} {diagnostic.Message}"); continue; } string diagnosticId = AnalysisService.GetUniqueIdFromDiagnostic(diagnostic); if (corrections.TryGetValue(diagnosticId, out MarkerCorrection correction)) { codeActions.Add(new CodeAction { Title = correction.Name, Kind = CodeActionKind.QuickFix, Edit = new WorkspaceEdit { DocumentChanges = new Container <WorkspaceEditDocumentChange>( new WorkspaceEditDocumentChange( new TextDocumentEdit { TextDocument = new VersionedTextDocumentIdentifier { Uri = request.TextDocument.Uri }, Edits = new TextEditContainer(correction.Edits.Select(ScriptRegion.ToTextEdit)) })) } }); } } // Add "show documentation" commands last so they appear at the bottom of the client UI. // These commands do not require code fixes. Sometimes we get a batch of diagnostics // to create commands for. No need to create multiple show doc commands for the same rule. var ruleNamesProcessed = new HashSet <string>(); foreach (Diagnostic diagnostic in request.Context.Diagnostics) { if (!diagnostic.Code.IsString || string.IsNullOrEmpty(diagnostic.Code.String)) { continue; } if (string.Equals(diagnostic.Source, "PSScriptAnalyzer", StringComparison.OrdinalIgnoreCase) && !ruleNamesProcessed.Contains(diagnostic.Code.String)) { ruleNamesProcessed.Add(diagnostic.Code.String); var title = $"Show documentation for: {diagnostic.Code.String}"; codeActions.Add(new CodeAction { Title = title, // This doesn't fix anything, but I'm adding it here so that it shows up in VS Code's // Quick fix UI. The VS Code team is working on a way to support documentation CodeAction's better // but this is good for now until that's ready. Kind = CodeActionKind.QuickFix, Command = new Command { Title = title, Name = "PowerShell.ShowCodeActionDocumentation", Arguments = JArray.FromObject(new[] { diagnostic.Code.String }) } }); } } return(codeActions); }
private ScriptFile GetScriptFile(ScriptRegion scriptRegion) => workspace.GetFile(TestUtilities.GetSharedPath(scriptRegion.File));