diff options
Diffstat (limited to 'crates/hir_def')
-rw-r--r-- | crates/hir_def/src/attr.rs | 42 |
1 files changed, 14 insertions, 28 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 7791402c9..74bb6de35 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | //! A higher level attributes based on TokenTree, with also some shortcuts. | 1 | //! A higher level attributes based on TokenTree, with also some shortcuts. |
2 | 2 | ||
3 | use std::{ | 3 | use std::{ |
4 | cmp::Ordering, | 4 | convert::{TryFrom, TryInto}, |
5 | ops::{self, Range}, | 5 | ops, |
6 | sync::Arc, | 6 | sync::Arc, |
7 | }; | 7 | }; |
8 | 8 | ||
@@ -479,6 +479,7 @@ impl AttrsWithOwner { | |||
479 | if !doc.is_empty() { | 479 | if !doc.is_empty() { |
480 | for line in doc.split('\n') { | 480 | for line in doc.split('\n') { |
481 | let line = line.trim_end(); | 481 | let line = line.trim_end(); |
482 | let line_len = line.len(); | ||
482 | let (offset, line) = match line.char_indices().nth(indent) { | 483 | let (offset, line) = match line.char_indices().nth(indent) { |
483 | Some((offset, _)) => (offset, &line[offset..]), | 484 | Some((offset, _)) => (offset, &line[offset..]), |
484 | None => (0, line), | 485 | None => (0, line), |
@@ -486,9 +487,9 @@ impl AttrsWithOwner { | |||
486 | let buf_offset = buf.len(); | 487 | let buf_offset = buf.len(); |
487 | buf.push_str(line); | 488 | buf.push_str(line); |
488 | mapping.push(( | 489 | mapping.push(( |
489 | Range { start: buf_offset, end: buf.len() }, | 490 | TextRange::new(buf_offset.try_into().ok()?, buf.len().try_into().ok()?), |
490 | idx, | 491 | idx, |
491 | Range { start: offset, end: line.len() }, | 492 | TextRange::new(offset.try_into().ok()?, line_len.try_into().ok()?), |
492 | )); | 493 | )); |
493 | buf.push('\n'); | 494 | buf.push('\n'); |
494 | } | 495 | } |
@@ -565,31 +566,18 @@ pub struct DocsRangeMap { | |||
565 | // (docstring-line-range, attr_index, attr-string-range) | 566 | // (docstring-line-range, attr_index, attr-string-range) |
566 | // a mapping from the text range of a line of the [`Documentation`] to the attribute index and | 567 | // a mapping from the text range of a line of the [`Documentation`] to the attribute index and |
567 | // the original (untrimmed) syntax doc line | 568 | // the original (untrimmed) syntax doc line |
568 | mapping: Vec<(Range<usize>, u32, Range<usize>)>, | 569 | mapping: Vec<(TextRange, u32, TextRange)>, |
569 | } | 570 | } |
570 | 571 | ||
571 | impl DocsRangeMap { | 572 | impl DocsRangeMap { |
572 | pub fn map(&self, range: Range<usize>) -> Option<InFile<TextRange>> { | 573 | pub fn map(&self, range: TextRange) -> Option<InFile<TextRange>> { |
573 | let found = self | 574 | let found = self.mapping.binary_search_by(|(probe, ..)| probe.ordering(range)).ok()?; |
574 | .mapping | ||
575 | .binary_search_by(|(probe, ..)| { | ||
576 | if probe.contains(&range.start) { | ||
577 | Ordering::Equal | ||
578 | } else { | ||
579 | probe.start.cmp(&range.end) | ||
580 | } | ||
581 | }) | ||
582 | .ok()?; | ||
583 | let (line_docs_range, idx, original_line_src_range) = self.mapping[found].clone(); | 575 | let (line_docs_range, idx, original_line_src_range) = self.mapping[found].clone(); |
584 | if range.end > line_docs_range.end { | 576 | if !line_docs_range.contains_range(range) { |
585 | return None; | 577 | return None; |
586 | } | 578 | } |
587 | 579 | ||
588 | let relative_range = Range { | 580 | let relative_range = range - line_docs_range.start(); |
589 | start: range.start - line_docs_range.start, | ||
590 | end: range.end - line_docs_range.start, | ||
591 | }; | ||
592 | let range_len = TextSize::from((range.end - range.start) as u32); | ||
593 | 581 | ||
594 | let &InFile { file_id, value: ref source } = &self.source[idx as usize]; | 582 | let &InFile { file_id, value: ref source } = &self.source[idx as usize]; |
595 | match source { | 583 | match source { |
@@ -599,12 +587,10 @@ impl DocsRangeMap { | |||
599 | let text_range = comment.syntax().text_range(); | 587 | let text_range = comment.syntax().text_range(); |
600 | let range = TextRange::at( | 588 | let range = TextRange::at( |
601 | text_range.start() | 589 | text_range.start() |
602 | + TextSize::from( | 590 | + TextSize::try_from(comment.prefix().len()).ok()? |
603 | (comment.prefix().len() | 591 | + original_line_src_range.start() |
604 | + original_line_src_range.start | 592 | + relative_range.start(), |
605 | + relative_range.start) as u32, | 593 | text_range.len().min(range.len()), |
606 | ), | ||
607 | text_range.len().min(range_len), | ||
608 | ); | 594 | ); |
609 | Some(InFile { file_id, value: range }) | 595 | Some(InFile { file_id, value: range }) |
610 | } | 596 | } |