From b1d5817dd18b7b5fc102a63b084b1ee7ff4f9996 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 23:40:41 +0200 Subject: Convert code to text-size --- crates/ra_ide_db/src/line_index.rs | 54 ++++++++++++++++---------------- crates/ra_ide_db/src/line_index_utils.rs | 48 ++++++++++++++-------------- crates/ra_ide_db/src/search.rs | 9 +++--- 3 files changed, 55 insertions(+), 56 deletions(-) (limited to 'crates/ra_ide_db') diff --git a/crates/ra_ide_db/src/line_index.rs b/crates/ra_ide_db/src/line_index.rs index 8ae745ff2..7794dc9fd 100644 --- a/crates/ra_ide_db/src/line_index.rs +++ b/crates/ra_ide_db/src/line_index.rs @@ -1,14 +1,14 @@ -//! `LineIndex` maps flat `TextUnit` offsets into `(Line, Column)` +//! `LineIndex` maps flat `TextSize` offsets into `(Line, Column)` //! representation. use std::iter; - -use ra_syntax::{TextRange, TextUnit}; +// TODO: un TextSize +use ra_syntax::{TextRange, TextSize}; use rustc_hash::FxHashMap; use superslice::Ext; #[derive(Clone, Debug, PartialEq, Eq)] pub struct LineIndex { - pub(crate) newlines: Vec, + pub(crate) newlines: Vec, pub(crate) utf16_lines: FxHashMap>, } @@ -22,12 +22,12 @@ pub struct LineCol { #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub(crate) struct Utf16Char { - pub(crate) start: TextUnit, - pub(crate) end: TextUnit, + pub(crate) start: TextSize, + pub(crate) end: TextSize, } impl Utf16Char { - fn len(&self) -> TextUnit { + fn len(&self) -> TextSize { self.end - self.start } } @@ -42,7 +42,7 @@ impl LineIndex { let mut curr_col = 0.into(); let mut line = 0; for c in text.chars() { - curr_row += TextUnit::of_char(c); + curr_row += TextSize::of(c); if c == '\n' { newlines.push(curr_row); @@ -58,8 +58,8 @@ impl LineIndex { continue; } - let char_len = TextUnit::of_char(c); - if char_len > TextUnit::from_usize(1) { + let char_len = TextSize::of(c); + if char_len > TextSize::from_usize(1) { utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + char_len }); } @@ -74,7 +74,7 @@ impl LineIndex { LineIndex { newlines, utf16_lines } } - pub fn line_col(&self, offset: TextUnit) -> LineCol { + pub fn line_col(&self, offset: TextSize) -> LineCol { let line = self.newlines.upper_bound(&offset) - 1; let line_start_offset = self.newlines[line]; let col = offset - line_start_offset; @@ -82,7 +82,7 @@ impl LineIndex { LineCol { line: line as u32, col_utf16: self.utf8_to_utf16_col(line as u32, col) as u32 } } - pub fn offset(&self, line_col: LineCol) -> TextUnit { + pub fn offset(&self, line_col: LineCol) -> TextSize { //FIXME: return Result let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16); self.newlines[line_col.line as usize] + col @@ -97,16 +97,16 @@ impl LineIndex { all.clone() .zip(all.skip(1)) - .map(|(lo, hi)| TextRange::from_to(lo, hi)) + .map(|(lo, hi)| TextRange::new(lo, hi)) .filter(|it| !it.is_empty()) } - fn utf8_to_utf16_col(&self, line: u32, col: TextUnit) -> usize { + fn utf8_to_utf16_col(&self, line: u32, col: TextSize) -> usize { if let Some(utf16_chars) = self.utf16_lines.get(&line) { let mut correction = 0; for c in utf16_chars { if col >= c.end { - correction += c.len().to_usize() - 1; + correction += usize::from(c.len()) - 1; } else { // From here on, all utf16 characters come *after* the character we are mapping, // so we don't need to take them into account @@ -114,18 +114,18 @@ impl LineIndex { } } - col.to_usize() - correction + usize::from(col) - correction } else { - col.to_usize() + usize::from(col) } } - fn utf16_to_utf8_col(&self, line: u32, col: u32) -> TextUnit { - let mut col: TextUnit = col.into(); + fn utf16_to_utf8_col(&self, line: u32, col: u32) -> TextSize { + let mut col: TextSize = col.into(); if let Some(utf16_chars) = self.utf16_lines.get(&line) { for c in utf16_chars { if col >= c.start { - col += c.len() - TextUnit::from_usize(1); + col += c.len() - TextSize::from_usize(1); } else { // From here on, all utf16 characters come *after* the character we are mapping, // so we don't need to take them into account @@ -200,10 +200,10 @@ const C: char = 'メ'; assert_eq!(col_index.utf8_to_utf16_col(1, 22.into()), 20); // UTF-16 to UTF-8, no changes - assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextUnit::from(15)); + assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from(15)); // UTF-16 to UTF-8 - assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextUnit::from(21)); + assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21)); } #[test] @@ -228,18 +228,18 @@ const C: char = \"メ メ\"; assert!(col_index.utf8_to_utf16_col(2, 15.into()) == 15); // UTF-16 to UTF-8 - assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextUnit::from_usize(15)); + assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from_usize(15)); - assert_eq!(col_index.utf16_to_utf8_col(1, 18), TextUnit::from_usize(20)); - assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextUnit::from_usize(23)); + assert_eq!(col_index.utf16_to_utf8_col(1, 18), TextSize::from_usize(20)); + assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from_usize(23)); - assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextUnit::from_usize(15)); + assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextSize::from_usize(15)); } #[test] fn test_splitlines() { fn r(lo: u32, hi: u32) -> TextRange { - TextRange::from_to(lo.into(), hi.into()) + TextRange::new(lo.into(), hi.into()) } let text = "a\nbb\nccc\n"; diff --git a/crates/ra_ide_db/src/line_index_utils.rs b/crates/ra_ide_db/src/line_index_utils.rs index 2ebbabdc6..f050fe77f 100644 --- a/crates/ra_ide_db/src/line_index_utils.rs +++ b/crates/ra_ide_db/src/line_index_utils.rs @@ -1,20 +1,20 @@ //! Code actions can specify desirable final position of the cursor. //! -//! The position is specified as a `TextUnit` in the final file. We need to send +//! The position is specified as a `TextSize` in the final file. We need to send //! it in `(Line, Column)` coordinate though. However, we only have a LineIndex //! for a file pre-edit! //! //! Code in this module applies this "to (Line, Column) after edit" //! transformation. -use ra_syntax::{TextRange, TextUnit}; +use ra_syntax::{TextRange, TextSize}; use ra_text_edit::{AtomTextEdit, TextEdit}; use crate::line_index::{LineCol, LineIndex, Utf16Char}; pub fn translate_offset_with_edit( line_index: &LineIndex, - offset: TextUnit, + offset: TextSize, text_edit: &TextEdit, ) -> LineCol { let mut state = Edits::from_text_edit(&text_edit); @@ -84,7 +84,7 @@ pub fn translate_offset_with_edit( #[derive(Debug, Clone)] enum Step { - Newline(TextUnit), + Newline(TextSize), Utf16Char(TextRange), } @@ -92,7 +92,7 @@ enum Step { struct LineIndexStepIter<'a> { line_index: &'a LineIndex, next_newline_idx: usize, - utf16_chars: Option<(TextUnit, std::slice::Iter<'a, Utf16Char>)>, + utf16_chars: Option<(TextSize, std::slice::Iter<'a, Utf16Char>)>, } impl LineIndexStepIter<'_> { @@ -111,7 +111,7 @@ impl Iterator for LineIndexStepIter<'_> { .as_mut() .and_then(|(newline, x)| { let x = x.next()?; - Some(Step::Utf16Char(TextRange::from_to(*newline + x.start, *newline + x.end))) + Some(Step::Utf16Char(TextRange::new(*newline + x.start, *newline + x.end))) }) .or_else(|| { let next_newline = *self.line_index.newlines.get(self.next_newline_idx)?; @@ -129,7 +129,7 @@ impl Iterator for LineIndexStepIter<'_> { #[derive(Debug)] struct OffsetStepIter<'a> { text: &'a str, - offset: TextUnit, + offset: TextSize, } impl Iterator for OffsetStepIter<'_> { @@ -140,15 +140,15 @@ impl Iterator for OffsetStepIter<'_> { .char_indices() .filter_map(|(i, c)| { if c == '\n' { - let next_offset = self.offset + TextUnit::from_usize(i + 1); + let next_offset = self.offset + TextSize::from_usize(i + 1); let next = Step::Newline(next_offset); Some((next, next_offset)) } else { - let char_len = TextUnit::of_char(c); - if char_len > TextUnit::from_usize(1) { - let start = self.offset + TextUnit::from_usize(i); + let char_len = TextSize::of(c); + if char_len > TextSize::from_usize(1) { + let start = self.offset + TextSize::from_usize(i); let end = start + char_len; - let next = Step::Utf16Char(TextRange::from_to(start, end)); + let next = Step::Utf16Char(TextRange::new(start, end)); let next_offset = end; Some((next, next_offset)) } else { @@ -157,7 +157,7 @@ impl Iterator for OffsetStepIter<'_> { } }) .next()?; - let next_idx = (next_offset - self.offset).to_usize(); + let next_idx: usize = (next_offset - self.offset).into(); self.text = &self.text[next_idx..]; self.offset = next_offset; Some(next) @@ -195,7 +195,7 @@ impl<'a> Edits<'a> { match self.edits.split_first() { Some((next, rest)) => { let delete = self.translate_range(next.delete); - let diff = next.insert.len() as i64 - next.delete.len().to_usize() as i64; + let diff = next.insert.len() as i64 - usize::from(next.delete.len()) as i64; self.current = Some(TranslatedEdit { delete, insert: &next.insert, diff }); self.edits = rest; } @@ -244,15 +244,15 @@ impl<'a> Edits<'a> { } else { let start = self.translate(range.start()); let end = self.translate(range.end()); - TextRange::from_to(start, end) + TextRange::new(start, end) } } - fn translate(&self, x: TextUnit) -> TextUnit { + fn translate(&self, x: TextSize) -> TextSize { if self.acc_diff == 0 { x } else { - TextUnit::from((x.to_usize() as i64 + self.acc_diff) as u32) + TextSize::from((usize::from(x) as i64 + self.acc_diff) as u32) } } @@ -271,29 +271,29 @@ impl<'a> Edits<'a> { #[derive(Debug)] struct RunningLineCol { line: u32, - last_newline: TextUnit, - col_adjust: TextUnit, + last_newline: TextSize, + col_adjust: TextSize, } impl RunningLineCol { fn new() -> RunningLineCol { - RunningLineCol { line: 0, last_newline: TextUnit::from(0), col_adjust: TextUnit::from(0) } + RunningLineCol { line: 0, last_newline: TextSize::from(0), col_adjust: TextSize::from(0) } } - fn to_line_col(&self, offset: TextUnit) -> LineCol { + fn to_line_col(&self, offset: TextSize) -> LineCol { LineCol { line: self.line, col_utf16: ((offset - self.last_newline) - self.col_adjust).into(), } } - fn add_line(&mut self, newline: TextUnit) { + fn add_line(&mut self, newline: TextSize) { self.line += 1; self.last_newline = newline; - self.col_adjust = TextUnit::from(0); + self.col_adjust = TextSize::from(0); } fn adjust_col(&mut self, range: TextRange) { - self.col_adjust += range.len() - TextUnit::from(1); + self.col_adjust += range.len() - TextSize::from(1); } } diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs index 1bf014149..c66de4f42 100644 --- a/crates/ra_ide_db/src/search.rs +++ b/crates/ra_ide_db/src/search.rs @@ -10,7 +10,7 @@ use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; use once_cell::unsync::Lazy; use ra_db::{FileId, FileRange, SourceDatabaseExt}; use ra_prof::profile; -use ra_syntax::{ast, match_ast, AstNode, TextRange, TextUnit}; +use ra_syntax::{ast, match_ast, AstNode, TextRange, TextSize}; use rustc_hash::FxHashMap; use test_utils::tested_by; @@ -85,7 +85,7 @@ impl SearchScope { match (r1, r2) { (None, r) | (r, None) => Some(r), (Some(r1), Some(r2)) => { - let r = r1.intersection(&r2)?; + let r = r1.intersect(r2)?; Some(Some(r)) } } @@ -200,14 +200,13 @@ impl Definition { for (file_id, search_range) in search_scope { let text = db.file_text(file_id); - let search_range = - search_range.unwrap_or(TextRange::offset_len(0.into(), TextUnit::of_str(&text))); + let search_range = search_range.unwrap_or(TextRange::up_to(TextSize::of(&text))); let sema = Semantics::new(db); let tree = Lazy::new(|| sema.parse(file_id).syntax().clone()); for (idx, _) in text.match_indices(pat) { - let offset = TextUnit::from_usize(idx); + let offset = TextSize::from_usize(idx); if !search_range.contains_inclusive(offset) { tested_by!(search_filters_by_range; force); continue; -- cgit v1.2.3 From dc2151085e9b117bc87307bf47edf3d17a170b49 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 25 Apr 2020 00:17:50 +0200 Subject: Cleanups --- crates/ra_ide_db/src/line_index.rs | 24 ++++++++++-------------- crates/ra_ide_db/src/search.rs | 3 ++- 2 files changed, 12 insertions(+), 15 deletions(-) (limited to 'crates/ra_ide_db') diff --git a/crates/ra_ide_db/src/line_index.rs b/crates/ra_ide_db/src/line_index.rs index 7794dc9fd..81eebc711 100644 --- a/crates/ra_ide_db/src/line_index.rs +++ b/crates/ra_ide_db/src/line_index.rs @@ -1,9 +1,8 @@ //! `LineIndex` maps flat `TextSize` offsets into `(Line, Column)` //! representation. -use std::iter; -// TODO: un TextSize use ra_syntax::{TextRange, TextSize}; use rustc_hash::FxHashMap; +use std::iter; use superslice::Ext; #[derive(Clone, Debug, PartialEq, Eq)] @@ -42,7 +41,8 @@ impl LineIndex { let mut curr_col = 0.into(); let mut line = 0; for c in text.chars() { - curr_row += TextSize::of(c); + let c_len = TextSize::of(c); + curr_row += c_len; if c == '\n' { newlines.push(curr_row); @@ -58,12 +58,11 @@ impl LineIndex { continue; } - let char_len = TextSize::of(c); - if char_len > TextSize::from_usize(1) { - utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + char_len }); + if !c.is_ascii() { + utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + c_len }); } - curr_col += char_len; + curr_col += c_len; } // Save any utf-16 characters seen in the last line @@ -102,22 +101,19 @@ impl LineIndex { } fn utf8_to_utf16_col(&self, line: u32, col: TextSize) -> usize { + let mut res: usize = col.into(); if let Some(utf16_chars) = self.utf16_lines.get(&line) { - let mut correction = 0; for c in utf16_chars { - if col >= c.end { - correction += usize::from(c.len()) - 1; + if c.end <= col { + res -= usize::from(c.len()) - 1; } else { // From here on, all utf16 characters come *after* the character we are mapping, // so we don't need to take them into account break; } } - - usize::from(col) - correction - } else { - usize::from(col) } + res } fn utf16_to_utf8_col(&self, line: u32, col: u32) -> TextSize { diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs index c66de4f42..599b8e562 100644 --- a/crates/ra_ide_db/src/search.rs +++ b/crates/ra_ide_db/src/search.rs @@ -200,7 +200,8 @@ impl Definition { for (file_id, search_range) in search_scope { let text = db.file_text(file_id); - let search_range = search_range.unwrap_or(TextRange::up_to(TextSize::of(&text))); + let search_range = + search_range.unwrap_or(TextRange::up_to(TextSize::of(text.as_str()))); let sema = Semantics::new(db); let tree = Lazy::new(|| sema.parse(file_id).syntax().clone()); -- cgit v1.2.3 From 63a462f37ca584e1a585a69e30823ce25d4d252f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 25 Apr 2020 00:57:47 +0200 Subject: Switch to TryFrom --- crates/ra_ide_db/src/line_index.rs | 22 +++++++++++----------- crates/ra_ide_db/src/line_index_utils.rs | 11 +++++++---- crates/ra_ide_db/src/search.rs | 4 ++-- 3 files changed, 20 insertions(+), 17 deletions(-) (limited to 'crates/ra_ide_db') diff --git a/crates/ra_ide_db/src/line_index.rs b/crates/ra_ide_db/src/line_index.rs index 81eebc711..00ba95913 100644 --- a/crates/ra_ide_db/src/line_index.rs +++ b/crates/ra_ide_db/src/line_index.rs @@ -1,8 +1,9 @@ //! `LineIndex` maps flat `TextSize` offsets into `(Line, Column)` //! representation. +use std::iter; + use ra_syntax::{TextRange, TextSize}; use rustc_hash::FxHashMap; -use std::iter; use superslice::Ext; #[derive(Clone, Debug, PartialEq, Eq)] @@ -116,12 +117,11 @@ impl LineIndex { res } - fn utf16_to_utf8_col(&self, line: u32, col: u32) -> TextSize { - let mut col: TextSize = col.into(); + fn utf16_to_utf8_col(&self, line: u32, mut col: u32) -> TextSize { if let Some(utf16_chars) = self.utf16_lines.get(&line) { for c in utf16_chars { - if col >= c.start { - col += c.len() - TextSize::from_usize(1); + if col >= u32::from(c.start) { + col += u32::from(c.len()) - 1; } else { // From here on, all utf16 characters come *after* the character we are mapping, // so we don't need to take them into account @@ -130,12 +130,12 @@ impl LineIndex { } } - col + col.into() } } #[cfg(test)] -mod test_line_index { +mod tests { use super::*; #[test] @@ -224,12 +224,12 @@ const C: char = \"メ メ\"; assert!(col_index.utf8_to_utf16_col(2, 15.into()) == 15); // UTF-16 to UTF-8 - assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from_usize(15)); + assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from(15)); - assert_eq!(col_index.utf16_to_utf8_col(1, 18), TextSize::from_usize(20)); - assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from_usize(23)); + assert_eq!(col_index.utf16_to_utf8_col(1, 18), TextSize::from(20)); + assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(23)); - assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextSize::from_usize(15)); + assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextSize::from(15)); } #[test] diff --git a/crates/ra_ide_db/src/line_index_utils.rs b/crates/ra_ide_db/src/line_index_utils.rs index f050fe77f..039a12c0d 100644 --- a/crates/ra_ide_db/src/line_index_utils.rs +++ b/crates/ra_ide_db/src/line_index_utils.rs @@ -7,6 +7,8 @@ //! Code in this module applies this "to (Line, Column) after edit" //! transformation. +use std::convert::TryInto; + use ra_syntax::{TextRange, TextSize}; use ra_text_edit::{AtomTextEdit, TextEdit}; @@ -139,14 +141,15 @@ impl Iterator for OffsetStepIter<'_> { .text .char_indices() .filter_map(|(i, c)| { + let i: TextSize = i.try_into().unwrap(); + let char_len = TextSize::of(c); if c == '\n' { - let next_offset = self.offset + TextSize::from_usize(i + 1); + let next_offset = self.offset + i + char_len; let next = Step::Newline(next_offset); Some((next, next_offset)) } else { - let char_len = TextSize::of(c); - if char_len > TextSize::from_usize(1) { - let start = self.offset + TextSize::from_usize(i); + if !c.is_ascii() { + let start = self.offset + i; let end = start + char_len; let next = Step::Utf16Char(TextRange::new(start, end)); let next_offset = end; diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs index 599b8e562..596f957b8 100644 --- a/crates/ra_ide_db/src/search.rs +++ b/crates/ra_ide_db/src/search.rs @@ -4,7 +4,7 @@ //! get a super-set of matches. Then, we we confirm each match using precise //! name resolution. -use std::mem; +use std::{convert::TryInto, mem}; use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; use once_cell::unsync::Lazy; @@ -207,7 +207,7 @@ impl Definition { let tree = Lazy::new(|| sema.parse(file_id).syntax().clone()); for (idx, _) in text.match_indices(pat) { - let offset = TextSize::from_usize(idx); + let offset: TextSize = idx.try_into().unwrap(); if !search_range.contains_inclusive(offset) { tested_by!(search_filters_by_range; force); continue; -- cgit v1.2.3