Skip to content

Commit 3620348

Browse files
committed
yeast: Clarify guarding interpolation lowering
Adds comments (hopefully) making the purpose of the relevant structs more clear. Also, `DependencyScope` is now `ChoiceAlternativeScope` (that is, it's the scope associated with one of the alternatives in a choice), and `DependencyPreparation` is `GuardingInterpolation` (since it is essentially a representation of the `#{...}` interpolations that are used as guards.
1 parent 7027a76 commit 3620348

1 file changed

Lines changed: 31 additions & 19 deletions

File tree

‎shared/yeast-macros/src/lower.rs‎

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,26 @@ use crate::ast::{
99

1010
#[derive(Clone, Copy, Default)]
1111
struct LoweringContext<'a> {
12-
dependency_scope: Option<DependencyScope<'a>>,
12+
choice_alternative_scope: Option<ChoiceAlternativeScope<'a>>,
1313
}
1414

1515
#[derive(Clone, Copy)]
16-
struct DependencyScope<'a> {
17-
preparations: &'a RefCell<Vec<DependencyPreparation>>,
16+
struct ChoiceAlternativeScope<'a> {
17+
interpolations: &'a RefCell<Vec<GuardingInterpolation>>,
1818
}
1919

20-
struct DependencyPreparation {
20+
/// A `#{expr}` interpolation that must succeed before constructing a choice
21+
/// alternative. Lowering first emits `expression`, which evaluates `expr` and
22+
/// returns its rendered text and optional source range. A `None` result rejects
23+
/// the alternative without constructing any nodes. On success, the generated
24+
/// bindings are reused later when constructing the interpolated leaf.
25+
struct GuardingInterpolation {
26+
/// Generated binding for the interpolation's rendered text.
2127
value: Ident,
28+
/// Generated binding for the interpolation's optional source range.
2229
source_range: Ident,
30+
/// Generated `Option<(String, Option<Range>)>` expression that evaluates
31+
/// the original interpolation exactly once.
2332
expression: TokenStream,
2433
}
2534

@@ -368,20 +377,20 @@ impl Template {
368377

369378
impl Alternative {
370379
fn lower_candidate(&self, fallback: TokenStream) -> TokenStream {
371-
let preparations = RefCell::new(Vec::new());
380+
let interpolations = RefCell::new(Vec::new());
372381
let context = LoweringContext {
373-
dependency_scope: Some(DependencyScope {
374-
preparations: &preparations,
382+
choice_alternative_scope: Some(ChoiceAlternativeScope {
383+
interpolations: &interpolations,
375384
}),
376385
};
377386
let value = self.template.lower_single(context);
378-
let preparations = preparations.into_inner();
379-
let prepared_values = preparations
387+
let interpolations = interpolations.into_inner();
388+
let prepared_values = interpolations
380389
.iter()
381-
.flat_map(|preparation| {
390+
.flat_map(|interpolation| {
382391
[
383-
preparation.value.clone(),
384-
preparation.source_range.clone(),
392+
interpolation.value.clone(),
393+
interpolation.source_range.clone(),
385394
]
386395
})
387396
.collect::<Vec<_>>();
@@ -393,14 +402,14 @@ impl Alternative {
393402
// evaluated in source order. Construction happens only after the
394403
// resulting option has been matched, keeping it in a separate branch
395404
// from the fallback.
396-
let prepared = preparations.into_iter().rev().fold(
405+
let prepared = interpolations.into_iter().rev().fold(
397406
prepared,
398-
|candidate, preparation| {
399-
let DependencyPreparation {
407+
|candidate, interpolation| {
408+
let GuardingInterpolation {
400409
value,
401410
source_range,
402411
expression,
403-
} = preparation;
412+
} = interpolation;
404413
// Do not use `map`/`and_then` here: `candidate` may contain
405414
// embedded user Rust, and putting it in a closure would change
406415
// the target of `return` and the result type seen by `?`.
@@ -446,10 +455,13 @@ impl Node {
446455
Content::Static(lit) => quote! { #ctx.literal(#kind_str, #lit) },
447456
Content::Computed(block) => {
448457
let block = rust_block(block);
449-
if let Some(scope) = context.dependency_scope {
458+
if let Some(scope) = context.choice_alternative_scope {
450459
let value = fresh_prepared_ident("value");
451460
let source_range = fresh_prepared_ident("source_range");
452-
scope.preparations.borrow_mut().push(DependencyPreparation {
461+
scope
462+
.interpolations
463+
.borrow_mut()
464+
.push(GuardingInterpolation {
453465
value: value.clone(),
454466
source_range: source_range.clone(),
455467
expression: quote! {
@@ -471,7 +483,7 @@ impl Node {
471483
)
472484
}
473485
},
474-
});
486+
});
475487
quote! {
476488
#ctx.literal_with_source_range(
477489
#kind_str,

0 commit comments

Comments
 (0)