make things cool and good and wow

This commit is contained in:
nora 2022-12-17 18:18:21 +01:00
parent 958383f991
commit d9f3f347e9
8 changed files with 486 additions and 41 deletions

232
Cargo.lock generated
View file

@ -35,7 +35,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi 0.1.19",
"libc", "libc",
"winapi", "winapi",
] ]
@ -95,7 +95,7 @@ dependencies = [
"bytesize", "bytesize",
"cargo-platform", "cargo-platform",
"cargo-util", "cargo-util",
"clap", "clap 3.2.22",
"crates-io", "crates-io",
"crossbeam-utils", "crossbeam-utils",
"curl", "curl",
@ -151,10 +151,12 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cargo", "cargo",
"clap 4.0.29",
"prettyplease", "prettyplease",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
"walkdir",
] ]
[[package]] [[package]]
@ -211,13 +213,41 @@ checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
dependencies = [ dependencies = [
"atty", "atty",
"bitflags", "bitflags",
"clap_lex", "clap_lex 0.2.4",
"indexmap", "indexmap",
"strsim", "strsim",
"termcolor", "termcolor",
"textwrap", "textwrap",
] ]
[[package]]
name = "clap"
version = "4.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d"
dependencies = [
"bitflags",
"clap_derive",
"clap_lex 0.3.0",
"is-terminal",
"once_cell",
"strsim",
"termcolor",
]
[[package]]
name = "clap_derive"
version = "4.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.2.4" version = "0.2.4"
@ -227,6 +257,15 @@ dependencies = [
"os_str_bytes", "os_str_bytes",
] ]
[[package]]
name = "clap_lex"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
[[package]] [[package]]
name = "combine" name = "combine"
version = "4.6.6" version = "4.6.6"
@ -365,6 +404,27 @@ dependencies = [
"termcolor", "termcolor",
] ]
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "1.8.0" version = "1.8.0"
@ -383,7 +443,7 @@ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall", "redox_syscall",
"windows-sys", "windows-sys 0.36.1",
] ]
[[package]] [[package]]
@ -489,6 +549,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.19" version = "0.1.19"
@ -498,6 +564,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "hex" name = "hex"
version = "0.3.2" version = "0.3.2"
@ -586,6 +661,28 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "io-lifetimes"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
dependencies = [
"libc",
"windows-sys 0.42.0",
]
[[package]]
name = "is-terminal"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
dependencies = [
"hermit-abi 0.2.6",
"io-lifetimes",
"rustix",
"windows-sys 0.42.0",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.10.5" version = "0.10.5"
@ -597,9 +694,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.3" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
@ -687,6 +784,12 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "linux-raw-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.17" version = "0.4.17"
@ -726,7 +829,7 @@ version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi 0.1.19",
"libc", "libc",
] ]
@ -828,14 +931,38 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]] [[package]]
name = "prettyplease" name = "prettyplease"
version = "0.1.19" version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a49e86d2c26a24059894a3afa13fd17d063419b05dfb83f06d9c3566060c3f5a" checksum = "83fead41e178796ef8274dc612a7d8ce4c7e10ca35cd2c5b5ad24cac63aeb6c0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"syn", "syn",
] ]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.46" version = "1.0.46"
@ -928,6 +1055,20 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "rustix"
version = "0.36.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys 0.42.0",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.11" version = "1.0.11"
@ -950,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"windows-sys", "windows-sys 0.36.1",
] ]
[[package]] [[package]]
@ -1051,9 +1192,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.101" version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1273,39 +1414,96 @@ version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [ dependencies = [
"windows_aarch64_msvc", "windows_aarch64_msvc 0.36.1",
"windows_i686_gnu", "windows_i686_gnu 0.36.1",
"windows_i686_msvc", "windows_i686_msvc 0.36.1",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.36.1",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.36.1",
] ]
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.42.0",
"windows_i686_gnu 0.42.0",
"windows_i686_msvc 0.42.0",
"windows_x86_64_gnu 0.42.0",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.42.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"

View file

@ -11,7 +11,9 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.65" anyhow = "1.0.65"
cargo = "0.65.0" cargo = "0.65.0"
clap = { version = "4.0.29", features = ["derive"] }
prettyplease = "0.1.19" prettyplease = "0.1.19"
proc-macro2 = "1.0.46" proc-macro2 = "1.0.46"
quote = "1.0.21" quote = "1.0.21"
syn = { version = "1.0.101", features = ["full", "visit", "visit-mut"] } syn = { version = "1.0.101", features = ["full", "visit", "visit-mut"] }
walkdir = "2.3.2"

