Skip to content

Commit 30eb458

Browse files
bors[bot]matklad
andauthored
Merge #4332
4332: Refactor TextEdit r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents 78c82ef + ca9e0f5 commit 30eb458

File tree

20 files changed

+271
-227
lines changed

20 files changed

+271
-227
lines changed

crates/ra_assists/src/assist_ctx.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ use ra_db::FileRange;
44
use ra_fmt::{leading_indent, reindent};
55
use ra_ide_db::RootDatabase;
66
use ra_syntax::{
7-
algo::{self, find_covering_element, find_node_at_offset},
7+
algo::{self, find_covering_element, find_node_at_offset, SyntaxRewriter},
88
AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize,
99
TokenAtOffset,
1010
};
1111
use ra_text_edit::TextEditBuilder;
1212

1313
use crate::{AssistAction, AssistFile, AssistId, AssistLabel, GroupLabel, ResolvedAssist};
14-
use algo::SyntaxRewriter;
1514

1615
#[derive(Clone, Debug)]
1716
pub(crate) struct Assist(pub(crate) Vec<AssistInfo>);
@@ -42,8 +41,6 @@ impl AssistInfo {
4241
}
4342
}
4443

45-
pub(crate) type AssistHandler = fn(AssistCtx) -> Option<Assist>;
46-
4744
/// `AssistCtx` allows to apply an assist or check if it could be applied.
4845
///
4946
/// Assists use a somewhat over-engineered approach, given the current needs. The

crates/ra_assists/src/doc_tests.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ fn check(assist_id: &str, before: &str, after: &str) {
3030
)
3131
});
3232

33-
let actual = assist.action.edit.apply(&before);
33+
let actual = {
34+
let mut actual = before.clone();
35+
assist.action.edit.apply(&mut actual);
36+
actual
37+
};
3438
assert_eq_text!(after, &actual);
3539
}

crates/ra_assists/src/lib.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use ra_ide_db::RootDatabase;
2323
use ra_syntax::{TextRange, TextSize};
2424
use ra_text_edit::TextEdit;
2525

26-
pub(crate) use crate::assist_ctx::{Assist, AssistCtx, AssistHandler};
26+
pub(crate) use crate::assist_ctx::{Assist, AssistCtx};
2727

2828
/// Unique identifier of the assist, should not be shown to the user
2929
/// directly.
@@ -109,7 +109,9 @@ pub fn resolved_assists(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssi
109109
}
110110

