Ejemplo n.º 1
0
        public async Task <ExcerptResult?> TryExcerptAsync(
            Document document,
            TextSpan span,
            ExcerptMode mode,
            CancellationToken cancellationToken
            )
        {
            var razorMode = mode switch
            {
                ExcerptMode.SingleLine => RazorExcerptMode.SingleLine,
                ExcerptMode.Tooltip => RazorExcerptMode.Tooltip,
                _ => throw new InvalidEnumArgumentException($"Unsupported enum type {mode}."),
            };
            var nullableRazorExcerpt = await _razorDocumentExcerptService
                                       .TryExcerptAsync(document, span, razorMode, cancellationToken)
                                       .ConfigureAwait(false);

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

            var razorExcerpt  = nullableRazorExcerpt.Value;
            var roslynExcerpt = new ExcerptResult(
                razorExcerpt.Content,
                razorExcerpt.MappedSpan,
                razorExcerpt.ClassifiedSpans,
                razorExcerpt.Document,
                razorExcerpt.Span
                );

            return(roslynExcerpt);
        }
        public async Task <ExcerptResult?> TryExcerptAsync(
            Document document,
            TextSpan span,
            ExcerptMode mode,
            CancellationToken cancellationToken)
        {
            var result = await TryGetExcerptInternalAsync(document, span, (ExcerptModeInternal)mode, cancellationToken).ConfigureAwait(false);

            return(result?.ToExcerptResult());
        }
        private TextSpan ChooseExcerptSpan(SourceText primaryText, TextSpan primarySpan, ExcerptMode mode)
        {
            var startLine = primaryText.Lines.GetLineFromPosition(primarySpan.Start);
            var endLine   = primaryText.Lines.GetLineFromPosition(primarySpan.End);

            // If we're showing a single line then this will do. Otherwise expand the range by 1 in
            // each direction (if possible).
            if (mode == ExcerptMode.Tooltip && startLine.LineNumber > 0)
            {
                startLine = primaryText.Lines[startLine.LineNumber - 1];
            }

            if (mode == ExcerptMode.Tooltip && endLine.LineNumber < primaryText.Lines.Count - 1)
            {
                endLine = primaryText.Lines[endLine.LineNumber + 1];
            }

            return(new TextSpan(startLine.Start, endLine.End - startLine.Start));
        }
        public async Task <ExcerptResult?> TryExcerptAsync(
            Document document,
            TextSpan span,
            ExcerptMode mode,
            CancellationToken cancellationToken)
        {
            if (_document == null)
            {
                return(null);
            }

            var mapped = await _mapper.MapSpansAsync(document, new[] { span }, cancellationToken).ConfigureAwait(false);

            if (mapped.Length == 0 || mapped[0].Equals(default(MappedSpanResult)))
            {
                return(null);
            }

            var project         = _document.Project;
            var primaryDocument = project.GetDocument(mapped[0].FilePath);

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

            var primaryText = await primaryDocument.GetTextAsync().ConfigureAwait(false);

            var primarySpan = primaryText.Lines.GetTextSpan(mapped[0].LinePositionSpan);

            var secondaryDocument = document;
            var secondarySpan     = span;

            // First compute the range of text we want to we to display relative to the primary document.
            var excerptSpan = ChooseExcerptSpan(primaryText, primarySpan, mode);

            // Then we'll classify the spans based on the primary document, since that's the coordinate
            // space that our output mappings use.
            var output = await _document.GetGeneratedOutputAsync().ConfigureAwait(false);

            var mappings        = output.GetCSharpDocument().SourceMappings;
            var classifiedSpans = await ClassifyPreviewAsync(
                primaryText,
                excerptSpan,
                secondaryDocument,
                mappings,
                cancellationToken).ConfigureAwait(false);

            // Now translate everything to be relative to the excerpt
            var offset      = 0 - excerptSpan.Start;
            var excerptText = primaryText.GetSubText(excerptSpan);

            excerptSpan = new TextSpan(excerptSpan.Start + offset, excerptSpan.Length);

            for (var i = 0; i < classifiedSpans.Count; i++)
            {
                var classifiedSpan = classifiedSpans[i];
                var updated        = new TextSpan(classifiedSpan.TextSpan.Start + offset, classifiedSpan.TextSpan.Length);
                Debug.Assert(excerptSpan.Contains(updated));

                classifiedSpans[i] = new ClassifiedSpan(classifiedSpan.ClassificationType, updated);
            }

            return(new ExcerptResult(excerptText, excerptSpan, classifiedSpans.ToImmutable(), document, span));
        }