Skip to content

Commit

Permalink
foreign types that are not capabilities, Range<Idx>, Request
Browse files Browse the repository at this point in the history
  • Loading branch information
StuartHarris committed Dec 12, 2024
1 parent 47af93d commit fb795cf
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 14 deletions.
15 changes: 10 additions & 5 deletions crux_cli/src/codegen/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,23 @@ ascent! {
local_type_of(effect_ffi_item, effect_ffi),
if effect_impl.has_associated_item(effect_ffi_item, "Ffi");

// Capability is a struct/enum with an implementation of the Capability trait
relation capability(ItemNode, ItemNode);
capability(cap, cap_impl) <--
subset(cap),
subset(cap_impl),
if cap_impl.is_impl_for(cap, "Capability");

// Operation is an associated type of an impl of the Capability trait
relation operation(ItemNode);
operation(op) <--
subset(cap),
subset(cap_impl),
if cap_impl.is_impl_for(cap, "Capability"),
capability(cap, cap_impl),
local_type_of(item, op),
if cap_impl.has_associated_item(item, "Operation");
operation(op) <--
start_with(s),
has_summary(cap, s),
subset(cap_impl),
if cap_impl.is_impl_for(cap, "Capability"),
capability(cap, cap_impl),
local_type_of(item, op),
if cap_impl.has_associated_item(item, "Operation");

Expand All @@ -118,6 +122,7 @@ ascent! {
root(x) <-- effect(app, x);
root(x) <-- operation(x);
root(x) <-- output(x);
root(x) <-- start_with(s), has_summary(x, s), !capability(x, _);

// set of all the edges we are interested in
relation edge(ItemNode, ItemNode);
Expand Down
68 changes: 61 additions & 7 deletions crux_cli/src/codegen/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,28 @@ ascent! {
relation container(String, ContainerFormat);
container(name, container) <--
struct_plain(s),
agg fields = collect(format) in format_named(s, format),
if let Some(name) = s.name(),
let container = make_struct_plain(&fields);
agg field_formats = collect(format) in format_named(s, format),
let container = make_struct_plain(&field_formats);
container(name, container) <--
struct_unit(s),
if let Some(name) = s.name(),
let container = make_struct_unit();
container(name, container) <--
struct_tuple(s),
agg fields = collect(format) in format(s, format),
if let Some(name) = s.name(),
let container = make_struct_tuple(&fields);
agg field_formats = collect(format) in format(s, format),
let container = make_struct_tuple(&field_formats);
container(name, container) <--
variant(e, _),
agg variants = collect(format) in format_variant(e, format),
if let Some(name) = e.name(),
let container = make_enum(&variants);
agg variant_formats = collect(format) in format_variant(e, format),
let container = make_enum(&variant_formats);
container("Range".to_string(), container) <--
field(_, f), if f.is_range(),
if let Some(container) = make_range(f);
container("Request".to_string(), container) <--
let container = make_request();
}

fn make_format(field: &ItemNode, all_fields: &Vec<ItemNode>) -> Option<Indexed<Format>> {
Expand Down Expand Up @@ -321,6 +326,55 @@ fn make_enum(formats: &Vec<(&Indexed<Named<VariantFormat>>,)>) -> ContainerForma
ContainerFormat::Enum(map)
}

fn make_range(field: &ItemNode) -> Option<ContainerFormat> {
match &field.0.inner {
ItemEnum::StructField(range_type) => {
let field_format: Option<Format> = match range_type {
Type::ResolvedPath(path) => match &path.args {
Some(args) => match args.as_ref() {
GenericArgs::AngleBracketed { args, .. } => {
let type_ = args.iter().next()?;
match type_ {
GenericArg::Type(ref type_) => Some(type_.into()),
_ => None,
}
}
_ => None,
},
_ => None,
},
_ => None,
};
field_format.map(|f| {
ContainerFormat::Struct(vec![
Named {
name: "start".to_string(),
value: f.clone(),
},
Named {
name: "end".to_string(),
value: f.clone(),
},
])
})
}
_ => None,
}
}

fn make_request() -> ContainerFormat {
ContainerFormat::Struct(vec![
Named {
name: "id".to_string(),
value: Format::U32,
},
Named {
name: "effect".to_string(),
value: Format::TypeName("Effect".to_string()),
},
])
}

impl From<&Type> for Format {
fn from(type_: &Type) -> Self {
match type_ {
Expand Down Expand Up @@ -358,7 +412,7 @@ impl From<&Type> for Format {
}
}
Type::DynTrait(_dyn_trait) => todo!(),
Type::Generic(_) => todo!(),
Type::Generic(_param_name) => todo!(),
Type::Primitive(s) => match s.as_ref() {
"bool" => Format::Bool,
"char" => Format::Char,
Expand Down
2 changes: 1 addition & 1 deletion crux_cli/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ fn format(edges: Vec<(ItemNode, ItemNode)>) -> Registry {
formatter.container.into_iter().collect()
}

fn load_crate(name: &str, manifest_paths: &BTreeMap<&str, &str>) -> Result<Crate, anyhow::Error> {
fn load_crate(name: &str, manifest_paths: &BTreeMap<&str, &str>) -> Result<Crate> {
// TODO: ensure that the user has installed the core rustdoc JSON files
// e.g. `rustup component add --toolchain nightly rust-docs-json`

Expand Down
12 changes: 11 additions & 1 deletion crux_cli/src/codegen/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,16 @@ impl ItemNode {
}
}

pub fn is_range(&self) -> bool {
matches!(
&self.0,
Item {
inner: ItemEnum::StructField(Type::ResolvedPath(Path { name, .. })),
..
} if name == "std::ops::Range"
)
}

fn should_skip(&self) -> bool {
self.0
.attrs
Expand Down Expand Up @@ -368,7 +378,7 @@ fn check_type(parent: &Id, type_: &Type, is_remote: bool) -> bool {
match type_ {
Type::ResolvedPath(Path { name, id, args }) => {
if is_remote {
if let "Option" | "String" | "Vec" = name.as_str() {
if let "Option" | "String" | "Vec" | "std::ops::Range" = name.as_str() {
return false;
}
}
Expand Down

0 comments on commit fb795cf

Please sign in to comment.