Cleanup TextEdit API

This commit is contained in:
Aleksey Kladov 2020-08-12 16:58:56 +02:00
parent 8d34262956
commit 7510048ec0
9 changed files with 34 additions and 24 deletions

2
Cargo.lock generated
View file

@ -1205,7 +1205,7 @@ dependencies = [
[[package]] [[package]]
name = "ra_text_edit" name = "ra_text_edit"
version = "0.1.0" version = "0.0.0"
dependencies = [ dependencies = [
"text-size", "text-size",
] ]

View file

@ -15,7 +15,7 @@ use ra_syntax::{
AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize, AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize,
TokenAtOffset, TokenAtOffset,
}; };
use ra_text_edit::TextEditBuilder; use ra_text_edit::{TextEdit, TextEditBuilder};
use crate::{ use crate::{
assist_config::{AssistConfig, SnippetCap}, assist_config::{AssistConfig, SnippetCap},
@ -214,7 +214,7 @@ pub(crate) struct AssistBuilder {
impl AssistBuilder { impl AssistBuilder {
pub(crate) fn new(file_id: FileId) -> AssistBuilder { pub(crate) fn new(file_id: FileId) -> AssistBuilder {
AssistBuilder { AssistBuilder {
edit: TextEditBuilder::default(), edit: TextEdit::builder(),
file_id, file_id,
is_snippet: false, is_snippet: false,
change: SourceChange::default(), change: SourceChange::default(),

View file

@ -14,7 +14,7 @@ use ra_syntax::{
ast::{self, AstNode}, ast::{self, AstNode},
SyntaxNode, TextRange, T, SyntaxNode, TextRange, T,
}; };
use ra_text_edit::{TextEdit, TextEditBuilder}; use ra_text_edit::TextEdit;
use crate::{Diagnostic, FileId, Fix, SourceFileEdit}; use crate::{Diagnostic, FileId, Fix, SourceFileEdit};
@ -103,7 +103,7 @@ fn check_unnecessary_braces_in_use_statement(
text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(&single_use_tree) text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(&single_use_tree)
.unwrap_or_else(|| { .unwrap_or_else(|| {
let to_replace = single_use_tree.syntax().text().to_string(); let to_replace = single_use_tree.syntax().text().to_string();
let mut edit_builder = TextEditBuilder::default(); let mut edit_builder = TextEdit::builder();
edit_builder.delete(use_range); edit_builder.delete(use_range);
edit_builder.insert(use_range.start(), to_replace); edit_builder.insert(use_range.start(), to_replace);
edit_builder.finish() edit_builder.finish()
@ -149,7 +149,7 @@ fn check_struct_shorthand_initialization(
let field_expr = expr.syntax().text().to_string(); let field_expr = expr.syntax().text().to_string();
let field_name_is_tup_index = name_ref.as_tuple_field().is_some(); let field_name_is_tup_index = name_ref.as_tuple_field().is_some();
if field_name == field_expr && !field_name_is_tup_index { if field_name == field_expr && !field_name_is_tup_index {
let mut edit_builder = TextEditBuilder::default(); let mut edit_builder = TextEdit::builder();
edit_builder.delete(record_field.syntax().text_range()); edit_builder.delete(record_field.syntax().text_range());
edit_builder.insert(record_field.syntax().text_range().start(), field_name); edit_builder.insert(record_field.syntax().text_range().start(), field_name);
let edit = edit_builder.finish(); let edit = edit_builder.finish();

View file

@ -13,7 +13,7 @@ use ra_ide_db::{
RootDatabase, RootDatabase,
}; };
use ra_syntax::{algo, ast, AstNode}; use ra_syntax::{algo, ast, AstNode};
use ra_text_edit::{TextEdit, TextEditBuilder}; use ra_text_edit::TextEdit;
/// A [Diagnostic] that potentially has a fix available. /// A [Diagnostic] that potentially has a fix available.
/// ///
@ -70,7 +70,7 @@ impl DiagnosticWithFix for MissingFields {
} }
let edit = { let edit = {
let mut builder = TextEditBuilder::default(); let mut builder = TextEdit::builder();
algo::diff(&old_field_list.syntax(), &new_field_list.syntax()) algo::diff(&old_field_list.syntax(), &new_field_list.syntax())
.into_text_edit(&mut builder); .into_text_edit(&mut builder);
builder.finish() builder.finish()

View file

@ -23,7 +23,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
let syntax = file.syntax(); let syntax = file.syntax();
let text = syntax.text().slice(range.start()..); let text = syntax.text().slice(range.start()..);
let pos = match text.find_char('\n') { let pos = match text.find_char('\n') {
None => return TextEditBuilder::default().finish(), None => return TextEdit::builder().finish(),
Some(pos) => pos, Some(pos) => pos,
}; };
TextRange::at(range.start() + pos, TextSize::of('\n')) TextRange::at(range.start() + pos, TextSize::of('\n'))
@ -35,7 +35,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
NodeOrToken::Node(node) => node, NodeOrToken::Node(node) => node,
NodeOrToken::Token(token) => token.parent(), NodeOrToken::Token(token) => token.parent(),
}; };
let mut edit = TextEditBuilder::default(); let mut edit = TextEdit::builder();
for token in node.descendants_with_tokens().filter_map(|it| it.into_token()) { for token in node.descendants_with_tokens().filter_map(|it| it.into_token()) {
let range = match range.intersect(token.text_range()) { let range = match range.intersect(token.text_range()) {
Some(range) => range, Some(range) => range,

View file

@ -281,7 +281,7 @@ mod tests {
let ra_fixture_after = &trim_indent(ra_fixture_after); let ra_fixture_after = &trim_indent(ra_fixture_after);
let (analysis, position) = analysis_and_position(ra_fixture_before); let (analysis, position) = analysis_and_position(ra_fixture_before);
let source_change = analysis.rename(position, new_name).unwrap(); let source_change = analysis.rename(position, new_name).unwrap();
let mut text_edit_builder = TextEditBuilder::default(); let mut text_edit_builder = TextEdit::builder();
let mut file_id: Option<FileId> = None; let mut file_id: Option<FileId> = None;
if let Some(change) = source_change { if let Some(change) = source_change {
for edit in change.info.source_file_edits { for edit in change.info.source_file_edits {

View file

@ -24,7 +24,7 @@ fn matches_to_edit_at_offset(
relative_start: TextSize, relative_start: TextSize,
rules: &[ResolvedRule], rules: &[ResolvedRule],
) -> TextEdit { ) -> TextEdit {
let mut edit_builder = ra_text_edit::TextEditBuilder::default(); let mut edit_builder = TextEdit::builder();
for m in &matches.matches { for m in &matches.matches {
edit_builder.replace( edit_builder.replace(
m.range.range.checked_sub(relative_start).unwrap(), m.range.range.checked_sub(relative_start).unwrap(),

View file

@ -1,10 +1,9 @@
[package] [package]
edition = "2018"
name = "ra_text_edit" name = "ra_text_edit"
version = "0.1.0" version = "0.0.0"
authors = ["rust-analyzer developers"]
publish = false
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
authors = ["rust-analyzer developers"]
edition = "2018"
[lib] [lib]
doctest = false doctest = false

View file

@ -3,8 +3,6 @@
//! `rust-analyzer` never mutates text itself and only sends diffs to clients, //! `rust-analyzer` never mutates text itself and only sends diffs to clients,
//! so `TextEdit` is the ultimate representation of the work done by //! so `TextEdit` is the ultimate representation of the work done by
//! rust-analyzer. //! rust-analyzer.
use std::{slice, vec};
pub use text_size::{TextRange, TextSize}; pub use text_size::{TextRange, TextSize};
/// `InsertDelete` -- a single "atomic" change to text /// `InsertDelete` -- a single "atomic" change to text
@ -46,20 +44,24 @@ impl Indel {
} }
impl TextEdit { impl TextEdit {
pub fn builder() -> TextEditBuilder {
TextEditBuilder::default()
}
pub fn insert(offset: TextSize, text: String) -> TextEdit { pub fn insert(offset: TextSize, text: String) -> TextEdit {
let mut builder = TextEditBuilder::default(); let mut builder = TextEdit::builder();
builder.insert(offset, text); builder.insert(offset, text);
builder.finish() builder.finish()
} }
pub fn delete(range: TextRange) -> TextEdit { pub fn delete(range: TextRange) -> TextEdit {
let mut builder = TextEditBuilder::default(); let mut builder = TextEdit::builder();
builder.delete(range); builder.delete(range);
builder.finish() builder.finish()
} }
pub fn replace(range: TextRange, replace_with: String) -> TextEdit { pub fn replace(range: TextRange, replace_with: String) -> TextEdit {
let mut builder = TextEditBuilder::default(); let mut builder = TextEdit::builder();
builder.replace(range, replace_with); builder.replace(range, replace_with);
builder.finish() builder.finish()
} }
@ -72,8 +74,8 @@ impl TextEdit {
self.indels.is_empty() self.indels.is_empty()
} }
pub fn iter(&self) -> slice::Iter<'_, Indel> { pub fn iter(&self) -> std::slice::Iter<'_, Indel> {
self.indels.iter() self.into_iter()
} }
pub fn apply(&self, text: &mut String) { pub fn apply(&self, text: &mut String) {
@ -139,13 +141,22 @@ impl TextEdit {
impl IntoIterator for TextEdit { impl IntoIterator for TextEdit {
type Item = Indel; type Item = Indel;
type IntoIter = vec::IntoIter<Self::Item>; type IntoIter = std::vec::IntoIter<Indel>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.indels.into_iter() self.indels.into_iter()
} }
} }
impl<'a> IntoIterator for &'a TextEdit {
type Item = &'a Indel;
type IntoIter = std::slice::Iter<'a, Indel>;
fn into_iter(self) -> Self::IntoIter {
self.indels.iter()
}
}
impl TextEditBuilder { impl TextEditBuilder {
pub fn replace(&mut self, range: TextRange, replace_with: String) { pub fn replace(&mut self, range: TextRange, replace_with: String) {
self.indels.push(Indel::replace(range, replace_with)) self.indels.push(Indel::replace(range, replace_with))