From 0c5fd8f7cbf04eda763e55bc9a38dad5f7ec917d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 3 Feb 2019 21:26:35 +0300 Subject: move assists to a separate crate --- crates/ra_ide_api/src/assists.rs | 109 +++----------- 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/imp.rs | 11 +- crates/ra_ide_api/src/lib.rs | 2 +- 6 files changed, 24 insertions(+), 295 deletions(-) delete mode 100644 crates/ra_ide_api/src/assists/fill_match_arm.rs delete mode 100644 crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm1.snap delete mode 100644 crates/ra_ide_api/src/assists/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 index 2da251df5..2a96fdf47 100644 --- a/crates/ra_ide_api/src/assists.rs +++ b/crates/ra_ide_api/src/assists.rs @@ -1,89 +1,24 @@ -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)) +use ra_db::{FileRange, FilePosition}; + +use crate::{SourceFileEdit, SourceChange, db::RootDatabase}; + +pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec { + ra_assists::assists(db, frange) + .into_iter() + .map(|(label, action)| { + let file_id = frange.file_id; + let file_edit = SourceFileEdit { + file_id, + edit: action.edit, + }; + SourceChange { + label: label.label, + source_file_edits: vec![file_edit], + file_system_edits: vec![], + cursor_position: action + .cursor_position + .map(|offset| FilePosition { offset, file_id }), + } + }) .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 deleted file mode 100644 index 6ae829d85..000000000 --- a/crates/ra_ide_api/src/assists/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::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 deleted file mode 100644 index 980726d92..000000000 --- a/crates/ra_ide_api/src/assists/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/assists/snapshots/tests__fill_match_arm2.snap b/crates/ra_ide_api/src/assists/snapshots/tests__fill_match_arm2.snap deleted file mode 100644 index cee0efe74..000000000 --- a/crates/ra_ide_api/src/assists/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 fd8637ad2..b139efabf 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs @@ -19,7 +19,7 @@ use ra_syntax::{ use crate::{ AnalysisChange, - CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, + CrateId, db, Diagnostic, FileId, FilePosition, FileSystemEdit, Query, RootChange, SourceChange, SourceFileEdit, symbol_index::{FileSymbol, SymbolsDatabase}, status::syntax_tree_stats @@ -236,15 +236,6 @@ impl db::RootDatabase { res } - pub(crate) fn assists(&self, frange: FileRange) -> Vec { - let file = self.parse(frange.file_id); - ra_ide_api_light::assists::assists(&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() - } - pub(crate) fn index_resolve(&self, name_ref: &ast::NameRef) -> Vec { let name = name_ref.text(); let mut query = Query::new(name.to_string()); diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 3a187d7a5..8beaba5de 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -477,7 +477,7 @@ impl Analysis { /// Computes assists (aks code actons aka intentions) for the given /// position. pub fn assists(&self, frange: FileRange) -> Cancelable> { - self.with_db(|db| db.assists(frange)) + self.with_db(|db| assists::assists(db, frange)) } /// Computes the set of diagnostics for the given file. -- cgit v1.2.3