Skip to content

Commit f7876bb

Browse files
authored
Merge pull request #5 from wuwbobo2021/main
Port java-spaghetti-gen to cafebabe; cache method/field IDs; fix jclass memory leaks
2 parents 5beb30d + 1989162 commit f7876bb

23 files changed

+1296
-774
lines changed

.github/workflows/rust.yml renamed to .github/workflows/rust_nightly.yml

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Rust
1+
name: Rust - Nightly
22

33
on:
44
push:
@@ -11,10 +11,12 @@ env:
1111
CARGO_TERM_COLOR: always
1212

1313
jobs:
14-
build:
14+
build_and_test:
1515
runs-on: ubuntu-latest
1616
steps:
17-
- uses: actions/checkout@v3
17+
- uses: actions/checkout@v4
18+
- run: rustup update nightly && rustup default nightly
19+
- run: rustup component add rustfmt
1820
- name: Check fmt
1921
run: cargo fmt -- --check
2022
- name: Test

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ The full list of differences are:
2121
- You can filter which classes are generated in the TOML config.
2222
- Generated code uses relative paths (`super::...`) instead of absolute paths (`crate::...`), so it works if you place it in a submodule not at the crate root.
2323
- Generated code is a single `.rs` file, there's no support for spltting it in one file per class. You can still run the output through [form](https://github.com/djmcgill/form), if you want.
24+
- Generated code uses cached method IDs and field IDs stored in `OnceLock` to speed up invocations by several times. Used classes are also stored as JNI global references in order to keep the validity of cached IDs. This may not ensure memory safety when class redefinition features (e.g. `java.lang.instrument` which is unavailable on Android) of the JVM is being used.
2425
- Generated code doesn't use macros.
2526
- No support for generating Cargo features per class.
2627
- Modernized rust, updated dependencies.

java-spaghetti-gen/Cargo.toml

+8-8
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ categories = ["development-tools::ffi"]
99
license = "MIT OR Apache-2.0"
1010

1111
[dependencies]
12-
jreflection = "0.0.11"
13-
clap = { version = "4", features = ["derive"] }
14-
bitflags = "2.4.2"
15-
serde = "1.0.197"
16-
serde_derive = "1.0.197"
17-
toml = "0.8.10"
18-
zip = "0.6.6"
12+
cafebabe = "0.8.0"
13+
clap = { version = "4", features = ["derive"] }
14+
bitflags = "2.8.0"
15+
serde = "1.0.197"
16+
serde_derive = "1.0.197"
17+
toml = "0.8.10"
18+
zip = "2.2.2"
1919

2020
[dev-dependencies]
21-
jni-sys = "0.4.0"
21+
jni-sys = "0.4.0"

java-spaghetti-gen/src/emit_rust/context.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ use std::rc::Rc;
55
use std::sync::Mutex;
66
use std::time::Duration;
77

8-
use jreflection::class;
9-
108
use super::modules::Module;
119
use super::preamble::write_preamble;
1210
use super::structs::Struct;
13-
use crate::{config, util};
11+
use crate::{config, parser_util, util};
1412

1513
pub struct Context<'a> {
1614
pub(crate) config: &'a config::runtime::Config,
@@ -32,10 +30,11 @@ impl<'a> Context<'a> {
3230
}
3331

3432
pub(crate) fn throwable_rust_path(&self, mod_: &str) -> String {
35-
self.java_to_rust_path(class::Id("java/lang/Throwable"), mod_).unwrap()
33+
self.java_to_rust_path(parser_util::Id("java/lang/Throwable"), mod_)
34+
.unwrap()
3635
}
3736

38-
pub fn java_to_rust_path(&self, java_class: class::Id, mod_: &str) -> Result<String, Box<dyn Error>> {
37+
pub fn java_to_rust_path(&self, java_class: parser_util::Id, mod_: &str) -> Result<String, Box<dyn Error>> {
3938
let m = Struct::mod_for(self, java_class)?;
4039
let s = Struct::name_for(self, java_class)?;
4140
let fqn = format!("{}::{}", m, s);
@@ -92,18 +91,18 @@ impl<'a> Context<'a> {
9291
pat.pop();
9392
}
9493

95-
return false;
94+
false
9695
}
9796

98-
pub fn add_struct(&mut self, class: jreflection::Class) -> Result<(), Box<dyn Error>> {
99-
if self.config.ignore_classes.contains(class.path.as_str()) {
97+
pub fn add_struct(&mut self, class: parser_util::Class) -> Result<(), Box<dyn Error>> {
98+
if self.config.ignore_classes.contains(class.path().as_str()) {
10099
return Ok(());
101100
}
102-
if !self.struct_included(class.path.as_str()) {
101+
if !self.struct_included(class.path().as_str()) {
103102
return Ok(());
104103
}
105104

106-
let java_path = class.path.as_str().to_string();
105+
let java_path = class.path().as_str().to_string();
107106
let s = Rc::new(Struct::new(self, class)?);
108107

109108
self.all_classes.insert(java_path, s.clone());

0 commit comments

Comments
 (0)