Example #1
0
        private static async Task <ImmutableArray <DocumentHighlight> > GetReferenceHighlightsAsync(Document document, SourceText text, int position, CancellationToken cancellationToken)
        {
            var documentHighlightService = document.GetRequiredLanguageService <IDocumentHighlightsService>();
            var options    = DocumentHighlightingOptions.From(document.Project);
            var highlights = await documentHighlightService.GetDocumentHighlightsAsync(
                document,
                position,
                ImmutableHashSet.Create(document),
                options,
                cancellationToken).ConfigureAwait(false);

            if (!highlights.IsDefaultOrEmpty)
            {
                // LSP requests are only for a single document. So just get the highlights for the requested document.
                var highlightsForDocument = highlights.FirstOrDefault(h => h.Document.Id == document.Id);

                return(highlightsForDocument.HighlightSpans.SelectAsArray(h => new DocumentHighlight
                {
                    Range = ProtocolConversions.TextSpanToRange(h.TextSpan, text),
                    Kind = ProtocolConversions.HighlightSpanKindToDocumentHighlightKind(h.Kind),
                }));
            }

            return(ImmutableArray <DocumentHighlight> .Empty);
        }
Example #2
0
        private static async Task ProduceTagsAsync(
            TaggerContext <NavigableHighlightTag> context,
            SnapshotPoint position,
            Document document,
            DocumentHighlightingOptions options,
            CancellationToken cancellationToken)
        {
            var solution = document.Project.Solution;

            using (Logger.LogBlock(FunctionId.Tagger_ReferenceHighlighting_TagProducer_ProduceTags, cancellationToken))
            {
                if (document != null)
                {
                    var service = document.GetLanguageService <IDocumentHighlightsService>();
                    if (service != null)
                    {
                        // We only want to search inside documents that correspond to the snapshots
                        // we're looking at
                        var documentsToSearch      = ImmutableHashSet.CreateRange(context.SpansToTag.Select(vt => vt.Document).WhereNotNull());
                        var documentHighlightsList = await service.GetDocumentHighlightsAsync(
                            document, position, documentsToSearch, options, cancellationToken).ConfigureAwait(false);

                        if (documentHighlightsList != null)
                        {
                            foreach (var documentHighlights in documentHighlightsList)
                            {
                                AddTagSpans(context, documentHighlights, cancellationToken);
                            }
                        }
                    }
                }
            }
        }
Example #3
0
        protected override Task ProduceTagsAsync(
            TaggerContext <NavigableHighlightTag> context, CancellationToken cancellationToken)
        {
            // NOTE(cyrusn): Normally we'd limit ourselves to producing tags in the span we were
            // asked about.  However, we want to produce all tags here so that the user can actually
            // navigate between all of them using the appropriate tag navigation commands.  If we
            // don't generate all the tags then the user will cycle through an incorrect subset.
            if (context.CaretPosition == null)
            {
                return(Task.CompletedTask);
            }

            var caretPosition = context.CaretPosition.Value;

            // GetSpansToTag may have produced no actual spans to tag.  Be resilient to that.
            var document = context.SpansToTag.FirstOrDefault(vt => vt.SnapshotSpan.Snapshot == caretPosition.Snapshot).Document;

            if (document == null)
            {
                return(Task.CompletedTask);
            }

            // Don't produce tags if the feature is not enabled.
            if (!_globalOptions.GetOption(FeatureOnOffOptions.ReferenceHighlighting, document.Project.Language))
            {
                return(Task.CompletedTask);
            }

            // See if the user is just moving their caret around in an existing tag.  If so, we don't
            // want to actually go recompute things.  Note: this only works for containment.  If the
            // user moves their caret to the end of a highlighted reference, we do want to recompute
            // as they may now be at the start of some other reference that should be highlighted instead.
            var existingTags = context.GetExistingContainingTags(caretPosition);

            if (!existingTags.IsEmpty())
            {
                context.SetSpansTagged(SpecializedCollections.EmptyEnumerable <DocumentSnapshotSpan>());
                return(Task.CompletedTask);
            }

            // Otherwise, we need to go produce all tags.
            var options = DocumentHighlightingOptions.From(document.Project);

            return(ProduceTagsAsync(context, caretPosition, document, options, cancellationToken));
        }
        public override async Task <DocumentHighlight[]?> HandleRequestAsync(TextDocumentPositionParams request, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

            if (document == null)
            {
                return(null);
            }

            var documentHighlightService = document.Project.LanguageServices.GetRequiredService <IDocumentHighlightsService>();
            var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);

            var options = DocumentHighlightingOptions.From(document.Project);

            var highlights = await documentHighlightService.GetDocumentHighlightsAsync(
                document,
                position,
                ImmutableHashSet.Create(document),
                options,
                cancellationToken).ConfigureAwait(false);

            if (!highlights.IsDefaultOrEmpty)
            {
                // LSP requests are only for a single document. So just get the highlights for the requested document.
                var highlightsForDocument = highlights.FirstOrDefault(h => h.Document.Id == document.Id);
                var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                return(highlightsForDocument.HighlightSpans.Select(h => new DocumentHighlight
                {
                    Range = ProtocolConversions.TextSpanToRange(h.TextSpan, text),
                    Kind = ProtocolConversions.HighlightSpanKindToDocumentHighlightKind(h.Kind),
                }).ToArray());
            }

            return(Array.Empty <DocumentHighlight>());
        }
        public async Task <ImmutableArray <DocumentHighlights> > GetDocumentHighlightsAsync(Document document, int position, IImmutableSet <Document> documentsToSearch, DocumentHighlightingOptions options, CancellationToken cancellationToken)
        {
            var highlights = await _service.GetDocumentHighlightsAsync(document, position, documentsToSearch, cancellationToken).ConfigureAwait(false);

            return(highlights.SelectAsArray(x => new DocumentHighlights(x.Document, MapHighlightSpans(x.HighlightSpans))));
        }
Example #6
0
 Task <ImmutableArray <DocumentHighlights> > IDocumentHighlightsService.GetDocumentHighlightsAsync(
     Document document, int position, IImmutableSet <Document> documentsToSearch, DocumentHighlightingOptions options, CancellationToken cancellationToken)
 => GetDocumentHighlightsAsync(document, position, documentsToSearch, cancellationToken);