fix private fields in #[hdl] pub struct #50
5 changed files with 163 additions and 26 deletions
|
|
@ -224,7 +224,7 @@ impl Builder {
|
||||||
.args
|
.args
|
||||||
.push_value(match get_field_state(field_index) {
|
.push_value(match get_field_state(field_index) {
|
||||||
BuilderFieldState::Unfilled => parse_quote_spanned! {self.ident.span()=>
|
BuilderFieldState::Unfilled => parse_quote_spanned! {self.ident.span()=>
|
||||||
::fayalite::bundle::Unfilled<#ty>
|
()
|
||||||
},
|
},
|
||||||
BuilderFieldState::Generic => {
|
BuilderFieldState::Generic => {
|
||||||
let type_var = type_var_for_field_name(ident);
|
let type_var = type_var_for_field_name(ident);
|
||||||
|
|
@ -383,7 +383,7 @@ impl ToTokens for Builder {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
#ident {
|
#ident {
|
||||||
#phantom_field_name: ::fayalite::__std::marker::PhantomData,
|
#phantom_field_name: ::fayalite::__std::marker::PhantomData,
|
||||||
#(#field_idents: ::fayalite::__std::default::Default::default(),)*
|
#(#field_idents: (),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -395,7 +395,7 @@ impl ToTokens for Builder {
|
||||||
let type_generics = self.generics.split_for_impl().1;
|
let type_generics = self.generics.split_for_impl().1;
|
||||||
quote_spanned! {self.ident.span()=>
|
quote_spanned! {self.ident.span()=>
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
#[allow(non_camel_case_types, dead_code)]
|
#[allow(non_camel_case_types, dead_code, private_interfaces)]
|
||||||
impl #filled_impl_generics ::fayalite::expr::ToExpr for #filled_ty
|
impl #filled_impl_generics ::fayalite::expr::ToExpr for #filled_ty
|
||||||
#filled_where_clause
|
#filled_where_clause
|
||||||
{
|
{
|
||||||
|
|
@ -499,7 +499,6 @@ impl ToTokens for ParsedBundle {
|
||||||
};
|
};
|
||||||
builder.to_tokens(tokens);
|
builder.to_tokens(tokens);
|
||||||
let unfilled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Unfilled);
|
let unfilled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Unfilled);
|
||||||
let filled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Filled);
|
|
||||||
let mut mask_type_fields = FieldsNamed::from(fields.clone());
|
let mut mask_type_fields = FieldsNamed::from(fields.clone());
|
||||||
for Field { ty, .. } in &mut mask_type_fields.named {
|
for Field { ty, .. } in &mut mask_type_fields.named {
|
||||||
*ty = parse_quote_spanned! {span=>
|
*ty = parse_quote_spanned! {span=>
|
||||||
|
|
@ -517,8 +516,6 @@ impl ToTokens for ParsedBundle {
|
||||||
mask_type_builder.to_tokens(tokens);
|
mask_type_builder.to_tokens(tokens);
|
||||||
let unfilled_mask_type_builder_ty =
|
let unfilled_mask_type_builder_ty =
|
||||||
mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled);
|
mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled);
|
||||||
let filled_mask_type_builder_ty =
|
|
||||||
mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Filled);
|
|
||||||
ItemStruct {
|
ItemStruct {
|
||||||
attrs: vec![
|
attrs: vec![
|
||||||
common_derives(span),
|
common_derives(span),
|
||||||
|
|
@ -785,7 +782,6 @@ impl ToTokens for ParsedBundle {
|
||||||
#where_clause
|
#where_clause
|
||||||
{
|
{
|
||||||
type Builder = #unfilled_mask_type_builder_ty;
|
type Builder = #unfilled_mask_type_builder_ty;
|
||||||
type FilledBuilder = #filled_mask_type_builder_ty;
|
|
||||||
fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
|
fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
|
||||||
::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..])
|
::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..])
|
||||||
}
|
}
|
||||||
|
|
@ -935,7 +931,6 @@ impl ToTokens for ParsedBundle {
|
||||||
#where_clause
|
#where_clause
|
||||||
{
|
{
|
||||||
type Builder = #unfilled_builder_ty;
|
type Builder = #unfilled_builder_ty;
|
||||||
type FilledBuilder = #filled_builder_ty;
|
|
||||||
fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
|
fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
|
||||||
::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..])
|
::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4612,3 +4612,124 @@ impl MakeHdlTypeExpr for ParsedTypeTuple {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub(crate) enum ParsedSimpleVisibility {
|
||||||
|
Public(Token![pub]),
|
||||||
|
PubCrate {
|
||||||
|
pub_token: Token![pub],
|
||||||
|
paren_token: Paren,
|
||||||
|
crate_token: Token![crate],
|
||||||
|
},
|
||||||
|
Inherited,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParsedSimpleVisibility> for Visibility {
|
||||||
|
fn from(value: ParsedSimpleVisibility) -> Self {
|
||||||
|
match value {
|
||||||
|
ParsedSimpleVisibility::Public(v) => Visibility::Public(v),
|
||||||
|
ParsedSimpleVisibility::PubCrate {
|
||||||
|
pub_token,
|
||||||
|
paren_token,
|
||||||
|
crate_token,
|
||||||
|
} => Visibility::Restricted(syn::VisRestricted {
|
||||||
|
pub_token,
|
||||||
|
paren_token,
|
||||||
|
in_token: None,
|
||||||
|
path: Box::new(Ident::new("crate", crate_token.span).into()),
|
||||||
|
}),
|
||||||
|
ParsedSimpleVisibility::Inherited => Visibility::Inherited,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for ParsedSimpleVisibility {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for ParsedSimpleVisibility {
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
self.visibility_level().cmp(&other.visibility_level())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParsedSimpleVisibility {
|
||||||
|
const VISIBILITY_LEVEL_INHERITED: u8 = 0;
|
||||||
|
const VISIBILITY_LEVEL_RESTRICTED: u8 = 1 + Self::VISIBILITY_LEVEL_INHERITED;
|
||||||
|
const VISIBILITY_LEVEL_PUB_CRATE: u8 = 1 + Self::VISIBILITY_LEVEL_RESTRICTED;
|
||||||
|
const VISIBILITY_LEVEL_PUB: u8 = 1 + Self::VISIBILITY_LEVEL_PUB_CRATE;
|
||||||
|
fn visibility_level(self) -> u8 {
|
||||||
|
match self {
|
||||||
|
Self::Public(_) => Self::VISIBILITY_LEVEL_PUB,
|
||||||
|
Self::PubCrate { .. } => Self::VISIBILITY_LEVEL_PUB_CRATE,
|
||||||
|
Self::Inherited => Self::VISIBILITY_LEVEL_INHERITED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn parse(vis: Visibility) -> Result<Self, syn::VisRestricted> {
|
||||||
|
match vis {
|
||||||
|
Visibility::Public(v) => Ok(Self::Public(v)),
|
||||||
|
Visibility::Restricted(syn::VisRestricted {
|
||||||
|
pub_token,
|
||||||
|
paren_token,
|
||||||
|
in_token: None,
|
||||||
|
path,
|
||||||
|
}) if path.is_ident("crate") => Ok(Self::PubCrate {
|
||||||
|
pub_token,
|
||||||
|
paren_token,
|
||||||
|
crate_token: Token.expect("just checked").span()),
|
||||||
|
}),
|
||||||
|
Visibility::Restricted(v) => Err(v),
|
||||||
|
Visibility::Inherited => Ok(Self::Inherited),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub(crate) enum ParsedVisibility {
|
||||||
|
Simple(ParsedSimpleVisibility),
|
||||||
|
Restricted(syn::VisRestricted),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParsedVisibility> for Visibility {
|
||||||
|
fn from(value: ParsedVisibility) -> Self {
|
||||||
|
match value {
|
||||||
|
ParsedVisibility::Simple(v) => v.into(),
|
||||||
|
ParsedVisibility::Restricted(v) => Visibility::Restricted(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for ParsedVisibility {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
match (self, other) {
|
||||||
|
(ParsedVisibility::Simple(l), ParsedVisibility::Simple(r)) => Some(l.cmp(r)),
|
||||||
|
(ParsedVisibility::Simple(l), ParsedVisibility::Restricted(_)) => Some(
|
||||||
|
l.visibility_level()
|
||||||
|
.cmp(&ParsedSimpleVisibility::VISIBILITY_LEVEL_RESTRICTED),
|
||||||
|
),
|
||||||
|
(ParsedVisibility::Restricted(_), ParsedVisibility::Simple(r)) => {
|
||||||
|
Some(ParsedSimpleVisibility::VISIBILITY_LEVEL_RESTRICTED.cmp(&r.visibility_level()))
|
||||||
|
}
|
||||||
|
(ParsedVisibility::Restricted(l), ParsedVisibility::Restricted(r)) => {
|
||||||
|
(l == r).then_some(std::cmp::Ordering::Equal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParsedVisibility {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) fn parse(vis: Visibility) -> Self {
|
||||||
|
match ParsedSimpleVisibility::parse(vis) {
|
||||||
|
Ok(simple) => Self::Simple(simple),
|
||||||
|
Err(restricted) => Self::Restricted(restricted),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) fn min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
|
||||||
|
self.partial_cmp(other)
|
||||||
|
.map(|ord| if ord.is_lt() { self } else { other })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,6 @@ impl Type for Bundle {
|
||||||
|
|
||||||
pub trait BundleType: Type<BaseType = Bundle> {
|
pub trait BundleType: Type<BaseType = Bundle> {
|
||||||
type Builder: Default;
|
type Builder: Default;
|
||||||
type FilledBuilder: ToExpr<Type = Self>;
|
|
||||||
fn fields(&self) -> Interned<[BundleField]>;
|
fn fields(&self) -> Interned<[BundleField]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -374,17 +373,8 @@ impl<'a> BundleSimValueToOpaque<'a> {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct NoBuilder;
|
pub struct NoBuilder;
|
||||||
|
|
||||||
pub struct Unfilled<T: Type>(PhantomData<T>);
|
|
||||||
|
|
||||||
impl<T: Type> Default for Unfilled<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self(PhantomData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BundleType for Bundle {
|
impl BundleType for Bundle {
|
||||||
type Builder = NoBuilder;
|
type Builder = NoBuilder;
|
||||||
type FilledBuilder = Expr<Bundle>;
|
|
||||||
fn fields(&self) -> Interned<[BundleField]> {
|
fn fields(&self) -> Interned<[BundleField]> {
|
||||||
self.0.fields
|
self.0.fields
|
||||||
}
|
}
|
||||||
|
|
@ -420,15 +410,14 @@ macro_rules! impl_tuple_builder_fields {
|
||||||
) => {
|
) => {
|
||||||
impl<
|
impl<
|
||||||
$($head_type_var,)*
|
$($head_type_var,)*
|
||||||
$cur_type_var: Type,
|
|
||||||
$($tail_type_var,)*
|
$($tail_type_var,)*
|
||||||
> TupleBuilder<(
|
> TupleBuilder<(
|
||||||
$($head_type_var,)*
|
$($head_type_var,)*
|
||||||
Unfilled<$cur_type_var>,
|
(),
|
||||||
$($tail_type_var,)*
|
$($tail_type_var,)*
|
||||||
)>
|
)>
|
||||||
{
|
{
|
||||||
pub fn $cur_field(self, $cur_var: impl ToExpr<Type = $cur_type_var>) -> TupleBuilder<(
|
pub fn $cur_field<$cur_type_var: Type>(self, $cur_var: impl ToExpr<Type = $cur_type_var>) -> TupleBuilder<(
|
||||||
$($head_type_var,)*
|
$($head_type_var,)*
|
||||||
Expr<$cur_type_var>,
|
Expr<$cur_type_var>,
|
||||||
$($tail_type_var,)*
|
$($tail_type_var,)*
|
||||||
|
|
@ -452,6 +441,12 @@ macro_rules! impl_tuple_builder_fields {
|
||||||
($global:tt []) => {};
|
($global:tt []) => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! get_unit_ty {
|
||||||
|
($($tt:tt)*) => {
|
||||||
|
()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! impl_tuples {
|
macro_rules! impl_tuples {
|
||||||
(
|
(
|
||||||
[$({
|
[$({
|
||||||
|
|
@ -545,8 +540,7 @@ macro_rules! impl_tuples {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<$($T: Type,)*> BundleType for ($($T,)*) {
|
impl<$($T: Type,)*> BundleType for ($($T,)*) {
|
||||||
type Builder = TupleBuilder<($(Unfilled<$T>,)*)>;
|
type Builder = TupleBuilder<($(get_unit_ty!($T),)*)>;
|
||||||
type FilledBuilder = TupleBuilder<($(Expr<$T>,)*)>;
|
|
||||||
fn fields(&self) -> Interned<[BundleField]> {
|
fn fields(&self) -> Interned<[BundleField]> {
|
||||||
let ($($var,)*) = self;
|
let ($($var,)*) = self;
|
||||||
[$(BundleField { name: stringify!($num).intern(), flipped: false, ty: $var.canonical() }),*].intern_slice()
|
[$(BundleField { name: stringify!($num).intern(), flipped: false, ty: $var.canonical() }),*].intern_slice()
|
||||||
|
|
@ -791,7 +785,6 @@ impl<T: ?Sized + Send + Sync + 'static> ToExpr for PhantomDataBuilder<T> {
|
||||||
|
|
||||||
impl<T: ?Sized + Send + Sync + 'static> BundleType for PhantomData<T> {
|
impl<T: ?Sized + Send + Sync + 'static> BundleType for PhantomData<T> {
|
||||||
type Builder = PhantomDataBuilder<T>;
|
type Builder = PhantomDataBuilder<T>;
|
||||||
type FilledBuilder = PhantomDataBuilder<T>;
|
|
||||||
fn fields(&self) -> Interned<[BundleField]> {
|
fn fields(&self) -> Interned<[BundleField]> {
|
||||||
Interned::default()
|
Interned::default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,6 @@ impl Type for UIntInRangeMaskType {
|
||||||
|
|
||||||
impl BundleType for UIntInRangeMaskType {
|
impl BundleType for UIntInRangeMaskType {
|
||||||
type Builder = NoBuilder;
|
type Builder = NoBuilder;
|
||||||
type FilledBuilder = Expr<UIntInRangeMaskType>;
|
|
||||||
|
|
||||||
fn fields(&self) -> Interned<[BundleField]> {
|
fn fields(&self) -> Interned<[BundleField]> {
|
||||||
let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES;
|
let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES;
|
||||||
|
|
@ -400,7 +399,6 @@ macro_rules! define_uint_in_range_type {
|
||||||
|
|
||||||
impl<Start: Size, End: Size> BundleType for $UIntInRangeType<Start, End> {
|
impl<Start: Size, End: Size> BundleType for $UIntInRangeType<Start, End> {
|
||||||
type Builder = NoBuilder;
|
type Builder = NoBuilder;
|
||||||
type FilledBuilder = Expr<Self>;
|
|
||||||
|
|
||||||
fn fields(&self) -> Interned<[BundleField]> {
|
fn fields(&self) -> Interned<[BundleField]> {
|
||||||
let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES;
|
let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES;
|
||||||
|
|
|
||||||
|
|
@ -214,3 +214,33 @@ pub struct MyTypeWithPhantomConstParameter<P: PhantomConstGet<MyPhantomConstInne
|
||||||
pub a: ArrayType<Bool, GetA<P>>,
|
pub a: ArrayType<Bool, GetA<P>>,
|
||||||
pub b: HdlOption<GetB<P>>,
|
pub b: HdlOption<GetB<P>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[hdl(outline_generated)]
|
||||||
|
struct MyPrivateType {}
|
||||||
|
|
||||||
|
#[hdl(outline_generated)]
|
||||||
|
pub(crate) struct MyPubCrateType {}
|
||||||
|
|
||||||
|
#[hdl(outline_generated)]
|
||||||
|
pub struct MyTypeWithPrivateMembers {
|
||||||
|
a: MyPrivateType,
|
||||||
|
pub(crate) b: MyPubCrateType,
|
||||||
|
pub c: Bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl(outline_generated)]
|
||||||
|
struct MyPrivateTypeWithArg<T> {
|
||||||
|
v: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl(outline_generated)]
|
||||||
|
pub(crate) struct MyPubCrateTypeWithArg<T> {
|
||||||
|
v: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl(outline_generated)]
|
||||||
|
pub struct MyTypeWithPrivateMembersWithArg<T> {
|
||||||
|
a: MyPrivateTypeWithArg<T>,
|
||||||
|
pub(crate) b: MyPubCrateTypeWithArg<T>,
|
||||||
|
pub c: T,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue