obfuskator/crates/noxis-analysis/tests/mixins.rs
loki5512344 90506a4736
passes: rename mixin classes + patch mixins.json/refmap like OBF
- Remove absorb_mixins keep rule (mixin classes now renameable)
- Add mixins.rs: patch_mixins_json rewrites package + entries via
  common prefix of mapped names; patch_refmap_json rewrites all strings
- Resources pass routes *.mixins.json and *refmap.json to specialized
  patchers, falls back to generic text remap

Reference: OBF fabric-obfuscator patchMixinsJson/patchRefmapJson.
2026-10-12 14:18:19 +02:00

73 lines
2.3 KiB
Rust

//! Mixin keep: classes listed in `*.mixins.json` are now renameable.
//!
//! The resources pass patches mixins.json (rewrites package + entries),
//! so mixin classes can be renamed. Reference: OBF fabric-obfuscator.
#![allow(clippy::expect_used, clippy::unwrap_used)]
use noxis_analysis::Analysis;
use noxis_classfile::{ClassBuilder, Program, Resource, Version};
use noxis_core::Config;
const MIXINS: &str = r#"{
"package": "demo.mixin",
"plugin": "demo.mixin.Plugin",
"mixins": ["TargetMixin", "other.Helper"],
"client": ["ClientMixin"]
}"#;
const FABRIC: &str = r#"{
"id": "demo",
"mixins": ["demo.mixins.json"]
}"#;
fn sample() -> Program {
let mut program = Program {
classes: vec![
ClassBuilder::new("demo/mixin/TargetMixin", Some("java/lang/Object"))
.version(Version::JAVA_21)
.build(),
ClassBuilder::new("demo/mixin/other/Helper", Some("java/lang/Object"))
.version(Version::JAVA_21)
.build(),
ClassBuilder::new("demo/mixin/ClientMixin", Some("java/lang/Object"))
.version(Version::JAVA_21)
.build(),
ClassBuilder::new("demo/mixin/Plugin", Some("java/lang/Object"))
.version(Version::JAVA_21)
.build(),
ClassBuilder::new("demo/App", Some("java/lang/Object"))
.version(Version::JAVA_21)
.build(),
],
resources: Vec::new(),
};
program.resources.push(Resource {
path: "demo.mixins.json".into(),
data: MIXINS.as_bytes().to_vec(),
});
program.resources.push(Resource {
path: "fabric.mod.json".into(),
data: FABRIC.as_bytes().to_vec(),
});
program
}
#[test]
fn mixin_classes_are_renameable() {
let program = sample();
let analysis = Analysis::run(&program, &Config::default()).expect("analysis");
// Mixin classes are no longer locked - resources pass patches the config.
for renameable in [
"demo/mixin/TargetMixin",
"demo/mixin/other/Helper",
"demo/mixin/ClientMixin",
"demo/mixin/Plugin",
] {
assert!(
!analysis.is_locked(renameable),
"{renameable} should be renameable now"
);
}
}