View file

@ -1,28 +1,60 @@
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use std::path::PathBuf; use std::{fmt::Display, path::PathBuf};
#[derive(Debug)]
pub struct Build { pub struct Build {
path: PathBuf, cargo: bool,
script_path: Option<PathBuf>,
input_path: PathBuf,
} }
impl Build { impl Build {
pub fn new(path: impl Into<PathBuf>) -> Self { pub fn new(cargo: bool, script_path: Option<PathBuf>, input_path: PathBuf) -> Self {
Self { path: path.into() } Self {
cargo,
script_path,
input_path,
}
} }
pub fn build(&self) -> Result<BuildResult> { pub fn build(&self) -> Result<BuildResult> {
let mut cmd = std::process::Command::new("cargo"); let reproduces_issue = if self.cargo {
let mut cmd = std::process::Command::new("cargo");
cmd.arg("build");
cmd.current_dir(&self.path).arg("build"); let output =
String::from_utf8(cmd.output().context("spawning rustc process")?.stderr).unwrap();
let output = cmd.output().context("spawning cargo")?; output.contains("internal compiler error")
} else if let Some(script_path) = &self.script_path {
let mut cmd = std::process::Command::new(script_path);
Ok(BuildResult { cmd.output().context("spawning script")?.status.success()
success: output.status.success(), } else {
}) let mut cmd = std::process::Command::new("rustc");
cmd.args(["--edition", "2018"]);
cmd.arg(&self.input_path);
cmd.output()
.context("spawning rustc process")?
.status
.code()
== Some(101)
};
Ok(BuildResult { reproduces_issue })
} }
} }
pub struct BuildResult { pub struct BuildResult {
pub success: bool, pub reproduces_issue: bool,
}
impl Display for BuildResult {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.reproduces_issue {
true => f.write_str("yes"),
false => f.write_str("no"),
}
}
} }

46
src/everybody_loops.rs Normal file
View file

@ -0,0 +1,46 @@
use syn::{parse_quote, visit_mut::VisitMut};
use crate::processor::Processor;
struct Visitor {
loop_expr: syn::Block,
has_made_change: bool,
}
impl Visitor {
fn new() -> Self {
Self {
has_made_change: false,
loop_expr: parse_quote! { { loop {} } },
}
}
}
impl VisitMut for Visitor {
fn visit_block_mut(&mut self, block: &mut syn::Block) {
match block.stmts.as_slice() {
[syn::Stmt::Expr(syn::Expr::Loop(syn::ExprLoop {
body: loop_body, ..
}))] if loop_body.stmts.is_empty() => {}
_ => {
*block = self.loop_expr.clone();
self.has_made_change = true;
}
}
}
}
#[derive(Default)]
pub struct EverybodyLoops;
impl Processor for EverybodyLoops {
fn process_file(&mut self, krate: &mut syn::File) -> bool {
let mut visitor = Visitor::new();
visitor.visit_file_mut(krate);
visitor.has_made_change
}
fn name(&self) -> &'static str {
"everybody-loops"
}
}

View file

@ -1,15 +1,48 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::path::Path; use std::path::PathBuf;
mod build; mod build;
mod everybody_loops;
mod expand; mod expand;
mod privatize;
mod processor;
use anyhow::{Context, Result}; use anyhow::Result;
use clap::Parser;
use processor::Minimizer;
pub fn minimize(cargo_dir: &Path) -> Result<()> { use crate::{everybody_loops::EverybodyLoops, privatize::Privarize, processor::Processor};
let file = expand::expand(cargo_dir).context("during expansion")?;
#[derive(clap::Parser)]
pub struct Options {
#[arg(short, long)]
verify_error_path: Option<PathBuf>,
#[arg(long)]
cargo: bool,
path: PathBuf,
}
pub fn minimize() -> Result<()> {
let options = Options::parse();
let dir = options.path;
let build = build::Build::new(options.cargo, options.verify_error_path, dir.clone());
let mut minimizer = Minimizer::new_glob_dir(&dir, build);
println!("{minimizer:?}");
minimizer.run_passes([
//Box::new(Privarize::default()) as Box<dyn Processor>,
Box::new(EverybodyLoops::default()) as Box<dyn Processor>,
])?;
/*
let file = expand::expand(&dir).context("during expansion")?;
//let file = syn::parse_str("extern { pub fn printf(format: *const ::c_char, ...) -> ::c_int; }",).unwrap();
let file = prettyplease::unparse(&file); let file = prettyplease::unparse(&file);
println!("// EXPANDED-START\n\n{file}\n\n// EXPANDED-END"); println!("// EXPANDED-START\n\n{file}\n\n// EXPANDED-END");
@ -17,7 +50,7 @@ pub fn minimize(cargo_dir: &Path) -> Result<()> {
std::fs::write("expanded.rs", file)?; std::fs::write("expanded.rs", file)?;
println!("wow, expanded"); println!("wow, expanded");
Ok(()) */
/* /*
let build = Build::new(cargo_dir); let build = Build::new(cargo_dir);
@ -26,4 +59,6 @@ pub fn minimize(cargo_dir: &Path) -> Result<()> {
bail!("build must initially fail!"); bail!("build must initially fail!");
} }
*/ */
Ok(())
} }

