Skip to content

Commit

Permalink
Merge pull request #2099 from fzyzcjy/feat/12336
Browse files Browse the repository at this point in the history
  • Loading branch information
fzyzcjy authored Jun 18, 2024
2 parents 1231a44 + 0c5895a commit 97f4df4
Show file tree
Hide file tree
Showing 34 changed files with 6,739 additions and 2,331 deletions.
1 change: 1 addition & 0 deletions frb_codegen/src/library/codegen/ir/mir/skip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(crate) enum MirSkipReason {
IgnoreBecauseParseOwnerCannotFindTrait,
IgnoreBecauseNotAllowedOwner,
IgnoreBecauseOwnerTyShouldIgnore,
IgnoreBecauseSelfTypeNotAllowed,
IgnoreSilently,
Err,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ fn parse_function_inner(
default_rust_opaque_codec: partial_context.default_rust_opaque_codec,
enable_lifetime: partial_context.enable_lifetime,
type_64bit_int: partial_context.type_64bit_int,
forbid_type_self: false,
parse_mode: partial_context.parse_mode,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ fn create_parsing_context(
owner: None,
enable_lifetime,
type_64bit_int,
forbid_type_self: false,
parse_mode,
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use crate::codegen::ir::mir::func::{
MirFuncOutput, MirFuncOwnerInfo, MirFuncOwnerInfoMethod,
};
use crate::codegen::ir::mir::skip::MirSkipReason::{
IgnoreBecauseExplicitAttribute, IgnoreBecauseFunctionGeneric, IgnoreSilently,
IgnoreBecauseExplicitAttribute, IgnoreBecauseFunctionGeneric, IgnoreBecauseSelfTypeNotAllowed,
IgnoreSilently,
};
use crate::codegen::ir::mir::skip::{MirSkip, MirSkipReason};
use crate::codegen::ir::mir::ty::delegate::MirTypeDelegate;
Expand All @@ -19,6 +20,7 @@ use crate::codegen::parser::mir::parser::attribute::FrbAttributes;
use crate::codegen::parser::mir::parser::function::func_or_skip::MirFuncOrSkip;
use crate::codegen::parser::mir::parser::function::real::lifetime::parse_function_lifetime;
use crate::codegen::parser::mir::parser::function::real::owner::OwnerInfoOrSkip;
use crate::codegen::parser::mir::parser::ty::concrete::ERROR_MESSAGE_FORBID_TYPE_SELF;
use crate::codegen::parser::mir::parser::ty::generics::should_ignore_because_generics;
use crate::codegen::parser::mir::parser::ty::misc::parse_comments;
use crate::codegen::parser::mir::parser::ty::{TypeParser, TypeParserParsingContext};
Expand Down Expand Up @@ -150,25 +152,31 @@ impl<'a, 'b> FunctionParser<'a, 'b> {

let dart_name = parse_dart_name(&attributes, &func.item_fn.name());

let create_context = |owner: Option<MirFuncOwnerInfo>| TypeParserParsingContext {
initiated_namespace: func.namespace.clone(),
func_attributes: attributes.clone(),
struct_or_enum_attributes: None,
rust_output_path_namespace: rust_output_path_namespace.clone(),
default_stream_sink_codec,
default_rust_opaque_codec,
owner,
enable_lifetime,
type_64bit_int,
parse_mode,
};
let create_context =
|owner: Option<MirFuncOwnerInfo>, forbid_type_self: bool| TypeParserParsingContext {
initiated_namespace: func.namespace.clone(),
func_attributes: attributes.clone(),
struct_or_enum_attributes: None,
rust_output_path_namespace: rust_output_path_namespace.clone(),
default_stream_sink_codec,
default_rust_opaque_codec,
owner,
enable_lifetime,
type_64bit_int,
forbid_type_self,
parse_mode,
};

let is_owner_trait_def = matches!(func.owner, HirFlatFunctionOwner::TraitDef { .. });
let owner =
match self.parse_owner(func, &create_context(None), dart_name.clone(), &attributes)? {
OwnerInfoOrSkip::Info(info) => info,
OwnerInfoOrSkip::Skip(reason) => return Ok(create_output_skip(func, reason)),
};
let owner = match self.parse_owner(
func,
&create_context(None, false),
dart_name.clone(),
&attributes,
)? {
OwnerInfoOrSkip::Info(info) => info,
OwnerInfoOrSkip::Skip(reason) => return Ok(create_output_skip(func, reason)),
};

let func_name = parse_name(&func.item_fn.name(), &owner);

Expand All @@ -178,19 +186,38 @@ impl<'a, 'b> FunctionParser<'a, 'b> {

let lifetime_info = parse_function_lifetime(func.item_fn.sig(), &owner)?;

let context = create_context(Some(owner.clone()));
let context_input = create_context(
Some(owner.clone()),
should_forbid_type_self_for_inputs(&owner),
);
let context_output = create_context(Some(owner.clone()), false);
let mut info = FunctionPartialInfo::default();
for (i, sig_input) in func.item_fn.sig().inputs.iter().enumerate() {
info = info.merge(self.parse_fn_arg(
let arg_info = match self.parse_fn_arg(
sig_input,
&owner,
&context,
&context_input,
is_owner_trait_def,
lifetime_info.needs_extend_lifetime_per_arg[i],
)?)?;
) {
Ok(x) => x,
Err(e) => {
// TODO later use real error enums
return if e.to_string().contains(ERROR_MESSAGE_FORBID_TYPE_SELF) {
Ok(create_output_skip(func, IgnoreBecauseSelfTypeNotAllowed))
} else {
Err(e)
}
}
};
info = info.merge(arg_info)?;
}
info =
info.merge(self.parse_fn_output(func.item_fn.sig(), &owner, &context, &attributes)?)?;
info = info.merge(self.parse_fn_output(
func.item_fn.sig(),
&owner,
&context_output,
&attributes,
)?)?;
info = self.transform_fn_info(info);

let codec_mode_pack = compute_codec_mode_pack(&attributes, force_codec_mode_pack);
Expand Down Expand Up @@ -236,6 +263,16 @@ impl<'a, 'b> FunctionParser<'a, 'b> {
}
}

fn should_forbid_type_self_for_inputs(owner: &MirFuncOwnerInfo) -> bool {
if let MirFuncOwnerInfo::Method(method) = owner {
if matches!(method.owner_ty, MirType::TraitDef(_)) {
// #2089
return true;
}
}
false
}

fn create_output_skip(func: &HirFlatFunction, reason: MirSkipReason) -> MirFuncOrSkip {
MirFuncOrSkip::Skip(MirSkip {
name: NamespacedName::new(func.namespace.clone(), func.item_fn.name().to_string()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub(crate) fn parse(
owner: None,
enable_lifetime,
type_64bit_int,
forbid_type_self: false,
parse_mode,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> {
}

fn parse_type_self(&mut self) -> anyhow::Result<MirType> {
if self.context.forbid_type_self {
bail!("{}", ERROR_MESSAGE_FORBID_TYPE_SELF);
}

let enum_or_struct_name = if_then_some!(
let MirFuncOwnerInfo::Method(info) = self.context.owner.as_ref().context("owner is null")?,
info.owner_ty_name().context("owner_ty_name is null")?.name.clone()
Expand Down Expand Up @@ -137,3 +141,5 @@ fn parse_stream_sink_codec(codec: &Type) -> anyhow::Result<CodecMode> {
fn stream_sink_err_type() -> Box<MirType> {
Box::new(MirType::Delegate(MirTypeDelegate::AnyhowException))
}

pub(crate) const ERROR_MESSAGE_FORBID_TYPE_SELF: &str = "ERROR_MESSAGE_FORBID_TYPE_SELF";
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ pub(crate) struct TypeParserParsingContext {
pub(crate) owner: Option<MirFuncOwnerInfo>,
pub(crate) enable_lifetime: bool,
pub(crate) type_64bit_int: bool,
pub(crate) forbid_type_self: bool,
pub(crate) parse_mode: ParseMode,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::codegen::ir::mir::field::MirField;
use crate::library::codegen::ir::mir::ty::MirTypeTrait;
use crate::utils::namespace::NamespacedName;
use itertools::Itertools;
use log::warn;
use log::info;

pub(crate) fn check_field(
struct_name: &NamespacedName,
Expand All @@ -18,7 +18,7 @@ pub(crate) fn report(hints: &[SanityCheckHint]) {
return;
}

warn!(
info!(
"To use the automatically generated getters of the following fields of opaque types, \
it is suggested to read https://fzyzcjy.github.io/flutter_rust_bridge/guides/types/arbitrary/rust-auto-opaque/properties to know more details. \
(Related fields: {})",
Expand Down
Loading

0 comments on commit 97f4df4

Please sign in to comment.