/// <summary> /// Get the Pester CodeLenses for a given Pester symbol. /// </summary> /// <param name="pesterSymbol">The Pester symbol to get CodeLenses for.</param> /// <param name="scriptFile">The script file the Pester symbol comes from.</param> /// <returns>All CodeLenses for the given Pester symbol.</returns> private CodeLens[] GetPesterLens( PesterSymbolReference pesterSymbol, ScriptFile scriptFile) { var codeLensResults = new CodeLens[] { new CodeLens( this, scriptFile, pesterSymbol.ScriptRegion, new ClientCommand( "PowerShell.RunPesterTests", "Run tests", new object[] { scriptFile.ClientFilePath, false /* No debug */, pesterSymbol.TestName })), new CodeLens( this, scriptFile, pesterSymbol.ScriptRegion, new ClientCommand( "PowerShell.RunPesterTests", "Debug tests", new object[] { scriptFile.ClientFilePath, true /* Run in debugger */, pesterSymbol.TestName })), }; return(codeLensResults); }
/// <summary> /// Resolve the CodeLens provision asynchronously -- just wraps the CodeLens argument in a task. /// </summary> /// <param name="codeLens">The code lens to resolve.</param> /// <param name="cancellationToken"></param> /// <returns>The given CodeLens, wrapped in a task.</returns> public Task <CodeLens> ResolveCodeLensAsync( CodeLens codeLens, CancellationToken cancellationToken) { // This provider has no specific behavior for // resolving CodeLenses. return(Task.FromResult(codeLens)); }
/// <summary> /// Take a codelens and create a new codelens object with updated references. /// </summary> /// <param name="codeLens">The old code lens to get updated references for.</param> /// <returns>A new code lens object describing the same data as the old one but with updated references.</returns> public CodeLens ResolveCodeLens(CodeLens codeLens, ScriptFile scriptFile) { ScriptFile[] references = _workspaceService.ExpandScriptReferences( scriptFile); SymbolReference foundSymbol = _symbolsService.FindFunctionDefinitionAtLocation( scriptFile, codeLens.Range.Start.Line + 1, codeLens.Range.Start.Character + 1); List <SymbolReference> referencesResult = _symbolsService.FindReferencesOfSymbol( foundSymbol, references, _workspaceService); Location[] referenceLocations; if (referencesResult == null) { referenceLocations = s_emptyLocationArray; } else { var acc = new List <Location>(); foreach (SymbolReference foundReference in referencesResult) { if (IsReferenceDefinition(foundSymbol, foundReference)) { continue; } acc.Add(new Location { Uri = DocumentUri.From(foundReference.FilePath), Range = foundReference.ScriptRegion.ToRange() }); } referenceLocations = acc.ToArray(); } return(new CodeLens { Data = codeLens.Data, Range = codeLens.Range, Command = new Command { Name = "editor.action.showReferences", Title = GetReferenceCountHeader(referenceLocations.Length), Arguments = JArray.FromObject(new object[] { scriptFile.DocumentUri, codeLens.Range.Start, referenceLocations }, Serializer.Instance.JsonSerializer) } }); }
/// <summary> /// Take a codelens and create a new codelens object with updated references. /// </summary> /// <param name="codeLens">The old code lens to get updated references for.</param> /// <param name="cancellationToken">The cancellation token for this request.</param> /// <returns>A new code lens object describing the same data as the old one but with updated references.</returns> public async Task <CodeLens> ResolveCodeLensAsync( CodeLens codeLens, CancellationToken cancellationToken) { ScriptFile[] references = _editorSession.Workspace.ExpandScriptReferences( codeLens.File); SymbolReference foundSymbol = _editorSession.LanguageService.FindFunctionDefinitionAtLocation( codeLens.File, codeLens.ScriptExtent.StartLineNumber, codeLens.ScriptExtent.StartColumnNumber); FindReferencesResult referencesResult = await _editorSession.LanguageService.FindReferencesOfSymbol( foundSymbol, references, _editorSession.Workspace); Location[] referenceLocations; if (referencesResult == null) { referenceLocations = s_emptyLocationArray; } else { var acc = new List <Location>(); foreach (SymbolReference foundReference in referencesResult.FoundReferences) { if (!NotReferenceDefinition(foundSymbol, foundReference)) { continue; } acc.Add(new Location { Uri = GetFileUri(foundReference.FilePath), Range = foundReference.ScriptRegion.ToRange() }); } referenceLocations = acc.ToArray(); } return(new CodeLens( codeLens, new ClientCommand( "editor.action.showReferences", GetReferenceCountHeader(referenceLocations.Length), new object[] { codeLens.File.ClientFilePath, codeLens.ScriptExtent.ToRange().Start, referenceLocations, } ))); }
/// <summary> /// Creates an instance of the CodeLens class based on an /// original CodeLens instance, generally used when resolving /// the Command for a CodeLens. /// </summary> /// <param name="originalCodeLens"> /// The original CodeLens upon which this instance is based. /// </param> /// <param name="resolvedCommand"> /// The resolved ClientCommand for the original CodeLens. /// </param> public CodeLens( CodeLens originalCodeLens, ClientCommand resolvedCommand) { Validate.IsNotNull(nameof(originalCodeLens), originalCodeLens); Validate.IsNotNull(nameof(resolvedCommand), resolvedCommand); this.Provider = originalCodeLens.Provider; this.File = originalCodeLens.File; this.ScriptExtent = originalCodeLens.ScriptExtent; this.Command = resolvedCommand; }
/// <summary> /// Get the Pester CodeLenses for a given Pester symbol. /// </summary> /// <param name="pesterSymbol">The Pester symbol to get CodeLenses for.</param> /// <param name="scriptFile">The script file the Pester symbol comes from.</param> /// <returns>All CodeLenses for the given Pester symbol.</returns> private static CodeLens[] GetPesterLens(PesterSymbolReference pesterSymbol, ScriptFile scriptFile) { string word = pesterSymbol.Command == PesterCommandType.It ? "test" : "tests"; CodeLens[] codeLensResults = new CodeLens[] { new CodeLens() { Range = pesterSymbol.ScriptRegion.ToRange(), Data = JToken.FromObject(new { Uri = scriptFile.DocumentUri, ProviderId = nameof(PesterCodeLensProvider) }, LspSerializer.Instance.JsonSerializer), Command = new Command() { Name = "PowerShell.RunPesterTests", Title = $"Run {word}", Arguments = JArray.FromObject(new object[] { scriptFile.DocumentUri, false /* No debug */, pesterSymbol.TestName, pesterSymbol.ScriptRegion?.StartLineNumber }, LspSerializer.Instance.JsonSerializer) } }, new CodeLens() { Range = pesterSymbol.ScriptRegion.ToRange(), Data = JToken.FromObject(new { Uri = scriptFile.DocumentUri, ProviderId = nameof(PesterCodeLensProvider) }, LspSerializer.Instance.JsonSerializer), Command = new Command() { Name = "PowerShell.RunPesterTests", Title = $"Debug {word}", Arguments = JArray.FromObject(new object[] { scriptFile.DocumentUri, true /* No debug */, pesterSymbol.TestName, pesterSymbol.ScriptRegion?.StartLineNumber }, LspSerializer.Instance.JsonSerializer) } } }; return(codeLensResults); }
public async Task <CodeLens> ResolveCodeLensAsync( CodeLens codeLens, CancellationToken cancellationToken) { ScriptFile[] references = editorSession.Workspace.ExpandScriptReferences( codeLens.File); var foundSymbol = this.editorSession.LanguageService.FindFunctionDefinitionAtLocation( codeLens.File, codeLens.ScriptExtent.StartLineNumber, codeLens.ScriptExtent.StartColumnNumber); FindReferencesResult referencesResult = await editorSession.LanguageService.FindReferencesOfSymbol( foundSymbol, references, editorSession.Workspace); Location[] referenceLocations = referencesResult == null ? new Location[0] : referencesResult .FoundReferences .Where(r => NotReferenceDefinition(foundSymbol, r)) .Select( r => new Location { Uri = GetFileUri(r.FilePath), Range = r.ScriptRegion.ToRange() }) .ToArray(); return (new CodeLens( codeLens, new ClientCommand( "editor.action.showReferences", referenceLocations.Length == 1 ? "1 reference" : $"{referenceLocations.Length} references", new object[] { codeLens.File.ClientFilePath, codeLens.ScriptExtent.ToRange().Start, referenceLocations, } ))); }
/// <summary> /// Handle a CodeLens resolve request from VSCode. /// </summary> /// <param name="codeLens">The CodeLens to be resolved/updated.</param> /// <param name="requestContext"></param> private async Task HandleCodeLensResolveRequest( LanguageServer.CodeLens codeLens, RequestContext <LanguageServer.CodeLens> requestContext) { if (codeLens.Data != null) { // TODO: Catch deserializtion exception on bad object CodeLensData codeLensData = codeLens.Data.ToObject <CodeLensData>(); ICodeLensProvider originalProvider = Providers.FirstOrDefault( provider => provider.ProviderId.Equals(codeLensData.ProviderId)); if (originalProvider != null) { ScriptFile scriptFile = _editorSession.Workspace.GetFile( codeLensData.Uri); ScriptRegion region = new ScriptRegion { StartLineNumber = codeLens.Range.Start.Line + 1, StartColumnNumber = codeLens.Range.Start.Character + 1, EndLineNumber = codeLens.Range.End.Line + 1, EndColumnNumber = codeLens.Range.End.Character + 1 }; CodeLens originalCodeLens = new CodeLens( originalProvider, scriptFile, region); var resolvedCodeLens = await originalProvider.ResolveCodeLensAsync( originalCodeLens, CancellationToken.None); await requestContext.SendResult( resolvedCodeLens.ToProtocolCodeLens( _jsonSerializer)); } else { await requestContext.SendError( $"Could not find provider for the original CodeLens: {codeLensData.ProviderId}"); } } }
/// <summary> /// Get the Pester CodeLenses for a given Pester symbol. /// </summary> /// <param name="pesterSymbol">The Pester symbol to get CodeLenses for.</param> /// <param name="scriptFile">The script file the Pester symbol comes from.</param> /// <returns>All CodeLenses for the given Pester symbol.</returns> private CodeLens[] GetPesterLens(PesterSymbolReference pesterSymbol, ScriptFile scriptFile) { var codeLensResults = new CodeLens[] { new CodeLens() { Range = pesterSymbol.ScriptRegion.ToRange(), Data = JToken.FromObject(new { Uri = scriptFile.DocumentUri, ProviderId = nameof(PesterCodeLensProvider) }), Command = new Command() { Name = "PowerShell.RunPesterTests", Title = "Run tests", Arguments = JArray.FromObject(new object[] { scriptFile.DocumentUri, false /* No debug */, pesterSymbol.TestName, pesterSymbol.ScriptRegion?.StartLineNumber }) } }, new CodeLens() { Range = pesterSymbol.ScriptRegion.ToRange(), Data = JToken.FromObject(new { Uri = scriptFile.DocumentUri, ProviderId = nameof(PesterCodeLensProvider) }), Command = new Command() { Name = "PowerShell.RunPesterTests", Title = "Debug tests", Arguments = JArray.FromObject(new object[] { scriptFile.DocumentUri, true /* No debug */, pesterSymbol.TestName, pesterSymbol.ScriptRegion?.StartLineNumber }) } } }; return(codeLensResults); }
/// <summary> /// Resolve the CodeLens provision asynchronously -- just wraps the CodeLens argument in a task. /// </summary> /// <param name="codeLens">The code lens to resolve.</param> /// <param name="scriptFile">The script file.</param> /// <returns>The given CodeLens, wrapped in a task.</returns> public CodeLens ResolveCodeLens(CodeLens codeLens, ScriptFile scriptFile) { // This provider has no specific behavior for // resolving CodeLenses. return(codeLens); }
/// <summary> /// Resolve the CodeLens provision asynchronously -- just wraps the CodeLens argument in a task. /// </summary> /// <param name="codeLens">The code lens to resolve.</param> /// <param name="scriptFile">The script file.</param> /// <returns>The given CodeLens, wrapped in a task.</returns> public Task <CodeLens> ResolveCodeLens(CodeLens codeLens, ScriptFile scriptFile) => // This provider has no specific behavior for // resolving CodeLenses. Task.FromResult(codeLens);
/// <summary> /// Take a codelens and create a new codelens object with updated references. /// </summary> /// <param name="codeLens">The old code lens to get updated references for.</param> /// <param name="scriptFile"></param> /// <returns>A new code lens object describing the same data as the old one but with updated references.</returns> public async Task <CodeLens> ResolveCodeLens(CodeLens codeLens, ScriptFile scriptFile) { ScriptFile[] references = _workspaceService.ExpandScriptReferences( scriptFile); SymbolReference foundSymbol = SymbolsService.FindFunctionDefinitionAtLocation( scriptFile, codeLens.Range.Start.Line + 1, codeLens.Range.Start.Character + 1); List <SymbolReference> referencesResult = await _symbolsService.FindReferencesOfSymbol( foundSymbol, references, _workspaceService).ConfigureAwait(false); Location[] referenceLocations; if (referencesResult == null) { referenceLocations = s_emptyLocationArray; } else { List <Location> acc = new(); foreach (SymbolReference foundReference in referencesResult) { if (IsReferenceDefinition(foundSymbol, foundReference)) { continue; } DocumentUri uri = DocumentUri.From(foundReference.FilePath); // For any vscode-notebook-cell, we need to ignore the backing file on disk. if (uri.Scheme == "file" && scriptFile.DocumentUri.Scheme == "vscode-notebook-cell" && uri.Path == scriptFile.DocumentUri.Path) { continue; } acc.Add(new Location { Uri = uri, Range = foundReference.ScriptRegion.ToRange() }); } referenceLocations = acc.ToArray(); } return(new CodeLens { Data = codeLens.Data, Range = codeLens.Range, Command = new Command { Name = "editor.action.showReferences", Title = GetReferenceCountHeader(referenceLocations.Length), Arguments = JArray.FromObject(new object[] { scriptFile.DocumentUri, codeLens.Range.Start, referenceLocations }, LspSerializer.Instance.JsonSerializer) } }); }