aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/attr.rs42
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
3use std::{ 3use 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
571impl DocsRangeMap { 572impl 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 }