aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-09-26 20:08:44 +0100
committerAleksey Kladov <[email protected]>2019-09-26 20:22:08 +0100
commitd847d53e36571c8f7925b72cedf66bb203976148 (patch)
tree3fd5903b67b498a39660b2dafdc929f33d41900e
parent1a4b42400544a652a053a34263967689d47f554b (diff)
Start simplifying editing API
-rw-r--r--Cargo.lock12
-rw-r--r--crates/ra_assists/src/assists/add_missing_impl_members.rs8
-rw-r--r--crates/ra_assists/src/assists/auto_import.rs1
-rw-r--r--crates/ra_assists/src/ast_editor.rs72
-rw-r--r--crates/ra_assists/src/lib.rs1
-rw-r--r--crates/ra_ide_api/src/line_index.rs1
-rw-r--r--crates/ra_ide_api/src/runnables.rs1
-rw-r--r--crates/ra_lsp_server/src/markdown.rs1
-rw-r--r--crates/ra_parser/src/grammar.rs1
-rw-r--r--crates/ra_syntax/Cargo.toml2
-rw-r--r--crates/ra_syntax/src/ast.rs1
-rw-r--r--crates/ra_syntax/src/ast/edit.rs52
-rw-r--r--crates/ra_syntax/src/ast/make.rs48
13 files changed, 114 insertions, 87 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 275b27775..69b78e7de 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -761,7 +761,7 @@ dependencies = [
761 761
762[[package]] 762[[package]]
763name = "once_cell" 763name = "once_cell"
764version = "1.0.2" 764version = "1.2.0"
765source = "registry+https://github.com/rust-lang/crates.io-index" 765source = "registry+https://github.com/rust-lang/crates.io-index"
766 766
767[[package]] 767[[package]]
@@ -897,7 +897,7 @@ dependencies = [
897 "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 897 "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
898 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 898 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
899 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 899 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
900 "once_cell 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 900 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
901 "ra_db 0.1.0", 901 "ra_db 0.1.0",
902 "ra_fmt 0.1.0", 902 "ra_fmt 0.1.0",
903 "ra_hir 0.1.0", 903 "ra_hir 0.1.0",
@@ -968,7 +968,7 @@ dependencies = [
968 "insta 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 968 "insta 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
969 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", 969 "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
970 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 970 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
971 "once_cell 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 971 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
972 "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 972 "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
973 "ra_arena 0.1.0", 973 "ra_arena 0.1.0",
974 "ra_db 0.1.0", 974 "ra_db 0.1.0",
@@ -1065,7 +1065,7 @@ dependencies = [
1065 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1065 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1066 "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 1066 "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
1067 "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1067 "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
1068 "once_cell 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1068 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1069] 1069]
1070 1070
1071[[package]] 1071[[package]]
@@ -1085,7 +1085,9 @@ dependencies = [
1085name = "ra_syntax" 1085name = "ra_syntax"
1086version = "0.1.0" 1086version = "0.1.0"
1087dependencies = [ 1087dependencies = [
1088 "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
1088 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1089 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1090 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1089 "ra_parser 0.1.0", 1091 "ra_parser 0.1.0",
1090 "ra_text_edit 0.1.0", 1092 "ra_text_edit 0.1.0",
1091 "rowan 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 1093 "rowan 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1854,7 +1856,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1854"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" 1856"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
1855"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" 1857"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
1856"checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee" 1858"checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee"
1857"checksum once_cell 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd38c1bb51148ca239ec38ef1bb4f7570d432861f03e91774d53b01c2ba2132f" 1859"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed"
1858"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" 1860"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
1859"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" 1861"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
1860"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" 1862"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs
index 23da1e65f..682455bce 100644
--- a/crates/ra_assists/src/assists/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs
@@ -100,12 +100,11 @@ fn strip_docstring(item: ast::ImplItem) -> ast::ImplItem {
100} 100}
101 101
102fn add_body(fn_def: ast::FnDef) -> ast::FnDef { 102fn add_body(fn_def: ast::FnDef) -> ast::FnDef {
103 let mut ast_editor = AstEditor::new(fn_def.clone());
104 if fn_def.body().is_none() { 103 if fn_def.body().is_none() {
105 let body = make::block_from_expr(make::expr_unimplemented()); 104 fn_def.with_body(make::block_from_expr(make::expr_unimplemented()))
106 ast_editor.set_body(&body); 105 } else {
106 fn_def
107 } 107 }
108 ast_editor.ast().to_owned()
109} 108}
110 109
111/// Given an `ast::ImplBlock`, resolves the target trait (the one being 110/// Given an `ast::ImplBlock`, resolves the target trait (the one being
@@ -332,5 +331,4 @@ impl Foo for S {
332}", 331}",
333 ) 332 )
334 } 333 }
335
336} 334}
diff --git a/crates/ra_assists/src/assists/auto_import.rs b/crates/ra_assists/src/assists/auto_import.rs
index 5aae98546..a91c170b9 100644
--- a/crates/ra_assists/src/assists/auto_import.rs
+++ b/crates/ra_assists/src/assists/auto_import.rs
@@ -448,7 +448,6 @@ fn make_assist_add_in_tree_list(
448 fmt_segments_raw(target, &mut buf); 448 fmt_segments_raw(target, &mut buf);
449 edit.insert(offset, buf); 449 edit.insert(offset, buf);
450 } else { 450 } else {
451
452 } 451 }
453} 452}
454 453
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs
index 2a685f26e..72c8c478a 100644
--- a/crates/ra_assists/src/ast_editor.rs
+++ b/crates/ra_assists/src/ast_editor.rs
@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
6use ra_fmt::leading_indent; 6use ra_fmt::leading_indent;
7use ra_syntax::{ 7use ra_syntax::{
8 algo, 8 algo,
9 ast::{self, TypeBoundsOwner}, 9 ast::{self, make::tokens, TypeBoundsOwner},
10 AstNode, Direction, InsertPosition, SyntaxElement, 10 AstNode, Direction, InsertPosition, SyntaxElement,
11 SyntaxKind::*, 11 SyntaxKind::*,
12 T, 12 T,
@@ -229,26 +229,6 @@ impl AstEditor<ast::ImplItem> {
229 } 229 }
230} 230}
231 231
232impl AstEditor<ast::FnDef> {
233 pub fn set_body(&mut self, body: &ast::Block) {
234 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
235 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.ast().body() {
236 old_body.syntax().clone().into()
237 } else if let Some(semi) = self.ast().semicolon_token() {
238 to_insert.push(tokens::single_space().into());
239 semi.into()
240 } else {
241 to_insert.push(tokens::single_space().into());
242 to_insert.push(body.syntax().clone().into());
243 self.ast = self.insert_children(InsertPosition::Last, to_insert.into_iter());
244 return;
245 };
246 to_insert.push(body.syntax().clone().into());
247 let replace_range = RangeInclusive::new(old_body_or_semi.clone(), old_body_or_semi);
248 self.ast = self.replace_children(replace_range, to_insert.into_iter())
249 }
250}
251
252impl AstEditor<ast::TypeParam> { 232impl AstEditor<ast::TypeParam> {
253 pub fn remove_bounds(&mut self) -> &mut Self { 233 pub fn remove_bounds(&mut self) -> &mut Self {
254 let colon = match self.ast.colon_token() { 234 let colon = match self.ast.colon_token() {
@@ -263,53 +243,3 @@ impl AstEditor<ast::TypeParam> {
263 self 243 self
264 } 244 }
265} 245}
266
267mod tokens {
268 use once_cell::sync::Lazy;
269 use ra_syntax::{AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken, T};
270
271 static SOURCE_FILE: Lazy<Parse<SourceFile>> = Lazy::new(|| SourceFile::parse(",\n; ;"));
272
273 pub(crate) fn comma() -> SyntaxToken {
274 SOURCE_FILE
275 .tree()
276 .syntax()
277 .descendants_with_tokens()
278 .filter_map(|it| it.into_token())
279 .find(|it| it.kind() == T![,])
280 .unwrap()
281 }
282
283 pub(crate) fn single_space() -> SyntaxToken {
284 SOURCE_FILE
285 .tree()
286 .syntax()
287 .descendants_with_tokens()
288 .filter_map(|it| it.into_token())
289 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == " ")
290 .unwrap()
291 }
292
293 #[allow(unused)]
294 pub(crate) fn single_newline() -> SyntaxToken {
295 SOURCE_FILE
296 .tree()
297 .syntax()
298 .descendants_with_tokens()
299 .filter_map(|it| it.into_token())
300 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == "\n")
301 .unwrap()
302 }
303
304 pub(crate) struct WsBuilder(SourceFile);
305
306 impl WsBuilder {
307 pub(crate) fn new(text: &str) -> WsBuilder {
308 WsBuilder(SourceFile::parse(text).ok().unwrap())
309 }
310 pub(crate) fn ws(&self) -> SyntaxToken {
311 self.0.syntax().first_child_or_token().unwrap().into_token().unwrap()
312 }
313 }
314
315}
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index 897af2b02..3ca3320f7 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -340,5 +340,4 @@ mod tests {
340 assert_eq!(assists.next().expect("expected assist").0.label, "introduce variable"); 340 assert_eq!(assists.next().expect("expected assist").0.label, "introduce variable");
341 assert_eq!(assists.next().expect("expected assist").0.label, "replace with match"); 341 assert_eq!(assists.next().expect("expected assist").0.label, "replace with match");
342 } 342 }
343
344} 343}
diff --git a/crates/ra_ide_api/src/line_index.rs b/crates/ra_ide_api/src/line_index.rs
index 71de8a928..5fedad696 100644
--- a/crates/ra_ide_api/src/line_index.rs
+++ b/crates/ra_ide_api/src/line_index.rs
@@ -278,5 +278,4 @@ const C: char = \"メ メ\";
278 278
279 assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextUnit::from_usize(15)); 279 assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextUnit::from_usize(15));
280 } 280 }
281
282} 281}
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs
index 095ca56c4..8cf58fe79 100644
--- a/crates/ra_ide_api/src/runnables.rs
+++ b/crates/ra_ide_api/src/runnables.rs
@@ -229,5 +229,4 @@ mod tests {
229 let runnables = analysis.runnables(pos.file_id).unwrap(); 229 let runnables = analysis.runnables(pos.file_id).unwrap();
230 assert!(runnables.is_empty()) 230 assert!(runnables.is_empty())
231 } 231 }
232
233} 232}
diff --git a/crates/ra_lsp_server/src/markdown.rs b/crates/ra_lsp_server/src/markdown.rs
index c1eb0236a..3659edf8e 100644
--- a/crates/ra_lsp_server/src/markdown.rs
+++ b/crates/ra_lsp_server/src/markdown.rs
@@ -70,5 +70,4 @@ let a = 1;
70 "```rust\nfn main(){}\n```\nSome comment.\n```rust\nlet a = 1;\n```" 70 "```rust\nfn main(){}\n```\nSome comment.\n```rust\nlet a = 1;\n```"
71 ); 71 );
72 } 72 }
73
74} 73}
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index e2355aff9..6e9e212b7 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -135,7 +135,6 @@ pub(crate) mod fragments {
135 135
136 m.complete(p, MACRO_STMTS); 136 m.complete(p, MACRO_STMTS);
137 } 137 }
138
139} 138}
140 139
141pub(crate) fn reparser( 140pub(crate) fn reparser(
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
index 724c38e17..9bc85404a 100644
--- a/crates/ra_syntax/Cargo.toml
+++ b/crates/ra_syntax/Cargo.toml
@@ -12,6 +12,8 @@ itertools = "0.8.0"
12rowan = "0.6.1" 12rowan = "0.6.1"
13rustc_lexer = "0.1.0" 13rustc_lexer = "0.1.0"
14rustc-hash = "1.0.1" 14rustc-hash = "1.0.1"
15arrayvec = "0.4.10"
16once_cell = "1.2.0"
15 17
16# ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here 18# ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here
17# to reduce number of compilations 19# to reduce number of compilations
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index f464d6534..fdffd8cb1 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -5,6 +5,7 @@ mod traits;
5mod tokens; 5mod tokens;
6mod extensions; 6mod extensions;
7mod expr_extensions; 7mod expr_extensions;
8mod edit;
8pub mod make; 9pub mod make;
9 10
10use std::marker::PhantomData; 11use std::marker::PhantomData;
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
new file mode 100644
index 000000000..c65899812
--- /dev/null
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -0,0 +1,52 @@
1//! This module contains functions for editing syntax trees. As the trees are
2//! immutable, all function here return a fresh copy of the tree, instead of
3//! doing an in-place modification.
4
5use arrayvec::ArrayVec;
6use std::ops::RangeInclusive;
7
8use crate::{
9 algo,
10 ast::{self, make, AstNode},
11 InsertPosition, SyntaxElement,
12};
13
14impl ast::FnDef {
15 #[must_use]
16 pub fn with_body(&self, body: ast::Block) -> ast::FnDef {
17 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
18 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() {
19 old_body.syntax().clone().into()
20 } else if let Some(semi) = self.semicolon_token() {
21 to_insert.push(make::tokens::single_space().into());
22 semi.into()
23 } else {
24 to_insert.push(make::tokens::single_space().into());
25 to_insert.push(body.syntax().clone().into());
26 return insert_children(self, InsertPosition::Last, to_insert.into_iter());
27 };
28 to_insert.push(body.syntax().clone().into());
29 let replace_range = RangeInclusive::new(old_body_or_semi.clone(), old_body_or_semi);
30 replace_children(self, replace_range, to_insert.into_iter())
31 }
32}
33
34#[must_use]
35fn insert_children<N: AstNode>(
36 parent: &N,
37 position: InsertPosition<SyntaxElement>,
38 mut to_insert: impl Iterator<Item = SyntaxElement>,
39) -> N {
40 let new_syntax = algo::insert_children(parent.syntax(), position, &mut to_insert);
41 N::cast(new_syntax).unwrap()
42}
43
44#[must_use]
45fn replace_children<N: AstNode>(
46 parent: &N,
47 to_replace: RangeInclusive<SyntaxElement>,
48 mut to_insert: impl Iterator<Item = SyntaxElement>,
49) -> N {
50 let new_syntax = algo::replace_children(parent.syntax(), to_replace, &mut to_insert);
51 N::cast(new_syntax).unwrap()
52}
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index c06c62b3b..287a40bee 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -133,3 +133,51 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
133 let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); 133 let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap();
134 res 134 res
135} 135}
136
137pub mod tokens {
138 use crate::{AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken, T};
139 use once_cell::sync::Lazy;
140
141 static SOURCE_FILE: Lazy<Parse<SourceFile>> = Lazy::new(|| SourceFile::parse(",\n; ;"));
142
143 pub fn comma() -> SyntaxToken {
144 SOURCE_FILE
145 .tree()
146 .syntax()
147 .descendants_with_tokens()
148 .filter_map(|it| it.into_token())
149 .find(|it| it.kind() == T![,])
150 .unwrap()
151 }
152
153 pub fn single_space() -> SyntaxToken {
154 SOURCE_FILE
155 .tree()
156 .syntax()
157 .descendants_with_tokens()
158 .filter_map(|it| it.into_token())
159 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == " ")
160 .unwrap()
161 }
162
163 pub fn single_newline() -> SyntaxToken {
164 SOURCE_FILE
165 .tree()
166 .syntax()
167 .descendants_with_tokens()
168 .filter_map(|it| it.into_token())
169 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == "\n")
170 .unwrap()
171 }
172
173 pub struct WsBuilder(SourceFile);
174
175 impl WsBuilder {
176 pub fn new(text: &str) -> WsBuilder {
177 WsBuilder(SourceFile::parse(text).ok().unwrap())
178 }
179 pub fn ws(&self) -> SyntaxToken {
180 self.0.syntax().first_child_or_token().unwrap().into_token().unwrap()
181 }
182 }
183}