cargo-minimize/src/passes/privatize.rs
moxian 6d4331b16b Allow bisecting privatizer use changes
Currently all the use items have the same AstPath,
which means that privatizer tries to change all of them at once.
Which means that if *any* of them can't get privated, then
*all* of them stay unprivated, with all the consequences..
2025-04-20 15:54:50 +02:00

75 lines
2.1 KiB
Rust

use quote::ToTokens;
use syn::{parse_quote, visit_mut::VisitMut, Visibility};
use crate::processor::{tracking, Pass, PassController, ProcessState, SourceFile};
struct Visitor<'a> {
pub_crate: Visibility,
process_state: ProcessState,
current_path: Vec<String>,
checker: &'a mut PassController,
}
impl<'a> Visitor<'a> {
fn new(checker: &'a mut PassController) -> Self {
Self {
process_state: ProcessState::NoChange,
pub_crate: parse_quote! { pub(crate) },
current_path: Vec::new(),
checker,
}
}
}
impl VisitMut for Visitor<'_> {
fn visit_visibility_mut(&mut self, vis: &mut Visibility) {
if let Visibility::Public(_) = vis {
self.current_path.push("{{vis}}".to_string());
if self.checker.can_process(&self.current_path) {
self.process_state = ProcessState::Changed;
*vis = self.pub_crate.clone();
}
self.current_path.pop();
}
}
fn visit_item_mut(&mut self, item: &mut syn::Item) {
match item {
syn::Item::Use(u) => {
if let Visibility::Public(_) = u.vis {
let mut path = self.current_path.clone();
path.push(u.to_token_stream().to_string());
if self.checker.can_process(&path) {
self.process_state = ProcessState::Changed;
u.vis = self.pub_crate.clone();
}
path.pop();
}
return; // early return; do not walk the child items
}
_ => {}
}
syn::visit_mut::visit_item_mut(self, item);
}
tracking!();
}
#[derive(Default)]
pub struct Privatize {}
impl Pass for Privatize {
fn process_file(
&mut self,
krate: &mut syn::File,
_: &SourceFile,
checker: &mut PassController,
) -> ProcessState {
let mut visitor = Visitor::new(checker);
visitor.visit_file_mut(krate);
visitor.process_state
}
fn name(&self) -> &'static str {
"privatize"
}
}