Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Desdaemon committed Jul 10, 2022
2 parents 495c43d + b380458 commit c2c3741
Show file tree
Hide file tree
Showing 35 changed files with 619 additions and 393 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
- uses: mislav/bump-homebrew-formula-action@v2
with:
formula-name: flutter_rust_bridge_codegen
homebrew-tap: Desdaemon/repo
homebrew-tap: Desdaemon/homebrew-repo
tag-name: ${{ github.ref_name }}
env:
COMMITTER_TOKEN: ${{ secrets.GH_PAT }}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.37.2

* Fix compile errors when using enums within fields #564 (thanks @Desdaemon)

## 1.37.1

* Update doc #552 (thanks @dbsxdbsx)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d

More specifically, thanks for all these contributions:

* [Desdaemon](https://github.com/Desdaemon): Support not only simple enums but also enums with fields which gets translated to native enum or freezed class in Dart. Support the Option type as nullable types in Dart. Support Vec of Strings type. Support comments in code. Add marker attributes for future usage. Add Linux and Windows support for with-flutter example, and make CI works for that. Avoid parameter collision. Overhaul the documentation and add several chapters to demonstrate configuring a Flutter+Rust project in all five platforms. Refactor command module.
* [Desdaemon](https://github.com/Desdaemon): Support not only simple enums but also enums with fields which gets translated to native enum or freezed class in Dart. Support the Option type as nullable types in Dart. Support Vec of Strings type. Support comments in code. Add marker attributes for future usage. Add Linux and Windows support for with-flutter example, and make CI works for that. Avoid parameter collision. Overhaul the documentation and add several chapters to demonstrate configuring a Flutter+Rust project in all five platforms. Refactor command module. Fix bugs.
* [SecondFlight](https://github.com/SecondFlight): Allow structs and enums to be imported from other files within the crate by creating source graph. Auto-create relavent dir. Fix `store_dart_post_cobject` error with ffigen 6.0.
* [Unoqwy](https://github.com/Unoqwy): Add struct mirrors, such that types in the external crates can be imported and used without redefining and copying.
* [antonok-edm](https://github.com/antonok-edm): Avoid converting syn types to strings before parsing to improve code and be more robust.
Expand All @@ -104,7 +104,7 @@ More specifically, thanks for all these contributions:
* [bus710](https://github.com/bus710): Add a case in troubleshooting.
* [Syndim](https://github.com/Syndim): Add a bracket to box.
* [banool](https://github.com/banool): Fix symbol-stripping doc.
* [TENX-S](https://github.com/TENX-S): Improve doc.
* [TENX-S](https://github.com/TENX-S): Improve doc. Reproduce a bug.
* [raphaelrobert](https://github.com/raphaelrobert): Remove oudated doc.
* [thomas725](https://github.com/thomas725): Improve doc.
* [feber](https://github.com/feber): Fix doc link.
Expand Down
2 changes: 1 addition & 1 deletion frb_codegen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "flutter_rust_bridge_codegen"
version = "1.37.1"
version = "1.37.2"
edition = "2018"
description = "High-level memory-safe bindgen for Dart/Flutter <-> Rust"
license = "MIT"
Expand Down
4 changes: 2 additions & 2 deletions frb_codegen/src/generator/dart/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ fn get_dart_api_spec_from_ir_file(ir_file: &IrFile, block_index: BlockIndex) ->
.collect::<Vec<_>>();

let needs_freezed = distinct_types.iter().any(|ty| match ty {
EnumRef(e) if e.is_struct => true,
StructRef(s) if s.freezed => true,
EnumRef(_) => true,
StructRef(st) if st.freezed => true,
_ => false,
});

Expand Down
48 changes: 22 additions & 26 deletions frb_codegen/src/generator/dart/ty_boxed.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::generator::dart::gen_wire2api_simple_type_cast;
use crate::generator::dart::ty::*;
use crate::ir::IrType::{EnumRef, Primitive, StructRef};
use crate::ir::IrType::{EnumRef, StructRef};
use crate::ir::*;
use crate::type_dart_generator_struct;
use crate::utils::BlockIndex;
Expand All @@ -9,36 +9,32 @@ type_dart_generator_struct!(TypeBoxedGenerator, IrTypeBoxed);

impl TypeDartGeneratorTrait for TypeBoxedGenerator<'_> {
fn api2wire_body(&self, block_index: BlockIndex) -> Option<String> {
Some(match &*self.ir.inner {
Primitive(_) => {
format!(
"return inner.new_{}_{}(raw);",
self.ir.safe_ident(),
block_index
)
}
inner => {
format!(
"final ptr = inner.new_{}_{}();
_api_fill_to_wire_{}(raw, ptr.ref);
return ptr;",
self.ir.safe_ident(),
block_index,
inner.safe_ident(),
)
}
})
if self.ir.inner.is_primitive() {
Some(format!(
"return inner.new_{}_{}(_api2wire_{}(raw));",
self.ir.safe_ident(),
block_index,
self.ir.inner.safe_ident(),
))
} else {
Some(format!(
"final ptr = inner.new_{}_{}();
_api_fill_to_wire_{}(raw, ptr.ref);
return ptr;",
self.ir.safe_ident(),
block_index,
self.ir.inner.safe_ident(),
))
}
}

fn api_fill_to_wire_body(&self) -> Option<String> {
if !matches!(*self.ir.inner, Primitive(_)) {
Some(format!(
(!self.ir.inner.is_primitive()).then(|| {
format!(
" _api_fill_to_wire_{}(apiObj, wireObj.ref);",
self.ir.inner.safe_ident()
))
} else {
None
}
)
})
}

fn wire2api_body(&self) -> String {
Expand Down
19 changes: 18 additions & 1 deletion frb_codegen/src/generator/dart/ty_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ impl TypeDartGeneratorTrait for TypeDelegateGenerator<'_> {
self.ir.get_delegate().safe_ident()
)
}

IrTypeDelegate::StringList => format!(
"final ans = inner.new_StringList_{}(raw.length);
for (var i = 0; i < raw.length; i++){{
Expand All @@ -28,6 +27,9 @@ impl TypeDartGeneratorTrait for TypeDelegateGenerator<'_> {
return ans;",
block_index
),
IrTypeDelegate::PrimitiveEnum { ref repr, .. } => {
format!("return _api2wire_{}(raw.index);", repr.safe_ident())
}
})
}

Expand All @@ -41,6 +43,21 @@ impl TypeDartGeneratorTrait for TypeDelegateGenerator<'_> {
IrTypeDelegate::StringList => {
"return (raw as List<dynamic>).cast<String>();".to_owned()
}
IrTypeDelegate::PrimitiveEnum { ir, .. } => {
format!("return {}.values[raw];", ir.dart_api_type())
}
}
}

fn structs(&self) -> String {
if let IrTypeDelegate::PrimitiveEnum { ir, .. } = &self.ir {
super::TypeEnumRefGenerator {
ir: ir.clone(),
context: self.context.clone(),
}
.structs()
} else {
"".into()
}
}
}
174 changes: 80 additions & 94 deletions frb_codegen/src/generator/dart/ty_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,108 +8,94 @@ type_dart_generator_struct!(TypeEnumRefGenerator, IrTypeEnumRef);

impl TypeDartGeneratorTrait for TypeEnumRefGenerator<'_> {
fn api2wire_body(&self, _block_index: BlockIndex) -> Option<String> {
if !self.ir.is_struct {
Some("return raw.index;".to_owned())
} else {
None
}
None
}

fn api_fill_to_wire_body(&self) -> Option<String> {
if self.ir.is_struct {
Some(
self.ir
.get(self.context.ir_file)
.variants()
.iter()
.enumerate()
.map(|(idx, variant)| {
if let IrVariantKind::Value = &variant.kind {
format!(
"if (apiObj is {}) {{ wireObj.tag = {}; return; }}",
variant.name, idx
)
} else {
let r = format!("wireObj.kind.ref.{}.ref", variant.name);
let body: Vec<_> = match &variant.kind {
IrVariantKind::Struct(st) => st
.fields
.iter()
.map(|field| {
format!(
"{}.{} = _api2wire_{}(apiObj.{});",
r,
field.name.rust_style(),
field.ty.safe_ident(),
field.name.dart_style()
)
})
.collect(),
_ => unreachable!(),
};
format!(
"if (apiObj is {0}) {{
wireObj.tag = {1};
wireObj.kind = inner.inflate_{2}_{0}();
{3}
}}",
variant.name,
idx,
self.ir.name,
body.join("\n")
)
}
})
.collect::<Vec<_>>()
.join("\n"),
)
} else {
None
}
}

fn wire2api_body(&self) -> String {
if self.ir.is_struct {
let enu = self.ir.get(self.context.ir_file);
let variants = enu
Some(
self.ir
.get(self.context.ir_file)
.variants()
.iter()
.enumerate()
.map(|(idx, variant)| {
let args = match &variant.kind {
IrVariantKind::Value => "".to_owned(),
IrVariantKind::Struct(st) => st
.fields
.iter()
.enumerate()
.map(|(idx, field)| {
let val = format!(
"_wire2api_{}(raw[{}]),",
field.ty.safe_ident(),
idx + 1
);
if st.is_fields_named {
format!("{}: {}", field.name.dart_style(), val)
} else {
val
}
})
.collect::<Vec<_>>()
.join(""),
};
format!("case {}: return {}({});", idx, variant.name, args)
if let IrVariantKind::Value = &variant.kind {
format!(
"if (apiObj is {}) {{ wireObj.tag = {}; return; }}",
variant.name, idx
)
} else {
let r = format!("wireObj.kind.ref.{}.ref", variant.name);
let body: Vec<_> = match &variant.kind {
IrVariantKind::Struct(st) => st
.fields
.iter()
.map(|field| {
format!(
"{}.{} = _api2wire_{}(apiObj.{});",
r,
field.name.rust_style(),
field.ty.safe_ident(),
field.name.dart_style()
)
})
.collect(),
_ => unreachable!(),
};
format!(
"if (apiObj is {0}) {{
wireObj.tag = {1};
wireObj.kind = inner.inflate_{2}_{0}();
{3}
}}",
variant.name,
idx,
self.ir.name,
body.join("\n")
)
}
})
.collect::<Vec<_>>();
format!(
"switch (raw[0]) {{
{}
default: throw Exception(\"unreachable\");
}}",
variants.join("\n"),
)
} else {
format!("return {}.values[raw];", self.ir.name)
}
.collect::<Vec<_>>()
.join("\n"),
)
}

fn wire2api_body(&self) -> String {
let enu = self.ir.get(self.context.ir_file);
assert!(enu.is_struct());
let variants = enu
.variants()
.iter()
.enumerate()
.map(|(idx, variant)| {
let args = match &variant.kind {
IrVariantKind::Value => "".to_owned(),
IrVariantKind::Struct(st) => st
.fields
.iter()
.enumerate()
.map(|(idx, field)| {
let val =
format!("_wire2api_{}(raw[{}]),", field.ty.safe_ident(), idx + 1);
if st.is_fields_named {
format!("{}: {}", field.name.dart_style(), val)
} else {
val
}
})
.collect::<Vec<_>>()
.join(""),
};
format!("case {}: return {}({});", idx, variant.name, args)
})
.collect::<Vec<_>>();
format!(
"switch (raw[0]) {{
{}
default: throw Exception(\"unreachable\");
}}",
variants.join("\n"),
)
}

fn structs(&self) -> String {
Expand Down
4 changes: 3 additions & 1 deletion frb_codegen/src/generator/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,9 @@ impl Generator {

fn generate_wrapper_struct(&mut self, ty: &IrType, ir_file: &IrFile) -> Option<String> {
match ty {
IrType::StructRef(_) | IrType::EnumRef(_) => {
IrType::StructRef(_)
| IrType::EnumRef(_)
| IrType::Delegate(IrTypeDelegate::PrimitiveEnum { .. }) => {
TypeRustGenerator::new(ty.clone(), ir_file)
.wrapper_struct()
.map(|wrapper| {
Expand Down
Loading

0 comments on commit c2c3741

Please sign in to comment.