diff options
Diffstat (limited to 'crates/ra_assists')
-rw-r--r-- | crates/ra_assists/src/add_missing_impl_members.rs | 14 | ||||
-rw-r--r-- | crates/ra_assists/src/ast_editor.rs | 116 | ||||
-rw-r--r-- | crates/ra_assists/src/change_visibility.rs | 2 | ||||
-rw-r--r-- | crates/ra_assists/src/fill_match_arms.rs | 195 |
4 files changed, 184 insertions, 143 deletions
diff --git a/crates/ra_assists/src/add_missing_impl_members.rs b/crates/ra_assists/src/add_missing_impl_members.rs index 31c7d4e80..cbeb7054f 100644 --- a/crates/ra_assists/src/add_missing_impl_members.rs +++ b/crates/ra_assists/src/add_missing_impl_members.rs | |||
@@ -1,13 +1,14 @@ | |||
1 | use hir::{db::HirDatabase, HasSource}; | ||
2 | use ra_syntax::{ | ||
3 | ast::{self, AstNode, NameOwner}, | ||
4 | SmolStr, | ||
5 | }; | ||
6 | |||
1 | use crate::{ | 7 | use crate::{ |
2 | ast_editor::{AstBuilder, AstEditor}, | 8 | ast_editor::{AstBuilder, AstEditor}, |
3 | Assist, AssistCtx, AssistId, | 9 | Assist, AssistCtx, AssistId, |
4 | }; | 10 | }; |
5 | 11 | ||
6 | use hir::{db::HirDatabase, HasSource}; | ||
7 | use ra_db::FilePosition; | ||
8 | use ra_syntax::ast::{self, AstNode, NameOwner}; | ||
9 | use ra_syntax::SmolStr; | ||
10 | |||
11 | #[derive(PartialEq)] | 12 | #[derive(PartialEq)] |
12 | enum AddMissingImplMembersMode { | 13 | enum AddMissingImplMembersMode { |
13 | DefaultMethodsOnly, | 14 | DefaultMethodsOnly, |
@@ -43,8 +44,7 @@ fn add_missing_impl_members_inner( | |||
43 | 44 | ||
44 | let trait_def = { | 45 | let trait_def = { |
45 | let file_id = ctx.frange.file_id; | 46 | let file_id = ctx.frange.file_id; |
46 | let position = FilePosition { file_id, offset: impl_node.syntax().text_range().start() }; | 47 | let analyzer = hir::SourceAnalyzer::new(ctx.db, file_id, impl_node.syntax(), None); |
47 | let analyzer = hir::SourceAnalyzer::new(ctx.db, position.file_id, impl_node.syntax(), None); | ||
48 | 48 | ||
49 | resolve_target_trait_def(ctx.db, &analyzer, &impl_node)? | 49 | resolve_target_trait_def(ctx.db, &analyzer, &impl_node)? |
50 | }; | 50 | }; |
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs index 95b871b30..6815638dc 100644 --- a/crates/ra_assists/src/ast_editor.rs +++ b/crates/ra_assists/src/ast_editor.rs | |||
@@ -1,6 +1,8 @@ | |||
1 | use std::{iter, ops::RangeInclusive}; | 1 | use std::{iter, ops::RangeInclusive}; |
2 | 2 | ||
3 | use arrayvec::ArrayVec; | 3 | use arrayvec::ArrayVec; |
4 | use itertools::Itertools; | ||
5 | |||
4 | use hir::Name; | 6 | use hir::Name; |
5 | use ra_fmt::leading_indent; | 7 | use ra_fmt::leading_indent; |
6 | use ra_syntax::{ | 8 | use ra_syntax::{ |
@@ -17,7 +19,10 @@ pub struct AstEditor<N: AstNode> { | |||
17 | } | 19 | } |
18 | 20 | ||
19 | impl<N: AstNode> AstEditor<N> { | 21 | impl<N: AstNode> AstEditor<N> { |
20 | pub fn new(node: N) -> AstEditor<N> { | 22 | pub fn new(node: N) -> AstEditor<N> |
23 | where | ||
24 | N: Clone, | ||
25 | { | ||
21 | AstEditor { original_ast: node.clone(), ast: node } | 26 | AstEditor { original_ast: node.clone(), ast: node } |
22 | } | 27 | } |
23 | 28 | ||
@@ -88,15 +93,15 @@ impl<N: AstNode> AstEditor<N> { | |||
88 | } | 93 | } |
89 | } | 94 | } |
90 | 95 | ||
91 | impl AstEditor<ast::NamedFieldList> { | 96 | impl AstEditor<ast::RecordFieldList> { |
92 | pub fn append_field(&mut self, field: &ast::NamedField) { | 97 | pub fn append_field(&mut self, field: &ast::RecordField) { |
93 | self.insert_field(InsertPosition::Last, field) | 98 | self.insert_field(InsertPosition::Last, field) |
94 | } | 99 | } |
95 | 100 | ||
96 | pub fn insert_field( | 101 | pub fn insert_field( |
97 | &mut self, | 102 | &mut self, |
98 | position: InsertPosition<&'_ ast::NamedField>, | 103 | position: InsertPosition<&'_ ast::RecordField>, |
99 | field: &ast::NamedField, | 104 | field: &ast::RecordField, |
100 | ) { | 105 | ) { |
101 | let is_multiline = self.ast().syntax().text().contains_char('\n'); | 106 | let is_multiline = self.ast().syntax().text().contains_char('\n'); |
102 | let ws; | 107 | let ws; |
@@ -168,8 +173,7 @@ impl AstEditor<ast::NamedFieldList> { | |||
168 | 173 | ||
169 | impl AstEditor<ast::ItemList> { | 174 | impl AstEditor<ast::ItemList> { |
170 | pub fn append_items(&mut self, items: impl Iterator<Item = ast::ImplItem>) { | 175 | pub fn append_items(&mut self, items: impl Iterator<Item = ast::ImplItem>) { |
171 | let n_existing_items = self.ast().impl_items().count(); | 176 | if !self.ast().syntax().text().contains_char('\n') { |
172 | if n_existing_items == 0 { | ||
173 | self.do_make_multiline(); | 177 | self.do_make_multiline(); |
174 | } | 178 | } |
175 | items.for_each(|it| self.append_item(it)); | 179 | items.for_each(|it| self.append_item(it)); |
@@ -241,16 +245,16 @@ pub struct AstBuilder<N: AstNode> { | |||
241 | _phantom: std::marker::PhantomData<N>, | 245 | _phantom: std::marker::PhantomData<N>, |
242 | } | 246 | } |
243 | 247 | ||
244 | impl AstBuilder<ast::NamedField> { | 248 | impl AstBuilder<ast::RecordField> { |
245 | pub fn from_name(name: &Name) -> ast::NamedField { | 249 | pub fn from_name(name: &Name) -> ast::RecordField { |
246 | ast_node_from_file_text(&format!("fn f() {{ S {{ {}: (), }} }}", name)) | 250 | ast_node_from_file_text(&format!("fn f() {{ S {{ {}: (), }} }}", name)) |
247 | } | 251 | } |
248 | 252 | ||
249 | fn from_text(text: &str) -> ast::NamedField { | 253 | fn from_text(text: &str) -> ast::RecordField { |
250 | ast_node_from_file_text(&format!("fn f() {{ S {{ {}, }} }}", text)) | 254 | ast_node_from_file_text(&format!("fn f() {{ S {{ {}, }} }}", text)) |
251 | } | 255 | } |
252 | 256 | ||
253 | pub fn from_pieces(name: &ast::NameRef, expr: Option<&ast::Expr>) -> ast::NamedField { | 257 | pub fn from_pieces(name: &ast::NameRef, expr: Option<&ast::Expr>) -> ast::RecordField { |
254 | match expr { | 258 | match expr { |
255 | Some(expr) => Self::from_text(&format!("{}: {}", name.syntax(), expr.syntax())), | 259 | Some(expr) => Self::from_text(&format!("{}: {}", name.syntax(), expr.syntax())), |
256 | None => Self::from_text(&name.syntax().to_string()), | 260 | None => Self::from_text(&name.syntax().to_string()), |
@@ -288,9 +292,97 @@ impl AstBuilder<ast::NameRef> { | |||
288 | } | 292 | } |
289 | } | 293 | } |
290 | 294 | ||
295 | impl AstBuilder<ast::Path> { | ||
296 | fn from_text(text: &str) -> ast::Path { | ||
297 | ast_node_from_file_text(text) | ||
298 | } | ||
299 | |||
300 | pub fn from_pieces(enum_name: ast::Name, var_name: ast::Name) -> ast::Path { | ||
301 | Self::from_text(&format!("{}::{}", enum_name.syntax(), var_name.syntax())) | ||
302 | } | ||
303 | } | ||
304 | |||
305 | impl AstBuilder<ast::BindPat> { | ||
306 | fn from_text(text: &str) -> ast::BindPat { | ||
307 | ast_node_from_file_text(&format!("fn f({}: ())", text)) | ||
308 | } | ||
309 | |||
310 | pub fn from_name(name: &ast::Name) -> ast::BindPat { | ||
311 | Self::from_text(name.text()) | ||
312 | } | ||
313 | } | ||
314 | |||
315 | impl AstBuilder<ast::PlaceholderPat> { | ||
316 | fn from_text(text: &str) -> ast::PlaceholderPat { | ||
317 | ast_node_from_file_text(&format!("fn f({}: ())", text)) | ||
318 | } | ||
319 | |||
320 | pub fn placeholder() -> ast::PlaceholderPat { | ||
321 | Self::from_text("_") | ||
322 | } | ||
323 | } | ||
324 | |||
325 | impl AstBuilder<ast::TupleStructPat> { | ||
326 | fn from_text(text: &str) -> ast::TupleStructPat { | ||
327 | ast_node_from_file_text(&format!("fn f({}: ())", text)) | ||
328 | } | ||
329 | |||
330 | pub fn from_pieces( | ||
331 | path: &ast::Path, | ||
332 | pats: impl Iterator<Item = ast::Pat>, | ||
333 | ) -> ast::TupleStructPat { | ||
334 | let pats_str = pats.map(|p| p.syntax().to_string()).collect::<Vec<_>>().join(", "); | ||
335 | Self::from_text(&format!("{}({})", path.syntax(), pats_str)) | ||
336 | } | ||
337 | } | ||
338 | |||
339 | impl AstBuilder<ast::RecordPat> { | ||
340 | fn from_text(text: &str) -> ast::RecordPat { | ||
341 | ast_node_from_file_text(&format!("fn f({}: ())", text)) | ||
342 | } | ||
343 | |||
344 | pub fn from_pieces(path: &ast::Path, pats: impl Iterator<Item = ast::Pat>) -> ast::RecordPat { | ||
345 | let pats_str = pats.map(|p| p.syntax().to_string()).collect::<Vec<_>>().join(", "); | ||
346 | Self::from_text(&format!("{}{{ {} }}", path.syntax(), pats_str)) | ||
347 | } | ||
348 | } | ||
349 | |||
350 | impl AstBuilder<ast::PathPat> { | ||
351 | fn from_text(text: &str) -> ast::PathPat { | ||
352 | ast_node_from_file_text(&format!("fn f({}: ())", text)) | ||
353 | } | ||
354 | |||
355 | pub fn from_path(path: &ast::Path) -> ast::PathPat { | ||
356 | let path_str = path.syntax().text().to_string(); | ||
357 | Self::from_text(path_str.as_str()) | ||
358 | } | ||
359 | } | ||
360 | |||
361 | impl AstBuilder<ast::MatchArm> { | ||
362 | fn from_text(text: &str) -> ast::MatchArm { | ||
363 | ast_node_from_file_text(&format!("fn f() {{ match () {{{}}} }}", text)) | ||
364 | } | ||
365 | |||
366 | pub fn from_pieces(pats: impl Iterator<Item = ast::Pat>, expr: &ast::Expr) -> ast::MatchArm { | ||
367 | let pats_str = pats.map(|p| p.syntax().to_string()).join(" | "); | ||
368 | Self::from_text(&format!("{} => {}", pats_str, expr.syntax())) | ||
369 | } | ||
370 | } | ||
371 | |||
372 | impl AstBuilder<ast::MatchArmList> { | ||
373 | fn from_text(text: &str) -> ast::MatchArmList { | ||
374 | ast_node_from_file_text(&format!("fn f() {{ match () {{{}}} }}", text)) | ||
375 | } | ||
376 | |||
377 | pub fn from_arms(arms: impl Iterator<Item = ast::MatchArm>) -> ast::MatchArmList { | ||
378 | let arms_str = arms.map(|arm| format!("\n {}", arm.syntax())).join(","); | ||
379 | Self::from_text(&format!("{},\n", arms_str)) | ||
380 | } | ||
381 | } | ||
382 | |||
291 | fn ast_node_from_file_text<N: AstNode>(text: &str) -> N { | 383 | fn ast_node_from_file_text<N: AstNode>(text: &str) -> N { |
292 | let parse = SourceFile::parse(text); | 384 | let parse = SourceFile::parse(text); |
293 | let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap().to_owned(); | 385 | let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); |
294 | res | 386 | res |
295 | } | 387 | } |
296 | 388 | ||
diff --git a/crates/ra_assists/src/change_visibility.rs b/crates/ra_assists/src/change_visibility.rs index d28cdd07b..60c74debc 100644 --- a/crates/ra_assists/src/change_visibility.rs +++ b/crates/ra_assists/src/change_visibility.rs | |||
@@ -38,7 +38,7 @@ fn add_vis(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
38 | (vis_offset(&parent), keyword.text_range()) | 38 | (vis_offset(&parent), keyword.text_range()) |
39 | } else { | 39 | } else { |
40 | let ident = ctx.token_at_offset().find(|leaf| leaf.kind() == IDENT)?; | 40 | let ident = ctx.token_at_offset().find(|leaf| leaf.kind() == IDENT)?; |
41 | let field = ident.parent().ancestors().find_map(ast::NamedFieldDef::cast)?; | 41 | let field = ident.parent().ancestors().find_map(ast::RecordFieldDef::cast)?; |
42 | if field.name()?.syntax().text_range() != ident.text_range() && field.visibility().is_some() | 42 | if field.name()?.syntax().text_range() != ident.text_range() && field.visibility().is_some() |
43 | { | 43 | { |
44 | return None; | 44 | return None; |
diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index 85ff5c052..cc3879562 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs | |||
@@ -1,97 +1,91 @@ | |||
1 | use itertools::Itertools; | 1 | use std::iter; |
2 | use std::fmt::Write; | ||
3 | 2 | ||
4 | use hir::{db::HirDatabase, AdtDef, FieldSource, HasSource}; | 3 | use hir::{db::HirDatabase, AdtDef, HasSource}; |
5 | use ra_syntax::ast::{self, AstNode}; | 4 | use ra_syntax::ast::{self, AstNode, NameOwner}; |
6 | 5 | ||
7 | use crate::{Assist, AssistCtx, AssistId}; | 6 | use crate::{ast_editor::AstBuilder, Assist, AssistCtx, AssistId}; |
8 | |||
9 | fn is_trivial_arm(arm: &ast::MatchArm) -> bool { | ||
10 | fn single_pattern(arm: &ast::MatchArm) -> Option<ast::Pat> { | ||
11 | let (pat,) = arm.pats().collect_tuple()?; | ||
12 | Some(pat) | ||
13 | } | ||
14 | match single_pattern(arm) { | ||
15 | Some(ast::Pat::PlaceholderPat(..)) => true, | ||
16 | _ => false, | ||
17 | } | ||
18 | } | ||
19 | 7 | ||
20 | pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 8 | pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
21 | let match_expr = ctx.node_at_offset::<ast::MatchExpr>()?; | 9 | let match_expr = ctx.node_at_offset::<ast::MatchExpr>()?; |
10 | let match_arm_list = match_expr.match_arm_list()?; | ||
22 | 11 | ||
23 | // We already have some match arms, so we don't provide any assists. | 12 | // We already have some match arms, so we don't provide any assists. |
24 | // Unless if there is only one trivial match arm possibly created | 13 | // Unless if there is only one trivial match arm possibly created |
25 | // by match postfix complete. Trivial match arm is the catch all arm. | 14 | // by match postfix complete. Trivial match arm is the catch all arm. |
26 | if let Some(arm_list) = match_expr.match_arm_list() { | 15 | let mut existing_arms = match_arm_list.arms(); |
27 | let mut arm_iter = arm_list.arms(); | 16 | if let Some(arm) = existing_arms.next() { |
28 | let first = arm_iter.next(); | 17 | if !is_trivial(&arm) || existing_arms.next().is_some() { |
29 | 18 | return None; | |
30 | match &first { | ||
31 | // If there arm list is empty or there is only one trivial arm, then proceed. | ||
32 | Some(arm) if is_trivial_arm(arm) => { | ||
33 | if arm_iter.next() != None { | ||
34 | return None; | ||
35 | } | ||
36 | } | ||
37 | None => {} | ||
38 | |||
39 | _ => { | ||
40 | return None; | ||
41 | } | ||
42 | } | 19 | } |
43 | }; | 20 | }; |
44 | 21 | ||
45 | let expr = match_expr.expr()?; | 22 | let expr = match_expr.expr()?; |
46 | let analyzer = hir::SourceAnalyzer::new(ctx.db, ctx.frange.file_id, expr.syntax(), None); | 23 | let enum_def = { |
47 | let match_expr_ty = analyzer.type_of(ctx.db, &expr)?; | 24 | let file_id = ctx.frange.file_id; |
48 | let enum_def = analyzer.autoderef(ctx.db, match_expr_ty).find_map(|ty| match ty.as_adt() { | 25 | let analyzer = hir::SourceAnalyzer::new(ctx.db, file_id, expr.syntax(), None); |
49 | Some((AdtDef::Enum(e), _)) => Some(e), | 26 | resolve_enum_def(ctx.db, &analyzer, &expr)? |
50 | _ => None, | 27 | }; |
51 | })?; | 28 | let variant_list = enum_def.variant_list()?; |
52 | let enum_name = enum_def.name(ctx.db)?; | ||
53 | let db = ctx.db; | ||
54 | 29 | ||
55 | ctx.add_action(AssistId("fill_match_arms"), "fill match arms", |edit| { | 30 | ctx.add_action(AssistId("fill_match_arms"), "fill match arms", |edit| { |
56 | let mut buf = format!("match {} {{\n", expr.syntax().text().to_string()); | 31 | let variants = variant_list.variants(); |
57 | let variants = enum_def.variants(db); | 32 | let arms = variants.into_iter().filter_map(build_pat).map(|pat| { |
58 | for variant in variants { | 33 | AstBuilder::<ast::MatchArm>::from_pieces( |
59 | let name = match variant.name(db) { | 34 | iter::once(pat), |
60 | Some(it) => it, | 35 | &AstBuilder::<ast::Expr>::unit(), |
61 | None => continue, | 36 | ) |
62 | }; | 37 | }); |
63 | write!(&mut buf, " {}::{}", enum_name, name.to_string()).unwrap(); | 38 | let new_arm_list = AstBuilder::<ast::MatchArmList>::from_arms(arms); |
64 | |||
65 | let pat = variant | ||
66 | .fields(db) | ||
67 | .into_iter() | ||
68 | .map(|field| { | ||
69 | let name = field.name(db).to_string(); | ||
70 | let src = field.source(db); | ||
71 | match src.ast { | ||
72 | FieldSource::Named(_) => name, | ||
73 | FieldSource::Pos(_) => "_".to_string(), | ||
74 | } | ||
75 | }) | ||
76 | .collect::<Vec<_>>(); | ||
77 | 39 | ||
78 | match pat.first().map(|s| s.as_str()) { | ||
79 | Some("_") => write!(&mut buf, "({})", pat.join(", ")).unwrap(), | ||
80 | Some(_) => write!(&mut buf, "{{{}}}", pat.join(", ")).unwrap(), | ||
81 | None => (), | ||
82 | }; | ||
83 | |||
84 | buf.push_str(" => (),\n"); | ||
85 | } | ||
86 | buf.push_str("}"); | ||
87 | edit.target(match_expr.syntax().text_range()); | 40 | edit.target(match_expr.syntax().text_range()); |
88 | edit.set_cursor(expr.syntax().text_range().start()); | 41 | edit.set_cursor(expr.syntax().text_range().start()); |
89 | edit.replace_node_and_indent(match_expr.syntax(), buf); | 42 | edit.replace_node_and_indent(match_arm_list.syntax(), new_arm_list.syntax().text()); |
90 | }); | 43 | }); |
91 | 44 | ||
92 | ctx.build() | 45 | ctx.build() |
93 | } | 46 | } |
94 | 47 | ||
48 | fn is_trivial(arm: &ast::MatchArm) -> bool { | ||
49 | arm.pats().any(|pat| match pat { | ||
50 | ast::Pat::PlaceholderPat(..) => true, | ||
51 | _ => false, | ||
52 | }) | ||
53 | } | ||
54 | |||
55 | fn resolve_enum_def( | ||
56 | db: &impl HirDatabase, | ||
57 | analyzer: &hir::SourceAnalyzer, | ||
58 | expr: &ast::Expr, | ||
59 | ) -> Option<ast::EnumDef> { | ||
60 | let expr_ty = analyzer.type_of(db, &expr)?; | ||
61 | |||
62 | analyzer.autoderef(db, expr_ty).find_map(|ty| match ty.as_adt() { | ||
63 | Some((AdtDef::Enum(e), _)) => Some(e.source(db).ast), | ||
64 | _ => None, | ||
65 | }) | ||
66 | } | ||
67 | |||
68 | fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> { | ||
69 | let path = &AstBuilder::<ast::Path>::from_pieces(var.parent_enum().name()?, var.name()?); | ||
70 | |||
71 | let pat: ast::Pat = match var.kind() { | ||
72 | ast::StructKind::Tuple(field_list) => { | ||
73 | let pats = iter::repeat(AstBuilder::<ast::PlaceholderPat>::placeholder().into()) | ||
74 | .take(field_list.fields().count()); | ||
75 | AstBuilder::<ast::TupleStructPat>::from_pieces(path, pats).into() | ||
76 | } | ||
77 | ast::StructKind::Named(field_list) => { | ||
78 | let pats = field_list | ||
79 | .fields() | ||
80 | .map(|f| AstBuilder::<ast::BindPat>::from_name(&f.name().unwrap()).into()); | ||
81 | AstBuilder::<ast::RecordPat>::from_pieces(path, pats).into() | ||
82 | } | ||
83 | ast::StructKind::Unit => AstBuilder::<ast::PathPat>::from_path(path).into(), | ||
84 | }; | ||
85 | |||
86 | Some(pat) | ||
87 | } | ||
88 | |||
95 | #[cfg(test)] | 89 | #[cfg(test)] |
96 | mod tests { | 90 | mod tests { |
97 | use crate::helpers::{check_assist, check_assist_target}; | 91 | use crate::helpers::{check_assist, check_assist_target}; |
@@ -108,7 +102,7 @@ mod tests { | |||
108 | Bs, | 102 | Bs, |
109 | Cs(String), | 103 | Cs(String), |
110 | Ds(String, String), | 104 | Ds(String, String), |
111 | Es{x: usize, y: usize} | 105 | Es{ x: usize, y: usize } |
112 | } | 106 | } |
113 | 107 | ||
114 | fn main() { | 108 | fn main() { |
@@ -122,7 +116,7 @@ mod tests { | |||
122 | Bs, | 116 | Bs, |
123 | Cs(String), | 117 | Cs(String), |
124 | Ds(String, String), | 118 | Ds(String, String), |
125 | Es{x: usize, y: usize} | 119 | Es{ x: usize, y: usize } |
126 | } | 120 | } |
127 | 121 | ||
128 | fn main() { | 122 | fn main() { |
@@ -132,7 +126,7 @@ mod tests { | |||
132 | A::Bs => (), | 126 | A::Bs => (), |
133 | A::Cs(_) => (), | 127 | A::Cs(_) => (), |
134 | A::Ds(_, _) => (), | 128 | A::Ds(_, _) => (), |
135 | A::Es{x, y} => (), | 129 | A::Es{ x, y } => (), |
136 | } | 130 | } |
137 | } | 131 | } |
138 | "#, | 132 | "#, |
@@ -170,7 +164,7 @@ mod tests { | |||
170 | fill_match_arms, | 164 | fill_match_arms, |
171 | r#" | 165 | r#" |
172 | enum A { | 166 | enum A { |
173 | Es{x: usize, y: usize} | 167 | Es{ x: usize, y: usize } |
174 | } | 168 | } |
175 | 169 | ||
176 | fn foo(a: &mut A) { | 170 | fn foo(a: &mut A) { |
@@ -180,57 +174,12 @@ mod tests { | |||
180 | "#, | 174 | "#, |
181 | r#" | 175 | r#" |
182 | enum A { | 176 | enum A { |
183 | Es{x: usize, y: usize} | 177 | Es{ x: usize, y: usize } |
184 | } | 178 | } |
185 | 179 | ||
186 | fn foo(a: &mut A) { | 180 | fn foo(a: &mut A) { |
187 | match <|>a { | 181 | match <|>a { |
188 | A::Es{x, y} => (), | 182 | A::Es{ x, y } => (), |
189 | } | ||
190 | } | ||
191 | "#, | ||
192 | ); | ||
193 | |||
194 | check_assist( | ||
195 | fill_match_arms, | ||
196 | r#" | ||
197 | enum E { X, Y} | ||
198 | |||
199 | fn main() { | ||
200 | match &E::X<|> | ||
201 | } | ||
202 | "#, | ||
203 | r#" | ||
204 | enum E { X, Y} | ||
205 | |||
206 | fn main() { | ||
207 | match <|>&E::X { | ||
208 | E::X => (), | ||
209 | E::Y => (), | ||
210 | } | ||
211 | } | ||
212 | "#, | ||
213 | ); | ||
214 | } | ||
215 | |||
216 | #[test] | ||
217 | fn fill_match_arms_no_body() { | ||
218 | check_assist( | ||
219 | fill_match_arms, | ||
220 | r#" | ||
221 | enum E { X, Y} | ||
222 | |||
223 | fn main() { | ||
224 | match E::X<|> | ||
225 | } | ||
226 | "#, | ||
227 | r#" | ||
228 | enum E { X, Y} | ||
229 | |||
230 | fn main() { | ||
231 | match <|>E::X { | ||
232 | E::X => (), | ||
233 | E::Y => (), | ||
234 | } | 183 | } |
235 | } | 184 | } |
236 | "#, | 185 | "#, |
@@ -242,7 +191,7 @@ mod tests { | |||
242 | check_assist_target( | 191 | check_assist_target( |
243 | fill_match_arms, | 192 | fill_match_arms, |
244 | r#" | 193 | r#" |
245 | enum E { X, Y} | 194 | enum E { X, Y } |
246 | 195 | ||
247 | fn main() { | 196 | fn main() { |
248 | match E::X<|> {} | 197 | match E::X<|> {} |