Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect and skip functions with generics #2015

Merged
merged 15 commits into from
Jun 3, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ pub(crate) trait SynItemStructOrEnum: Clone {
fn attrs(&self) -> &[Attribute];

fn attrs_mut(&mut self) -> &mut Vec<Attribute>;

fn generics(&self) -> &Generics;
}

macro_rules! impl_trait {
Expand All @@ -16,6 +18,10 @@ macro_rules! impl_trait {
fn attrs_mut(&mut self) -> &mut Vec<syn::Attribute> {
&mut self.attrs
}

fn generics(&self) -> &syn::Generics {
&self.generics
}
}
};
}
Expand Down
4 changes: 4 additions & 0 deletions frb_codegen/src/library/codegen/ir/mir/skip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct MirSkip {
#[derive(Copy, PartialOrd, Ord)]
pub(crate) enum MirSkipReason {
IgnoredFunctionNotPub,
IgnoredFunctionGeneric,
IgnoredTypeNotUsedByPub,
IgnoredMisc,
Err,
Expand All @@ -21,6 +22,9 @@ impl MirSkipReason {
Self::IgnoredFunctionNotPub => {
"These functions are ignored because they are not marked as `pub`"
}
Self::IgnoredFunctionGeneric => {
"These functions are ignored because they have generic arguments"
}
Self::IgnoredTypeNotUsedByPub => {
"These types are ignored because they are not used by any `pub` functions"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::codegen::parser::mir::sanity_checker::auto_accessor_checker;
use crate::codegen::parser::mir::type_parser::{
TypeParser, TypeParserParsingContext, TypeParserWithContext,
};
use crate::library::codegen::ir::mir::ty::MirTypeTrait;
use crate::utils::namespace::NamespacedName;
use field::parse_auto_accessor_of_field;
use itertools::Itertools;
Expand Down Expand Up @@ -63,6 +64,9 @@ fn parse_auto_accessors_of_struct(
if !matches!(ty_direct_parse, MirType::RustAutoOpaqueImplicit(_)) {
return Ok(vec![]);
}
if ty_direct_parse.should_ignore(type_parser) {
return Ok(vec![]);
}

let ty_struct_ref = TypeParserWithContext::new(type_parser, &context)
.parse_type_path_data_struct(&(&struct_name.name, &[]), Some(false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::codegen::ir::mir::func::{
MirFunc, MirFuncArgMode, MirFuncInput, MirFuncMode, MirFuncOutput, MirFuncOwnerInfo,
MirFuncOwnerInfoMethod, MirFuncOwnerInfoMethodMode,
};
use crate::codegen::ir::mir::skip::MirSkipReason::IgnoredFunctionGeneric;
use crate::codegen::ir::mir::skip::{MirSkip, MirSkipReason};
use crate::codegen::ir::mir::ty::primitive::MirTypePrimitive;
use crate::codegen::ir::mir::ty::rust_opaque::RustOpaqueCodecMode;
Expand Down Expand Up @@ -80,6 +81,13 @@ impl<'a, 'b> FunctionParser<'a, 'b> {
IgnoredFunctionNotPub,
));
}
if !func.sig().generics.params.is_empty() {
return Ok(create_output_skip(
func,
namespace_naive,
IgnoredFunctionGeneric,
));
}

let src_lineno = func.span().start().line;
let attributes = FrbAttributes::parse(func.attrs())?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use crate::codegen::ir::hir::hierarchical::struct_or_enum::HirStructOrEnum;
use crate::codegen::ir::hir::hierarchical::syn_item_struct_or_enum::SynItemStructOrEnum;
use crate::codegen::ir::mir::ty::MirType;
use crate::codegen::parser::mir::attribute_parser::FrbAttributes;
use crate::codegen::parser::mir::type_parser::misc::parse_type_should_ignore_simple;
use crate::codegen::parser::mir::type_parser::unencodable::SplayedSegment;
use crate::library::codegen::ir::mir::ty::MirTypeTrait;
use crate::utils::crate_name::CrateName;
use crate::utils::namespace::{Namespace, NamespacedName};
use log::debug;
use std::collections::{HashMap, HashSet};
Expand Down Expand Up @@ -37,7 +37,6 @@ where

if let Some(src_object) = self.src_objects().get(*name) {
let src_object = (*src_object).clone();
let vis = src_object.visibility;

let namespace = &src_object.namespaced_name.namespace;
let namespaced_name = NamespacedName::new(namespace.clone(), name.to_string());
Expand All @@ -47,7 +46,7 @@ where
if attrs_opaque == Some(true) {
debug!("Treat {name} as opaque since attribute says so");
return Ok(Some((
self.parse_opaque(&namespaced_name, &attrs, vis)?,
self.parse_opaque(&namespaced_name, &src_object)?,
attrs,
)));
}
Expand All @@ -70,7 +69,7 @@ where
{
debug!("Treat {name} as opaque by compute_default_opaque");
return Ok(Some((
self.parse_opaque(&namespaced_name, &attrs, vis)?,
self.parse_opaque(&namespaced_name, &src_object)?,
attrs,
)));
}
Expand Down Expand Up @@ -102,15 +101,13 @@ where
fn parse_opaque(
&mut self,
namespaced_name: &NamespacedName,
attrs: &FrbAttributes,
vis: HirVisibility,
src_object: &HirStructOrEnum<Item>,
) -> anyhow::Result<MirType> {
self.parse_type_rust_auto_opaque_implicit(
Some(namespaced_name.namespace.clone()),
&syn::parse_str(&namespaced_name.name)?,
Some(parse_type_should_ignore_simple(
attrs,
vis,
Some(parse_struct_or_enum_should_ignore(
src_object,
&namespaced_name.namespace.crate_name(),
)),
)
Expand Down Expand Up @@ -170,3 +167,16 @@ fn compute_name_and_wrapper_name(
};
(namespaced_name, wrapper_name)
}

pub(crate) fn parse_struct_or_enum_should_ignore<Item: SynItemStructOrEnum>(
src_object: &HirStructOrEnum<Item>,
crate_name: &CrateName,
) -> bool {
let attrs = FrbAttributes::parse(src_object.src.attrs()).unwrap();

attrs.ignore()
// For third party crates, if a struct is not public, then it is impossible to utilize it,
// thus we ignore it.
|| (crate_name != &CrateName::self_crate() && src_object.visibility != HirVisibility::Public)
|| !src_object.src.generics().params.is_empty()
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ use crate::codegen::ir::mir::ty::MirType;
use crate::codegen::ir::mir::ty::MirType::{Delegate, EnumRef};
use crate::codegen::parser::mir::attribute_parser::FrbAttributes;
use crate::codegen::parser::mir::type_parser::enum_or_struct::{
EnumOrStructParser, EnumOrStructParserInfo,
};
use crate::codegen::parser::mir::type_parser::misc::{
parse_comments, parse_type_should_ignore_simple,
parse_struct_or_enum_should_ignore, EnumOrStructParser, EnumOrStructParserInfo,
};
use crate::codegen::parser::mir::type_parser::misc::parse_comments;
use crate::codegen::parser::mir::type_parser::structure::structure_compute_default_opaque;
use crate::codegen::parser::mir::type_parser::unencodable::SplayedSegment;
use crate::codegen::parser::mir::type_parser::TypeParserWithContext;
Expand All @@ -39,8 +37,6 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> {
name: NamespacedName,
wrapper_name: Option<String>,
) -> anyhow::Result<MirEnum> {
let attributes = FrbAttributes::parse(&src_enum.src.attrs)?;

let comments = parse_comments(&src_enum.src.attrs);
let raw_variants = src_enum
.src
Expand All @@ -51,11 +47,7 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> {

let mode = compute_enum_mode(&raw_variants);
let variants = maybe_field_wrap_box(raw_variants, mode);
let ignore = parse_type_should_ignore_simple(
&attributes,
src_enum.visibility,
&name.namespace.crate_name(),
);
let ignore = parse_struct_or_enum_should_ignore(src_enum, &name.namespace.crate_name());

Ok(MirEnum {
name,
Expand Down
14 changes: 0 additions & 14 deletions frb_codegen/src/library/codegen/parser/mir/type_parser/misc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use crate::codegen::ir::hir::hierarchical::module::HirVisibility;
use crate::codegen::ir::mir::comment::MirComment;
use crate::codegen::parser::mir::attribute_parser::FrbAttributes;
use crate::utils::crate_name::CrateName;
use itertools::Itertools;
use syn::*;

Expand Down Expand Up @@ -48,14 +45,3 @@ fn parse_comment(input: &str) -> MirComment {
format!("///{input}")
})
}

pub(crate) fn parse_type_should_ignore_simple(
attrs: &FrbAttributes,
vis: HirVisibility,
crate_name: &CrateName,
) -> bool {
attrs.ignore()
// For third party crates, if a struct is not public, then it is impossible to utilize it,
// thus we ignore it.
|| (crate_name != &CrateName::self_crate() && vis != HirVisibility::Public)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ use crate::codegen::ir::mir::ty::MirType;
use crate::codegen::ir::mir::ty::MirType::StructRef;
use crate::codegen::parser::mir::attribute_parser::FrbAttributes;
use crate::codegen::parser::mir::type_parser::enum_or_struct::{
EnumOrStructParser, EnumOrStructParserInfo,
};
use crate::codegen::parser::mir::type_parser::misc::{
parse_comments, parse_type_should_ignore_simple,
parse_struct_or_enum_should_ignore, EnumOrStructParser, EnumOrStructParserInfo,
};
use crate::codegen::parser::mir::type_parser::misc::parse_comments;
use crate::codegen::parser::mir::type_parser::unencodable::SplayedSegment;
use crate::codegen::parser::mir::type_parser::TypeParserWithContext;
use crate::utils::namespace::{Namespace, NamespacedName};
Expand Down Expand Up @@ -53,11 +51,7 @@ impl<'a, 'b, 'c> TypeParserWithContext<'a, 'b, 'c> {
let attributes = FrbAttributes::parse(&src_struct.src.attrs)?;
let dart_metadata = attributes.dart_metadata();

let ignore = parse_type_should_ignore_simple(
&attributes,
src_struct.visibility,
&name.namespace.crate_name(),
);
let ignore = parse_struct_or_enum_should_ignore(src_struct, &name.namespace.crate_name());

Ok(MirStruct {
name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"enum_pool": {
"crate::api/MyGenericEnum": {
"comments": [],
"ignore": false,
"ignore": true,
"mode": "Complex",
"name": "crate::api/MyGenericEnum",
"variants": [
Expand Down Expand Up @@ -528,7 +528,7 @@
],
"generate_eq": true,
"generate_hash": true,
"ignore": false,
"ignore": true,
"is_fields_named": true,
"name": "crate::api/MyGenericStruct",
"wrapper_name": null
Expand Down
Loading