From e696342afad79b0aa7638a8c51ef3ce45489ed21 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Tue, 5 Feb 2019 08:13:16 -0500 Subject: Rename assits to assists --- crates/ra_ide_api/src/assists.rs | 89 ++++++++++++ crates/ra_ide_api/src/assists/fill_match_arm.rs | 157 +++++++++++++++++++++ .../assists/snapshots/tests__fill_match_arm1.snap | 20 +++ .../assists/snapshots/tests__fill_match_arm2.snap | 20 +++ crates/ra_ide_api/src/assits.rs | 89 ------------ crates/ra_ide_api/src/assits/fill_match_arm.rs | 157 --------------------- .../assits/snapshots/tests__fill_match_arm1.snap | 20 --- .../assits/snapshots/tests__fill_match_arm2.snap | 20 --- crates/ra_ide_api/src/imp.rs | 2 +- crates/ra_ide_api/src/lib.rs | 2 +- 10 files changed, 288 insertions(+), 288 deletions(-) create mode 100644 crates/ra_ide_api/src/assists.rs create mode 100644 crates/ra_ide_api/src/assists/fill_match_arm.rs create mode 100644 crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm1.snap create mode 100644 crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm2.snap delete mode 100644 crates/ra_ide_api/src/assits.rs delete mode 100644 crates/ra_ide_api/src/assits/fill_match_arm.rs delete mode 100644 crates/ra_ide_api/src/assits/snapshots/tests__fill_match_arm1.snap delete mode 100644 crates/ra_ide_api/src/assits/snapshots/tests__fill_match_arm2.snap (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/assists.rs b/crates/ra_ide_api/src/assists.rs new file mode 100644 index 000000000..2da251df5 --- /dev/null +++ b/crates/ra_ide_api/src/assists.rs @@ -0,0 +1,89 @@ +mod fill_match_arm; + +use ra_syntax::{ + TextRange, SourceFile, AstNode, + algo::find_node_at_offset, +}; +use ra_ide_api_light::{ + LocalEdit, + assists::{ + Assist, + AssistBuilder + } +}; +use crate::{ + db::RootDatabase, + FileId +}; + +/// Return all the assists applicable at the given position. +pub(crate) fn assists( + db: &RootDatabase, + file_id: FileId, + file: &SourceFile, + range: TextRange, +) -> Vec { + let ctx = AssistCtx::new(db, file_id, file, range); + [fill_match_arm::fill_match_arm] + .iter() + .filter_map(|&assist| ctx.clone().apply(assist)) + .collect() +} + +#[derive(Debug, Clone)] +pub struct AssistCtx<'a> { + file_id: FileId, + source_file: &'a SourceFile, + db: &'a RootDatabase, + range: TextRange, + should_compute_edit: bool, +} + +impl<'a> AssistCtx<'a> { + pub(crate) fn new( + db: &'a RootDatabase, + file_id: FileId, + source_file: &'a SourceFile, + range: TextRange, + ) -> AssistCtx<'a> { + AssistCtx { + source_file, + file_id, + db, + range, + should_compute_edit: false, + } + } + + pub fn apply(mut self, assist: fn(AssistCtx) -> Option) -> Option { + self.should_compute_edit = true; + match assist(self) { + None => None, + Some(Assist::Edit(e)) => Some(e), + Some(Assist::Applicable) => unreachable!(), + } + } + + #[allow(unused)] + pub fn check(mut self, assist: fn(AssistCtx) -> Option) -> bool { + self.should_compute_edit = false; + match assist(self) { + None => false, + Some(Assist::Edit(_)) => unreachable!(), + Some(Assist::Applicable) => true, + } + } + + fn build(self, label: impl Into, f: impl FnOnce(&mut AssistBuilder)) -> Option { + if !self.should_compute_edit { + return Some(Assist::Applicable); + } + let mut edit = AssistBuilder::default(); + f(&mut edit); + Some(edit.build(label)) + } + + pub(crate) fn node_at_offset(&self) -> Option<&'a N> { + find_node_at_offset(self.source_file.syntax(), self.range.start()) + } +} diff --git a/crates/ra_ide_api/src/assists/fill_match_arm.rs b/crates/ra_ide_api/src/assists/fill_match_arm.rs new file mode 100644 index 000000000..6ae829d85 --- /dev/null +++ b/crates/ra_ide_api/src/assists/fill_match_arm.rs @@ -0,0 +1,157 @@ +use std::fmt::Write; +use hir::{ + AdtDef, + source_binder, + Ty, + FieldSource, +}; +use ra_ide_api_light::{ + assists::{ + Assist, + AssistBuilder + } +}; +use ra_syntax::{ + ast::{ + self, + AstNode, + } +}; + +use crate::assists::AssistCtx; + +pub fn fill_match_arm(ctx: AssistCtx) -> Option { + let match_expr = ctx.node_at_offset::()?; + + // We already have some match arms, so we don't provide any assists. + match match_expr.match_arm_list() { + Some(arm_list) if arm_list.arms().count() > 0 => { + return None; + } + _ => {} + } + + let expr = match_expr.expr()?; + let function = source_binder::function_from_child_node(ctx.db, ctx.file_id, expr.syntax())?; + let infer_result = function.infer(ctx.db); + let syntax_mapping = function.body_syntax_mapping(ctx.db); + let node_expr = syntax_mapping.node_expr(expr)?; + let match_expr_ty = infer_result[node_expr].clone(); + match match_expr_ty { + Ty::Adt { def_id, .. } => match def_id { + AdtDef::Enum(e) => { + let mut buf = format!("match {} {{\n", expr.syntax().text().to_string()); + let variants = e.variants(ctx.db); + for variant in variants { + let name = variant.name(ctx.db)?; + write!( + &mut buf, + " {}::{}", + e.name(ctx.db)?.to_string(), + name.to_string() + ) + .expect("write fmt"); + + let pat = variant + .fields(ctx.db) + .into_iter() + .map(|field| { + let name = field.name(ctx.db).to_string(); + let (_, source) = field.source(ctx.db); + match source { + FieldSource::Named(_) => name, + FieldSource::Pos(_) => "_".to_string(), + } + }) + .collect::>(); + + match pat.first().map(|s| s.as_str()) { + Some("_") => write!(&mut buf, "({})", pat.join(", ")).expect("write fmt"), + Some(_) => write!(&mut buf, "{{{}}}", pat.join(", ")).expect("write fmt"), + None => (), + }; + + buf.push_str(" => (),\n"); + } + buf.push_str("}"); + ctx.build("fill match arms", |edit: &mut AssistBuilder| { + edit.replace_node_and_indent(match_expr.syntax(), buf); + }) + } + _ => None, + }, + _ => None, + } +} + +#[cfg(test)] +mod tests { + use insta::assert_debug_snapshot_matches; + + use ra_syntax::{TextRange, TextUnit}; + + use crate::{ + FileRange, + mock_analysis::{analysis_and_position, single_file_with_position} +}; + use ra_db::SourceDatabase; + + fn test_assit(name: &str, code: &str) { + let (analysis, position) = if code.contains("//-") { + analysis_and_position(code) + } else { + single_file_with_position(code) + }; + let frange = FileRange { + file_id: position.file_id, + range: TextRange::offset_len(position.offset, TextUnit::from(1)), + }; + let source_file = analysis + .with_db(|db| db.parse(frange.file_id)) + .expect("source file"); + let ret = analysis + .with_db(|db| crate::assists::assists(db, frange.file_id, &source_file, frange.range)) + .expect("assists"); + + assert_debug_snapshot_matches!(name, ret); + } + + #[test] + fn test_fill_match_arm() { + test_assit( + "fill_match_arm1", + r#" + enum A { + As, + Bs, + Cs(String), + Ds(String, String), + Es{x: usize, y: usize} + } + + fn main() { + let a = A::As; + match a<|> + } + "#, + ); + + test_assit( + "fill_match_arm2", + r#" + enum A { + As, + Bs, + Cs(String), + Ds(String, String), + Es{x: usize, y: usize} + } + + fn main() { + let a = A::As; + match a<|> {} + } + "#, + ); + } +} diff --git a/crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm1.snap b/crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm1.snap new file mode 100644 index 000000000..980726d92 --- /dev/null +++ b/crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm1.snap @@ -0,0 +1,20 @@ +--- +created: "2019-02-03T15:38:46.094184+00:00" +creator: insta@0.5.2 +expression: ret +source: crates/ra_ide_api/src/assits/fill_match_arm.rs +--- +[ + LocalEdit { + label: "fill match arms", + edit: TextEdit { + atoms: [ + AtomTextEdit { + delete: [211; 218), + insert: "match a {\n A::As => (),\n A::Bs => (),\n A::Cs(_) => (),\n A::Ds(_, _) => (),\n A::Es{x, y} => (),\n }" + } + ] + }, + cursor_position: None + } +] diff --git a/crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm2.snap b/crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm2.snap new file mode 100644 index 000000000..cee0efe74 --- /dev/null +++ b/crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm2.snap @@ -0,0 +1,20 @@ +--- +created: "2019-02-03T15:41:34.640074+00:00" +creator: insta@0.5.2 +expression: ret +source: crates/ra_ide_api/src/assits/fill_match_arm.rs +--- +[ + LocalEdit { + label: "fill match arms", + edit: TextEdit { + atoms: [ + AtomTextEdit { + delete: [211; 221), + insert: "match a {\n A::As => (),\n A::Bs => (),\n A::Cs(_) => (),\n A::Ds(_, _) => (),\n A::Es{x, y} => (),\n }" + } + ] + }, + cursor_position: None + } +] diff --git a/crates/ra_ide_api/src/assits.rs b/crates/ra_ide_api/src/assits.rs deleted file mode 100644 index 2da251df5..000000000 --- a/crates/ra_ide_api/src/assits.rs +++ /dev/null @@ -1,89 +0,0 @@ -mod fill_match_arm; - -use ra_syntax::{ - TextRange, SourceFile, AstNode, - algo::find_node_at_offset, -}; -use ra_ide_api_light::{ - LocalEdit, - assists::{ - Assist, - AssistBuilder - } -}; -use crate::{ - db::RootDatabase, - FileId -}; - -/// Return all the assists applicable at the given position. -pub(crate) fn assists( - db: &RootDatabase, - file_id: FileId, - file: &SourceFile, - range: TextRange, -) -> Vec { - let ctx = AssistCtx::new(db, file_id, file, range); - [fill_match_arm::fill_match_arm] - .iter() - .filter_map(|&assist| ctx.clone().apply(assist)) - .collect() -} - -#[derive(Debug, Clone)] -pub struct AssistCtx<'a> { - file_id: FileId, - source_file: &'a SourceFile, - db: &'a RootDatabase, - range: TextRange, - should_compute_edit: bool, -} - -impl<'a> AssistCtx<'a> { - pub(crate) fn new( - db: &'a RootDatabase, - file_id: FileId, - source_file: &'a SourceFile, - range: TextRange, - ) -> AssistCtx<'a> { - AssistCtx { - source_file, - file_id, - db, - range, - should_compute_edit: false, - } - } - - pub fn apply(mut self, assist: fn(AssistCtx) -> Option) -> Option { - self.should_compute_edit = true; - match assist(self) { - None => None, - Some(Assist::Edit(e)) => Some(e), - Some(Assist::Applicable) => unreachable!(), - } - } - - #[allow(unused)] - pub fn check(mut self, assist: fn(AssistCtx) -> Option) -> bool { - self.should_compute_edit = false; - match assist(self) { - None => false, - Some(Assist::Edit(_)) => unreachable!(), - Some(Assist::Applicable) => true, - } - } - - fn build(self, label: impl Into, f: impl FnOnce(&mut AssistBuilder)) -> Option { - if !self.should_compute_edit { - return Some(Assist::Applicable); - } - let mut edit = AssistBuilder::default(); - f(&mut edit); - Some(edit.build(label)) - } - - pub(crate) fn node_at_offset(&self) -> Option<&'a N> { - find_node_at_offset(self.source_file.syntax(), self.range.start()) - } -} diff --git a/crates/ra_ide_api/src/assits/fill_match_arm.rs b/crates/ra_ide_api/src/assits/fill_match_arm.rs deleted file mode 100644 index d433861a0..000000000 --- a/crates/ra_ide_api/src/assits/fill_match_arm.rs +++ /dev/null @@ -1,157 +0,0 @@ -use std::fmt::Write; -use hir::{ - AdtDef, - source_binder, - Ty, - FieldSource, -}; -use ra_ide_api_light::{ - assists::{ - Assist, - AssistBuilder - } -}; -use ra_syntax::{ - ast::{ - self, - AstNode, - } -}; - -use crate::assits::AssistCtx; - -pub fn fill_match_arm(ctx: AssistCtx) -> Option { - let match_expr = ctx.node_at_offset::()?; - - // We already have some match arms, so we don't provide any assists. - match match_expr.match_arm_list() { - Some(arm_list) if arm_list.arms().count() > 0 => { - return None; - } - _ => {} - } - - let expr = match_expr.expr()?; - let function = source_binder::function_from_child_node(ctx.db, ctx.file_id, expr.syntax())?; - let infer_result = function.infer(ctx.db); - let syntax_mapping = function.body_syntax_mapping(ctx.db); - let node_expr = syntax_mapping.node_expr(expr)?; - let match_expr_ty = infer_result[node_expr].clone(); - match match_expr_ty { - Ty::Adt { def_id, .. } => match def_id { - AdtDef::Enum(e) => { - let mut buf = format!("match {} {{\n", expr.syntax().text().to_string()); - let variants = e.variants(ctx.db); - for variant in variants { - let name = variant.name(ctx.db)?; - write!( - &mut buf, - " {}::{}", - e.name(ctx.db)?.to_string(), - name.to_string() - ) - .expect("write fmt"); - - let pat = variant - .fields(ctx.db) - .into_iter() - .map(|field| { - let name = field.name(ctx.db).to_string(); - let (_, source) = field.source(ctx.db); - match source { - FieldSource::Named(_) => name, - FieldSource::Pos(_) => "_".to_string(), - } - }) - .collect::>(); - - match pat.first().map(|s| s.as_str()) { - Some("_") => write!(&mut buf, "({})", pat.join(", ")).expect("write fmt"), - Some(_) => write!(&mut buf, "{{{}}}", pat.join(", ")).expect("write fmt"), - None => (), - }; - - buf.push_str(" => (),\n"); - } - buf.push_str("}"); - ctx.build("fill match arms", |edit: &mut AssistBuilder| { - edit.replace_node_and_indent(match_expr.syntax(), buf); - }) - } - _ => None, - }, - _ => None, - } -} - -#[cfg(test)] -mod tests { - use insta::assert_debug_snapshot_matches; - - use ra_syntax::{TextRange, TextUnit}; - - use crate::{ - FileRange, - mock_analysis::{analysis_and_position, single_file_with_position} -}; - use ra_db::SourceDatabase; - - fn test_assit(name: &str, code: &str) { - let (analysis, position) = if code.contains("//-") { - analysis_and_position(code) - } else { - single_file_with_position(code) - }; - let frange = FileRange { - file_id: position.file_id, - range: TextRange::offset_len(position.offset, TextUnit::from(1)), - }; - let source_file = analysis - .with_db(|db| db.parse(frange.file_id)) - .expect("source file"); - let ret = analysis - .with_db(|db| crate::assits::assists(db, frange.file_id, &source_file, frange.range)) - .expect("assits"); - - assert_debug_snapshot_matches!(name, ret); - } - - #[test] - fn test_fill_match_arm() { - test_assit( - "fill_match_arm1", - r#" - enum A { - As, - Bs, - Cs(String), - Ds(String, String), - Es{x: usize, y: usize} - } - - fn main() { - let a = A::As; - match a<|> - } - "#, - ); - - test_assit( - "fill_match_arm2", - r#" - enum A { - As, - Bs, - Cs(String), - Ds(String, String), - Es{x: usize, y: usize} - } - - fn main() { - let a = A::As; - match a<|> {} - } - "#, - ); - } -} diff --git a/crates/ra_ide_api/src/assits/snapshots/tests__fill_match_arm1.snap b/crates/ra_ide_api/src/assits/snapshots/tests__fill_match_arm1.snap deleted file mode 100644 index 980726d92..000000000 --- a/crates/ra_ide_api/src/assits/snapshots/tests__fill_match_arm1.snap +++ /dev/null @@ -1,20 +0,0 @@ ---- -created: "2019-02-03T15:38:46.094184+00:00" -creator: insta@0.5.2 -expression: ret -source: crates/ra_ide_api/src/assits/fill_match_arm.rs ---- -[ - LocalEdit { - label: "fill match arms", - edit: TextEdit { - atoms: [ - AtomTextEdit { - delete: [211; 218), - insert: "match a {\n A::As => (),\n A::Bs => (),\n A::Cs(_) => (),\n A::Ds(_, _) => (),\n A::Es{x, y} => (),\n }" - } - ] - }, - cursor_position: None - } -] diff --git a/crates/ra_ide_api/src/assits/snapshots/tests__fill_match_arm2.snap b/crates/ra_ide_api/src/assits/snapshots/tests__fill_match_arm2.snap deleted file mode 100644 index cee0efe74..000000000 --- a/crates/ra_ide_api/src/assits/snapshots/tests__fill_match_arm2.snap +++ /dev/null @@ -1,20 +0,0 @@ ---- -created: "2019-02-03T15:41:34.640074+00:00" -creator: insta@0.5.2 -expression: ret -source: crates/ra_ide_api/src/assits/fill_match_arm.rs ---- -[ - LocalEdit { - label: "fill match arms", - edit: TextEdit { - atoms: [ - AtomTextEdit { - delete: [211; 221), - insert: "match a {\n A::As => (),\n A::Bs => (),\n A::Cs(_) => (),\n A::Ds(_, _) => (),\n A::Es{x, y} => (),\n }" - } - ] - }, - cursor_position: None - } -] diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs index 5f672367c..fd8637ad2 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs @@ -240,7 +240,7 @@ impl db::RootDatabase { let file = self.parse(frange.file_id); ra_ide_api_light::assists::assists(&file, frange.range) .into_iter() - .chain(crate::assits::assists(self, frange.file_id, &file, frange.range).into_iter()) + .chain(crate::assists::assists(self, frange.file_id, &file, frange.range).into_iter()) .map(|local_edit| SourceChange::from_local_edit(frange.file_id, local_edit)) .collect() } diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 65941a5ca..3a187d7a5 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -30,7 +30,7 @@ mod syntax_highlighting; mod parent_module; mod rename; mod impls; -mod assits; +mod assists; #[cfg(test)] mod marks; -- cgit v1.2.3