Implement bounded typed data and identified interface contracts
This commit is contained in:
@@ -33,8 +33,13 @@ pub fn visit_element_refs(e: &mut Element, mut visit: impl FnMut(&mut Id)) {
|
||||
type_ref: TypeRef::Named(id),
|
||||
..
|
||||
} => visit(id),
|
||||
SharedBody::Interface { items } => {
|
||||
for id in items {
|
||||
SharedBody::Interface { supertype }
|
||||
| SharedBody::ExchangeItem { supertype, .. }
|
||||
| SharedBody::DataType {
|
||||
definition: DataTypeDefinition::Record { supertype },
|
||||
..
|
||||
} => {
|
||||
if let Some(id) = supertype {
|
||||
visit(id);
|
||||
}
|
||||
}
|
||||
@@ -83,6 +88,9 @@ pub fn visit_element_refs(e: &mut Element, mut visit: impl FnMut(&mut Id)) {
|
||||
visit(id);
|
||||
}
|
||||
for value in values {
|
||||
for id in &mut value.path {
|
||||
visit(id);
|
||||
}
|
||||
visit(&mut value.field);
|
||||
}
|
||||
}
|
||||
@@ -377,7 +385,12 @@ fn remove_objects(p: &mut Project, removed: BTreeSet<Id>) {
|
||||
}
|
||||
if let Some(shared) = e.shared_mut() {
|
||||
match shared {
|
||||
SharedBody::Interface { items } => items.retain(|id| !removed.contains(id)),
|
||||
SharedBody::Interface { supertype }
|
||||
| SharedBody::ExchangeItem { supertype, .. }
|
||||
| SharedBody::DataType {
|
||||
definition: DataTypeDefinition::Record { supertype },
|
||||
..
|
||||
} => clear(supertype),
|
||||
SharedBody::Event {
|
||||
body: EventBody::Signal { items },
|
||||
} => items.retain(|id| !removed.contains(id)),
|
||||
@@ -413,7 +426,10 @@ fn remove_objects(p: &mut Project, removed: BTreeSet<Id>) {
|
||||
clear(sender);
|
||||
clear(receiver);
|
||||
clear(reply_to);
|
||||
values.retain(|value| !removed.contains(&value.field));
|
||||
values.retain(|value| {
|
||||
!removed.contains(&value.field)
|
||||
&& value.path.iter().all(|id| !removed.contains(id))
|
||||
});
|
||||
}
|
||||
OccurrenceBody::Action { action, lifeline } => {
|
||||
clear(action);
|
||||
@@ -485,20 +501,37 @@ fn remove_objects(p: &mut Project, removed: BTreeSet<Id>) {
|
||||
exchange: Some(id), ..
|
||||
},
|
||||
..
|
||||
}) => p
|
||||
.relations
|
||||
.get(id)
|
||||
.map(|r| (e.id, crate::validation::carried_fields(p, r))),
|
||||
}) => p.relations.get(id).map(|r| {
|
||||
let Some(SharedBody::Occurrence {
|
||||
body: OccurrenceBody::Exchange { values, .. },
|
||||
..
|
||||
}) = e.shared()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
let retained: Vec<_> = values
|
||||
.iter()
|
||||
.filter(|value| {
|
||||
crate::data::carried_value_path(p, r, &value.path, value.field).is_some()
|
||||
|| (value.path.is_empty()
|
||||
&& crate::data::carried_field_paths(p, r)
|
||||
.iter()
|
||||
.any(|f| f.field == value.field))
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
(e.id, retained)
|
||||
}),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
for (id, fields) in allowed {
|
||||
for (id, retained) in allowed {
|
||||
if let Some(SharedBody::Occurrence {
|
||||
body: OccurrenceBody::Exchange { values, .. },
|
||||
..
|
||||
}) = p.elements.get_mut(&id).and_then(Element::shared_mut)
|
||||
{
|
||||
values.retain(|value| fields.contains(&value.field));
|
||||
*values = retained;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user