View file

@ -1,13 +1,7 @@
use std::path::Path; use anyhow::Result;
use anyhow::{Context, Result};
fn main() -> Result<()> { fn main() -> Result<()> {
let dir = std::env::args().nth(1).context("expected an argument")?; cargo_minimize::minimize()?;
cargo_minimize::minimize(&Path::new(&dir))?;
println!("Exit");
Ok(()) Ok(())
} }

41
src/privatize.rs Normal file
View file

@ -0,0 +1,41 @@
use syn::{parse_quote, visit_mut::VisitMut, Visibility};
use crate::processor::Processor;
struct Visitor {
pub_crate: Visibility,
has_made_change: bool,
}
impl Visitor {
fn new() -> Self {
Self {
has_made_change: false,
pub_crate: parse_quote! { pub(crate) },
}
}
}
impl VisitMut for Visitor {
fn visit_visibility_mut(&mut self, vis: &mut Visibility) {
if let Visibility::Public(_) = vis {
self.has_made_change = true;
*vis = self.pub_crate.clone();
}
}
}
#[derive(Default)]
pub struct Privarize {}
impl Processor for Privarize {
fn process_file(&mut self, krate: &mut syn::File) -> bool {
let mut visitor = Visitor::new();
visitor.visit_file_mut(krate);
visitor.has_made_change
}
fn name(&self) -> &'static str {
"privatize"
}
}

97
src/processor.rs Normal file
View file

@ -0,0 +1,97 @@
use std::{
ffi::OsStr,
path::{Path, PathBuf},
};
use anyhow::{ensure, Context, Result};
use crate::build::Build;
pub trait Processor {
fn process_file(&mut self, krate: &mut syn::File) -> bool;
fn name(&self) -> &'static str;
}
#[derive(Debug)]
pub struct Minimizer {
files: Vec<PathBuf>,
build: Build,
}
impl Minimizer {
pub fn new_glob_dir(path: &Path, build: Build) -> Self {
let walk = walkdir::WalkDir::new(path);
let files = walk
.into_iter()
.filter_map(|entry| match entry {
Ok(entry) => Some(entry),
Err(err) => {
eprintln!("WARN: Error in walkdir: {err}");
None
}
})
.filter(|entry| entry.path().extension() == Some(OsStr::new("rs")))
.map(|entry| entry.into_path())
.collect();
Self { files, build }
}
pub fn run_passes<'a>(
&mut self,
passes: impl IntoIterator<Item = Box<dyn Processor>>,
) -> Result<()> {
let inital_build = self.build.build()?;
println!("Initial build: {}", inital_build);
ensure!(
inital_build.reproduces_issue,
"Initial build must reproduce issue"
);
for mut pass in passes {
'pass: loop {
println!("Starting a round of {}", pass.name());
let mut any_change = false;
for file in &self.files {
let file_display = file.display();
let before_string = std::fs::read_to_string(file)
.with_context(|| format!("opening file {file_display}"))?;
let mut krate = syn::parse_file(&before_string)
.with_context(|| format!("parsing file {file_display}"))?;
let has_made_change = pass.process_file(&mut krate);
if has_made_change {
let result = prettyplease::unparse(&krate);
std::fs::write(file, &result)?;
let after = self.build.build()?;
println!("{file_display}: After {}: {after}", pass.name());
if after.reproduces_issue {
any_change = true;
} else {
std::fs::write(file, before_string)?;
}
} else {
println!("{file_display}: After {}: no change", pass.name());
}
}
if !any_change {
println!("Finished {}", pass.name());
break 'pass;
}
}
}
Ok(())
}
}