Skip to content

Commit

Permalink
fix resource-own-in-other-interface test for C
Browse files Browse the repository at this point in the history
Signed-off-by: Joel Dice <[email protected]>
  • Loading branch information
dicej committed Oct 5, 2023
1 parent 989259f commit 7f97c3f
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 14 deletions.
114 changes: 100 additions & 14 deletions crates/c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ use wit_bindgen_core::{
};
use wit_component::StringEncoding;

#[derive(Default, Copy, Clone, PartialEq, Eq)]
#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)]
enum Direction {
#[default]
Import,
Export,
}

#[derive(Default)]
#[derive(Default, Debug)]
struct ResourceInfo {
direction: Direction,
borrow: Option<TypeId>,
Expand Down Expand Up @@ -650,22 +650,21 @@ impl C {
resolve: &Resolve,
handle: &Handle,
handles: &HashMap<&Handle, TypeId>,
owner: TypeOwner,
) -> Option<TypeId> {
let mut target = match handle {
Handle::Borrow(target) => target,
Handle::Own(target) => target,
};
let (Handle::Borrow(mut target) | Handle::Own(mut target)) = handle;

loop {
if let TypeDefKind::Type(Type::Id(id)) = &resolve.types[*target].kind {
let def = &resolve.types[target];
if let TypeDefKind::Type(Type::Id(id)) = &def.kind {
let target_handle = match handle {
Handle::Borrow(_) => Handle::Borrow(*id),
Handle::Own(_) => Handle::Own(*id),
};
if let Some(ty) = handles.get(&target_handle) {
if let (true, Some(ty)) = (def.owner == owner, handles.get(&target_handle)) {
break Some(*ty);
} else {
target = id;
target = *id;
}
} else {
break None;
Expand Down Expand Up @@ -698,8 +697,8 @@ impl C {

let prev = mem::take(&mut self.src.h_defs);
self.src.h_defs("\ntypedef ");
let kind = &resolve.types[ty].kind;
match kind {
let def = &resolve.types[ty];
match &def.kind {
TypeDefKind::Type(_)
| TypeDefKind::Flags(_)
| TypeDefKind::Record(_)
Expand All @@ -709,9 +708,16 @@ impl C {
unreachable!()
}
TypeDefKind::Handle(handle) => {
let (Handle::Borrow(target) | Handle::Own(target)) = handle;

// If this is an alias to a handle _and_ a corresponding handle type exists for the target of the
// alias, generate a typedef alias. Otherwise, generate an independent type.
if let Some(ty) = self.find_handle_alias_target(resolve, handle, handles) {
if let Some(ty) = self.find_handle_alias_target(
resolve,
handle,
handles,
resolve.types[*target].owner,
) {
let mut name = self.owner_namespace(resolve, ty);
name.push_str("_");
push_ty_name(
Expand Down Expand Up @@ -1039,8 +1045,7 @@ impl C {
}
_ => {}
}
self.public_anonymous_types.insert(*id);
self.private_anonymous_types.remove(id);
self.visit_anonymous_types(resolve, &Type::Id(*id));
dst.push_str(&ns);
dst.push_str("_");
push_ty_name(
Expand All @@ -1057,6 +1062,87 @@ impl C {
}
}
}

fn visit_anonymous_types(&mut self, resolve: &Resolve, ty: &Type) {
match ty {
Type::String => {
self.needs_string = true;
}
Type::Id(id) => {
let ty = &resolve.types[*id];
if ty.name.is_none() {
match &ty.kind {
TypeDefKind::Type(_) => {}
TypeDefKind::Handle(Handle::Borrow(resource))
if matches!(
self.resources
.get(&dealias(resolve, *resource))
.map(|info| &info.direction),
Some(Direction::Export)
) => {}
_ => {
self.public_anonymous_types.insert(*id);
self.private_anonymous_types.remove(id);
}
}
}

match &ty.kind {
TypeDefKind::Type(t) => self.visit_anonymous_types(resolve, t),
TypeDefKind::Record(r) => {
for field in &r.fields {
self.visit_anonymous_types(resolve, &field.ty);
}
}
TypeDefKind::Resource
| TypeDefKind::Handle(_)
| TypeDefKind::Flags(_)
| TypeDefKind::Enum(_) => {}
TypeDefKind::Variant(v) => {
for case in &v.cases {
if let Some(ty) = &case.ty {
self.visit_anonymous_types(resolve, ty);
}
}
}
TypeDefKind::Tuple(t) => {
for ty in &t.types {
self.visit_anonymous_types(resolve, ty);
}
}
TypeDefKind::Option(ty) => {
self.visit_anonymous_types(resolve, ty);
}
TypeDefKind::Result(r) => {
if let Some(ty) = &r.ok {
self.visit_anonymous_types(resolve, ty);
}
if let Some(ty) = &r.err {
self.visit_anonymous_types(resolve, ty);
}
}
TypeDefKind::List(ty) => {
self.visit_anonymous_types(resolve, ty);
}
TypeDefKind::Future(ty) => {
if let Some(ty) = ty {
self.visit_anonymous_types(resolve, ty);
}
}
TypeDefKind::Stream(s) => {
if let Some(ty) = &s.element {
self.visit_anonymous_types(resolve, ty);
}
if let Some(ty) = &s.end {
self.visit_anonymous_types(resolve, ty);
}
}
TypeDefKind::Unknown => unreachable!(),
}
}
_ => {}
}
}
}

pub fn push_ty_name(
Expand Down
1 change: 1 addition & 0 deletions crates/go/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ macro_rules! codegen_test {
(resource_local_alias_borrow_import $name:tt $test:tt) => {};
(resource_borrow_in_record $name:tt $test:tt) => {};
(resource_borrow_in_record_export $name:tt $test:tt) => {};
(resource_own_in_other_interface $name:tt $test:tt) => {};
(resources_in_aggregates $name:tt $test:tt) => {};
(issue668 $name:tt $test:tt) => {};

Expand Down
1 change: 1 addition & 0 deletions crates/teavm-java/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ macro_rules! codegen_test {
(resource_local_alias_borrow_import $name:tt $test:tt) => {};
(resource_borrow_in_record $name:tt $test:tt) => {};
(resource_borrow_in_record_export $name:tt $test:tt) => {};
(resource_own_in_other_interface $name:tt $test:tt) => {};
(same_names5 $name:tt $test:tt) => {};
(resources_in_aggregates $name:tt $test:tt) => {};
(issue668 $name:tt $test:tt) => {};
Expand Down

0 comments on commit 7f97c3f

Please sign in to comment.