diff --git a/crux_cli/src/codegen/parser.rs b/crux_cli/src/codegen/parser.rs index 0a950a95..93c2f4cc 100644 --- a/crux_cli/src/codegen/parser.rs +++ b/crux_cli/src/codegen/parser.rs @@ -105,11 +105,6 @@ pub fn parse(crate_: &Crate) -> Result { fields, has_stripped_fields: _, } => { - // unit struct - if fields.is_empty() { - prog.edge.push((source.clone(), source.clone(), Edge::Unit)); - } - for id in fields { let Some(dest) = node_by_id(id) else { continue; @@ -128,24 +123,8 @@ pub fn parse(crate_: &Crate) -> Result { prog.edge .push((source.clone(), dest.clone(), Edge::ForType)); - // TODO: make recursive if let Some(args) = &path.args { - if let GenericArgs::AngleBracketed { args, .. } = args.as_ref() { - for arg in args { - if let GenericArg::Type(t) = arg { - if let Type::ResolvedPath(path) = t { - let Some(dest) = node_by_id(&path.id) else { - continue; - }; - prog.edge.push(( - source.clone(), - dest.clone(), - Edge::ForType, - )); - }; - } - } - } + process_args(source, args.as_ref(), &node_by_id, &mut prog); } } _ => (), @@ -191,34 +170,43 @@ pub fn parse(crate_: &Crate) -> Result { ItemEnum::Trait(_) => (), ItemEnum::TraitAlias(_trait_alias) => (), ItemEnum::Impl(Impl { + for_: + Type::ResolvedPath(Path { + id: for_type_id, .. + }), trait_: Some(Path { id: trait_id, - name, + name: trait_name, args: _, }), - for_: Type::ResolvedPath(target), items, .. }) => { - if !["App", "Effect"].contains(&name.as_str()) { + if !["App", "Effect"].contains(&trait_name.as_str()) { continue; } - let Some(dest) = node_by_id(&target.id) else { + // record an edge for the type the impl is for + let Some(dest) = node_by_id(&for_type_id) else { continue; }; prog.edge .push((source.clone(), dest.clone(), Edge::ForType)); + // record an edge for the trait the impl is of let Some(dest) = node_by_id(trait_id) else { continue; }; prog.edge.push((source.clone(), dest.clone(), Edge::Trait)); + + // record edges for the associated items in the impl for id in items { let Some(dest) = node_by_id(id) else { continue; }; + + // skip everything except the Event and ViewModel associated types if let Some(Item { name: Some(name), .. }) = &dest.item @@ -245,10 +233,10 @@ pub fn parse(crate_: &Crate) -> Result { ItemEnum::Primitive(_primitive) => (), ItemEnum::AssocConst { type_: _, value: _ } => (), ItemEnum::AssocType { - generics: _, - bounds: _, type_: Some(Type::ResolvedPath(target)), + .. } => { + // skip everything except the Event, ViewModel and Ffi associated types if let Item { name: Some(name), .. } = &item @@ -257,6 +245,8 @@ pub fn parse(crate_: &Crate) -> Result { continue; } } + + // record an edge for the associated type let Some(dest) = node_by_id(&target.id) else { continue; }; @@ -282,6 +272,32 @@ pub fn parse(crate_: &Crate) -> Result { Ok(format!("")) } +fn process_args<'a>( + source: &Node, + args: &GenericArgs, + node_by_id: &impl Fn(&Id) -> Option<&'a Node>, + prog: &mut AscentProgram, +) { + if let GenericArgs::AngleBracketed { args, .. } = args { + for arg in args { + if let GenericArg::Type(t) = arg { + if let Type::ResolvedPath(path) = t { + let Some(dest) = node_by_id(&path.id) else { + continue; + }; + prog.edge + .push((source.clone(), dest.clone(), Edge::ForType)); + + if let Some(args) = &path.args { + let generic_args = args.as_ref(); + process_args(source, generic_args, node_by_id, prog); + } + }; + } + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize)] struct Node { id: Id,