mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Add a simple SSR subcommand to the rust-analyzer command line binary
This commit is contained in:
parent
ca31b1d63a
commit
93a91ae9de
6 changed files with 73 additions and 0 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1464,10 +1464,12 @@ dependencies = [
|
|||
"ra_hir_def",
|
||||
"ra_hir_ty",
|
||||
"ra_ide",
|
||||
"ra_ide_db",
|
||||
"ra_mbe",
|
||||
"ra_proc_macro_srv",
|
||||
"ra_prof",
|
||||
"ra_project_model",
|
||||
"ra_ssr",
|
||||
"ra_syntax",
|
||||
"ra_text_edit",
|
||||
"ra_toolchain",
|
||||
|
|
|
@ -34,8 +34,10 @@ stdx = { path = "../stdx" }
|
|||
lsp-server = "0.3.3"
|
||||
flycheck = { path = "../flycheck" }
|
||||
ra_ide = { path = "../ra_ide" }
|
||||
ra_ide_db = { path = "../ra_ide_db" }
|
||||
ra_prof = { path = "../ra_prof" }
|
||||
ra_project_model = { path = "../ra_project_model" }
|
||||
ra_ssr = { path = "../ra_ssr" }
|
||||
ra_syntax = { path = "../ra_syntax" }
|
||||
ra_text_edit = { path = "../ra_text_edit" }
|
||||
vfs = { path = "../vfs" }
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
use anyhow::{bail, Result};
|
||||
use pico_args::Arguments;
|
||||
use ra_ssr::SsrRule;
|
||||
use rust_analyzer::cli::{BenchWhat, Position, Verbosity};
|
||||
|
||||
use std::{fmt::Write, path::PathBuf};
|
||||
|
@ -45,6 +46,9 @@ pub(crate) enum Command {
|
|||
/// this would include the parser test files.
|
||||
all: bool,
|
||||
},
|
||||
Ssr {
|
||||
rules: Vec<SsrRule>,
|
||||
},
|
||||
ProcMacro,
|
||||
RunServer,
|
||||
Version,
|
||||
|
@ -270,6 +274,32 @@ ARGS:
|
|||
Command::Diagnostics { path, load_output_dirs, with_proc_macro, all }
|
||||
}
|
||||
"proc-macro" => Command::ProcMacro,
|
||||
"ssr" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
rust-analyzer ssr
|
||||
|
||||
USAGE:
|
||||
rust-analyzer ssr [FLAGS] [RULE...]
|
||||
|
||||
EXAMPLE:
|
||||
rust-analyzer ssr '$a.foo($b) ==> bar($a, $b)'
|
||||
|
||||
FLAGS:
|
||||
-h, --help Prints help information
|
||||
|
||||
ARGS:
|
||||
<RULE> A structured search replace rule"
|
||||
);
|
||||
return Ok(Err(HelpPrinted));
|
||||
}
|
||||
let mut rules = Vec::new();
|
||||
while let Some(rule) = matches.free_from_str()? {
|
||||
rules.push(rule);
|
||||
}
|
||||
Command::Ssr { rules }
|
||||
}
|
||||
_ => {
|
||||
print_subcommands();
|
||||
return Ok(Err(HelpPrinted));
|
||||
|
@ -297,6 +327,7 @@ SUBCOMMANDS:
|
|||
diagnostics
|
||||
proc-macro
|
||||
parse
|
||||
ssr
|
||||
symbols"
|
||||
)
|
||||
}
|
||||
|
|
|
@ -60,6 +60,9 @@ fn main() -> Result<()> {
|
|||
args::Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } => {
|
||||
cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)?
|
||||
}
|
||||
args::Command::Ssr { rules } => {
|
||||
cli::apply_ssr_rules(rules)?;
|
||||
}
|
||||
args::Command::Version => println!("rust-analyzer {}", env!("REV")),
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -5,6 +5,7 @@ mod analysis_stats;
|
|||
mod analysis_bench;
|
||||
mod diagnostics;
|
||||
mod progress_report;
|
||||
mod ssr;
|
||||
|
||||
use std::io::Read;
|
||||
|
||||
|
@ -17,6 +18,7 @@ pub use analysis_bench::{analysis_bench, BenchWhat, Position};
|
|||
pub use analysis_stats::analysis_stats;
|
||||
pub use diagnostics::diagnostics;
|
||||
pub use load_cargo::load_cargo;
|
||||
pub use ssr::apply_ssr_rules;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Verbosity {
|
||||
|
|
33
crates/rust-analyzer/src/cli/ssr.rs
Normal file
33
crates/rust-analyzer/src/cli/ssr.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
//! Applies structured search replace rules from the command line.
|
||||
|
||||
use crate::cli::{load_cargo::load_cargo, Result};
|
||||
use ra_ide::SourceFileEdit;
|
||||
use ra_ssr::{MatchFinder, SsrRule};
|
||||
|
||||
pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
|
||||
use ra_db::SourceDatabaseExt;
|
||||
use ra_ide_db::symbol_index::SymbolsDatabase;
|
||||
let (host, vfs) = load_cargo(&std::env::current_dir()?, true, true)?;
|
||||
let db = host.raw_database();
|
||||
let mut match_finder = MatchFinder::new(db);
|
||||
for rule in rules {
|
||||
match_finder.add_rule(rule);
|
||||
}
|
||||
let mut edits = Vec::new();
|
||||
for &root in db.local_roots().iter() {
|
||||
let sr = db.source_root(root);
|
||||
for file_id in sr.iter() {
|
||||
if let Some(edit) = match_finder.edits_for_file(file_id) {
|
||||
edits.push(SourceFileEdit { file_id, edit });
|
||||
}
|
||||
}
|
||||
}
|
||||
for edit in edits {
|
||||
if let Some(path) = vfs.file_path(edit.file_id).as_path() {
|
||||
let mut contents = db.file_text(edit.file_id).to_string();
|
||||
edit.edit.apply(&mut contents);
|
||||
std::fs::write(path, contents)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in a new issue