Skip to content

Commit 6d29872

Browse files
authored
Rewrite source parser to use pulldown-cmark for comment parsing (#353)
Resolves #350 From a quick test of a few repos I have cloned, this fixes some false positives around unused deps in doc comments (one found in `diesel`, one found in `sqlx`) Perf looks to be unchanged: ``` > hyperfine -i cargo-shear-old cargo-shear Benchmark 1: cargo-shear-old Time (mean ± σ): 219.9 ms ± 4.7 ms [User: 946.7 ms, System: 54.5 ms] Range (min … max): 212.2 ms … 230.4 ms 20 runs Benchmark 2: cargo-shear Time (mean ± σ): 222.8 ms ± 6.7 ms [User: 983.8 ms, System: 46.5 ms] Range (min … max): 213.3 ms … 243.1 ms 20 runs Summary cargo-shear-old ran 1.01 ± 0.04 times faster than cargo-shear ``` `pulldown-cmark` does have SIMD support, but only on x86.
1 parent 850553b commit 6d29872

File tree

7 files changed

+612
-719
lines changed

7 files changed

+612
-719
lines changed

Cargo.lock

Lines changed: 27 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ walkdir = "2.5.0"
2323
cargo_metadata = "0.23.0"
2424
bpaf = { version = "0.9.19", features = ["derive", "batteries"] }
2525
ra_ap_syntax = "0.0.308"
26+
pulldown-cmark = { version = "0.13", default-features = false, features = [
27+
"simd",
28+
] }
2629
rayon = "1.10.0"
2730
serde = { version = "1.0.228", features = ["derive"] }
2831
toml = { version = "0.9.8", features = ["serde"] }

src/dependency_analyzer.rs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,7 @@
99
//! The analyzer walks through all source files in a package, collects import
1010
//! statements, and builds a set of used import names.
1111
12-
use std::{
13-
env,
14-
ffi::OsString,
15-
path::{Path, PathBuf},
16-
process::Command,
17-
};
12+
use std::{env, ffi::OsString, path::PathBuf, process::Command};
1813

1914
use anyhow::{Result, anyhow};
2015
use cargo_metadata::{Package, Target, TargetKind};
@@ -23,7 +18,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
2318
use toml::Spanned;
2419
use walkdir::{DirEntry, WalkDir};
2520

26-
use crate::{import_collector::collect_imports, manifest::Manifest};
21+
use crate::{manifest::Manifest, source_parser::ParsedSource};
2722

2823
/// How a dependency is referenced in `[features]`.
2924
///
@@ -164,14 +159,13 @@ impl DependencyAnalyzer {
164159
let target_kind = target.kind.first().ok_or_else(|| anyhow!("Target has no kind"))?;
165160
let rust_files = Self::get_target_rust_files(target);
166161

167-
let deps_vec: Vec<FxHashSet<String>> = rust_files
162+
let imports: FxHashSet<String> = rust_files
168163
.par_iter()
169-
.map(|path| Self::process_rust_source(path))
170-
.collect::<Result<Vec<_>>>()?;
171-
172-
let imports = deps_vec
164+
.map(|path| ParsedSource::from_path(path.as_path()))
165+
.collect::<Result<Vec<_>, _>>()?
173166
.into_iter()
174-
.fold(FxHashSet::default(), |a, b| a.union(&b).cloned().collect());
167+
.flat_map(|parsed| parsed.imports)
168+
.collect();
175169

176170
Self::categorize_imports(categorized, target_kind, imports);
177171
}
@@ -236,8 +230,8 @@ impl DependencyAnalyzer {
236230
));
237231
}
238232

239-
let imports = collect_imports(&output_str);
240-
Self::categorize_imports(categorized, target_kind, imports);
233+
let parsed = ParsedSource::from_str(&output_str);
234+
Self::categorize_imports(categorized, target_kind, parsed.imports);
241235
}
242236

243237
Ok(())
@@ -287,12 +281,6 @@ impl DependencyAnalyzer {
287281
}
288282
}
289283

290-
/// Parse a Rust source file and collect all import names.
291-
fn process_rust_source(path: &Path) -> Result<FxHashSet<String>> {
292-
let source_text = std::fs::read_to_string(path)?;
293-
Ok(collect_imports(&source_text))
294-
}
295-
296284
/// Collect import names for dependencies referenced in features.
297285
fn analyze_features(categorized: &mut CategorizedImports, manifest: &Manifest) {
298286
for (feature, values) in &manifest.features {

0 commit comments

Comments
 (0)