Skip to content

Commit

Permalink
recursively process generic args
Browse files Browse the repository at this point in the history
  • Loading branch information
StuartHarris committed Oct 28, 2024
1 parent b4aff89 commit bbfb454
Showing 1 changed file with 44 additions and 28 deletions.
72 changes: 44 additions & 28 deletions crux_cli/src/codegen/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,6 @@ pub fn parse(crate_: &Crate) -> Result<String> {
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;
Expand All @@ -128,24 +123,8 @@ pub fn parse(crate_: &Crate) -> Result<String> {
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);
}
}
_ => (),
Expand Down Expand Up @@ -191,34 +170,43 @@ pub fn parse(crate_: &Crate) -> Result<String> {
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
Expand All @@ -245,10 +233,10 @@ pub fn parse(crate_: &Crate) -> Result<String> {
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
Expand All @@ -257,6 +245,8 @@ pub fn parse(crate_: &Crate) -> Result<String> {
continue;
}
}

// record an edge for the associated type
let Some(dest) = node_by_id(&target.id) else {
continue;
};
Expand All @@ -282,6 +272,32 @@ pub fn parse(crate_: &Crate) -> Result<String> {
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,
Expand Down

0 comments on commit bbfb454

Please sign in to comment.