public async Task <bool> CanCreateDataPointAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext context, CancellationToken ct) => (descriptor.Kind is CodeElementKinds.Method || descriptor.Kind is CodeElementKinds.Property) && await callbackService.Value .InvokeAsync <bool>(this, nameof(IInstructionsProvider.IsMicroscopeEnabled)).Caf();
public async Task <CodeLensDataPointDescriptor?> GetDataAsync(CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { var codeElementKind = GetCodeElementKindsString(Descriptor.Kind); // we always get data through VS rather than Roslyn OOP directly since we want final data rather than // raw data from Roslyn OOP such as razor find all reference results var referenceCountOpt = await _callbackService.InvokeAsync <ReferenceCount?>( _owner, nameof(ICodeLensContext.GetReferenceCountAsync), new object[] { Descriptor, descriptorContext }, cancellationToken).ConfigureAwait(false); if (!referenceCountOpt.HasValue) { return(null); } var referenceCount = referenceCountOpt.Value; var referenceCountString = $"{referenceCount.Count}{(referenceCount.IsCapped ? "+" : string.Empty)}"; return(new CodeLensDataPointDescriptor() { Description = referenceCount.Count == 1 ? string.Format(CodeLensVSResources._0_reference, referenceCountString) : string.Format(CodeLensVSResources._0_references, referenceCountString), IntValue = referenceCount.Count, TooltipText = string.Format(CodeLensVSResources.This_0_has_1_references, codeElementKind, referenceCountString), ImageId = null });
public async Task <(string projectVersion, ImmutableArray <ReferenceLocationDescriptor> references)?> FindReferenceLocationsAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { var solution = _workspace.CurrentSolution; var(documentId, node) = await GetDocumentIdAndNodeAsync( solution, descriptor, descriptorContext, cancellationToken).ConfigureAwait(false); if (documentId == null) { return(null); } var service = _workspace.Services.GetRequiredService <ICodeLensReferencesService>(); var references = await service.FindReferenceLocationsAsync(solution, documentId, node, cancellationToken).ConfigureAwait(false); if (!references.HasValue) { return(null); } var projectVersion = await service.GetProjectCodeLensVersionAsync(solution, documentId.ProjectId, cancellationToken).ConfigureAwait(false); return(projectVersion.ToString(), references.Value); }
public async Task <CodeLensDataPointDescriptor> GetDataAsync(CodeLensDescriptorContext context, CancellationToken ct) { try { data = await LoadInstructions(context, ct).Caf(); dataLoaded.Set(); var description = data.IsFailure ? "- instructions" : data.InstructionsCount !.Value.Labeled("instruction"); var tooltip = data.IsFailure ? data.ErrorMessage ! : $"{data.BoxOpsCount!.Value.Labeled("boxing")}, " + $"{data.CallvirtOpsCount!.Value.Labeled("unconstrained virtual call")}, " + $"{data.MemberByteSize!.Value.Labeled("byte")}"; return(new CodeLensDataPointDescriptor { Description = description, TooltipText = tooltip, ImageId = null, IntValue = data.InstructionsCount }); } catch (Exception ex) { LogCL(ex); throw; } }
public Task <CodeLensDataPointDescriptor> GetDataAsync(CodeLensDescriptorContext context, CancellationToken token) { try { Changelist commit = HelixUtility.GetLastCommit(rep, descriptor.FilePath); if (commit == null) { return(Task.FromResult <CodeLensDataPointDescriptor>(null)); } CodeLensDataPointDescriptor response = new CodeLensDataPointDescriptor() { Description = commit.OwnerName, //commit.Author.Name, TooltipText = $"Last change committed by {commit.OwnerName} at {commit.ModifiedDate.ToString(CultureInfo.CurrentCulture)}", IntValue = null, // no int value ImageId = GetCommitTypeIcon(commit), }; return(Task.FromResult(response)); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show( "file: " + descriptor.FilePath + "\r\n" + "port: " + this.rep.Server.Address + "\r\n" + "user: "******"\r\n" + "client: " + this.rep.Connection.Client.Name + "\r\n" + "Exception:" + "\r\n" + ex.ToString()); return(Task.FromResult <CodeLensDataPointDescriptor>(null)); } }
public async Task <CodeLensDetailsDescriptor> GetDetailsAsync(CodeLensDescriptorContext context, CancellationToken ct) { try { // When opening the details pane, the data point is re-created leaving `data` uninitialized. VS will // then call `GetDataAsync()` and `GetDetailsAsync()` concurrently. if (!dataLoaded.Wait(timeout: TimeSpan.FromSeconds(.5), ct)) { data = await LoadInstructions(context, ct).Caf(); } if (data !.IsFailure) { throw new InvalidOperationException($"Getting CodeLens details for {context.FullName()} failed: {data.ErrorMessage}"); } return(new CodeLensDetailsDescriptor { // Since it's impossible to figure out how to use [DetailsTemplateName], we'll // just use the default grid template without any headers/entries and add // what we want to transmit to the custom data. Headers = Enumerable.Empty <CodeLensDetailHeaderDescriptor>(), Entries = Enumerable.Empty <CodeLensDetailEntryDescriptor>(), CustomData = new[] { new CodeLensDetails(id) }, PaneNavigationCommands = new[] { new CodeLensDetailPaneCommand { CommandDisplayName = "Refresh", CommandId = refreshCmdId, CommandArgs = new[] { (object)id } } } }); } catch (Exception ex) { LogCL(ex); throw; } }
public async Task <ReferenceCount?> GetReferenceCountAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, ReferenceCount?previousCount, CancellationToken cancellationToken) { var solution = _workspace.CurrentSolution; var(documentId, node) = await GetDocumentIdAndNodeAsync( solution, descriptor, descriptorContext, cancellationToken).ConfigureAwait(false); if (documentId == null) { return(null); } var service = _workspace.Services.GetRequiredService <ICodeLensReferencesService>(); if (previousCount is not null) { // Avoid calculating results if we already have a result for the current project version var currentProjectVersion = await service.GetProjectCodeLensVersionAsync(solution, documentId.ProjectId, cancellationToken).ConfigureAwait(false); if (previousCount.Value.Version == currentProjectVersion.ToString()) { return(previousCount); } } var maxSearchResults = await GetMaxResultCapAsync(cancellationToken).ConfigureAwait(false); return(await service.GetReferenceCountAsync(solution, documentId, node, maxSearchResults, cancellationToken).ConfigureAwait(false)); }
public Task <bool> CanCreateDataPointAsync(CodeLensDescriptor descriptor, CodeLensDescriptorContext context, CancellationToken token) { Debug.Assert(descriptor != null); var gitRepo = GitUtil.ProbeGitRepository(descriptor.FilePath, out string repoRoot); return(Task.FromResult <bool>(gitRepo != null)); }
private async Task <DpdtBindingReferenceSet?> GetReferenceSetAsync( CodeLensDescriptorContext context, CancellationToken token ) { DpdtBindingReferenceSet?bindings = null; try { bindings = await _callbackService .InvokeAsync <DpdtBindingReferenceSet>( this, nameof(IDpdtCodeLensListener.GetReferenceSet), new object[] { new CodeLensTarget( _descriptor.ProjectGuid, _descriptor.FilePath, (string)context.Properties["FullyQualifiedName"], context.ApplicableSpan.HasValue ? context.ApplicableSpan.Value.Start : (int?)null, context.ApplicableSpan.HasValue ? context.ApplicableSpan.Value.Length : (int?)null ) }, token ) .ConfigureAwait(false) ; } catch (Exception ex) { LogCL(ex); } return(bindings); }
public async Task <ImmutableArray <ReferenceMethodDescriptor>?> FindReferenceMethodsAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken ) { var solution = _workspace.CurrentSolution; var(documentId, node) = await GetDocumentIdAndNodeAsync( solution, descriptor, descriptorContext.ApplicableSpan, cancellationToken ) .ConfigureAwait(false); if (documentId == null) { return(null); } var service = _workspace.Services.GetRequiredService <ICodeLensReferencesService>(); return(await service .FindReferenceMethodsAsync(solution, documentId, node, cancellationToken) .ConfigureAwait(false)); }
public Task <bool> CanCreateDataPointAsync(CodeLensDescriptor descriptor, CodeLensDescriptorContext context, CancellationToken token) { Debug.Assert(descriptor != null); var Repo = HelixUtility.GetRepository(descriptor.FilePath, out string repoRoot, out Changelist latest); return(Task.FromResult <bool>(Repo != null && latest != null)); }
public Task <bool> CanCreateDataPointAsync(CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken token) { if (descriptor.Kind == CodeElementKinds.Method) { var projectId = descriptor.ProjectGuid; var connection = Shared.Server.SentryConnection.GetCurrent(projectId); return(Task.FromResult(connection.IsEnabled)); } return(Task.FromResult(false)); }
public Task <bool> CanCreateDataPointAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { if (descriptorContext != null && descriptorContext.ApplicableSpan.HasValue) { // we allow all reference points. // engine will call this for all points our roslyn code lens (reference) tagger tagged. return(SpecializedTasks.True); } return(SpecializedTasks.False); }
public async Task <IAsyncCodeLensDataPoint> CreateDataPointAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { var dataPoint = new DataPoint( this, _lazyCodeLensCallbackService.Value, descriptor, await GetConnectionAsync(cancellationToken).ConfigureAwait(false)); await dataPoint.TrackChangesAsync(cancellationToken).ConfigureAwait(false); return(dataPoint); }
public async Task <CodeLensDataPointDescriptor> GetDataAsync(CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { var codeElementKind = GetCodeElementKindsString(Descriptor.Kind); // we always get data through VS rather than Roslyn OOP directly since we want final data rather than // raw data from Roslyn OOP such as razor find all reference results var referenceCount = await _callbackService.InvokeAsync <ReferenceCount>( _owner, nameof(ICodeLensContext.GetReferenceCountAsync), new object[] { Descriptor, descriptorContext }, cancellationToken).ConfigureAwait(false); if (referenceCount == null) { return(null); } var referenceCountString = $"{referenceCount.Count}{(referenceCount.IsCapped ? "+" : string.Empty)}"; return(new CodeLensDataPointDescriptor() { Description = referenceCount.Count == 1 ? string.Format(CodeLensVSResources._0_reference, referenceCountString) : string.Format(CodeLensVSResources._0_references, referenceCountString), IntValue = referenceCount.Count, TooltipText = string.Format(CodeLensVSResources.This_0_has_1_references, codeElementKind, referenceCountString), ImageId = null }); string GetCodeElementKindsString(CodeElementKinds kind) { switch (kind) { case CodeElementKinds.Method: return(CodeLensVSResources.method); case CodeElementKinds.Type: return(CodeLensVSResources.type); case CodeElementKinds.Property: return(CodeLensVSResources.property); default: // code lens engine will catch and ignore exception // basically not showing data point throw new NotSupportedException(nameof(kind)); } } }
public async Task <IEnumerable <ReferenceLocationDescriptor> > FindReferenceLocationsAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { var solution = _workspace.CurrentSolution; var(documentId, node) = await GetDocumentIdAndNodeAsync( solution, descriptor, descriptorContext.ApplicableSpan.Value, cancellationToken).ConfigureAwait(false); if (documentId == null) { return(null); } var service = _workspace.Services.GetService <ICodeLensReferencesService>(); return(await service.FindReferenceLocationsAsync(solution, documentId, node, cancellationToken).ConfigureAwait(false)); }
public Task <CodeLensDetailsDescriptor> GetDetailsAsync(CodeLensDescriptorContext descriptorContext, CancellationToken token) { var args = new CodeLensCopyLinkResult { ApplicableSpan = descriptorContext.ApplicableSpan.GetValueOrDefault() }; var response = new CodeLensDetailsDescriptor { Headers = new List <CodeLensDetailHeaderDescriptor>(), Entries = new List <CodeLensDetailEntryDescriptor>(), PaneNavigationCommands = new List <CodeLensDetailPaneCommand>(), CustomData = new List <CodeLensCopyLinkResult> { args } }; return(Task.FromResult(response)); }
public async Task <IAsyncCodeLensDataPoint> CreateDataPointAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext context, CancellationToken ct) { try { var dp = new CodeLensDataPoint(callbackService.Value, descriptor); var vspid = await callbackService.Value .InvokeAsync <int>(this, nameof(IInstructionsProvider.GetVisualStudioPid)).Caf(); await dp.ConnectToVisualStudio(vspid).Caf(); return(dp); } catch (Exception ex) { LogCL(ex); throw; } }
public async Task <ReferenceCount?> GetReferenceCountAsync( CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { var solution = _workspace.CurrentSolution; var(documentId, node) = await GetDocumentIdAndNodeAsync( solution, descriptor, descriptorContext.ApplicableSpan, cancellationToken).ConfigureAwait(false); if (documentId == null) { return(null); } var maxSearchResults = await GetMaxResultCapAsync(cancellationToken).ConfigureAwait(false); var service = _workspace.Services.GetRequiredService <ICodeLensReferencesService>(); return(await service.GetReferenceCountAsync(solution, documentId, node, maxSearchResults, cancellationToken).ConfigureAwait(false)); }
public Task <CodeLensDataPointDescriptor> GetDataAsync(CodeLensDescriptorContext context, CancellationToken token) { // get the most recent commit Commit commit = GitUtil.GetCommits(this.gitRepo, this.descriptor.FilePath, 1).FirstOrDefault(); if (commit == null) { return(Task.FromResult <CodeLensDataPointDescriptor>(null)); } CodeLensDataPointDescriptor response = new CodeLensDataPointDescriptor() { Description = commit.Author.Name, TooltipText = $"Last change committed by {commit.Author.Name} at {commit.Author.When.ToString(CultureInfo.CurrentCulture)}", IntValue = null, // no int value ImageId = GetCommitTypeIcon(commit), }; return(Task.FromResult(response)); }
public Task <CodeLensDetailsDescriptor> GetDetailsAsync(CodeLensDescriptorContext context, CancellationToken token) { // get the most recent 5 commits var commits = GitUtil.GetCommits(this.gitRepo, this.descriptor.FilePath, 5).AsEnumerable(); if (commits == null || commits.Count() == 0) { return(Task.FromResult <CodeLensDetailsDescriptor>(null)); } var firstCommit = commits.First(); var result = new CodeLensDetailsDescriptor() { Headers = CreateHeaders(), Entries = CreateEntries(commits), CustomData = new List <GitCommitCustomDetailsData>() { new GitCommitCustomDetailsData() { CommitDescription = firstCommit.Message, CommitAuthor = firstCommit.Author.Name, CommitSha = firstCommit.Sha } }, PaneNavigationCommands = new List <CodeLensDetailPaneCommand>() { new CodeLensDetailPaneCommand() { CommandId = new CodeLensDetailEntryCommand() { CommandSet = new Guid("57735D06-C920-4415-A2E0-7D6E6FBDFA99"), CommandId = 0x1005, CommandName = "Git.ShowHistory", }, CommandDisplayName = "Show History" } }, }; return(Task.FromResult(result)); }
public async Task <CodeLensDetailsDescriptor> GetDetailsAsync(CodeLensDescriptorContext context, CancellationToken token) { try { // When opening the details pane, the data point is re-created leaving `data` uninitialized. VS will // then call `GetDataAsync()` and `GetDetailsAsync()` concurrently. if (!_dataHasLoaded.Wait(timeout: TimeSpan.FromSeconds(.5), token)) { _bindings = await GetReferenceSetAsync(context, token); } var result = new CodeLensDetailsDescriptor() { Headers = CreateHeaders(), Entries = CreateEntries(), CustomData = _bindings != null ? new List <object>() { _bindings } : new List <object>(), PaneNavigationCommands = new List <CodeLensDetailPaneCommand>() { //new CodeLensDetailPaneCommand //{ // CommandDisplayName = "Add binding...", // CommandId = _addBindingCommandId, // CommandArgs = new object[] { /*(object)id*/ } //} }, }; return(result); } catch (Exception ex) { LogCL(ex); throw; } }
public Task <CodeLensDataPointDescriptor?> GetDataAsync(CodeLensDescriptorContext descriptorContext, CancellationToken token) { if (!_repositoryService.TryGetKnownRepository( Descriptor.FilePath, out _, out RepositoryInfo? repositoryInfo) || repositoryInfo == null) { return(Task.FromResult <CodeLensDataPointDescriptor?>(null)); } var response = new CodeLensDataPointDescriptor { Description = $"Copy link to this {Descriptor.Kind.ToString().ToLower()}", TooltipText = $"Generate and copy a link to this {Descriptor.Kind.ToString().ToLower()}.", IntValue = null, // no int value ImageId = new ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.Link) }; return(Task.FromResult <CodeLensDataPointDescriptor?>(response)); }
public async Task <CodeLensDataPointDescriptor> GetDataAsync(CodeLensDescriptorContext descriptorContext, CancellationToken token) { Console.WriteLine(_descriptor.ElementDescription); if (!_sentryConnection.IsEnabled) { return(null); } var query = BuildIssueQuery(); Data = (await _sentryConnection.GetIssuesAsync(query)).ToList(); int errors = Data.Sum(x => int.TryParse(x.count, out var i) ? i : 0); return(new CodeLensDataPointDescriptor() { IntValue = errors, Description = $"{errors} exception{(errors == 1 ? "" : "s")}", ImageId = errors == 0 ? default : new ImageId(new Guid("ae27a6b0-e345-4288-96df-5eaf394ee369"), 3175), // TODO: Replace with custom Sentry icon TooltipText = "Errors recorded in Sentry", });
public async Task <CodeLensDataPointDescriptor> GetDataAsync(CodeLensDescriptorContext descriptorContext, CancellationToken token) { Console.WriteLine(_descriptor.ElementDescription); if (!_sentryConnection.IsEnabled) { return(null); } // TODO: Can do way better than this via using streams and only reading until the namespace is matched // it might reduce IO usage compared to reading the whole file var nsMatch = _nameSpaceRegex.Match(File.ReadAllText(_descriptor.FilePath)); string ns = string.Empty; if (nsMatch.Success) { ns = nsMatch.Groups[1].Value.Trim(); } var split = _descriptor.ElementDescription.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); var @class = split.First().Trim(); var method = split.Last().Trim(); query = $"stack.module:{ns}.{@class} stack.function:{method}"; Logging.LogCL($"Sentry Query: {query}"); Data = (await _sentryConnection.GetIssues($"stack.module:{ns}.{@class}+stack.function:{method}")).ToList(); int errors = Data.Sum(x => int.TryParse(x.count, out var i) ? i : 0); return(new CodeLensDataPointDescriptor() { IntValue = errors, Description = $"{errors} exception{(errors == 1 ? "" : "s")}", ImageId = errors == 0 ? default : new ImageId(new Guid("ae27a6b0-e345-4288-96df-5eaf394ee369"), 3175), // TODO: Replace with custom Sentry icon TooltipText = "Errors recorded in Sentry", });
public async Task <CodeLensDataPointDescriptor> GetDataAsync(CodeLensDescriptorContext context, CancellationToken token) { try { _bindings = await GetReferenceSetAsync(context, token); _dataHasLoaded.Set(); if (_bindings == null) { var response = new CodeLensDataPointDescriptor() { Description = $"Dpdt: no data available", TooltipText = $"Dpdt binding actual status", IntValue = null, // no int value ImageId = GetTypeIcon(), }; return(response); } if (_bindings.Status == DpdtBindingReferenceSetStatusEnum.Disabled) { var response = new CodeLensDataPointDescriptor() { Description = $"Dpdt: DISABLED", TooltipText = $"Dpdt binding actual status", IntValue = null, // no int value ImageId = GetTypeIcon(), }; return(response); } if (_bindings.Status == DpdtBindingReferenceSetStatusEnum.InProgress) { var response = new CodeLensDataPointDescriptor() { Description = $"Dpdt: scanning...", TooltipText = $"Dpdt binding actual status", IntValue = null, // no int value ImageId = GetTypeIcon(), }; return(response); } var bindCount = _bindings.GetBindingCount(); if (bindCount > 1) { var response = new CodeLensDataPointDescriptor() { Description = $"Dpdt: bind at {bindCount} points", TooltipText = $"Dpdt binding actual status", IntValue = null, // no int value ImageId = GetTypeIcon(), }; return(response); } else if (bindCount == 0) { var response = new CodeLensDataPointDescriptor() { Description = $"Dpdt: no bind found", TooltipText = $"Dpdt binding actual status", IntValue = null, // no int value ImageId = GetTypeIcon() }; return(response); } else { var response = new CodeLensDataPointDescriptor() { Description = $"Dpdt: bind at {_bindings.BindingTargets[0].ClusterDetail.FullName}", TooltipText = $"Dpdt binding actual status", IntValue = null, // no int value ImageId = GetTypeIcon(), }; return(response); } } catch (Exception ex) { LogCL(ex); throw; } }
public static string FullName(this CodeLensDescriptorContext ctx) => ctx.Get <string>("FullyQualifiedName");
public static T Get <T>(this CodeLensDescriptorContext ctx, string key) => (T)ctx.Properties[key];
public async Task <CodeLensDetailsDescriptor> GetDetailsAsync(CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { // we always get data through VS rather than Roslyn OOP directly since we want final data rather than // raw data from Roslyn OOP such as razor find all reference results var referenceLocationDescriptors = await _callbackService.InvokeAsync <IEnumerable <ReferenceLocationDescriptor> >( _owner, nameof(ICodeLensContext.FindReferenceLocationsAsync), new object[] { Descriptor, descriptorContext }, cancellationToken).ConfigureAwait(false); var details = new CodeLensDetailsDescriptor { Headers = s_header, Entries = referenceLocationDescriptors.Select(referenceLocationDescriptor => { ImageId imageId = default; if (referenceLocationDescriptor.Glyph.HasValue) { var moniker = referenceLocationDescriptor.Glyph.Value.GetImageMoniker(); imageId = new ImageId(moniker.Guid, moniker.Id); } return(new CodeLensDetailEntryDescriptor() { // use default since reference codelens don't require special behaviors NavigationCommand = null, NavigationCommandArgs = null, Tooltip = null, Fields = new List <CodeLensDetailEntryField>() { new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.FilePath }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.LineNumber.ToString() }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.ColumnNumber.ToString() }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.ReferenceLineText }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.ReferenceStart.ToString() }, new CodeLensDetailEntryField() { Text = (referenceLocationDescriptor.ReferenceStart + referenceLocationDescriptor.ReferenceLength).ToString() }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.LongDescription }, new CodeLensDetailEntryField() { ImageId = imageId }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.BeforeReferenceText2 }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.BeforeReferenceText1 }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.AfterReferenceText1 }, new CodeLensDetailEntryField() { Text = referenceLocationDescriptor.AfterReferenceText2 } }, }); }).ToList(), // use default behavior PaneNavigationCommands = null }; return(details); }
private async Task <(DocumentId?, SyntaxNode?)> GetDocumentIdAndNodeAsync( Solution solution, CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken cancellationToken) { if (descriptorContext.ApplicableSpan is null) { return(default);