This commit is contained in:
Aleksey Kladov 2020-02-07 14:53:50 +01:00
parent 8337dcd9e2
commit b831b17b3d
2 changed files with 29 additions and 42 deletions

View file

@ -69,23 +69,11 @@ impl<'a> Clone for AssistCtx<'a> {
} }
impl<'a> AssistCtx<'a> { impl<'a> AssistCtx<'a> {
pub(crate) fn with_ctx<F, T>( pub fn new(db: &RootDatabase, frange: FileRange, should_compute_edit: bool) -> AssistCtx {
db: &RootDatabase,
frange: FileRange,
should_compute_edit: bool,
f: F,
) -> T
where
F: FnOnce(AssistCtx) -> T,
{
let parse = db.parse(frange.file_id); let parse = db.parse(frange.file_id);
AssistCtx { db, frange, source_file: parse.tree(), should_compute_edit }
let ctx = AssistCtx { db, frange, source_file: parse.tree(), should_compute_edit };
f(ctx)
} }
}
impl<'a> AssistCtx<'a> {
pub(crate) fn add_assist( pub(crate) fn add_assist(
self, self,
id: AssistId, id: AssistId,

View file

@ -37,6 +37,7 @@ pub struct AssistAction {
pub label: Option<String>, pub label: Option<String>,
pub edit: TextEdit, pub edit: TextEdit,
pub cursor_position: Option<TextUnit>, pub cursor_position: Option<TextUnit>,
// FIXME: This belongs to `AssistLabel`
pub target: Option<TextRange>, pub target: Option<TextRange>,
} }
@ -60,16 +61,15 @@ impl ResolvedAssist {
/// Assists are returned in the "unresolved" state, that is only labels are /// Assists are returned in the "unresolved" state, that is only labels are
/// returned, without actual edits. /// returned, without actual edits.
pub fn unresolved_assists(db: &RootDatabase, range: FileRange) -> Vec<AssistLabel> { pub fn unresolved_assists(db: &RootDatabase, range: FileRange) -> Vec<AssistLabel> {
AssistCtx::with_ctx(db, range, false, |ctx| { let ctx = AssistCtx::new(db, range, false);
assists::all() assists::all()
.iter() .iter()
.filter_map(|f| f(ctx.clone())) .filter_map(|f| f(ctx.clone()))
.map(|a| match a { .map(|a| match a {
Assist::Unresolved { label } => label, Assist::Unresolved { label } => label,
Assist::Resolved { .. } => unreachable!(), Assist::Resolved { .. } => unreachable!(),
}) })
.collect() .collect()
})
} }
/// Return all the assists applicable at the given position. /// Return all the assists applicable at the given position.
@ -77,18 +77,17 @@ pub fn unresolved_assists(db: &RootDatabase, range: FileRange) -> Vec<AssistLabe
/// Assists are returned in the "resolved" state, that is with edit fully /// Assists are returned in the "resolved" state, that is with edit fully
/// computed. /// computed.
pub fn resolved_assists(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssist> { pub fn resolved_assists(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssist> {
AssistCtx::with_ctx(db, range, true, |ctx| { let ctx = AssistCtx::new(db, range, true);
let mut a = assists::all() let mut a = assists::all()
.iter() .iter()
.filter_map(|f| f(ctx.clone())) .filter_map(|f| f(ctx.clone()))
.map(|a| match a { .map(|a| match a {
Assist::Resolved { assist } => assist, Assist::Resolved { assist } => assist,
Assist::Unresolved { .. } => unreachable!(), Assist::Unresolved { .. } => unreachable!(),
}) })
.collect(); .collect();
sort_assists(&mut a); sort_assists(&mut a);
a a
})
} }
fn sort_assists(assists: &mut Vec<ResolvedAssist>) { fn sort_assists(assists: &mut Vec<ResolvedAssist>) {
@ -192,7 +191,7 @@ mod helpers {
let frange = let frange =
FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) };
let assist = let assist =
AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); assist(AssistCtx::new(&db, frange, true)).expect("code action is not applicable");
let action = match assist { let action = match assist {
Assist::Unresolved { .. } => unreachable!(), Assist::Unresolved { .. } => unreachable!(),
Assist::Resolved { assist } => assist.get_first_action(), Assist::Resolved { assist } => assist.get_first_action(),
@ -219,7 +218,7 @@ mod helpers {
let (db, file_id) = with_single_file(&before); let (db, file_id) = with_single_file(&before);
let frange = FileRange { file_id, range }; let frange = FileRange { file_id, range };
let assist = let assist =
AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); assist(AssistCtx::new(&db, frange, true)).expect("code action is not applicable");
let action = match assist { let action = match assist {
Assist::Unresolved { .. } => unreachable!(), Assist::Unresolved { .. } => unreachable!(),
Assist::Resolved { assist } => assist.get_first_action(), Assist::Resolved { assist } => assist.get_first_action(),
@ -242,7 +241,7 @@ mod helpers {
let frange = let frange =
FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) };
let assist = let assist =
AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); assist(AssistCtx::new(&db, frange, true)).expect("code action is not applicable");
let action = match assist { let action = match assist {
Assist::Unresolved { .. } => unreachable!(), Assist::Unresolved { .. } => unreachable!(),
Assist::Resolved { assist } => assist.get_first_action(), Assist::Resolved { assist } => assist.get_first_action(),
@ -261,7 +260,7 @@ mod helpers {
let (db, file_id) = with_single_file(&before); let (db, file_id) = with_single_file(&before);
let frange = FileRange { file_id, range }; let frange = FileRange { file_id, range };
let assist = let assist =
AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); assist(AssistCtx::new(&db, frange, true)).expect("code action is not applicable");
let action = match assist { let action = match assist {
Assist::Unresolved { .. } => unreachable!(), Assist::Unresolved { .. } => unreachable!(),
Assist::Resolved { assist } => assist.get_first_action(), Assist::Resolved { assist } => assist.get_first_action(),
@ -279,7 +278,7 @@ mod helpers {
let (db, file_id) = with_single_file(&before); let (db, file_id) = with_single_file(&before);
let frange = let frange =
FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) };
let assist = AssistCtx::with_ctx(&db, frange, true, assist); let assist = assist(AssistCtx::new(&db, frange, true));
assert!(assist.is_none()); assert!(assist.is_none());
} }
@ -290,7 +289,7 @@ mod helpers {
let (range, before) = extract_range(before); let (range, before) = extract_range(before);
let (db, file_id) = with_single_file(&before); let (db, file_id) = with_single_file(&before);
let frange = FileRange { file_id, range }; let frange = FileRange { file_id, range };
let assist = AssistCtx::with_ctx(&db, frange, true, assist); let assist = assist(AssistCtx::new(&db, frange, true));
assert!(assist.is_none()); assert!(assist.is_none());
} }
} }