Replace Range<usize> usage with TextRange

This commit is contained in:
Lukas Wirth 2021-03-30 22:26:03 +02:00
parent c43359b64e
commit 8d786dc4c3
2 changed files with 27 additions and 32 deletions

View File

@ -1,8 +1,8 @@
//! A higher level attributes based on TokenTree, with also some shortcuts. //! A higher level attributes based on TokenTree, with also some shortcuts.
use std::{ use std::{
cmp::Ordering, convert::{TryFrom, TryInto},
ops::{self, Range}, ops,
sync::Arc, sync::Arc,
}; };
@ -479,6 +479,7 @@ pub fn docs_with_rangemap(
if !doc.is_empty() { if !doc.is_empty() {
for line in doc.split('\n') { for line in doc.split('\n') {
let line = line.trim_end(); let line = line.trim_end();
let line_len = line.len();
let (offset, line) = match line.char_indices().nth(indent) { let (offset, line) = match line.char_indices().nth(indent) {
Some((offset, _)) => (offset, &line[offset..]), Some((offset, _)) => (offset, &line[offset..]),
None => (0, line), None => (0, line),
@ -486,9 +487,9 @@ pub fn docs_with_rangemap(
let buf_offset = buf.len(); let buf_offset = buf.len();
buf.push_str(line); buf.push_str(line);
mapping.push(( mapping.push((
Range { start: buf_offset, end: buf.len() }, TextRange::new(buf_offset.try_into().ok()?, buf.len().try_into().ok()?),
idx, idx,
Range { start: offset, end: line.len() }, TextRange::new(offset.try_into().ok()?, line_len.try_into().ok()?),
)); ));
buf.push('\n'); buf.push('\n');
} }
@ -565,31 +566,18 @@ pub struct DocsRangeMap {
// (docstring-line-range, attr_index, attr-string-range) // (docstring-line-range, attr_index, attr-string-range)
// a mapping from the text range of a line of the [`Documentation`] to the attribute index and // a mapping from the text range of a line of the [`Documentation`] to the attribute index and
// the original (untrimmed) syntax doc line // the original (untrimmed) syntax doc line
mapping: Vec<(Range<usize>, u32, Range<usize>)>, mapping: Vec<(TextRange, u32, TextRange)>,
} }
impl DocsRangeMap { impl DocsRangeMap {
pub fn map(&self, range: Range<usize>) -> Option<InFile<TextRange>> { pub fn map(&self, range: TextRange) -> Option<InFile<TextRange>> {
let found = self let found = self.mapping.binary_search_by(|(probe, ..)| probe.ordering(range)).ok()?;
.mapping
.binary_search_by(|(probe, ..)| {
if probe.contains(&range.start) {
Ordering::Equal
} else {
probe.start.cmp(&range.end)
}
})
.ok()?;
let (line_docs_range, idx, original_line_src_range) = self.mapping[found].clone(); let (line_docs_range, idx, original_line_src_range) = self.mapping[found].clone();
if range.end > line_docs_range.end { if !line_docs_range.contains_range(range) {
return None; return None;
} }
let relative_range = Range { let relative_range = range - line_docs_range.start();
start: range.start - line_docs_range.start,
end: range.end - line_docs_range.start,
};
let range_len = TextSize::from((range.end - range.start) as u32);
let &InFile { file_id, value: ref source } = &self.source[idx as usize]; let &InFile { file_id, value: ref source } = &self.source[idx as usize];
match source { match source {
@ -599,12 +587,10 @@ pub fn map(&self, range: Range<usize>) -> Option<InFile<TextRange>> {
let text_range = comment.syntax().text_range(); let text_range = comment.syntax().text_range();
let range = TextRange::at( let range = TextRange::at(
text_range.start() text_range.start()
+ TextSize::from( + TextSize::try_from(comment.prefix().len()).ok()?
(comment.prefix().len() + original_line_src_range.start()
+ original_line_src_range.start + relative_range.start(),
+ relative_range.start) as u32, text_range.len().min(range.len()),
),
text_range.len().min(range_len),
); );
Some(InFile { file_id, value: range }) Some(InFile { file_id, value: range })
} }

View File

@ -1,6 +1,9 @@
//! Extracts, resolves and rewrites links and intra-doc links in markdown documentation. //! Extracts, resolves and rewrites links and intra-doc links in markdown documentation.
use std::{convert::TryFrom, iter::once, ops::Range}; use std::{
convert::{TryFrom, TryInto},
iter::once,
};
use itertools::Itertools; use itertools::Itertools;
use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag};
@ -15,7 +18,9 @@
defs::{Definition, NameClass, NameRefClass}, defs::{Definition, NameClass, NameRefClass},
RootDatabase, RootDatabase,
}; };
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, TokenAtOffset, T}; use syntax::{
ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, TextRange, TokenAtOffset, T,
};
use crate::{FilePosition, Semantics}; use crate::{FilePosition, Semantics};
@ -115,7 +120,7 @@ pub(crate) fn external_docs(
/// Extracts all links from a given markdown text. /// Extracts all links from a given markdown text.
pub(crate) fn extract_definitions_from_markdown( pub(crate) fn extract_definitions_from_markdown(
markdown: &str, markdown: &str,
) -> Vec<(Range<usize>, String, Option<hir::Namespace>)> { ) -> Vec<(TextRange, String, Option<hir::Namespace>)> {
Parser::new_with_broken_link_callback( Parser::new_with_broken_link_callback(
markdown, markdown,
Options::empty(), Options::empty(),
@ -126,7 +131,11 @@ pub(crate) fn extract_definitions_from_markdown(
if let Event::Start(Tag::Link(_, target, title)) = event { if let Event::Start(Tag::Link(_, target, title)) = event {
let link = if target.is_empty() { title } else { target }; let link = if target.is_empty() { title } else { target };
let (link, ns) = parse_intra_doc_link(&link); let (link, ns) = parse_intra_doc_link(&link);
Some((range, link.to_string(), ns)) Some((
TextRange::new(range.start.try_into().ok()?, range.end.try_into().ok()?),
link.to_string(),
ns,
))
} else { } else {
None None
} }