private async Task <ImmutableArray <DocumentHighlights> > GetDocumentHighlightsInCurrentProcessAsync( Document document, int position, IImmutableSet <Document> documentsToSearch, DocumentHighlightingOptions options, CancellationToken cancellationToken) { var result = await TryGetEmbeddedLanguageHighlightsAsync( document, position, documentsToSearch, options, cancellationToken).ConfigureAwait(false); if (!result.IsDefaultOrEmpty) { return(result); } var solution = document.Project.Solution; var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var symbol = await SymbolFinder.FindSymbolAtPositionAsync( semanticModel, position, solution.Workspace, cancellationToken).ConfigureAwait(false); if (symbol == null) { return(ImmutableArray <DocumentHighlights> .Empty); } // Get unique tags for referenced symbols var tags = await GetTagsForReferencedSymbolAsync( symbol, document, documentsToSearch, cancellationToken).ConfigureAwait(false); // Only accept these highlights if at least one of them actually intersected with the // position the caller was asking for. For example, if the user had `$$new X();` then // SymbolFinder will consider that the symbol `X`. However, the doc highlights won't include // the `new` part, so it's not appropriate for us to highlight `X` in that case. if (!tags.Any(t => t.HighlightSpans.Any(hs => hs.TextSpan.IntersectsWith(position)))) { return(ImmutableArray <DocumentHighlights> .Empty); } return(tags); }
private static async Task <ImmutableArray <DocumentHighlights> > TryGetEmbeddedLanguageHighlightsAsync( Document document, int position, IImmutableSet <Document> documentsToSearch, DocumentHighlightingOptions options, CancellationToken cancellationToken) { var languagesProvider = document.GetLanguageService <IEmbeddedLanguagesProvider>(); if (languagesProvider != null) { foreach (var language in languagesProvider.Languages) { var highlighter = (language as IEmbeddedLanguageFeatures)?.DocumentHighlightsService; if (highlighter != null) { var highlights = await highlighter.GetDocumentHighlightsAsync( document, position, documentsToSearch, options, cancellationToken).ConfigureAwait(false); if (!highlights.IsDefaultOrEmpty) { return(highlights); } } } } return(default);
public async Task <ImmutableArray <DocumentHighlights> > GetDocumentHighlightsAsync( Document document, int position, IImmutableSet <Document> documentsToSearch, DocumentHighlightingOptions options, CancellationToken cancellationToken) { var solution = document.Project.Solution; var client = await RemoteHostClient.TryGetClientAsync(document.Project, cancellationToken).ConfigureAwait(false); if (client != null) { // Call the project overload. We don't need the full solution synchronized over to the OOP // in order to highlight values in this document. var result = await client.TryInvokeAsync <IRemoteDocumentHighlightsService, ImmutableArray <SerializableDocumentHighlights> >( document.Project, (service, solutionInfo, cancellationToken) => service.GetDocumentHighlightsAsync(solutionInfo, document.Id, position, documentsToSearch.SelectAsArray(d => d.Id), options, cancellationToken), cancellationToken).ConfigureAwait(false); if (!result.HasValue) { return(ImmutableArray <DocumentHighlights> .Empty); } return(await result.Value.SelectAsArrayAsync(h => h.RehydrateAsync(solution)).ConfigureAwait(false)); } return(await GetDocumentHighlightsInCurrentProcessAsync( document, position, documentsToSearch, options, cancellationToken).ConfigureAwait(false)); }