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)); }