mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Filter assists
This commit is contained in:
parent
853440775d
commit
aa598ecb75
6 changed files with 157 additions and 20 deletions
|
@ -19,7 +19,7 @@ use ra_text_edit::TextEditBuilder;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assist_config::{AssistConfig, SnippetCap},
|
assist_config::{AssistConfig, SnippetCap},
|
||||||
Assist, AssistId, GroupLabel, ResolvedAssist,
|
Assist, AssistId, AssistKind, GroupLabel, ResolvedAssist,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// `AssistContext` allows to apply an assist or check if it could be applied.
|
/// `AssistContext` allows to apply an assist or check if it could be applied.
|
||||||
|
@ -57,6 +57,7 @@ pub(crate) struct AssistContext<'a> {
|
||||||
pub(crate) sema: Semantics<'a, RootDatabase>,
|
pub(crate) sema: Semantics<'a, RootDatabase>,
|
||||||
pub(crate) frange: FileRange,
|
pub(crate) frange: FileRange,
|
||||||
source_file: SourceFile,
|
source_file: SourceFile,
|
||||||
|
allowed: Option<Vec<AssistKind>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AssistContext<'a> {
|
impl<'a> AssistContext<'a> {
|
||||||
|
@ -64,9 +65,10 @@ impl<'a> AssistContext<'a> {
|
||||||
sema: Semantics<'a, RootDatabase>,
|
sema: Semantics<'a, RootDatabase>,
|
||||||
config: &'a AssistConfig,
|
config: &'a AssistConfig,
|
||||||
frange: FileRange,
|
frange: FileRange,
|
||||||
|
allowed: Option<Vec<AssistKind>>,
|
||||||
) -> AssistContext<'a> {
|
) -> AssistContext<'a> {
|
||||||
let source_file = sema.parse(frange.file_id);
|
let source_file = sema.parse(frange.file_id);
|
||||||
AssistContext { config, sema, frange, source_file }
|
AssistContext { config, sema, frange, source_file, allowed }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn db(&self) -> &RootDatabase {
|
pub(crate) fn db(&self) -> &RootDatabase {
|
||||||
|
@ -103,14 +105,26 @@ pub(crate) struct Assists {
|
||||||
resolve: bool,
|
resolve: bool,
|
||||||
file: FileId,
|
file: FileId,
|
||||||
buf: Vec<(Assist, Option<SourceChange>)>,
|
buf: Vec<(Assist, Option<SourceChange>)>,
|
||||||
|
allowed: Option<Vec<AssistKind>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Assists {
|
impl Assists {
|
||||||
pub(crate) fn new_resolved(ctx: &AssistContext) -> Assists {
|
pub(crate) fn new_resolved(ctx: &AssistContext) -> Assists {
|
||||||
Assists { resolve: true, file: ctx.frange.file_id, buf: Vec::new() }
|
Assists {
|
||||||
|
resolve: true,
|
||||||
|
file: ctx.frange.file_id,
|
||||||
|
buf: Vec::new(),
|
||||||
|
allowed: ctx.allowed.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_unresolved(ctx: &AssistContext) -> Assists {
|
pub(crate) fn new_unresolved(ctx: &AssistContext) -> Assists {
|
||||||
Assists { resolve: false, file: ctx.frange.file_id, buf: Vec::new() }
|
Assists {
|
||||||
|
resolve: false,
|
||||||
|
file: ctx.frange.file_id,
|
||||||
|
buf: Vec::new(),
|
||||||
|
allowed: ctx.allowed.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn finish_unresolved(self) -> Vec<Assist> {
|
pub(crate) fn finish_unresolved(self) -> Vec<Assist> {
|
||||||
|
@ -139,9 +153,13 @@ impl Assists {
|
||||||
target: TextRange,
|
target: TextRange,
|
||||||
f: impl FnOnce(&mut AssistBuilder),
|
f: impl FnOnce(&mut AssistBuilder),
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
|
if !self.is_allowed(&id) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let label = Assist::new(id, label.into(), None, target);
|
let label = Assist::new(id, label.into(), None, target);
|
||||||
self.add_impl(label, f)
|
self.add_impl(label, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_group(
|
pub(crate) fn add_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
group: &GroupLabel,
|
group: &GroupLabel,
|
||||||
|
@ -150,9 +168,14 @@ impl Assists {
|
||||||
target: TextRange,
|
target: TextRange,
|
||||||
f: impl FnOnce(&mut AssistBuilder),
|
f: impl FnOnce(&mut AssistBuilder),
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
|
if !self.is_allowed(&id) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let label = Assist::new(id, label.into(), Some(group.clone()), target);
|
let label = Assist::new(id, label.into(), Some(group.clone()), target);
|
||||||
self.add_impl(label, f)
|
self.add_impl(label, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> {
|
fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> {
|
||||||
let source_change = if self.resolve {
|
let source_change = if self.resolve {
|
||||||
let mut builder = AssistBuilder::new(self.file);
|
let mut builder = AssistBuilder::new(self.file);
|
||||||
|
@ -170,6 +193,13 @@ impl Assists {
|
||||||
self.buf.sort_by_key(|(label, _edit)| label.target.len());
|
self.buf.sort_by_key(|(label, _edit)| label.target.len());
|
||||||
self.buf
|
self.buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_allowed(&self, id: &AssistId) -> bool {
|
||||||
|
match &self.allowed {
|
||||||
|
Some(allowed) => allowed.iter().any(|kind| kind.contains(id.1)),
|
||||||
|
None => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct AssistBuilder {
|
pub(crate) struct AssistBuilder {
|
||||||
|
|
|
@ -37,6 +37,25 @@ pub enum AssistKind {
|
||||||
RefactorRewrite,
|
RefactorRewrite,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AssistKind {
|
||||||
|
pub fn contains(self, other: AssistKind) -> bool {
|
||||||
|
if self == other {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self {
|
||||||
|
AssistKind::None | AssistKind::Generate => return true,
|
||||||
|
AssistKind::Refactor => match other {
|
||||||
|
AssistKind::RefactorExtract
|
||||||
|
| AssistKind::RefactorInline
|
||||||
|
| AssistKind::RefactorRewrite => return true,
|
||||||
|
_ => return false,
|
||||||
|
},
|
||||||
|
_ => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Unique identifier of the assist, should not be shown to the user
|
/// Unique identifier of the assist, should not be shown to the user
|
||||||
/// directly.
|
/// directly.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -67,9 +86,14 @@ impl Assist {
|
||||||
///
|
///
|
||||||
/// 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(db: &RootDatabase, config: &AssistConfig, range: FileRange) -> Vec<Assist> {
|
pub fn unresolved(
|
||||||
|
db: &RootDatabase,
|
||||||
|
config: &AssistConfig,
|
||||||
|
range: FileRange,
|
||||||
|
allowed: Option<Vec<AssistKind>>,
|
||||||
|
) -> Vec<Assist> {
|
||||||
let sema = Semantics::new(db);
|
let sema = Semantics::new(db);
|
||||||
let ctx = AssistContext::new(sema, config, range);
|
let ctx = AssistContext::new(sema, config, range, allowed);
|
||||||
let mut acc = Assists::new_unresolved(&ctx);
|
let mut acc = Assists::new_unresolved(&ctx);
|
||||||
handlers::all().iter().for_each(|handler| {
|
handlers::all().iter().for_each(|handler| {
|
||||||
handler(&mut acc, &ctx);
|
handler(&mut acc, &ctx);
|
||||||
|
@ -85,9 +109,10 @@ impl Assist {
|
||||||
db: &RootDatabase,
|
db: &RootDatabase,
|
||||||
config: &AssistConfig,
|
config: &AssistConfig,
|
||||||
range: FileRange,
|
range: FileRange,
|
||||||
|
allowed: Option<Vec<AssistKind>>,
|
||||||
) -> Vec<ResolvedAssist> {
|
) -> Vec<ResolvedAssist> {
|
||||||
let sema = Semantics::new(db);
|
let sema = Semantics::new(db);
|
||||||
let ctx = AssistContext::new(sema, config, range);
|
let ctx = AssistContext::new(sema, config, range, allowed);
|
||||||
let mut acc = Assists::new_resolved(&ctx);
|
let mut acc = Assists::new_resolved(&ctx);
|
||||||
handlers::all().iter().for_each(|handler| {
|
handlers::all().iter().for_each(|handler| {
|
||||||
handler(&mut acc, &ctx);
|
handler(&mut acc, &ctx);
|
||||||
|
|
|
@ -6,7 +6,7 @@ use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::TextRange;
|
use ra_syntax::TextRange;
|
||||||
use test_utils::{assert_eq_text, extract_offset, extract_range};
|
use test_utils::{assert_eq_text, extract_offset, extract_range};
|
||||||
|
|
||||||
use crate::{handlers::Handler, Assist, AssistConfig, AssistContext, Assists};
|
use crate::{handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, Assists};
|
||||||
use stdx::trim_indent;
|
use stdx::trim_indent;
|
||||||
|
|
||||||
pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
|
pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
|
||||||
|
@ -35,14 +35,14 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) {
|
||||||
let before = db.file_text(file_id).to_string();
|
let before = db.file_text(file_id).to_string();
|
||||||
let frange = FileRange { file_id, range: selection.into() };
|
let frange = FileRange { file_id, range: selection.into() };
|
||||||
|
|
||||||
let mut assist = Assist::resolved(&db, &AssistConfig::default(), frange)
|
let mut assist = Assist::resolved(&db, &AssistConfig::default(), frange, None)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|assist| assist.assist.id.0 == assist_id)
|
.find(|assist| assist.assist.id.0 == assist_id)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
panic!(
|
panic!(
|
||||||
"\n\nAssist is not applicable: {}\nAvailable assists: {}",
|
"\n\nAssist is not applicable: {}\nAvailable assists: {}",
|
||||||
assist_id,
|
assist_id,
|
||||||
Assist::resolved(&db, &AssistConfig::default(), frange)
|
Assist::resolved(&db, &AssistConfig::default(), frange, None)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|assist| assist.assist.id.0)
|
.map(|assist| assist.assist.id.0)
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
@ -73,7 +73,7 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult) {
|
||||||
|
|
||||||
let sema = Semantics::new(&db);
|
let sema = Semantics::new(&db);
|
||||||
let config = AssistConfig::default();
|
let config = AssistConfig::default();
|
||||||
let ctx = AssistContext::new(sema, &config, frange);
|
let ctx = AssistContext::new(sema, &config, frange, None);
|
||||||
let mut acc = Assists::new_resolved(&ctx);
|
let mut acc = Assists::new_resolved(&ctx);
|
||||||
handler(&mut acc, &ctx);
|
handler(&mut acc, &ctx);
|
||||||
let mut res = acc.finish_resolved();
|
let mut res = acc.finish_resolved();
|
||||||
|
@ -105,7 +105,7 @@ fn assist_order_field_struct() {
|
||||||
let (before_cursor_pos, before) = extract_offset(before);
|
let (before_cursor_pos, before) = extract_offset(before);
|
||||||
let (db, file_id) = with_single_file(&before);
|
let (db, file_id) = with_single_file(&before);
|
||||||
let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) };
|
let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) };
|
||||||
let assists = Assist::resolved(&db, &AssistConfig::default(), frange);
|
let assists = Assist::resolved(&db, &AssistConfig::default(), frange, None);
|
||||||
let mut assists = assists.iter();
|
let mut assists = assists.iter();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -128,9 +128,49 @@ fn assist_order_if_expr() {
|
||||||
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 assists = Assist::resolved(&db, &AssistConfig::default(), frange);
|
let assists = Assist::resolved(&db, &AssistConfig::default(), frange, None);
|
||||||
let mut assists = assists.iter();
|
let mut assists = assists.iter();
|
||||||
|
|
||||||
assert_eq!(assists.next().expect("expected assist").assist.label, "Extract into variable");
|
assert_eq!(assists.next().expect("expected assist").assist.label, "Extract into variable");
|
||||||
assert_eq!(assists.next().expect("expected assist").assist.label, "Replace with match");
|
assert_eq!(assists.next().expect("expected assist").assist.label, "Replace with match");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assist_filter_works() {
|
||||||
|
let before = "
|
||||||
|
pub fn test_some_range(a: int) -> bool {
|
||||||
|
if let 2..6 = <|>5<|> {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}";
|
||||||
|
let (range, before) = extract_range(before);
|
||||||
|
let (db, file_id) = with_single_file(&before);
|
||||||
|
let frange = FileRange { file_id, range };
|
||||||
|
|
||||||
|
{
|
||||||
|
let allowed = Some(vec![AssistKind::Refactor]);
|
||||||
|
|
||||||
|
let assists = Assist::resolved(&db, &AssistConfig::default(), frange, allowed);
|
||||||
|
let mut assists = assists.iter();
|
||||||
|
|
||||||
|
assert_eq!(assists.next().expect("expected assist").assist.label, "Extract into variable");
|
||||||
|
assert_eq!(assists.next().expect("expected assist").assist.label, "Replace with match");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let allowed = Some(vec![AssistKind::RefactorExtract]);
|
||||||
|
let assists = Assist::resolved(&db, &AssistConfig::default(), frange, allowed);
|
||||||
|
assert_eq!(assists.len(), 1);
|
||||||
|
|
||||||
|
let mut assists = assists.iter();
|
||||||
|
assert_eq!(assists.next().expect("expected assist").assist.label, "Extract into variable");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let allowed = Some(vec![AssistKind::QuickFix]);
|
||||||
|
let assists = Assist::resolved(&db, &AssistConfig::default(), frange, allowed);
|
||||||
|
assert!(assists.is_empty(), "All asserts but quickfixes should be filtered out");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -476,8 +476,9 @@ impl Analysis {
|
||||||
&self,
|
&self,
|
||||||
config: &AssistConfig,
|
config: &AssistConfig,
|
||||||
frange: FileRange,
|
frange: FileRange,
|
||||||
|
allowed: Option<Vec<AssistKind>>,
|
||||||
) -> Cancelable<Vec<ResolvedAssist>> {
|
) -> Cancelable<Vec<ResolvedAssist>> {
|
||||||
self.with_db(|db| ra_assists::Assist::resolved(db, config, frange))
|
self.with_db(|db| ra_assists::Assist::resolved(db, config, frange, allowed))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes unresolved assists (aka code actions aka intentions) for the given
|
/// Computes unresolved assists (aka code actions aka intentions) for the given
|
||||||
|
@ -486,8 +487,9 @@ impl Analysis {
|
||||||
&self,
|
&self,
|
||||||
config: &AssistConfig,
|
config: &AssistConfig,
|
||||||
frange: FileRange,
|
frange: FileRange,
|
||||||
|
allowed: Option<Vec<AssistKind>>,
|
||||||
) -> Cancelable<Vec<Assist>> {
|
) -> Cancelable<Vec<Assist>> {
|
||||||
self.with_db(|db| Assist::unresolved(db, config, frange))
|
self.with_db(|db| Assist::unresolved(db, config, frange, allowed))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the set of diagnostics for the given file.
|
/// Computes the set of diagnostics for the given file.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use ra_db::{FileId, FilePosition, FileRange};
|
use ra_db::{FileId, FilePosition, FileRange};
|
||||||
use ra_ide::{LineCol, LineIndex};
|
use ra_ide::{AssistKind, LineCol, LineIndex};
|
||||||
use ra_syntax::{TextRange, TextSize};
|
use ra_syntax::{TextRange, TextSize};
|
||||||
use vfs::AbsPathBuf;
|
use vfs::AbsPathBuf;
|
||||||
|
|
||||||
|
@ -52,3 +52,17 @@ pub(crate) fn file_range(
|
||||||
let range = text_range(&line_index, range);
|
let range = text_range(&line_index, range);
|
||||||
Ok(FileRange { file_id, range })
|
Ok(FileRange { file_id, range })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn assist_kind(kind: lsp_types::CodeActionKind) -> Option<AssistKind> {
|
||||||
|
let assist_kind = match &kind {
|
||||||
|
k if k == &lsp_types::CodeActionKind::EMPTY => AssistKind::None,
|
||||||
|
k if k == &lsp_types::CodeActionKind::QUICKFIX => AssistKind::QuickFix,
|
||||||
|
k if k == &lsp_types::CodeActionKind::REFACTOR => AssistKind::Refactor,
|
||||||
|
k if k == &lsp_types::CodeActionKind::REFACTOR => AssistKind::RefactorExtract,
|
||||||
|
k if k == &lsp_types::CodeActionKind::REFACTOR => AssistKind::RefactorInline,
|
||||||
|
k if k == &lsp_types::CodeActionKind::REFACTOR => AssistKind::RefactorRewrite,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(assist_kind)
|
||||||
|
}
|
||||||
|
|
|
@ -746,6 +746,19 @@ fn handle_fixes(
|
||||||
let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
|
let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
|
||||||
let line_index = snap.analysis.file_line_index(file_id)?;
|
let line_index = snap.analysis.file_line_index(file_id)?;
|
||||||
let range = from_proto::text_range(&line_index, params.range);
|
let range = from_proto::text_range(&line_index, params.range);
|
||||||
|
|
||||||
|
match ¶ms.context.only {
|
||||||
|
Some(v) => {
|
||||||
|
if v.iter().any(|it| {
|
||||||
|
it == &lsp_types::CodeActionKind::EMPTY
|
||||||
|
|| it == &lsp_types::CodeActionKind::QUICKFIX
|
||||||
|
}) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
};
|
||||||
|
|
||||||
let diagnostics = snap.analysis.diagnostics(file_id)?;
|
let diagnostics = snap.analysis.diagnostics(file_id)?;
|
||||||
|
|
||||||
let fixes_from_diagnostics = diagnostics
|
let fixes_from_diagnostics = diagnostics
|
||||||
|
@ -792,18 +805,26 @@ pub(crate) fn handle_code_action(
|
||||||
let line_index = snap.analysis.file_line_index(file_id)?;
|
let line_index = snap.analysis.file_line_index(file_id)?;
|
||||||
let range = from_proto::text_range(&line_index, params.range);
|
let range = from_proto::text_range(&line_index, params.range);
|
||||||
let frange = FileRange { file_id, range };
|
let frange = FileRange { file_id, range };
|
||||||
|
|
||||||
let mut res: Vec<lsp_ext::CodeAction> = Vec::new();
|
let mut res: Vec<lsp_ext::CodeAction> = Vec::new();
|
||||||
|
|
||||||
handle_fixes(&snap, ¶ms, &mut res)?;
|
handle_fixes(&snap, ¶ms, &mut res)?;
|
||||||
|
|
||||||
|
let only =
|
||||||
|
params.context.only.map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect());
|
||||||
|
|
||||||
if snap.config.client_caps.resolve_code_action {
|
if snap.config.client_caps.resolve_code_action {
|
||||||
for (index, assist) in
|
for (index, assist) in snap
|
||||||
snap.analysis.unresolved_assists(&snap.config.assist, frange)?.into_iter().enumerate()
|
.analysis
|
||||||
|
.unresolved_assists(&snap.config.assist, frange, only)?
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
{
|
{
|
||||||
res.push(to_proto::unresolved_code_action(&snap, assist, index)?);
|
res.push(to_proto::unresolved_code_action(&snap, assist, index)?);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for assist in snap.analysis.resolved_assists(&snap.config.assist, frange)?.into_iter() {
|
for assist in snap.analysis.resolved_assists(&snap.config.assist, frange, only)?.into_iter()
|
||||||
|
{
|
||||||
res.push(to_proto::resolved_code_action(&snap, assist)?);
|
res.push(to_proto::resolved_code_action(&snap, assist)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -820,8 +841,13 @@ pub(crate) fn handle_resolve_code_action(
|
||||||
let line_index = snap.analysis.file_line_index(file_id)?;
|
let line_index = snap.analysis.file_line_index(file_id)?;
|
||||||
let range = from_proto::text_range(&line_index, params.code_action_params.range);
|
let range = from_proto::text_range(&line_index, params.code_action_params.range);
|
||||||
let frange = FileRange { file_id, range };
|
let frange = FileRange { file_id, range };
|
||||||
|
let only = params
|
||||||
|
.code_action_params
|
||||||
|
.context
|
||||||
|
.only
|
||||||
|
.map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect());
|
||||||
|
|
||||||
let assists = snap.analysis.resolved_assists(&snap.config.assist, frange)?;
|
let assists = snap.analysis.resolved_assists(&snap.config.assist, frange, only)?;
|
||||||
let (id_string, index) = split_delim(¶ms.id, ':').unwrap();
|
let (id_string, index) = split_delim(¶ms.id, ':').unwrap();
|
||||||
let index = index.parse::<usize>().unwrap();
|
let index = index.parse::<usize>().unwrap();
|
||||||
let assist = &assists[index];
|
let assist = &assists[index];
|
||||||
|
|
Loading…
Reference in a new issue