tamer: asg::graph: Revert removal of AsgRelMut::pre_add_edge commit callback

I changed my mind from the previous commit---I do in fact want to inhibit
edge additions in some cases, to override what is added (e.g. to wrap a
template application in an Expr workspace).

The approach that I was trying to take was to override `from_oi` and return
it to the caller, but with all the dynamic edges, that ended up being a lot
more code than I feel was worth it; it was too complex.  This is a much
simpler (and more flexible) approach---we simply carry out whatever graph
operations we want in `pre_add_edge` using the provided `asg` reference, and
then after we're done, simply omit `commit` on the original.

DEV-13163
main
Mike Gerwitz 2023-07-28 00:13:35 -04:00
parent d889aca13a
commit 5dd7b7f1e8
3 changed files with 21 additions and 7 deletions

View File

@ -211,8 +211,8 @@ impl Asg {
to_oi: ObjectIndex<OB>,
ctx_span: Option<Span>,
) -> Result<(), AsgError> {
from_oi.pre_add_edge(self, to_oi, ctx_span).map(|()| {
self.graph.add_edge(
from_oi.pre_add_edge(self, to_oi, ctx_span, |asg| {
asg.graph.add_edge(
from_oi.widen().into(),
to_oi.into(),
(from_oi.src_rel_ty(), OB::rel_ty(), ctx_span),
@ -512,6 +512,7 @@ pub trait AsgRelMut<OB: ObjectRelatable>: ObjectRelatable {
fn pre_add_edge(
asg: &mut Asg,
rel: ProposedRel<Self, OB>,
commit: impl FnOnce(&mut Asg),
) -> Result<(), AsgError>;
}
@ -528,11 +529,12 @@ impl<OA: ObjectRelatable, OB: ObjectRelatable> AsgRelMut<OB> for OA {
/// overridden for a particular edge for a particular object
/// (see [`object::tpl`] as an example).
default fn pre_add_edge(
_asg: &mut Asg,
asg: &mut Asg,
_rel: ProposedRel<Self, OB>,
commit: impl FnOnce(&mut Asg),
) -> Result<(), AsgError> {
let _ = _rel.ctx_span; // TODO: remove when used (dead_code)
Ok(())
Ok(commit(asg))
}
}

View File

@ -864,6 +864,7 @@ pub trait ObjectIndexRelTo<OB: ObjectRelatable>: Sized + Clone + Copy {
asg: &mut Asg,
to_oi: ObjectIndex<OB>,
ctx_span: Option<Span>,
commit: impl FnOnce(&mut Asg),
) -> Result<(), AsgError>;
/// Check whether an edge exists from `self` to `to_oi`.
@ -947,6 +948,7 @@ where
asg: &mut Asg,
to_oi: ObjectIndex<OB>,
ctx_span: Option<Span>,
commit: impl FnOnce(&mut Asg),
) -> Result<(), AsgError> {
O::pre_add_edge(
asg,
@ -955,6 +957,7 @@ where
to_oi,
ctx_span,
},
commit,
)
}
}
@ -975,6 +978,7 @@ impl<OB: ObjectRelatable> ObjectIndexRelTo<OB> for ObjectIndexTo<OB> {
asg: &mut Asg,
to_oi: ObjectIndex<OB>,
ctx_span: Option<Span>,
commit: impl FnOnce(&mut Asg),
) -> Result<(), AsgError> {
macro_rules! pre_add_edge {
($ty:ident) => {
@ -985,6 +989,7 @@ impl<OB: ObjectRelatable> ObjectIndexRelTo<OB> for ObjectIndexTo<OB> {
to_oi,
ctx_span,
},
commit,
)
};
}
@ -1019,9 +1024,10 @@ impl<OB: ObjectRelatable> ObjectIndexRelTo<OB> for ObjectIndexToTree<OB> {
asg: &mut Asg,
to_oi: ObjectIndex<OB>,
ctx_span: Option<Span>,
commit: impl FnOnce(&mut Asg),
) -> Result<(), AsgError> {
match self {
Self(oito) => oito.pre_add_edge(asg, to_oi, ctx_span),
Self(oito) => oito.pre_add_edge(asg, to_oi, ctx_span, commit),
}
}
}

View File

@ -221,6 +221,7 @@ object_rel! {
fn pre_add_edge(
asg: &mut Asg,
rel: ProposedRel<Self, Expr>,
commit: impl FnOnce(&mut Asg),
) -> Result<(), AsgError> {
let tpl_name = rel.from_oi.name(asg);
let span = rel.to_oi.resolve(asg).span();
@ -228,7 +229,9 @@ object_rel! {
rel.from_oi.try_map_obj_inner(
asg,
try_adapt_to(TplShape::Expr(span), tpl_name),
).map(|_| ())
)?;
Ok(commit(asg))
}
},
@ -241,6 +244,7 @@ object_rel! {
fn pre_add_edge(
asg: &mut Asg,
rel: ProposedRel<Self, Tpl>,
commit: impl FnOnce(&mut Asg),
) -> Result<(), AsgError> {
let tpl_name = rel.from_oi.name(asg);
let apply = rel.to_oi.resolve(asg);
@ -251,7 +255,9 @@ object_rel! {
rel.from_oi.try_map_obj_inner(
asg,
try_adapt_to(apply_shape, tpl_name),
).map(|_| ())
)?;
Ok(commit(asg))
}
},