2021-03-08 23:11:28 -06:00
|
|
|
//! This module provides an SSR assist. It is not desirable to include this
|
|
|
|
//! assist in ide_assists because that would require the ide_assists crate
|
|
|
|
//! depend on the ide_ssr crate.
|
|
|
|
|
2021-05-03 09:08:09 -05:00
|
|
|
use ide_assists::{Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel};
|
2021-03-08 23:11:28 -06:00
|
|
|
use ide_db::{base_db::FileRange, label::Label, source_change::SourceChange, RootDatabase};
|
|
|
|
|
2021-05-03 09:08:09 -05:00
|
|
|
pub(crate) fn ssr_assists(
|
2021-03-08 23:11:28 -06:00
|
|
|
db: &RootDatabase,
|
2021-05-03 10:03:28 -05:00
|
|
|
resolve: &AssistResolveStrategy,
|
2021-03-08 23:11:28 -06:00
|
|
|
frange: FileRange,
|
2021-05-03 09:08:09 -05:00
|
|
|
) -> Vec<Assist> {
|
|
|
|
let mut ssr_assists = Vec::with_capacity(2);
|
2021-03-08 23:11:28 -06:00
|
|
|
|
2021-05-03 09:08:09 -05:00
|
|
|
let (match_finder, comment_range) = match ide_ssr::ssr_from_comment(db, frange) {
|
2021-05-03 10:44:58 -05:00
|
|
|
Some(ssr_data) => ssr_data,
|
2021-05-03 09:08:09 -05:00
|
|
|
None => return ssr_assists,
|
|
|
|
};
|
|
|
|
let id = AssistId("ssr", AssistKind::RefactorRewrite);
|
|
|
|
|
|
|
|
let (source_change_for_file, source_change_for_workspace) = if resolve.should_resolve(&id) {
|
2021-03-08 23:11:28 -06:00
|
|
|
let edits = match_finder.edits();
|
|
|
|
|
|
|
|
let source_change_for_file = {
|
|
|
|
let text_edit_for_file = edits.get(&frange.file_id).cloned().unwrap_or_default();
|
|
|
|
SourceChange::from_text_edit(frange.file_id, text_edit_for_file)
|
|
|
|
};
|
|
|
|
|
|
|
|
let source_change_for_workspace = SourceChange::from(match_finder.edits());
|
|
|
|
|
|
|
|
(Some(source_change_for_file), Some(source_change_for_workspace))
|
|
|
|
} else {
|
|
|
|
(None, None)
|
|
|
|
};
|
|
|
|
|
|
|
|
let assists = vec![
|
|
|
|
("Apply SSR in file", source_change_for_file),
|
|
|
|
("Apply SSR in workspace", source_change_for_workspace),
|
|
|
|
];
|
|
|
|
|
|
|
|
for (label, source_change) in assists.into_iter() {
|
|
|
|
let assist = Assist {
|
2021-05-03 09:08:09 -05:00
|
|
|
id,
|
2021-08-29 04:31:42 -05:00
|
|
|
label: Label::new(label.to_string()),
|
2021-03-08 23:11:28 -06:00
|
|
|
group: Some(GroupLabel("Apply SSR".into())),
|
|
|
|
target: comment_range,
|
|
|
|
source_change,
|
|
|
|
};
|
|
|
|
|
2021-05-03 09:08:09 -05:00
|
|
|
ssr_assists.push(assist);
|
2021-03-08 23:11:28 -06:00
|
|
|
}
|
2021-05-03 09:08:09 -05:00
|
|
|
|
|
|
|
ssr_assists
|
2021-03-08 23:11:28 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
use expect_test::expect;
|
2021-05-03 09:08:09 -05:00
|
|
|
use ide_assists::{Assist, AssistResolveStrategy};
|
2021-03-08 23:11:28 -06:00
|
|
|
use ide_db::{
|
|
|
|
base_db::{fixture::WithFixture, salsa::Durability, FileRange},
|
|
|
|
symbol_index::SymbolsDatabase,
|
|
|
|
RootDatabase,
|
|
|
|
};
|
|
|
|
use rustc_hash::FxHashSet;
|
|
|
|
|
2021-05-03 09:08:09 -05:00
|
|
|
use super::ssr_assists;
|
2021-03-08 23:11:28 -06:00
|
|
|
|
2021-05-03 09:08:09 -05:00
|
|
|
fn get_assists(ra_fixture: &str, resolve: AssistResolveStrategy) -> Vec<Assist> {
|
2021-03-08 23:11:28 -06:00
|
|
|
let (mut db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture);
|
|
|
|
let mut local_roots = FxHashSet::default();
|
|
|
|
local_roots.insert(ide_db::base_db::fixture::WORKSPACE);
|
|
|
|
db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
|
2021-05-03 10:03:28 -05:00
|
|
|
ssr_assists(&db, &resolve, FileRange { file_id, range: range_or_offset.into() })
|
2021-03-08 23:11:28 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn not_applicable_comment_not_ssr() {
|
|
|
|
let ra_fixture = r#"
|
|
|
|
//- /lib.rs
|
|
|
|
|
|
|
|
// This is foo $0
|
|
|
|
fn foo() {}
|
|
|
|
"#;
|
2021-05-03 09:08:09 -05:00
|
|
|
let assists = get_assists(ra_fixture, AssistResolveStrategy::All);
|
2021-03-08 23:11:28 -06:00
|
|
|
|
|
|
|
assert_eq!(0, assists.len());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn resolve_edits_true() {
|
|
|
|
let assists = get_assists(
|
|
|
|
r#"
|
|
|
|
//- /lib.rs
|
|
|
|
mod bar;
|
|
|
|
|
|
|
|
// 2 ==>> 3$0
|
|
|
|
fn foo() { 2 }
|
|
|
|
|
|
|
|
//- /bar.rs
|
|
|
|
fn bar() { 2 }
|
|
|
|
"#,
|
2021-05-03 09:08:09 -05:00
|
|
|
AssistResolveStrategy::All,
|
2021-03-08 23:11:28 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(2, assists.len());
|
|
|
|
let mut assists = assists.into_iter();
|
|
|
|
|
|
|
|
let apply_in_file_assist = assists.next().unwrap();
|
|
|
|
expect![[r#"
|
|
|
|
Assist {
|
|
|
|
id: AssistId(
|
|
|
|
"ssr",
|
|
|
|
RefactorRewrite,
|
|
|
|
),
|
|
|
|
label: "Apply SSR in file",
|
|
|
|
group: Some(
|
|
|
|
GroupLabel(
|
|
|
|
"Apply SSR",
|
|
|
|
),
|
|
|
|
),
|
|
|
|
target: 10..21,
|
|
|
|
source_change: Some(
|
|
|
|
SourceChange {
|
|
|
|
source_file_edits: {
|
|
|
|
FileId(
|
|
|
|
0,
|
|
|
|
): TextEdit {
|
|
|
|
indels: [
|
|
|
|
Indel {
|
|
|
|
insert: "3",
|
|
|
|
delete: 33..34,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
file_system_edits: [],
|
|
|
|
is_snippet: false,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
}
|
|
|
|
"#]]
|
|
|
|
.assert_debug_eq(&apply_in_file_assist);
|
|
|
|
|
|
|
|
let apply_in_workspace_assist = assists.next().unwrap();
|
|
|
|
expect![[r#"
|
|
|
|
Assist {
|
|
|
|
id: AssistId(
|
|
|
|
"ssr",
|
|
|
|
RefactorRewrite,
|
|
|
|
),
|
|
|
|
label: "Apply SSR in workspace",
|
|
|
|
group: Some(
|
|
|
|
GroupLabel(
|
|
|
|
"Apply SSR",
|
|
|
|
),
|
|
|
|
),
|
|
|
|
target: 10..21,
|
|
|
|
source_change: Some(
|
|
|
|
SourceChange {
|
|
|
|
source_file_edits: {
|
|
|
|
FileId(
|
|
|
|
0,
|
|
|
|
): TextEdit {
|
|
|
|
indels: [
|
|
|
|
Indel {
|
|
|
|
insert: "3",
|
|
|
|
delete: 33..34,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
FileId(
|
|
|
|
1,
|
|
|
|
): TextEdit {
|
|
|
|
indels: [
|
|
|
|
Indel {
|
|
|
|
insert: "3",
|
|
|
|
delete: 11..12,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
file_system_edits: [],
|
|
|
|
is_snippet: false,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
}
|
|
|
|
"#]]
|
|
|
|
.assert_debug_eq(&apply_in_workspace_assist);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn resolve_edits_false() {
|
|
|
|
let assists = get_assists(
|
|
|
|
r#"
|
|
|
|
//- /lib.rs
|
|
|
|
mod bar;
|
|
|
|
|
|
|
|
// 2 ==>> 3$0
|
|
|
|
fn foo() { 2 }
|
|
|
|
|
|
|
|
//- /bar.rs
|
|
|
|
fn bar() { 2 }
|
|
|
|
"#,
|
2021-05-03 09:08:09 -05:00
|
|
|
AssistResolveStrategy::None,
|
2021-03-08 23:11:28 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(2, assists.len());
|
|
|
|
let mut assists = assists.into_iter();
|
|
|
|
|
|
|
|
let apply_in_file_assist = assists.next().unwrap();
|
|
|
|
expect![[r#"
|
|
|
|
Assist {
|
|
|
|
id: AssistId(
|
|
|
|
"ssr",
|
|
|
|
RefactorRewrite,
|
|
|
|
),
|
|
|
|
label: "Apply SSR in file",
|
|
|
|
group: Some(
|
|
|
|
GroupLabel(
|
|
|
|
"Apply SSR",
|
|
|
|
),
|
|
|
|
),
|
|
|
|
target: 10..21,
|
|
|
|
source_change: None,
|
|
|
|
}
|
|
|
|
"#]]
|
|
|
|
.assert_debug_eq(&apply_in_file_assist);
|
|
|
|
|
|
|
|
let apply_in_workspace_assist = assists.next().unwrap();
|
|
|
|
expect![[r#"
|
|
|
|
Assist {
|
|
|
|
id: AssistId(
|
|
|
|
"ssr",
|
|
|
|
RefactorRewrite,
|
|
|
|
),
|
|
|
|
label: "Apply SSR in workspace",
|
|
|
|
group: Some(
|
|
|
|
GroupLabel(
|
|
|
|
"Apply SSR",
|
|
|
|
),
|
|
|
|
),
|
|
|
|
target: 10..21,
|
|
|
|
source_change: None,
|
|
|
|
}
|
|
|
|
"#]]
|
|
|
|
.assert_debug_eq(&apply_in_workspace_assist);
|
|
|
|
}
|
|
|
|
}
|