}]))
}
-pub fn handle_code_action(
- snap: GlobalStateSnapshot,
- params: lsp_types::CodeActionParams,
-) -> Result<Option<Vec<lsp_ext::CodeAction>>> {
- let _p = profile("handle_code_action");
- // We intentionally don't support command-based actions, as those either
- // requires custom client-code anyway, or requires server-initiated edits.
- // Server initiated edits break causality, so we avoid those as well.
- if !snap.config.client_caps.code_action_literals {
- return Ok(None);
- }
-
+fn handle_fixes(
- world: &WorldSnapshot,
++ snap: &GlobalStateSnapshot,
+ params: &lsp_types::CodeActionParams,
+ res: &mut Vec<lsp_ext::CodeAction>,
+) -> Result<()> {
- let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?;
- let line_index = world.analysis().file_line_index(file_id)?;
+ let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
+ let line_index = snap.analysis().file_line_index(file_id)?;
let range = from_proto::text_range(&line_index, params.range);
- let frange = FileRange { file_id, range };
--
- let diagnostics = world.analysis().diagnostics(file_id)?;
+ let diagnostics = snap.analysis().diagnostics(file_id)?;
- let mut res: Vec<lsp_ext::CodeAction> = Vec::new();
let fixes_from_diagnostics = diagnostics
.into_iter()
.filter_map(|d| Some((d.range, d.fix?)))
.filter(|(diag_range, _fix)| diag_range.intersect(range).is_some())
.map(|(_range, fix)| fix);
-
for fix in fixes_from_diagnostics {
let title = fix.label;
- let edit = to_proto::snippet_workspace_edit(&world, fix.source_change)?;
+ let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?;
let action = lsp_ext::CodeAction {
title,
+ id: None,
group: None,
- kind: None,
+ kind: Some(lsp_types::code_action_kind::QUICKFIX.into()),
edit: Some(edit),
command: None,
};
}
res.push(fix.action.clone());
}
- world: WorldSnapshot,
+ Ok(())
+}
+
+pub fn handle_code_action(
- if !world.config.client_caps.code_action_literals {
++ snap: GlobalStateSnapshot,
+ params: lsp_types::CodeActionParams,
+) -> Result<Option<Vec<lsp_ext::CodeAction>>> {
+ let _p = profile("handle_code_action");
+ // We intentionally don't support command-based actions, as those either
+ // requires custom client-code anyway, or requires server-initiated edits.
+ // Server initiated edits break causality, so we avoid those as well.
- let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?;
- let line_index = world.analysis().file_line_index(file_id)?;
++ if !snap.config.client_caps.code_action_literals {
+ return Ok(None);
+ }
+
++ let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
++ let line_index = snap.analysis().file_line_index(file_id)?;
+ let range = from_proto::text_range(&line_index, params.range);
+ let frange = FileRange { file_id, range };
+ let mut res: Vec<lsp_ext::CodeAction> = Vec::new();
- handle_fixes(&world, ¶ms, &mut res)?;
- for assist in snap.analysis().assists(&snap.config.assist, frange)?.into_iter() {
- res.push(to_proto::code_action(&snap, assist)?.into());
++ handle_fixes(&snap, ¶ms, &mut res)?;
+
- if world.config.client_caps.resolve_code_action {
- for (index, assist) in world
- .analysis()
- .unresolved_assists(&world.config.assist, frange)?
- .into_iter()
- .enumerate()
++ if snap.config.client_caps.resolve_code_action {
++ for (index, assist) in
++ snap.analysis().unresolved_assists(&snap.config.assist, frange)?.into_iter().enumerate()
+ {
- res.push(to_proto::unresolved_code_action(&world, assist, index)?);
++ res.push(to_proto::unresolved_code_action(&snap, assist, index)?);
+ }
+ } else {
- for assist in world.analysis().resolved_assists(&world.config.assist, frange)?.into_iter() {
- res.push(to_proto::resolved_code_action(&world, assist)?);
++ for assist in snap.analysis().resolved_assists(&snap.config.assist, frange)?.into_iter() {
++ res.push(to_proto::resolved_code_action(&snap, assist)?);
+ }
}
+
Ok(Some(res))
}
- world: WorldSnapshot,
+pub fn handle_resolve_code_action(
- let file_id = from_proto::file_id(&world, ¶ms.code_action_params.text_document.uri)?;
- let line_index = world.analysis().file_line_index(file_id)?;
++ snap: GlobalStateSnapshot,
+ params: lsp_ext::ResolveCodeActionParams,
+) -> Result<Option<lsp_ext::SnippetWorkspaceEdit>> {
+ let _p = profile("handle_resolve_code_action");
- let assists = world.analysis().resolved_assists(&world.config.assist, frange)?;
++ let file_id = from_proto::file_id(&snap, ¶ms.code_action_params.text_document.uri)?;
++ let line_index = snap.analysis().file_line_index(file_id)?;
+ let range = from_proto::text_range(&line_index, params.code_action_params.range);
+ let frange = FileRange { file_id, range };
+
- Ok(to_proto::resolved_code_action(&world, assist.clone())?.edit)
++ let assists = snap.analysis().resolved_assists(&snap.config.assist, frange)?;
+ let id_components = params.id.split(":").collect::<Vec<&str>>();
+ let index = id_components.last().unwrap().parse::<usize>().unwrap();
+ let id_string = id_components.first().unwrap();
+ let assist = &assists[index];
+ assert!(assist.assist.id.0 == *id_string);
++ Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit)
+}
+
pub fn handle_code_lens(
- world: WorldSnapshot,
+ snap: GlobalStateSnapshot,
params: lsp_types::CodeLensParams,
) -> Result<Option<Vec<CodeLens>>> {
let _p = profile("handle_code_lens");
}
}
-pub(crate) fn code_action(
+pub(crate) fn unresolved_code_action(
- world: &WorldSnapshot,
+ snap: &GlobalStateSnapshot,
assist: Assist,
+ index: usize,
) -> Result<lsp_ext::CodeAction> {
let res = lsp_ext::CodeAction {
title: assist.label,
- group: if snap.config.client_caps.code_action_group { assist.group_label } else { None },
+ id: Some(format!("{}:{}", assist.id.0.to_owned(), index.to_string())),
- group: assist.group.filter(|_| world.config.client_caps.code_action_group).map(|gr| gr.0),
++ group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
kind: Some(String::new()),
- edit: Some(snippet_workspace_edit(snap, assist.source_change)?),
+ edit: None,
command: None,
};
Ok(res)
}
- world: &WorldSnapshot,
+pub(crate) fn resolved_code_action(
- unresolved_code_action(world, assist.assist, 0).and_then(|it| {
++ snap: &GlobalStateSnapshot,
+ assist: ResolvedAssist,
+) -> Result<lsp_ext::CodeAction> {
+ let change = assist.source_change;
- edit: Some(snippet_workspace_edit(world, change)?),
++ unresolved_code_action(snap, assist.assist, 0).and_then(|it| {
+ Ok(lsp_ext::CodeAction {
+ id: None,
++ edit: Some(snippet_workspace_edit(snap, change)?),
+ ..it
+ })
+ })
+}
+
pub(crate) fn runnable(
- world: &WorldSnapshot,
+ snap: &GlobalStateSnapshot,
file_id: FileId,
runnable: Runnable,
) -> Result<lsp_ext::Runnable> {