Skip to content

Commit 1290543

Browse files
authored
Merge pull request #1978 from fzyzcjy/feat/12081
Hint users when using opaque types inside non opaque structs
2 parents 193f5d0 + 2d4665d commit 1290543

File tree

9 files changed

+82
-20
lines changed

9 files changed

+82
-20
lines changed

frb_codegen/src/library/codegen/parser/auto_accessor_parser/field.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::codegen::parser::function_parser::{
1414
compute_codec_mode_pack, parse_effective_function_name_of_method,
1515
};
1616
use crate::codegen::parser::internal_config::ParserInternalConfig;
17+
use crate::codegen::parser::sanity_checker::auto_accessor_checker;
1718
use crate::codegen::parser::type_parser::{TypeParser, TypeParserParsingContext};
1819
use sha1::{Digest, Sha1};
1920

@@ -88,7 +89,7 @@ pub(super) fn parse_auto_accessor_of_field(
8889

8990
Ok(IrFuncAndSanityCheckInfo {
9091
ir_func,
91-
sanity_check_hint: super::sanity_checker::check_field(struct_name, field),
92+
sanity_check_hint: auto_accessor_checker::check_field(struct_name, field),
9293
})
9394
}
9495

frb_codegen/src/library/codegen/parser/auto_accessor_parser/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
mod field;
2-
mod sanity_checker;
32

