Skip to content

Commit f95cd4b

Browse files
committed
Some fix with the prune feature
1 parent 1dcca50 commit f95cd4b

5 files changed

Lines changed: 93 additions & 18 deletions

File tree

cli/src/commands.rs

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,52 @@ fn scan_layout(layout: &workspace::Layout, use_cargo_check_fallback: bool) -> Re
4444
let manifest = Manifest::load(&layout.bindings_root.join("features.json"))?;
4545

4646
let listed = toml_writer::read_features(&layout.features_manifest).unwrap_or_default();
47+
48+
// Seed the enabled set from whatever Cargo.toml already lists.
4749
let mut enabled: BTreeSet<String> = BTreeSet::new();
4850
for f in &listed {
4951
enabled.extend(manifest.closure(f));
5052
}
5153

52-
let mut referenced_paths = BTreeSet::new();
54+
// Finding references is a fixpoint, not one pass. The hand-written wrappers
55+
// in the bindings (ext.rs) hide their references behind #[cfg(feature = "...")],
56+
// so a wrapper's references only become visible once that wrapper's feature is
57+
// on. Each pass turns on the features we found last pass, which can uncover
58+
// more, so we loop until the enabled set stops growing. Without this a single
59+
// `apply` only peels off the first layer and the build still reports the next
60+
// layer as missing (you'd have to run apply again).
61+
let bindings_src = layout.bindings_root.join("src");
62+
let mut referenced_paths;
5363

54-
for root in &layout.scan_roots {
55-
let found = scan::collect_paths(root, &manifest, &[], &[], &enabled)?;
56-
referenced_paths.extend(found);
57-
}
64+
loop {
65+
let mut found = BTreeSet::new();
5866

59-
let bindings_src = layout.bindings_root.join("src");
67+
for root in &layout.scan_roots {
68+
found.extend(scan::collect_paths(root, &manifest, &[], &[], &enabled)?);
69+
}
70+
71+
if bindings_src.exists() {
72+
found.extend(scan::collect_paths(
73+
&bindings_src,
74+
&manifest,
75+
&["crate"],
76+
&["generated"],
77+
&enabled,
78+
)?);
79+
}
80+
81+
// Turn on whatever this pass referenced and see if that grew the set. If it
82+
// didn't, this pass already saw everything reachable, so we're converged.
83+
let before = enabled.len();
84+
for f in scan::paths_to_features(&found, &manifest) {
85+
enabled.extend(manifest.closure(&f));
86+
}
6087

61-
if bindings_src.exists() {
62-
let found = scan::collect_paths(
63-
&bindings_src,
64-
&manifest,
65-
&["crate"],
66-
&["generated"],
67-
&enabled,
68-
)?;
69-
referenced_paths.extend(found);
88+
referenced_paths = found;
89+
90+
if enabled.len() == before {
91+
break;
92+
}
7093
}
7194

7295
if use_cargo_check_fallback {

cli/src/manifest.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ pub struct Manifest {
1515
pub dependencies: BTreeMap<String, Vec<String>>,
1616
#[serde(skip)]
1717
pub ext_wrappers: BTreeMap<String, Vec<String>>,
18+
/// Short re-export path -> canonical path. Types live at
19+
/// `engage_il2cpp::<ns>::<module>::<Type>` but the generated `<ns>` module
20+
/// re-exports them one level up (the `pub use <module>::{Type}` lines in
21+
/// app.rs etc), so code usually imports the short `engage_il2cpp::<ns>::<Type>`.
22+
/// This maps that short form back so the scanner recognizes it.
23+
#[serde(skip)]
24+
pub reexports: BTreeMap<String, String>,
1825
}
1926

2027
const SCHEMA_VERSION: u32 = 1;
@@ -37,6 +44,8 @@ impl Manifest {
3744
m.ext_wrappers = load_ext_wrappers(bindings_root).unwrap_or_default();
3845
}
3946

47+
m.reexports = build_reexports(&m.paths);
48+
4049
Ok(m)
4150
}
4251

@@ -70,6 +79,41 @@ impl Manifest {
7079
}
7180
}
7281

82+
/// Invert the namespace-root re-exports: for each canonical
83+
/// `engage_il2cpp::<ns>::<module>::<Type>`, the `<ns>` module re-exports it as
84+
/// `engage_il2cpp::<ns>::<Type>`, so drop the module segment (second to last) to
85+
/// get the short form code actually imports. A real `pub use` at one level can't
86+
/// name two types the same way, so if two canonicals ever collapse to the same
87+
/// short form we drop it rather than guess.
88+
fn build_reexports(paths: &BTreeMap<String, String>) -> BTreeMap<String, String> {
89+
let mut grouped: BTreeMap<String, Vec<&String>> = BTreeMap::new();
90+
91+
for canonical in paths.keys() {
92+
let segs: Vec<&str> = canonical.split("::").collect();
93+
94+
// Need at least crate::ns::module::Type for there to be a module to drop.
95+
if segs.len() < 4 {
96+
continue;
97+
}
98+
99+
let mut short_segs = segs.clone();
100+
short_segs.remove(segs.len() - 2);
101+
let short = short_segs.join("::");
102+
103+
if short != *canonical {
104+
grouped.entry(short).or_default().push(canonical);
105+
}
106+
}
107+
108+
grouped
109+
.into_iter()
110+
.filter_map(|(short, canonicals)| match canonicals.as_slice() {
111+
[only] => Some((short, (*only).clone())),
112+
_ => None,
113+
})
114+
.collect()
115+
}
116+
73117
fn load_ext_wrappers(bindings_root: &Path) -> Option<BTreeMap<String, Vec<String>>> {
74118
let ext_path = bindings_root.join("src").join("ext.rs");
75119
let text = std::fs::read_to_string(&ext_path).ok()?;

cli/src/scan.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ impl<'a> PathVisitor<'a> {
115115
return;
116116
}
117117

118+
// Code usually imports the short re-export path (engage_il2cpp::app::Fade)
119+
// rather than the canonical one (engage_il2cpp::app::fade::Fade). Record the
120+
// canonical so it maps to a feature downstream.
121+
if let Some(canonical) = self.manifest.reexports.get(&candidate) {
122+
self.out.insert(canonical.clone());
123+
return;
124+
}
125+
118126
if let Some(leaf) = segments.get(n - 1) {
119127
if self.manifest.ext_wrappers.contains_key(leaf) {
120128
self.out.insert(candidate);

vscode/package-lock.json

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

vscode/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "engage-vscode",
33
"displayName": "engage",
44
"description": "Manage engage-il2cpp Cargo features from VS Code",
5-
"version": "0.2.2",
5+
"version": "0.2.3",
66
"publisher": "DivineDragonFanClub",
77
"repository": {
88
"type": "git",

0 commit comments

Comments
 (0)