tamer: asg::air::tpl: Refactor TplEndRef parsing
This removes the token of lookahead and just does what needs to be done in a more clear manner. There is no room for interpretation in what this is doing now, and `TplEnd` delegates to `close` just as this does. DEV-13163main
parent
9f74c0fc92
commit
d42c5584d0
|
@ -121,14 +121,18 @@ impl TplState {
|
||||||
/// This updates the span of the template to encompass the entire
|
/// This updates the span of the template to encompass the entire
|
||||||
/// definition,
|
/// definition,
|
||||||
/// even if an error occurs.
|
/// even if an error occurs.
|
||||||
fn close(self, asg: &mut Asg, close_span: Span) -> Result<(), AsgError> {
|
fn close(
|
||||||
|
self,
|
||||||
|
asg: &mut Asg,
|
||||||
|
close_span: Span,
|
||||||
|
) -> Result<ObjectIndex<Tpl>, AsgError> {
|
||||||
let oi = self.oi().close(asg, close_span);
|
let oi = self.oi().close(asg, close_span);
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Dangling(_) => {
|
Self::Dangling(_) => {
|
||||||
Err(AsgError::DanglingTpl(oi.resolve(asg).span()))
|
Err(AsgError::DanglingTpl(oi.resolve(asg).span()))
|
||||||
}
|
}
|
||||||
Self::AnonymousReachable(..) | Self::Identified(..) => Ok(()),
|
Self::AnonymousReachable(..) | Self::Identified(..) => Ok(oi),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,25 +222,31 @@ impl ParseState for AirTplAggregate {
|
||||||
.transition(Toplevel(tpl)),
|
.transition(Toplevel(tpl)),
|
||||||
|
|
||||||
(Toplevel(tpl), AirTpl(TplEnd(span))) => {
|
(Toplevel(tpl), AirTpl(TplEnd(span))) => {
|
||||||
tpl.close(ctx.asg_mut(), span).transition(Done)
|
tpl.close(ctx.asg_mut(), span).map(|_| ()).transition(Done)
|
||||||
}
|
}
|
||||||
|
|
||||||
(Toplevel(tpl), AirTpl(TplEndRef(span))) => {
|
(Toplevel(tpl), AirTpl(TplEndRef(span))) => {
|
||||||
// Note that we utilize lookahead in either case,
|
|
||||||
// but in the case of an error,
|
|
||||||
// we are effectively discarding the ref and translating
|
|
||||||
// into a `TplEnd`.
|
|
||||||
match ctx.expansion_oi() {
|
match ctx.expansion_oi() {
|
||||||
|
// The template will be the equivalent of `TplEnd`'d
|
||||||
|
// before `IdentRef`'d,
|
||||||
|
// to ensure the definition has been completed.
|
||||||
Some(oi_target) => tpl
|
Some(oi_target) => tpl
|
||||||
.oi()
|
.anonymous_reachable()
|
||||||
.close(ctx.asg_mut(), span)
|
.close(ctx.asg_mut(), span)
|
||||||
.expand_into(ctx.asg_mut(), oi_target)
|
.and_then(|oi| oi.expand_into(ctx.asg_mut(), oi_target))
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.transition(Toplevel(tpl.anonymous_reachable())),
|
.transition(Done),
|
||||||
None => Transition(Toplevel(tpl))
|
|
||||||
.err(AsgError::InvalidExpansionContext(span)),
|
// An invalid context will act as a `TplEnd`,
|
||||||
|
// effectively discarding the `Ref` part of the token.
|
||||||
|
None => tpl
|
||||||
|
.anonymous_reachable()
|
||||||
|
.close(ctx.asg_mut(), span)
|
||||||
|
.and(Err::<(), _>(AsgError::InvalidExpansionContext(
|
||||||
|
span,
|
||||||
|
)))
|
||||||
|
.transition(Done),
|
||||||
}
|
}
|
||||||
.with_lookahead(AirTpl(TplEnd(span)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we just finished a template then this end may represent
|
// If we just finished a template then this end may represent
|
||||||
|
|
|
@ -357,8 +357,7 @@ fn tpl_inner_apply_expr_alongside_another_apply_expr() {
|
||||||
)
|
)
|
||||||
)),
|
)),
|
||||||
// RECOVERY: We ignore the template by not adding the edge.
|
// RECOVERY: We ignore the template by not adding the edge.
|
||||||
Ok(Parsed::Incomplete), // TplEnd >LA
|
Ok(Parsed::Incomplete), // TplEnd
|
||||||
Ok(Parsed::Incomplete), // TplEnd <LA
|
|
||||||
Ok(Parsed::Incomplete), // PkgEnd
|
Ok(Parsed::Incomplete), // PkgEnd
|
||||||
],
|
],
|
||||||
sut.by_ref().collect::<Vec<_>>(),
|
sut.by_ref().collect::<Vec<_>>(),
|
||||||
|
|
Loading…
Reference in New Issue