diff options
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/bin/args.rs | 31 | ||||
-rw-r--r-- | crates/rust-analyzer/src/bin/main.rs | 3 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/ssr.rs | 33 |
6 files changed, 73 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock index b19d697f5..cf0479f0b 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1464,10 +1464,12 @@ dependencies = [ | |||
1464 | "ra_hir_def", | 1464 | "ra_hir_def", |
1465 | "ra_hir_ty", | 1465 | "ra_hir_ty", |
1466 | "ra_ide", | 1466 | "ra_ide", |
1467 | "ra_ide_db", | ||
1467 | "ra_mbe", | 1468 | "ra_mbe", |
1468 | "ra_proc_macro_srv", | 1469 | "ra_proc_macro_srv", |
1469 | "ra_prof", | 1470 | "ra_prof", |
1470 | "ra_project_model", | 1471 | "ra_project_model", |
1472 | "ra_ssr", | ||
1471 | "ra_syntax", | 1473 | "ra_syntax", |
1472 | "ra_text_edit", | 1474 | "ra_text_edit", |
1473 | "ra_toolchain", | 1475 | "ra_toolchain", |
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 53621fb44..97d9bf5d4 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -34,8 +34,10 @@ stdx = { path = "../stdx" } | |||
34 | lsp-server = "0.3.3" | 34 | lsp-server = "0.3.3" |
35 | flycheck = { path = "../flycheck" } | 35 | flycheck = { path = "../flycheck" } |
36 | ra_ide = { path = "../ra_ide" } | 36 | ra_ide = { path = "../ra_ide" } |
37 | ra_ide_db = { path = "../ra_ide_db" } | ||
37 | ra_prof = { path = "../ra_prof" } | 38 | ra_prof = { path = "../ra_prof" } |
38 | ra_project_model = { path = "../ra_project_model" } | 39 | ra_project_model = { path = "../ra_project_model" } |
40 | ra_ssr = { path = "../ra_ssr" } | ||
39 | ra_syntax = { path = "../ra_syntax" } | 41 | ra_syntax = { path = "../ra_syntax" } |
40 | ra_text_edit = { path = "../ra_text_edit" } | 42 | ra_text_edit = { path = "../ra_text_edit" } |
41 | vfs = { path = "../vfs" } | 43 | vfs = { path = "../vfs" } |
diff --git a/crates/rust-analyzer/src/bin/args.rs b/crates/rust-analyzer/src/bin/args.rs index 8e3ca9343..3f0bb3865 100644 --- a/crates/rust-analyzer/src/bin/args.rs +++ b/crates/rust-analyzer/src/bin/args.rs | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | use anyhow::{bail, Result}; | 6 | use anyhow::{bail, Result}; |
7 | use pico_args::Arguments; | 7 | use pico_args::Arguments; |
8 | use ra_ssr::SsrRule; | ||
8 | use rust_analyzer::cli::{BenchWhat, Position, Verbosity}; | 9 | use rust_analyzer::cli::{BenchWhat, Position, Verbosity}; |
9 | 10 | ||
10 | use std::{fmt::Write, path::PathBuf}; | 11 | use std::{fmt::Write, path::PathBuf}; |
@@ -45,6 +46,9 @@ pub(crate) enum Command { | |||
45 | /// this would include the parser test files. | 46 | /// this would include the parser test files. |
46 | all: bool, | 47 | all: bool, |
47 | }, | 48 | }, |
49 | Ssr { | ||
50 | rules: Vec<SsrRule>, | ||
51 | }, | ||
48 | ProcMacro, | 52 | ProcMacro, |
49 | RunServer, | 53 | RunServer, |
50 | Version, | 54 | Version, |
@@ -270,6 +274,32 @@ ARGS: | |||
270 | Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } | 274 | Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } |
271 | } | 275 | } |
272 | "proc-macro" => Command::ProcMacro, | 276 | "proc-macro" => Command::ProcMacro, |
277 | "ssr" => { | ||
278 | if matches.contains(["-h", "--help"]) { | ||
279 | eprintln!( | ||
280 | "\ | ||
281 | rust-analyzer ssr | ||
282 | |||
283 | USAGE: | ||
284 | rust-analyzer ssr [FLAGS] [RULE...] | ||
285 | |||
286 | EXAMPLE: | ||
287 | rust-analyzer ssr '$a.foo($b) ==> bar($a, $b)' | ||
288 | |||
289 | FLAGS: | ||
290 | -h, --help Prints help information | ||
291 | |||
292 | ARGS: | ||
293 | <RULE> A structured search replace rule" | ||
294 | ); | ||
295 | return Ok(Err(HelpPrinted)); | ||
296 | } | ||
297 | let mut rules = Vec::new(); | ||
298 | while let Some(rule) = matches.free_from_str()? { | ||
299 | rules.push(rule); | ||
300 | } | ||
301 | Command::Ssr { rules } | ||
302 | } | ||
273 | _ => { | 303 | _ => { |
274 | print_subcommands(); | 304 | print_subcommands(); |
275 | return Ok(Err(HelpPrinted)); | 305 | return Ok(Err(HelpPrinted)); |
@@ -297,6 +327,7 @@ SUBCOMMANDS: | |||
297 | diagnostics | 327 | diagnostics |
298 | proc-macro | 328 | proc-macro |
299 | parse | 329 | parse |
330 | ssr | ||
300 | symbols" | 331 | symbols" |
301 | ) | 332 | ) |
302 | } | 333 | } |
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 45204d1a3..16882fc13 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs | |||
@@ -60,6 +60,9 @@ fn main() -> Result<()> { | |||
60 | args::Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } => { | 60 | args::Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } => { |
61 | cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)? | 61 | cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)? |
62 | } | 62 | } |
63 | args::Command::Ssr { rules } => { | ||
64 | cli::apply_ssr_rules(rules)?; | ||
65 | } | ||
63 | args::Command::Version => println!("rust-analyzer {}", env!("REV")), | 66 | args::Command::Version => println!("rust-analyzer {}", env!("REV")), |
64 | } | 67 | } |
65 | Ok(()) | 68 | Ok(()) |
diff --git a/crates/rust-analyzer/src/cli.rs b/crates/rust-analyzer/src/cli.rs index c5faec83a..13e3d75be 100644 --- a/crates/rust-analyzer/src/cli.rs +++ b/crates/rust-analyzer/src/cli.rs | |||
@@ -5,6 +5,7 @@ mod analysis_stats; | |||
5 | mod analysis_bench; | 5 | mod analysis_bench; |
6 | mod diagnostics; | 6 | mod diagnostics; |
7 | mod progress_report; | 7 | mod progress_report; |
8 | mod ssr; | ||
8 | 9 | ||
9 | use std::io::Read; | 10 | use std::io::Read; |
10 | 11 | ||
@@ -17,6 +18,7 @@ pub use analysis_bench::{analysis_bench, BenchWhat, Position}; | |||
17 | pub use analysis_stats::analysis_stats; | 18 | pub use analysis_stats::analysis_stats; |
18 | pub use diagnostics::diagnostics; | 19 | pub use diagnostics::diagnostics; |
19 | pub use load_cargo::load_cargo; | 20 | pub use load_cargo::load_cargo; |
21 | pub use ssr::apply_ssr_rules; | ||
20 | 22 | ||
21 | #[derive(Clone, Copy)] | 23 | #[derive(Clone, Copy)] |
22 | pub enum Verbosity { | 24 | pub enum Verbosity { |
diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs new file mode 100644 index 000000000..a5265ac15 --- /dev/null +++ b/crates/rust-analyzer/src/cli/ssr.rs | |||
@@ -0,0 +1,33 @@ | |||
1 | //! Applies structured search replace rules from the command line. | ||
2 | |||
3 | use crate::cli::{load_cargo::load_cargo, Result}; | ||
4 | use ra_ide::SourceFileEdit; | ||
5 | use ra_ssr::{MatchFinder, SsrRule}; | ||
6 | |||
7 | pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> { | ||
8 | use ra_db::SourceDatabaseExt; | ||
9 | use ra_ide_db::symbol_index::SymbolsDatabase; | ||
10 | let (host, vfs) = load_cargo(&std::env::current_dir()?, true, true)?; | ||
11 | let db = host.raw_database(); | ||
12 | let mut match_finder = MatchFinder::new(db); | ||
13 | for rule in rules { | ||
14 | match_finder.add_rule(rule); | ||
15 | } | ||
16 | let mut edits = Vec::new(); | ||
17 | for &root in db.local_roots().iter() { | ||
18 | let sr = db.source_root(root); | ||
19 | for file_id in sr.iter() { | ||
20 | if let Some(edit) = match_finder.edits_for_file(file_id) { | ||
21 | edits.push(SourceFileEdit { file_id, edit }); | ||
22 | } | ||
23 | } | ||
24 | } | ||
25 | for edit in edits { | ||
26 | if let Some(path) = vfs.file_path(edit.file_id).as_path() { | ||
27 | let mut contents = db.file_text(edit.file_id).to_string(); | ||
28 | edit.edit.apply(&mut contents); | ||
29 | std::fs::write(path, contents)?; | ||
30 | } | ||
31 | } | ||
32 | Ok(()) | ||
33 | } | ||