diff options
Diffstat (limited to 'crates/ra_assists/src/lib.rs')
-rw-r--r-- | crates/ra_assists/src/lib.rs | 124 |
1 files changed, 51 insertions, 73 deletions
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index f4f37614f..b6dc7cb1b 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -10,7 +10,7 @@ macro_rules! eprintln { | |||
10 | ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; | 10 | ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; |
11 | } | 11 | } |
12 | 12 | ||
13 | mod assist_ctx; | 13 | mod assist_context; |
14 | mod marks; | 14 | mod marks; |
15 | #[cfg(test)] | 15 | #[cfg(test)] |
16 | mod tests; | 16 | mod tests; |
@@ -18,20 +18,22 @@ pub mod utils; | |||
18 | pub mod ast_transform; | 18 | pub mod ast_transform; |
19 | 19 | ||
20 | use hir::Semantics; | 20 | use hir::Semantics; |
21 | use ra_db::{FileId, FileRange}; | 21 | use ra_db::FileRange; |
22 | use ra_ide_db::RootDatabase; | 22 | use ra_ide_db::{source_change::SourceChange, RootDatabase}; |
23 | use ra_syntax::{TextRange, TextSize}; | 23 | use ra_syntax::TextRange; |
24 | use ra_text_edit::TextEdit; | ||
25 | 24 | ||
26 | pub(crate) use crate::assist_ctx::{Assist, AssistCtx}; | 25 | pub(crate) use crate::assist_context::{AssistContext, Assists}; |
27 | 26 | ||
28 | /// Unique identifier of the assist, should not be shown to the user | 27 | /// Unique identifier of the assist, should not be shown to the user |
29 | /// directly. | 28 | /// directly. |
30 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 29 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
31 | pub struct AssistId(pub &'static str); | 30 | pub struct AssistId(pub &'static str); |
32 | 31 | ||
32 | #[derive(Clone, Debug)] | ||
33 | pub struct GroupLabel(pub String); | ||
34 | |||
33 | #[derive(Debug, Clone)] | 35 | #[derive(Debug, Clone)] |
34 | pub struct AssistLabel { | 36 | pub struct Assist { |
35 | pub id: AssistId, | 37 | pub id: AssistId, |
36 | /// Short description of the assist, as shown in the UI. | 38 | /// Short description of the assist, as shown in the UI. |
37 | pub label: String, | 39 | pub label: String, |
@@ -41,93 +43,69 @@ pub struct AssistLabel { | |||
41 | pub target: TextRange, | 43 | pub target: TextRange, |
42 | } | 44 | } |
43 | 45 | ||
44 | #[derive(Clone, Debug)] | 46 | #[derive(Debug, Clone)] |
45 | pub struct GroupLabel(pub String); | 47 | pub struct ResolvedAssist { |
48 | pub assist: Assist, | ||
49 | pub source_change: SourceChange, | ||
50 | } | ||
51 | |||
52 | impl Assist { | ||
53 | /// Return all the assists applicable at the given position. | ||
54 | /// | ||
55 | /// Assists are returned in the "unresolved" state, that is only labels are | ||
56 | /// returned, without actual edits. | ||
57 | pub fn unresolved(db: &RootDatabase, range: FileRange) -> Vec<Assist> { | ||
58 | let sema = Semantics::new(db); | ||
59 | let ctx = AssistContext::new(sema, range); | ||
60 | let mut acc = Assists::new_unresolved(&ctx); | ||
61 | handlers::all().iter().for_each(|handler| { | ||
62 | handler(&mut acc, &ctx); | ||
63 | }); | ||
64 | acc.finish_unresolved() | ||
65 | } | ||
66 | |||
67 | /// Return all the assists applicable at the given position. | ||
68 | /// | ||
69 | /// Assists are returned in the "resolved" state, that is with edit fully | ||
70 | /// computed. | ||
71 | pub fn resolved(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssist> { | ||
72 | let sema = Semantics::new(db); | ||
73 | let ctx = AssistContext::new(sema, range); | ||
74 | let mut acc = Assists::new_resolved(&ctx); | ||
75 | handlers::all().iter().for_each(|handler| { | ||
76 | handler(&mut acc, &ctx); | ||
77 | }); | ||
78 | acc.finish_resolved() | ||
79 | } | ||
46 | 80 | ||
47 | impl AssistLabel { | ||
48 | pub(crate) fn new( | 81 | pub(crate) fn new( |
49 | id: AssistId, | 82 | id: AssistId, |
50 | label: String, | 83 | label: String, |
51 | group: Option<GroupLabel>, | 84 | group: Option<GroupLabel>, |
52 | target: TextRange, | 85 | target: TextRange, |
53 | ) -> AssistLabel { | 86 | ) -> Assist { |
54 | // FIXME: make fields private, so that this invariant can't be broken | 87 | // FIXME: make fields private, so that this invariant can't be broken |
55 | assert!(label.starts_with(|c: char| c.is_uppercase())); | 88 | assert!(label.starts_with(|c: char| c.is_uppercase())); |
56 | AssistLabel { id, label, group, target } | 89 | Assist { id, label, group, target } |
57 | } | ||
58 | } | ||
59 | |||
60 | #[derive(Debug, Clone)] | ||
61 | pub struct AssistAction { | ||
62 | pub edit: TextEdit, | ||
63 | pub cursor_position: Option<TextSize>, | ||
64 | pub file: AssistFile, | ||
65 | } | ||
66 | |||
67 | #[derive(Debug, Clone)] | ||
68 | pub struct ResolvedAssist { | ||
69 | pub label: AssistLabel, | ||
70 | pub action: AssistAction, | ||
71 | } | ||
72 | |||
73 | #[derive(Debug, Clone, Copy)] | ||
74 | pub enum AssistFile { | ||
75 | CurrentFile, | ||
76 | TargetFile(FileId), | ||
77 | } | ||
78 | |||
79 | impl Default for AssistFile { | ||
80 | fn default() -> Self { | ||
81 | Self::CurrentFile | ||
82 | } | 90 | } |
83 | } | 91 | } |
84 | 92 | ||
85 | /// Return all the assists applicable at the given position. | ||
86 | /// | ||
87 | /// Assists are returned in the "unresolved" state, that is only labels are | ||
88 | /// returned, without actual edits. | ||
89 | pub fn unresolved_assists(db: &RootDatabase, range: FileRange) -> Vec<AssistLabel> { | ||
90 | let sema = Semantics::new(db); | ||
91 | let ctx = AssistCtx::new(&sema, range, false); | ||
92 | handlers::all() | ||
93 | .iter() | ||
94 | .filter_map(|f| f(ctx.clone())) | ||
95 | .flat_map(|it| it.0) | ||
96 | .map(|a| a.label) | ||
97 | .collect() | ||
98 | } | ||
99 | |||
100 | /// Return all the assists applicable at the given position. | ||
101 | /// | ||
102 | /// Assists are returned in the "resolved" state, that is with edit fully | ||
103 | /// computed. | ||
104 | pub fn resolved_assists(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssist> { | ||
105 | let sema = Semantics::new(db); | ||
106 | let ctx = AssistCtx::new(&sema, range, true); | ||
107 | let mut a = handlers::all() | ||
108 | .iter() | ||
109 | .filter_map(|f| f(ctx.clone())) | ||
110 | .flat_map(|it| it.0) | ||
111 | .map(|it| it.into_resolved().unwrap()) | ||
112 | .collect::<Vec<_>>(); | ||
113 | a.sort_by_key(|it| it.label.target.len()); | ||
114 | a | ||
115 | } | ||
116 | |||
117 | mod handlers { | 93 | mod handlers { |
118 | use crate::{Assist, AssistCtx}; | 94 | use crate::{AssistContext, Assists}; |
119 | 95 | ||
120 | pub(crate) type Handler = fn(AssistCtx) -> Option<Assist>; | 96 | pub(crate) type Handler = fn(&mut Assists, &AssistContext) -> Option<()>; |
121 | 97 | ||
122 | mod add_custom_impl; | 98 | mod add_custom_impl; |
123 | mod add_derive; | 99 | mod add_derive; |
124 | mod add_explicit_type; | 100 | mod add_explicit_type; |
101 | mod add_from_impl_for_enum; | ||
125 | mod add_function; | 102 | mod add_function; |
126 | mod add_impl; | 103 | mod add_impl; |
127 | mod add_missing_impl_members; | 104 | mod add_missing_impl_members; |
128 | mod add_new; | 105 | mod add_new; |
129 | mod apply_demorgan; | 106 | mod apply_demorgan; |
130 | mod auto_import; | 107 | mod auto_import; |
108 | mod change_return_type_to_result; | ||
131 | mod change_visibility; | 109 | mod change_visibility; |
132 | mod early_return; | 110 | mod early_return; |
133 | mod fill_match_arms; | 111 | mod fill_match_arms; |
@@ -144,13 +122,12 @@ mod handlers { | |||
144 | mod raw_string; | 122 | mod raw_string; |
145 | mod remove_dbg; | 123 | mod remove_dbg; |
146 | mod remove_mut; | 124 | mod remove_mut; |
125 | mod reorder_fields; | ||
147 | mod replace_if_let_with_match; | 126 | mod replace_if_let_with_match; |
148 | mod replace_let_with_if_let; | 127 | mod replace_let_with_if_let; |
149 | mod replace_qualified_name_with_use; | 128 | mod replace_qualified_name_with_use; |
150 | mod replace_unwrap_with_match; | 129 | mod replace_unwrap_with_match; |
151 | mod split_import; | 130 | mod split_import; |
152 | mod add_from_impl_for_enum; | ||
153 | mod reorder_fields; | ||
154 | mod unwrap_block; | 131 | mod unwrap_block; |
155 | 132 | ||
156 | pub(crate) fn all() -> &'static [Handler] { | 133 | pub(crate) fn all() -> &'static [Handler] { |
@@ -165,6 +142,7 @@ mod handlers { | |||
165 | add_new::add_new, | 142 | add_new::add_new, |
166 | apply_demorgan::apply_demorgan, | 143 | apply_demorgan::apply_demorgan, |
167 | auto_import::auto_import, | 144 | auto_import::auto_import, |
145 | change_return_type_to_result::change_return_type_to_result, | ||
168 | change_visibility::change_visibility, | 146 | change_visibility::change_visibility, |
169 | early_return::convert_to_guarded_return, | 147 | early_return::convert_to_guarded_return, |
170 | fill_match_arms::fill_match_arms, | 148 | fill_match_arms::fill_match_arms, |