43
use crate::codegen::generator::codec::structs::CodecMode;
54
use crate::codegen::ir::func::{IrFunc, IrFuncAccessorMode};
@@ -9,6 +8,7 @@ use crate::codegen::ir::ty::{IrContext, IrType};
98
use crate::codegen::parser::attribute_parser::FrbAttributes;
109
use crate::codegen::parser::internal_config::ParserInternalConfig;
1110
use crate::codegen::parser::misc::extract_src_types_in_paths;
11+
use crate::codegen::parser::sanity_checker::auto_accessor_checker;
1212
use crate::codegen::parser::source_graph::modules::Struct;
1313
use crate::codegen::parser::type_parser::{
1414
TypeParser, TypeParserParsingContext, TypeParserWithContext,
@@ -36,7 +36,7 @@ pub(crate) fn parse_auto_accessors(
3636
.flatten()
3737
.collect_vec();
3838

39-
sanity_checker::report(
39+
auto_accessor_checker::report(
4040
&infos
4141
.iter()
4242
.flat_map(|x| x.sanity_check_hint.clone())
@@ -113,5 +113,5 @@ fn create_parsing_context(
113113

114114
struct IrFuncAndSanityCheckInfo {
115115
ir_func: IrFunc,
116-
sanity_check_hint: Option<sanity_checker::SanityCheckHint>,
116+
sanity_check_hint: Option<auto_accessor_checker::SanityCheckHint>,
117117
}

frb_codegen/src/library/codegen/parser/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ pub(crate) mod function_parser;
66
pub(crate) mod internal_config;
77
pub(crate) mod misc;
88
pub(crate) mod reader;
9-
mod sanity_checker;
9+
pub(crate) mod sanity_checker;
1010
pub(crate) mod source_graph;
1111
pub(crate) mod type_alias_resolver;
1212
pub(crate) mod type_parser;
13-
mod unused_checker;
1413

1514
use crate::codegen::dumper::Dumper;
1615
use crate::codegen::ir::func::IrFunc;
@@ -25,11 +24,12 @@ use crate::codegen::parser::function_parser::FunctionParser;
2524
use crate::codegen::parser::internal_config::ParserInternalConfig;
2625
use crate::codegen::parser::misc::parse_has_executor;
2726
use crate::codegen::parser::reader::CachedRustReader;
28-
use crate::codegen::parser::sanity_checker::check_suppressed_input_path_no_content;
27+
use crate::codegen::parser::sanity_checker::misc_checker::check_suppressed_input_path_no_content;
28+
use crate::codegen::parser::sanity_checker::opaque_inside_translatable_checker::check_opaque_inside_translatable;
29+
use crate::codegen::parser::sanity_checker::unused_checker::get_unused_types;
2930
use crate::codegen::parser::source_graph::modules::Struct;
3031
use crate::codegen::parser::type_alias_resolver::resolve_type_aliases;
3132
use crate::codegen::parser::type_parser::TypeParser;
32-
use crate::codegen::parser::unused_checker::get_unused_types;
3333
use crate::codegen::ConfigDumpContent;
3434
use crate::library::misc::consts::HANDLER_NAME;
3535
use anyhow::ensure;
@@ -109,6 +109,8 @@ pub(crate) fn parse(
109109
&config.rust_crate_dir,
110110
)?;
111111

112+
check_opaque_inside_translatable(&ans);
113+
112114
Ok(ans)
113115
}
114116

frb_codegen/src/library/codegen/parser/auto_accessor_parser/sanity_checker.rs renamed to frb_codegen/src/library/codegen/parser/sanity_checker/auto_accessor_checker.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::library::codegen::ir::ty::IrTypeTrait;
44
use itertools::Itertools;
55
use log::warn;
66

7-
pub(super) fn check_field(
7+
pub(crate) fn check_field(
88
struct_name: &NamespacedName,
99
field: &IrField,
1010
) -> Option<SanityCheckHint> {
@@ -13,7 +13,7 @@ pub(super) fn check_field(
1313
})
1414
}
1515

16-
pub(super) fn report(hints: &[SanityCheckHint]) {
16+
pub(crate) fn report(hints: &[SanityCheckHint]) {
1717
if hints.is_empty() {
1818
return;
1919
}
@@ -27,7 +27,7 @@ pub(super) fn report(hints: &[SanityCheckHint]) {
2727
}
2828

2929
#[derive(Clone)]
30-
pub(super) struct SanityCheckHint {
30+
pub(crate) struct SanityCheckHint {
3131
name: String,
3232
}
3333

frb_codegen/src/library/codegen/parser/sanity_checker.rs renamed to frb_codegen/src/library/codegen/parser/sanity_checker/misc_checker.rs

File renamed without changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub(crate) mod auto_accessor_checker;
2+
pub(crate) mod misc_checker;
3+
pub(crate) mod opaque_inside_translatable_checker;
4+
pub(crate) mod unused_checker;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use crate::codegen::ir::field::IrField;
2+
use crate::codegen::ir::pack::IrPack;
3+
use crate::codegen::ir::ty::enumeration::IrVariantKind;
4+
use crate::codegen::ir::ty::structure::IrStruct;
5+
use crate::codegen::ir::ty::IrType;
6+
use itertools::Itertools;
7+
use log::info;
8+
9+
pub(crate) fn check_opaque_inside_translatable(pack: &IrPack) {
10+
let hint_names = (pack.distinct_types(None).into_iter())
11+
.flat_map(|ty| handle_type(pack, ty))
12+
.collect_vec();
13+
if !hint_names.is_empty() {
14+
info!(
15+
"It is suggested (but not required) to wrap opaque inside non-opaque type with `RustAutoOpaque<..>`. \
16+
See https://fzyzcjy.github.io/flutter_rust_bridge/guides/types/arbitrary/rust-auto-opaque/opaque-in-translatable for more details. \
17+
Related types: {}",
18+
hint_names.join(", "),
19+
);
20+
}
21+
}
22+
23+
fn handle_type(pack: &IrPack, ty: IrType) -> Vec<String> {
24+
match ty {
25+
IrType::StructRef(ty) => {
26+
let st = ty.get(pack);
27+
handle_struct(st, &ty.ident.0.rust_style())
28+
}
29+
IrType::EnumRef(ty) => {
30+
let en = ty.get(pack);
31+
en.variants
32+
.iter()
33+
.flat_map(|variant| match &variant.kind {
34+
IrVariantKind::Value => vec![],
35+
IrVariantKind::Struct(st) => handle_struct(
36+
st,
37+
&format!("{}.{}", ty.ident.0.rust_style(), variant.name.rust_style()),
38+
),
39+
})
40+
.collect_vec()
41+
}
42+
// TODO also check and hint `Vec<OpaqueType>`, etc
43+
_ => vec![],
44+
}
45+
}
46+
47+
fn handle_struct(st: &IrStruct, partial_name: &str) -> Vec<String> {
48+
(st.fields.iter())
49+
.filter_map(|field| handle_field(field, partial_name))
50+
.collect()
51+
}
52+
53+
fn handle_field(field: &IrField, partial_name: &str) -> Option<String> {
54+
if matches!(field.ty, IrType::RustAutoOpaqueImplicit(_)) {
55+
Some(format!("{partial_name}.{}", field.name.rust_style()))
56+
} else {
57+
None
58+
}
59+
}

frb_codegen/src/library/codegen/parser/unused_checker.rs renamed to frb_codegen/src/library/codegen/parser/sanity_checker/unused_checker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::collections::{HashMap, HashSet};
1010
use std::path::{Path, PathBuf};
1111
use syn::Type;
1212

13-
pub(super) fn get_unused_types(
13+
pub(crate) fn get_unused_types(
1414
pack: &IrPack,
1515
src_structs: &HashMap<String, &Struct>,
1616
src_enums: &HashMap<String, &Enum>,

website/docs/guides/types/arbitrary/rust-auto-opaque/opaque-in-translatable.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,13 @@ There is no need to memorize anything here (or anything in doc) -
55
the code generator will provide warnings when detecting non-best-practices.
66
:::
77

8-
Suppose you want to have a translatable struct, and it has an auto opaque field:
8+
Suppose you want to have a translatable struct, and it has an (auto) opaque field:
99

1010
```rust
11-
pub struct A {
12-
pub name: String,
13-
pub b: B,
14-
}
11+
pub struct A { pub b: B }
1512

16-
pub struct B {
17-
db: FancyDatabaseConnection,
18-
}
13+
// Suppose it is opaque
14+
pub struct B { ... }
1915
```
2016

2117
If you want to use the same object of type `A` multiple times,

0 commit comments

Comments
 (0)