111111
mod handlers {
112-
use crate::AssistHandler;
112+
use crate::{Assist, AssistCtx};
113+
114+
pub(crate) type Handler = fn(AssistCtx) -> Option<Assist>;
113115

114116
mod add_custom_impl;
115117
mod add_derive;
@@ -145,12 +147,13 @@ mod handlers {
145147
mod reorder_fields;
146148
mod unwrap_block;
147149

148-
pub(crate) fn all() -> &'static [AssistHandler] {
150+
pub(crate) fn all() -> &'static [Handler] {
149151
&[
150152
// These are alphabetic for the foolish consistency
151153
add_custom_impl::add_custom_impl,
152154
add_derive::add_derive,
153155
add_explicit_type::add_explicit_type,
156+
add_from_impl_for_enum::add_from_impl_for_enum,
154157
add_function::add_function,
155158
add_impl::add_impl,
156159
add_new::add_new,
@@ -176,17 +179,18 @@ mod handlers {
176179
raw_string::remove_hash,
177180
remove_dbg::remove_dbg,
178181
remove_mut::remove_mut,
182+
reorder_fields::reorder_fields,
179183
replace_if_let_with_match::replace_if_let_with_match,
180184
replace_let_with_if_let::replace_let_with_if_let,
181185
replace_qualified_name_with_use::replace_qualified_name_with_use,
182186
replace_unwrap_with_match::replace_unwrap_with_match,
183187
split_import::split_import,
184-
add_from_impl_for_enum::add_from_impl_for_enum,
185188
unwrap_block::unwrap_block,
186189
// These are manually sorted for better priorities
187190
add_missing_impl_members::add_missing_impl_members,
188191
add_missing_impl_members::add_missing_default_members,
189-
reorder_fields::reorder_fields,
192+
// Are you sure you want to add new assist here, and not to the
193+
// sorted list above?
190194
]
191195
}
192196
}
@@ -195,12 +199,12 @@ mod handlers {
195199
mod helpers {
196200
use std::sync::Arc;
197201

202+
use hir::Semantics;
198203
use ra_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
199204
use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase};
200205
use test_utils::{add_cursor, assert_eq_text, extract_range_or_offset, RangeOrOffset};
201206

202-
use crate::{AssistCtx, AssistFile, AssistHandler};
203-
use hir::Semantics;
207+
use crate::{handlers::Handler, AssistCtx, AssistFile};
204208

205209
pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
206210
let (mut db, file_id) = RootDatabase::with_single_file(text);
@@ -210,22 +214,18 @@ mod helpers {
210214
(db, file_id)
211215
}
212216

213-
pub(crate) fn check_assist(
214-
assist: AssistHandler,
215-
ra_fixture_before: &str,
216-
ra_fixture_after: &str,
217-
) {
217+
pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) {
218218
check(assist, ra_fixture_before, ExpectedResult::After(ra_fixture_after));
219219
}
220220

221221
// FIXME: instead of having a separate function here, maybe use
222222
// `extract_ranges` and mark the target as `<target> </target>` in the
223223
// fixuture?
224-
pub(crate) fn check_assist_target(assist: AssistHandler, ra_fixture: &str, target: &str) {
224+
pub(crate) fn check_assist_target(assist: Handler, ra_fixture: &str, target: &str) {
225225
check(assist, ra_fixture, ExpectedResult::Target(target));
226226
}
227227

228-
pub(crate) fn check_assist_not_applicable(assist: AssistHandler, ra_fixture: &str) {
228+
pub(crate) fn check_assist_not_applicable(assist: Handler, ra_fixture: &str) {
229229
check(assist, ra_fixture, ExpectedResult::NotApplicable);
230230
}
231231

@@ -235,7 +235,7 @@ mod helpers {
235235
Target(&'a str),
236236
}
237237

238-
fn check(assist: AssistHandler, before: &str, expected: ExpectedResult) {
238+
fn check(assist: Handler, before: &str, expected: ExpectedResult) {
239239
let (text_without_caret, file_with_caret_id, range_or_offset, db) =
240240
if before.contains("//-") {
241241
let (mut db, position) = RootDatabase::with_position(before);
@@ -261,13 +261,13 @@ mod helpers {
261261
(Some(assist), ExpectedResult::After(after)) => {
262262
let action = assist.0[0].action.clone().unwrap();
263263

264-
let assisted_file_text = if let AssistFile::TargetFile(file_id) = action.file {
264+
let mut actual = if let AssistFile::TargetFile(file_id) = action.file {
265265
db.file_text(file_id).as_ref().to_owned()
266266
} else {
267267
text_without_caret
268268
};
269+
action.edit.apply(&mut actual);
269270

270-
let mut actual = action.edit.apply(&assisted_file_text);
271271
match action.cursor_position {
272272
None => {
273273
if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset {

crates/ra_ide/src/completion/completion_context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use ra_syntax::{
99
SyntaxKind::*,
1010
SyntaxNode, SyntaxToken, TextRange, TextSize,
1111
};
12-
use ra_text_edit::AtomTextEdit;
12+
use ra_text_edit::Indel;
1313

1414
use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition};
1515

@@ -76,7 +76,7 @@ impl<'a> CompletionContext<'a> {
7676
// actual completion.
7777
let file_with_fake_ident = {
7878
let parse = db.parse(position.file_id);
79-
let edit = AtomTextEdit::insert(position.offset, "intellijRulezz".to_string());
79+
let edit = Indel::insert(position.offset, "intellijRulezz".to_string());
8080
parse.reparse(&edit).tree()
8181
};
8282
let fake_ident_token =

crates/ra_ide/src/completion/completion_item.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ impl fmt::Debug for CompletionItem {
6262
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6363
let mut s = f.debug_struct("CompletionItem");
6464
s.field("label", &self.label()).field("source_range", &self.source_range());
65-
if self.text_edit().as_atoms().len() == 1 {
66-
let atom = &self.text_edit().as_atoms()[0];
65+
if self.text_edit().as_indels().len() == 1 {
66+
let atom = &self.text_edit().as_indels()[0];
6767
s.field("delete", &atom.delete);
6868
s.field("insert", &atom.insert);
6969
} else {

crates/ra_ide/src/diagnostics.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,11 @@ mod tests {
241241
diagnostics.pop().unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before));
242242
let mut fix = diagnostic.fix.unwrap();
243243
let edit = fix.source_file_edits.pop().unwrap().edit;
244-
let actual = edit.apply(&before);
244+
let actual = {
245+
let mut actual = before.to_string();
246+
edit.apply(&mut actual);
247+
actual
248+
};
245249
assert_eq_text!(after, &actual);
246250
}
247251

@@ -256,7 +260,11 @@ mod tests {
256260
let mut fix = diagnostic.fix.unwrap();
257261
let edit = fix.source_file_edits.pop().unwrap().edit;
258262
let target_file_contents = analysis.file_text(file_position.file_id).unwrap();
259-
let actual = edit.apply(&target_file_contents);
263+
let actual = {
264+
let mut actual = target_file_contents.to_string();
265+
edit.apply(&mut actual);
266+
actual
267+
};
260268

261269
// Strip indent and empty lines from `after`, to match the behaviour of
262270
// `parse_fixture` called from `analysis_and_position`.
@@ -288,7 +296,11 @@ mod tests {
288296
let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap();
289297
let mut fix = diagnostic.fix.unwrap();
290298
let edit = fix.source_file_edits.pop().unwrap().edit;
291-
let actual = edit.apply(&before);
299+
let actual = {
300+
let mut actual = before.to_string();
301+
edit.apply(&mut actual);
302+
actual
303+
};
292304
assert_eq_text!(after, &actual);
293305
}
294306

@@ -662,10 +674,10 @@ mod tests {
662674
1,
663675
),
664676
edit: TextEdit {
665-
atoms: [
666-
AtomTextEdit {
667-
delete: 3..9,
677+
indels: [
678+
Indel {
668679
insert: "{a:42, b: ()}",
680+
delete: 3..9,
669681
},
670682
],
671683
},

crates/ra_ide/src/join_lines.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,11 @@ fn foo() {
569569
let (sel, before) = extract_range(before);
570570
let parse = SourceFile::parse(&before);
571571
let result = join_lines(&parse.tree(), sel);
572-
let actual = result.apply(&before);
572+
let actual = {
573+
let mut actual = before.to_string();
574+
result.apply(&mut actual);
575+
actual
576+
};
573577
assert_eq_text!(after, &actual);
574578
}
575579

crates/ra_ide/src/references/rename.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -537,10 +537,10 @@ mod tests {
537537
2,
538538
),
539539
edit: TextEdit {
540-
atoms: [
541-
AtomTextEdit {
542-
delete: 4..7,
540+
indels: [
541+
Indel {
543542
insert: "foo2",
543+
delete: 4..7,
544544
},
545545
],
546546
},
@@ -589,10 +589,10 @@ mod tests {
589589
1,
590590
),
591591
edit: TextEdit {
592-
atoms: [
593-
AtomTextEdit {
594-
delete: 4..7,
592+
indels: [
593+
Indel {
595594
insert: "foo2",
595+
delete: 4..7,
596596
},
597597
],
598598
},
@@ -672,10 +672,10 @@ mod tests {
672672
2,
673673
),
674674
edit: TextEdit {
675-
atoms: [
676-
AtomTextEdit {
677-
delete: 8..11,
675+
indels: [
676+
Indel {
678677
insert: "foo2",
678+
delete: 8..11,
679679
},
680680
],
681681
},
@@ -685,10 +685,10 @@ mod tests {
685685
1,
686686
),
687687
edit: TextEdit {
688-
atoms: [
689-
AtomTextEdit {
690-
delete: 27..30,
688+
indels: [
689+
Indel {
691690
insert: "foo2",
691+
delete: 27..30,
692692
},
693693
],
694694
},
@@ -720,13 +720,13 @@ mod tests {
720720
if let Some(change) = source_change {
721721
for edit in change.info.source_file_edits {
722722
file_id = Some(edit.file_id);
723-
for atom in edit.edit.as_atoms() {
724-
text_edit_builder.replace(atom.delete, atom.insert.clone());
723+
for indel in edit.edit.as_indels() {
724+
text_edit_builder.replace(indel.delete, indel.insert.clone());
725725
}
726726
}
727727
}
728-
let result =
729-
text_edit_builder.finish().apply(&*analysis.file_text(file_id.unwrap()).unwrap());
728+
let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string();
729+
text_edit_builder.finish().apply(&mut result);
730730
assert_eq_text!(expected, &*result);
731731
}
732732
}

crates/ra_ide/src/ssr.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -401,16 +401,22 @@ fn render_replace(
401401
ignored_comments: &Vec<Comment>,
402402
template: &SsrTemplate,
403403
) -> String {
404-
let mut builder = TextEditBuilder::default();
405-
for element in template.template.descendants() {
406-
if let Some(var) = template.placeholders.get(&element) {
407-
builder.replace(element.text_range(), binding[var].to_string())
404+
let edit = {
405+
let mut builder = TextEditBuilder::default();
406+
for element in template.template.descendants() {
407+
if let Some(var) = template.placeholders.get(&element) {
408+
builder.replace(element.text_range(), binding[var].to_string())
409+
}
408410
}
409-
}
410-
for comment in ignored_comments {
411-
builder.insert(template.template.text_range().end(), comment.syntax().to_string())
412-
}
413-
builder.finish().apply(&template.template.text().to_string())
411+
for comment in ignored_comments {
412+
builder.insert(template.template.text_range().end(), comment.syntax().to_string())
413+
}
414+
builder.finish()
415+
};
416+
417+
let mut text = template.template.text().to_string();
418+
edit.apply(&mut text);
419+
text
414420
}
415421

416422
#[cfg(test)]
@@ -505,15 +511,19 @@ mod tests {
505511
);
506512

507513
let edit = replace(&matches, &query.template);
508-
assert_eq!(edit.apply(input), "fn main() { bar(1+2); }");
514+
let mut after = input.to_string();
515+
edit.apply(&mut after);
516+
assert_eq!(after, "fn main() { bar(1+2); }");
509517
}
510518

511519
fn assert_ssr_transform(query: &str, input: &str, result: &str) {
512520
let query: SsrQuery = query.parse().unwrap();
513521
let code = SourceFile::parse(input).tree();
514522
let matches = find(&query.pattern, code.syntax());
515523
let edit = replace(&matches, &query.template);
516-
assert_eq!(edit.apply(input), result);
524+
let mut after = input.to_string();
525+
edit.apply(&mut after);
526+
assert_eq!(after, result);
517527
}
518528

519529
#[test]

crates/ra_ide/src/test_utils.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ pub fn check_action<F: Fn(&SourceFile, TextSize) -> Option<TextEdit>>(
1313
let (before_cursor_pos, before) = extract_offset(before);
1414
let file = SourceFile::parse(&before).ok().unwrap();
1515
let result = f(&file, before_cursor_pos).expect("code action is not applicable");
16-
let actual = result.apply(&before);
16+
let actual = {
17+
let mut actual = before.to_string();
18+
result.apply(&mut actual);
19+
actual
20+
};
1721
let actual_cursor_pos =
1822
result.apply_to_offset(before_cursor_pos).expect("cursor position is affected by the edit");
1923
let actual = add_cursor(&actual, actual_cursor_pos);

0 commit comments

Comments
 (0)