diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-30 00:33:34 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-30 00:33:34 +0100 |
commit | 2bd717139918e15e537dcd833bb003e85d24b3d1 (patch) | |
tree | b289dd362a6da8124003cd66edf4f8674139f03f /crates | |
parent | 8035b0a27ebfa4a64fbb55eada1df63ac3e54835 (diff) | |
parent | 867f29559f0f49bb19ff4625e4bd59b278474bde (diff) |
Merge #5120
5120: Add a simple SSR subcommand to the rust-analyzer command line binary r=davidlattimore a=davidlattimore
Is adding the dependency on ra_ide_db OK? It's needed for the call to `db.local_roots()`
Co-authored-by: David Lattimore <[email protected]>
Diffstat (limited to 'crates')
-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 |
5 files changed, 71 insertions, 0 deletions
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 53621fb44..803755106 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -45,6 +45,8 @@ ra_toolchain = { path = "../ra_toolchain" } | |||
45 | 45 | ||
46 | # This should only be used in CLI | 46 | # This should only be used in CLI |
47 | ra_db = { path = "../ra_db" } | 47 | ra_db = { path = "../ra_db" } |
48 | ra_ide_db = { path = "../ra_ide_db" } | ||
49 | ra_ssr = { path = "../ra_ssr" } | ||
48 | hir = { path = "../ra_hir", package = "ra_hir" } | 50 | hir = { path = "../ra_hir", package = "ra_hir" } |
49 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | 51 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } |
50 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } | 52 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } |
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 | } | ||