]> git.lizzy.rs Git - rust.git/blob - crates/rust-analyzer/src/cli/ssr.rs
Replaced fold with for loop
[rust.git] / crates / rust-analyzer / src / cli / ssr.rs
1 //! Applies structured search replace rules from the command line.
2
3 use ide_ssr::MatchFinder;
4 use project_model::CargoConfig;
5
6 use crate::cli::{
7     flags,
8     load_cargo::{load_workspace_at, LoadCargoConfig},
9     Result,
10 };
11
12 impl flags::Ssr {
13     pub fn run(self) -> Result<()> {
14         use ide_db::base_db::SourceDatabaseExt;
15         let cargo_config = CargoConfig::default();
16         let load_cargo_config = LoadCargoConfig {
17             load_out_dirs_from_check: true,
18             with_proc_macro: true,
19             prefill_caches: false,
20         };
21         let (host, vfs, _proc_macro) = load_workspace_at(
22             &std::env::current_dir()?,
23             &cargo_config,
24             &load_cargo_config,
25             &|_| {},
26         )?;
27         let db = host.raw_database();
28         let mut match_finder = MatchFinder::at_first_file(db)?;
29         for rule in self.rule {
30             match_finder.add_rule(rule)?;
31         }
32         let edits = match_finder.edits();
33         for (file_id, edit) in edits {
34             if let Some(path) = vfs.file_path(file_id).as_path() {
35                 let mut contents = db.file_text(file_id).to_string();
36                 edit.apply(&mut contents);
37                 std::fs::write(path, contents)?;
38             }
39         }
40         Ok(())
41     }
42 }
43
44 impl flags::Search {
45     /// Searches for `patterns`, printing debug information for any nodes whose text exactly matches
46     /// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful
47     /// for much else.
48     pub fn run(self) -> Result<()> {
49         use ide_db::base_db::SourceDatabaseExt;
50         use ide_db::symbol_index::SymbolsDatabase;
51         let cargo_config = CargoConfig::default();
52         let load_cargo_config = LoadCargoConfig {
53             load_out_dirs_from_check: true,
54             with_proc_macro: true,
55             prefill_caches: false,
56         };
57         let (host, _vfs, _proc_macro) = load_workspace_at(
58             &std::env::current_dir()?,
59             &cargo_config,
60             &load_cargo_config,
61             &|_| {},
62         )?;
63         let db = host.raw_database();
64         let mut match_finder = MatchFinder::at_first_file(db)?;
65         for pattern in self.pattern {
66             match_finder.add_search_pattern(pattern)?;
67         }
68         if let Some(debug_snippet) = &self.debug {
69             for &root in db.local_roots().iter() {
70                 let sr = db.source_root(root);
71                 for file_id in sr.iter() {
72                     for debug_info in match_finder.debug_where_text_equal(file_id, debug_snippet) {
73                         println!("{:#?}", debug_info);
74                     }
75                 }
76             }
77         } else {
78             for m in match_finder.matches().flattened().matches {
79                 // We could possibly at some point do something more useful than just printing
80                 // the matched text. For now though, that's the easiest thing to do.
81                 println!("{}", m.matched_text());
82             }
83         }
84         Ok(())
85     }
86 }