mirror of
https://github.com/Noratrieb/cargo-minimize.git
synced 2026-01-14 16:35:01 +01:00
checker
This commit is contained in:
parent
865d8a7bc9
commit
a36bf95c3e
4 changed files with 106 additions and 53 deletions
|
|
@ -1,18 +1,18 @@
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use syn::{parse_quote, visit_mut::VisitMut};
|
use syn::{parse_quote, visit_mut::VisitMut};
|
||||||
|
|
||||||
use crate::processor::{ProcessChecker, ProcessState, Processor, SourceFile};
|
use crate::processor::{tracking, PassController, ProcessState, Processor, SourceFile};
|
||||||
|
|
||||||
struct Visitor<'a> {
|
struct Visitor<'a> {
|
||||||
current_path: Vec<String>,
|
current_path: Vec<String>,
|
||||||
checker: &'a mut ProcessChecker,
|
checker: &'a mut PassController,
|
||||||
|
|
||||||
loop_expr: syn::Block,
|
loop_expr: syn::Block,
|
||||||
process_state: ProcessState,
|
process_state: ProcessState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Visitor<'a> {
|
impl<'a> Visitor<'a> {
|
||||||
fn new(checker: &'a mut ProcessChecker) -> Self {
|
fn new(checker: &'a mut PassController) -> Self {
|
||||||
Self {
|
Self {
|
||||||
current_path: Vec::new(),
|
current_path: Vec::new(),
|
||||||
checker,
|
checker,
|
||||||
|
|
@ -35,30 +35,7 @@ impl VisitMut for Visitor<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item_fn_mut(&mut self, func: &mut syn::ItemFn) {
|
tracking!();
|
||||||
self.current_path.push(func.sig.ident.to_string());
|
|
||||||
syn::visit_mut::visit_item_fn_mut(self, func);
|
|
||||||
self.current_path.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_impl_item_method_mut(&mut self, method: &mut syn::ImplItemMethod) {
|
|
||||||
self.current_path.push(method.sig.ident.to_string());
|
|
||||||
syn::visit_mut::visit_impl_item_method_mut(self, method);
|
|
||||||
self.current_path.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_item_impl_mut(&mut self, item: &mut syn::ItemImpl) {
|
|
||||||
self.current_path
|
|
||||||
.push(item.self_ty.clone().into_token_stream().to_string());
|
|
||||||
syn::visit_mut::visit_item_impl_mut(self, item);
|
|
||||||
self.current_path.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_item_mod_mut(&mut self, module: &mut syn::ItemMod) {
|
|
||||||
self.current_path.push(module.ident.to_string());
|
|
||||||
syn::visit_mut::visit_item_mod_mut(self, module);
|
|
||||||
self.current_path.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -69,7 +46,7 @@ impl Processor for EverybodyLoops {
|
||||||
&mut self,
|
&mut self,
|
||||||
krate: &mut syn::File,
|
krate: &mut syn::File,
|
||||||
_: &SourceFile,
|
_: &SourceFile,
|
||||||
checker: &mut ProcessChecker,
|
checker: &mut PassController,
|
||||||
) -> ProcessState {
|
) -> ProcessState {
|
||||||
let mut visitor = Visitor::new(checker);
|
let mut visitor = Visitor::new(checker);
|
||||||
visitor.visit_file_mut(krate);
|
visitor.visit_file_mut(krate);
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,50 @@
|
||||||
|
use quote::ToTokens;
|
||||||
use syn::{parse_quote, visit_mut::VisitMut, Visibility};
|
use syn::{parse_quote, visit_mut::VisitMut, Visibility};
|
||||||
|
|
||||||
use crate::processor::{ProcessChecker, ProcessState, Processor, SourceFile};
|
use crate::processor::{tracking, PassController, ProcessState, Processor, SourceFile};
|
||||||
|
|
||||||
struct Visitor {
|
struct Visitor<'a> {
|
||||||
pub_crate: Visibility,
|
pub_crate: Visibility,
|
||||||
process_state: ProcessState,
|
process_state: ProcessState,
|
||||||
|
current_path: Vec<String>,
|
||||||
|
checker: &'a mut PassController,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitor {
|
impl<'a> Visitor<'a> {
|
||||||
fn new() -> Self {
|
fn new(checker: &'a mut PassController) -> Self {
|
||||||
Self {
|
Self {
|
||||||
process_state: ProcessState::NoChange,
|
process_state: ProcessState::NoChange,
|
||||||
pub_crate: parse_quote! { pub(crate) },
|
pub_crate: parse_quote! { pub(crate) },
|
||||||
|
current_path: Vec::new(),
|
||||||
|
checker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VisitMut for Visitor {
|
impl VisitMut for Visitor<'_> {
|
||||||
fn visit_visibility_mut(&mut self, vis: &mut Visibility) {
|
fn visit_visibility_mut(&mut self, vis: &mut Visibility) {
|
||||||
if let Visibility::Public(_) = vis {
|
if let Visibility::Public(_) = vis {
|
||||||
self.process_state = ProcessState::Changed;
|
if self.checker.can_process(&self.current_path) {
|
||||||
*vis = self.pub_crate.clone();
|
self.process_state = ProcessState::Changed;
|
||||||
|
*vis = self.pub_crate.clone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tracking!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Privatize {}
|
pub struct Privatize {}
|
||||||
|
|
||||||
impl Processor for Privatize {
|
impl Processor for Privatize {
|
||||||
fn process_file(&mut self, krate: &mut syn::File, _: &SourceFile, _: &mut ProcessChecker) -> ProcessState {
|
fn process_file(
|
||||||
let mut visitor = Visitor::new();
|
&mut self,
|
||||||
|
krate: &mut syn::File,
|
||||||
|
_: &SourceFile,
|
||||||
|
checker: &mut PassController,
|
||||||
|
) -> ProcessState {
|
||||||
|
let mut visitor = Visitor::new(checker);
|
||||||
visitor.visit_file_mut(krate);
|
visitor.visit_file_mut(krate);
|
||||||
visitor.process_state
|
visitor.process_state
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ pub trait Processor {
|
||||||
&mut self,
|
&mut self,
|
||||||
krate: &mut syn::File,
|
krate: &mut syn::File,
|
||||||
file: &SourceFile,
|
file: &SourceFile,
|
||||||
checker: &mut ProcessChecker,
|
checker: &mut PassController,
|
||||||
) -> ProcessState;
|
) -> ProcessState;
|
||||||
|
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
@ -88,7 +88,7 @@ impl Minimizer {
|
||||||
|
|
||||||
let mut refresh_and_try_again = false;
|
let mut refresh_and_try_again = false;
|
||||||
|
|
||||||
'pass: loop {
|
loop {
|
||||||
println!("Starting a round of {}", pass.name());
|
println!("Starting a round of {}", pass.name());
|
||||||
let mut changes = Changes::default();
|
let mut changes = Changes::default();
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ impl Minimizer {
|
||||||
let mut krate = syn::parse_file(change.before_content())
|
let mut krate = syn::parse_file(change.before_content())
|
||||||
.with_context(|| format!("parsing file {file_display}"))?;
|
.with_context(|| format!("parsing file {file_display}"))?;
|
||||||
|
|
||||||
let has_made_change = pass.process_file(&mut krate, file, &mut ProcessChecker {});
|
let has_made_change = pass.process_file(&mut krate, file, &mut PassController {});
|
||||||
|
|
||||||
match has_made_change {
|
match has_made_change {
|
||||||
ProcessState::Changed | ProcessState::FileInvalidated => {
|
ProcessState::Changed | ProcessState::FileInvalidated => {
|
||||||
|
|
@ -143,20 +143,59 @@ impl Minimizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Finished {}", pass.name());
|
println!("Finished {}", pass.name());
|
||||||
break 'pass;
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
refresh_and_try_again = false;
|
refresh_and_try_again = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ProcessChecker {}
|
pub struct PassController {}
|
||||||
|
|
||||||
impl ProcessChecker {
|
impl PassController {
|
||||||
pub fn can_process(&mut self, _: &[String]) -> bool {
|
pub fn can_process(&mut self, _: &[String]) -> bool {
|
||||||
|
// FIXME: Actually do smart things here.
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! tracking {
|
||||||
|
() => {
|
||||||
|
tracking!(visit_item_fn_mut);
|
||||||
|
tracking!(visit_impl_item_method_mut);
|
||||||
|
tracking!(visit_item_impl_mut);
|
||||||
|
tracking!(visit_item_mod_mut);
|
||||||
|
};
|
||||||
|
(visit_item_fn_mut) => {
|
||||||
|
fn visit_item_fn_mut(&mut self, func: &mut syn::ItemFn) {
|
||||||
|
self.current_path.push(func.sig.ident.to_string());
|
||||||
|
syn::visit_mut::visit_item_fn_mut(self, func);
|
||||||
|
self.current_path.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(visit_impl_item_method_mut) => {
|
||||||
|
fn visit_impl_item_method_mut(&mut self, method: &mut syn::ImplItemMethod) {
|
||||||
|
self.current_path.push(method.sig.ident.to_string());
|
||||||
|
syn::visit_mut::visit_impl_item_method_mut(self, method);
|
||||||
|
self.current_path.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(visit_item_impl_mut) => {
|
||||||
|
fn visit_item_impl_mut(&mut self, item: &mut syn::ItemImpl) {
|
||||||
|
self.current_path
|
||||||
|
.push(item.self_ty.clone().into_token_stream().to_string());
|
||||||
|
syn::visit_mut::visit_item_impl_mut(self, item);
|
||||||
|
self.current_path.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(visit_item_mod_mut) => {
|
||||||
|
fn visit_item_mod_mut(&mut self, module: &mut syn::ItemMod) {
|
||||||
|
self.current_path.push(module.ident.to_string());
|
||||||
|
syn::visit_mut::visit_item_mod_mut(self, module);
|
||||||
|
self.current_path.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use tracking;
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,12 @@
|
||||||
|
|
||||||
use crate::build::Build;
|
use crate::build::Build;
|
||||||
|
|
||||||
use super::{files::Changes, Minimizer, ProcessState, Processor, SourceFile};
|
use super::{
|
||||||
|
files::Changes, tracking, Minimizer, PassController, ProcessState, Processor, SourceFile,
|
||||||
|
};
|
||||||
use anyhow::{ensure, Context, Result};
|
use anyhow::{ensure, Context, Result};
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
|
use quote::ToTokens;
|
||||||
use rustfix::{diagnostics::Diagnostic, Suggestion};
|
use rustfix::{diagnostics::Diagnostic, Suggestion};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
|
|
@ -120,14 +123,14 @@ impl Processor for DeleteUnusedFunctions {
|
||||||
&mut self,
|
&mut self,
|
||||||
krate: &mut syn::File,
|
krate: &mut syn::File,
|
||||||
file: &SourceFile,
|
file: &SourceFile,
|
||||||
_: &mut super::ProcessChecker,
|
checker: &mut super::PassController,
|
||||||
) -> ProcessState {
|
) -> ProcessState {
|
||||||
assert!(
|
assert!(
|
||||||
!self.invalid.contains(file),
|
!self.invalid.contains(file),
|
||||||
"processing with invalid state"
|
"processing with invalid state"
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut visitor = FindUnusedFunction::new(file, self.diags.iter());
|
let mut visitor = FindUnusedFunction::new(file, self.diags.iter(), checker);
|
||||||
visitor.visit_file_mut(krate);
|
visitor.visit_file_mut(krate);
|
||||||
|
|
||||||
if visitor.process_state == ProcessState::FileInvalidated {
|
if visitor.process_state == ProcessState::FileInvalidated {
|
||||||
|
|
@ -161,13 +164,19 @@ impl Unused {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FindUnusedFunction {
|
struct FindUnusedFunction<'a> {
|
||||||
unused_functions: Vec<Unused>,
|
unused_functions: Vec<Unused>,
|
||||||
process_state: ProcessState,
|
process_state: ProcessState,
|
||||||
|
current_path: Vec<String>,
|
||||||
|
checker: &'a mut PassController,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FindUnusedFunction {
|
impl<'a> FindUnusedFunction<'a> {
|
||||||
fn new<'a>(file: &SourceFile, diags: impl Iterator<Item = &'a Diagnostic>) -> Self {
|
fn new<'b>(
|
||||||
|
file: &SourceFile,
|
||||||
|
diags: impl Iterator<Item = &'b Diagnostic>,
|
||||||
|
checker: &'a mut PassController,
|
||||||
|
) -> Self {
|
||||||
let unused_functions = diags
|
let unused_functions = diags
|
||||||
.filter_map(|diag| {
|
.filter_map(|diag| {
|
||||||
// FIXME: use `code` correctly
|
// FIXME: use `code` correctly
|
||||||
|
|
@ -204,6 +213,8 @@ impl FindUnusedFunction {
|
||||||
Self {
|
Self {
|
||||||
unused_functions,
|
unused_functions,
|
||||||
process_state: ProcessState::NoChange,
|
process_state: ProcessState::NoChange,
|
||||||
|
current_path: Vec::new(),
|
||||||
|
checker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,12 +235,15 @@ impl FindUnusedFunction {
|
||||||
self.process_state = ProcessState::FileInvalidated;
|
self.process_state = ProcessState::FileInvalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
span_matches == 0
|
span_matches == 0 && self.checker.can_process(&self.current_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VisitMut for FindUnusedFunction {
|
impl VisitMut for FindUnusedFunction<'_> {
|
||||||
fn visit_item_impl_mut(&mut self, item_impl: &mut syn::ItemImpl) {
|
fn visit_item_impl_mut(&mut self, item_impl: &mut syn::ItemImpl) {
|
||||||
|
self.current_path
|
||||||
|
.push(item_impl.self_ty.clone().into_token_stream().to_string());
|
||||||
|
|
||||||
item_impl.items.retain(|item| match item {
|
item_impl.items.retain(|item| match item {
|
||||||
ImplItem::Method(method) => {
|
ImplItem::Method(method) => {
|
||||||
let span = method.sig.ident.span();
|
let span = method.sig.ident.span();
|
||||||
|
|
@ -240,6 +254,8 @@ impl VisitMut for FindUnusedFunction {
|
||||||
});
|
});
|
||||||
|
|
||||||
syn::visit_mut::visit_item_impl_mut(self, item_impl);
|
syn::visit_mut::visit_item_impl_mut(self, item_impl);
|
||||||
|
|
||||||
|
self.current_path.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_file_mut(&mut self, krate: &mut syn::File) {
|
fn visit_file_mut(&mut self, krate: &mut syn::File) {
|
||||||
|
|
@ -256,6 +272,8 @@ impl VisitMut for FindUnusedFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item_mod_mut(&mut self, module: &mut syn::ItemMod) {
|
fn visit_item_mod_mut(&mut self, module: &mut syn::ItemMod) {
|
||||||
|
self.current_path.push(module.ident.to_string());
|
||||||
|
|
||||||
if let Some((_, content)) = &mut module.content {
|
if let Some((_, content)) = &mut module.content {
|
||||||
content.retain(|item| match item {
|
content.retain(|item| match item {
|
||||||
Item::Fn(func) => {
|
Item::Fn(func) => {
|
||||||
|
|
@ -268,5 +286,10 @@ impl VisitMut for FindUnusedFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
syn::visit_mut::visit_item_mod_mut(self, module);
|
syn::visit_mut::visit_item_mod_mut(self, module);
|
||||||
|
|
||||||
|
self.current_path.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tracking!(visit_item_fn_mut);
|
||||||
|
tracking!(visit_impl_item_method_mut);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue