aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/assists.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/assists.rs')
-rw-r--r--crates/ra_ide_api/src/assists.rs109
1 files changed, 22 insertions, 87 deletions
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 @@
1mod fill_match_arm; 1use ra_db::{FileRange, FilePosition};
2 2
3use ra_syntax::{ 3use crate::{SourceFileEdit, SourceChange, db::RootDatabase};
4 TextRange, SourceFile, AstNode, 4
5 algo::find_node_at_offset, 5pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<SourceChange> {
6}; 6 ra_assists::assists(db, frange)
7use ra_ide_api_light::{ 7 .into_iter()
8 LocalEdit, 8 .map(|(label, action)| {
9 assists::{ 9 let file_id = frange.file_id;
10 Assist, 10 let file_edit = SourceFileEdit {
11 AssistBuilder 11 file_id,
12 } 12 edit: action.edit,
13}; 13 };
14use crate::{ 14 SourceChange {
15 db::RootDatabase, 15 label: label.label,
16 FileId 16 source_file_edits: vec![file_edit],
17}; 17 file_system_edits: vec![],
18 18 cursor_position: action
19/// Return all the assists applicable at the given position. 19 .cursor_position
20pub(crate) fn assists( 20 .map(|offset| FilePosition { offset, file_id }),
21 db: &RootDatabase, 21 }
22 file_id: FileId, 22 })
23 file: &SourceFile,
24 range: TextRange,
25) -> Vec<LocalEdit> {
26 let ctx = AssistCtx::new(db, file_id, file, range);
27 [fill_match_arm::fill_match_arm]
28 .iter()
29 .filter_map(|&assist| ctx.clone().apply(assist))
30 .collect() 23 .collect()
31} 24}
32
33#[derive(Debug, Clone)]
34pub struct AssistCtx<'a> {
35 file_id: FileId,
36 source_file: &'a SourceFile,
37 db: &'a RootDatabase,
38 range: TextRange,
39 should_compute_edit: bool,
40}
41
42impl<'a> AssistCtx<'a> {
43 pub(crate) fn new(
44 db: &'a RootDatabase,
45 file_id: FileId,
46 source_file: &'a SourceFile,
47 range: TextRange,
48 ) -> AssistCtx<'a> {
49 AssistCtx {
50 source_file,
51 file_id,
52 db,
53 range,
54 should_compute_edit: false,
55 }
56 }
57
58 pub fn apply(mut self, assist: fn(AssistCtx) -> Option<Assist>) -> Option<LocalEdit> {
59 self.should_compute_edit = true;
60 match assist(self) {
61 None => None,
62 Some(Assist::Edit(e)) => Some(e),
63 Some(Assist::Applicable) => unreachable!(),
64 }
65 }
66
67 #[allow(unused)]
68 pub fn check(mut self, assist: fn(AssistCtx) -> Option<Assist>) -> bool {
69 self.should_compute_edit = false;
70 match assist(self) {
71 None => false,
72 Some(Assist::Edit(_)) => unreachable!(),
73 Some(Assist::Applicable) => true,
74 }
75 }
76
77 fn build(self, label: impl Into<String>, f: impl FnOnce(&mut AssistBuilder)) -> Option<Assist> {
78 if !self.should_compute_edit {
79 return Some(Assist::Applicable);
80 }
81 let mut edit = AssistBuilder::default();
82 f(&mut edit);
83 Some(edit.build(label))
84 }
85
86 pub(crate) fn node_at_offset<N: AstNode>(&self) -> Option<&'a N> {
87 find_node_at_offset(self.source_file.syntax(), self.range.start())
88 }
89}