tamer: asg::graph::object: ObjectIndex::try_map_obj_inner

Continuing to clean house and make things more concise, not just for `tpl`
but for all future changes.

DEV-13163
main
Mike Gerwitz 2023-07-27 03:07:33 -04:00
parent 66512bf20d
commit 579575a358
2 changed files with 57 additions and 17 deletions

View File

@ -123,7 +123,7 @@ use super::{Asg, AsgError};
use crate::{
diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan},
diagnostic_panic,
f::Map,
f::{Map, TryMap},
parse::util::SPair,
span::{Span, UNKNOWN_SPAN},
};
@ -735,6 +735,26 @@ impl<O: ObjectKind> ObjectIndex<O> {
asg.try_map_obj(self, f)
}
/// Resolve the identifier and map over an inner `T` of the resulting
/// [`Object`] narrowed to [`ObjectKind`] `O`,
/// replacing the object on the given [`Asg`].
///
/// This uses [`Self::try_map_obj`] to retrieve the object from
/// the [`Asg`].
///
/// If this operation is [`Infallible`],
/// see [`Self::map_obj_inner`].
pub fn try_map_obj_inner<T, E>(
self,
asg: &mut Asg,
f: impl FnOnce(T) -> <O as TryMap<T>>::FnResult<E>,
) -> Result<Self, E>
where
O: TryMap<T, Result<E> = Result<O, (O, E)>>,
{
self.try_map_obj(asg, O::try_fmap(f))
}
/// Resolve the identifier and infallibly map over the resulting
/// [`Object`] narrowed to [`ObjectKind`] `O`,
/// replacing the object on the given [`Asg`].
@ -751,6 +771,22 @@ impl<O: ObjectKind> ObjectIndex<O> {
}
}
/// Resolve the identifier and map over an inner `T` of the resulting
/// [`Object`] narrowed to [`ObjectKind`] `O`,
/// replacing the object on the given [`Asg`].
///
/// This uses [`Self::map_obj`] to retrieve the object from
/// the [`Asg`].
///
/// If this operation is _not_ [`Infallible`],
/// see [`Self::try_map_obj_inner`].
pub fn map_obj_inner<T>(self, asg: &mut Asg, f: impl FnOnce(T) -> T) -> Self
where
O: Map<T, Target = O>,
{
self.map_obj(asg, O::fmap(f))
}
/// Lift [`Self`] into [`Option`] and [`filter`](Option::filter) based
/// on whether the [`ObjectRelatable::rel_ty`] of [`Self`]'s `O`
/// matches that of `OB`.

View File

@ -22,11 +22,7 @@
use std::fmt::Display;
use super::{prelude::*, Doc, Expr, Ident};
use crate::{
f::{Map, TryMap},
parse::util::SPair,
span::Span,
};
use crate::{f::Map, parse::util::SPair, span::Span};
/// Template with associated name.
#[derive(Debug, PartialEq, Eq)]
@ -193,6 +189,17 @@ impl TplShape {
}
}
/// Attempt to adapt a template shape to that of another.
///
/// This returns a partially applied [`TplShape::try_adapt_to`],
/// where the remaining argument is `self`.
fn try_adapt_to(
other: TplShape,
tpl_name: Option<SPair>,
) -> impl FnOnce(TplShape) -> Result<TplShape, (TplShape, AsgError)> {
move |s| s.try_adapt_to(other, tpl_name)
}
impl Display for TplShape {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
// phrase as "template with ..."
@ -221,11 +228,10 @@ object_rel! {
let tpl_name = from_oi.name(asg);
let span = to_oi.resolve(asg).span();
from_oi.try_map_obj(asg, |tpl| {
tpl.try_map(|shape: TplShape| {
shape.try_adapt_to(TplShape::Expr(span), tpl_name)
})
})?;
from_oi.try_map_obj_inner(
asg,
try_adapt_to(TplShape::Expr(span), tpl_name),
)?;
Ok(commit(asg))
}
@ -250,12 +256,10 @@ object_rel! {
.shape()
.overwrite_span_if_any(apply.span());
// TODO: Refactor; very similar to Expr edge above.
from_oi.try_map_obj(asg, |tpl| {
tpl.try_map(|shape: TplShape| {
shape.try_adapt_to(apply_shape, tpl_name)
})
})?;
from_oi.try_map_obj_inner(
asg,
try_adapt_to(apply_shape, tpl_name),
)?;
Ok(commit(asg))
}