From cda850d59375a2b0b89c52f88a025a7eea839411 Mon Sep 17 00:00:00 2001 From: Alex Povel Date: Mon, 18 Dec 2023 20:55:57 +0100 Subject: [PATCH] feat: Scope names in uses-declarations (Rust) --- README.md | 35 ++++++++++++++++++++++++++++++++++- src/scoping/langs/rust.rs | 17 +++++++++++++++++ tests/langs/rust/in/uses.rs | 22 ++++++++++++++++++++++ tests/langs/rust/mod.rs | 1 + tests/langs/rust/out/uses.rs | 22 ++++++++++++++++++++++ 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 tests/langs/rust/in/uses.rs create mode 100644 tests/langs/rust/out/uses.rs diff --git a/README.md b/README.md index 88a76713..1246b3ac 100644 --- a/README.md +++ b/README.md @@ -520,7 +520,7 @@ language such as `python`. See [below](#custom-queries) for more on this advance This section shows examples for some of the **premade queries**. -###### Mass import (module) renaming (Python) +###### Mass import (module) renaming (Python, Rust) As part of a large refactor (say, after an acquisition), imagine all imports of a specific package needed renaming: @@ -562,6 +562,39 @@ good_company = "good_company" # good_company Note how the last line remains untouched by this particular operation. To run across many files, see [the `files` option](#run-against-multiple-files). +Similar import-related edits are supported for other languages as well, for example +Rust: + +```rust imports.rs +use std::collections::HashMap; + +use good_company::infra; +use good_company::aws::auth as aws_auth; +use good_company::util::iter::dedupe; +use good_company::shopping::cart::*; + +good_company = "good_company"; // good_company +``` + +which, using + +```bash +cat imports.rs | srgn --rust 'uses' '^good_company' 'better_company' +``` + +becomes + +```rust output-imports.rs +use std::collections::HashMap; + +use better_company::infra; +use better_company::aws::auth as aws_auth; +use better_company::util::iter::dedupe; +use better_company::shopping::cart::*; + +good_company = "good_company"; // good_company +``` + ###### Assigning `TODO`s (TypeScript) Perhaps you're using a system of `TODO` notes in comments: diff --git a/src/scoping/langs/rust.rs b/src/scoping/langs/rust.rs index ae05e6b8..fe4eaab8 100644 --- a/src/scoping/langs/rust.rs +++ b/src/scoping/langs/rust.rs @@ -16,6 +16,8 @@ pub enum PremadeRustQuery { Comments, /// Doc comments (comment chars included). DocComments, + /// Use statements (paths only; excl. `use`/`as`/`*`). + Uses, /// Strings (regular, raw, byte; includes interpolation parts in format strings!). /// /// There is currently no support for an 'interpolation' type node in @@ -46,6 +48,21 @@ impl From for TSQuery { ) "# } + PremadeRustQuery::Uses => { + r#" + (scoped_identifier + path: [ + (scoped_identifier) + (identifier) + ] @use) + (scoped_use_list + path: [ + (scoped_identifier) + (identifier) + ] @use) + (use_wildcard (scoped_identifier) @use) + "# + } PremadeRustQuery::Strings => { r#" [ diff --git a/tests/langs/rust/in/uses.rs b/tests/langs/rust/in/uses.rs new file mode 100644 index 00000000..fb58cbd2 --- /dev/null +++ b/tests/langs/rust/in/uses.rs @@ -0,0 +1,22 @@ +#[rustfmt::skip] // `ignore` in `rustfmt.toml` is nightly-only +mod uses { + use super::mo__T__re::ParentModu__T__le; + use super::ParentModule; + use crate::mo__T__re::SiblingModule; + use crate::SiblingModule; + use std__T__::more::{cmp::Ordering, io}; + use std::collec__T__tions::mo__T__re::stuff::HashMap; + use std::collections__T__::HashMap; + use std::f__T__s::read_to_stri__T__ng; + use std::i__T__o::Re__T__sult as IoRes__T__ult; + pub use std::i__T__o::Result; + #[cfg(target_os = "linux")] + use std::os::__T__linux::fs::MetadataExt; + use std::other::collectio__T__ns::*; + use std::{cmp__T__::Ordering, io}; + use std::{io, more::__T__cmp::Ordering}; + use std::{ + io__T__::{Write, __T__self}, + net__T__, + }; +} diff --git a/tests/langs/rust/mod.rs b/tests/langs/rust/mod.rs index 1cf52944..1d3fc862 100644 --- a/tests/langs/rust/mod.rs +++ b/tests/langs/rust/mod.rs @@ -6,6 +6,7 @@ use super::{get_input_output, nuke_target}; #[rstest] #[case("comments.rs", RustQuery::Premade(PremadeRustQuery::Comments))] #[case("doc-comments.rs", RustQuery::Premade(PremadeRustQuery::DocComments))] +#[case("uses.rs", RustQuery::Premade(PremadeRustQuery::Uses))] #[case("strings.rs", RustQuery::Premade(PremadeRustQuery::Strings))] fn test_rust_nuke(#[case] file: &str, #[case] query: RustQuery) { let lang = Rust::new(query); diff --git a/tests/langs/rust/out/uses.rs b/tests/langs/rust/out/uses.rs new file mode 100644 index 00000000..6682bf61 --- /dev/null +++ b/tests/langs/rust/out/uses.rs @@ -0,0 +1,22 @@ +#[rustfmt::skip] // `ignore` in `rustfmt.toml` is nightly-only +mod uses { + use super::more::ParentModu__T__le; + use super::ParentModule; + use crate::more::SiblingModule; + use crate::SiblingModule; + use std::more::{cmp::Ordering, io}; + use std::collections::more::stuff::HashMap; + use std::collections::HashMap; + use std::fs::read_to_stri__T__ng; + use std::io::Re__T__sult as IoRes__T__ult; + pub use std::io::Result; + #[cfg(target_os = "linux")] + use std::os::linux::fs::MetadataExt; + use std::other::collections::*; + use std::{cmp::Ordering, io}; + use std::{io, more::cmp::Ordering}; + use std::{ + io::{Write, __T__self}, + net__T__, + }; +}