From bda8e7dae172de5934a5068ec0ebfc2864249434 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 26 Jun 2026 15:09:44 +0000 Subject: [PATCH] yeast-macros: Remove unused `.map` and `.reduce_left` chain syntax The `{expr}.map(p -> tpl)` and `{expr}.reduce_left(first -> init, acc, elem -> fold)` post-fix chains on `{expr}` placeholders had no remaining users in the codebase: `.map` was never used, and the 4 `.reduce_left` sites in `swift.rs` were rewritten to plain `Iterator::reduce` via an `and_chain` helper in an earlier commit. Removes the entire `parse_chain_suffix` function (~90 lines) and the `has_chain` detection / dispatch branches at the two call sites (field-position in `parse_direct_node_inner` and body-position in `parse_direct_list`). The remaining `{expr}` path is the trait-dispatched one introduced by the splice-syntax cleanup, which handles single ids and iterables uniformly via `IntoFieldIds`. Also strips the chain syntax from the `tree!` macro doc comment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shared/yeast-macros/src/lib.rs | 11 --- shared/yeast-macros/src/parse.rs | 137 ++----------------------------- 2 files changed, 9 insertions(+), 139 deletions(-) diff --git a/shared/yeast-macros/src/lib.rs b/shared/yeast-macros/src/lib.rs index 420f9fc70c6..7db97f9fb70 100644 --- a/shared/yeast-macros/src/lib.rs +++ b/shared/yeast-macros/src/lib.rs @@ -47,19 +47,8 @@ pub fn query(input: TokenStream) -> TokenStream { /// `Option`, iterator chains) splice /// their elements /// field: {expr} - extend a named field with `{expr}`'s ids -/// {expr}.map(p -> tpl) - apply tpl to each element; splice result -/// {expr}.reduce_left(f -> init, acc, e -> fold) -/// - fold with per-element init; splice 0 or 1 result /// ``` /// -/// Chain syntax after `{expr}`: -/// - `.map(param -> template)` — one output node per input element. -/// - `.reduce_left(first -> init, acc, elem -> fold)` — fold left; the first -/// element is converted by `init`, subsequent elements are folded by `fold` -/// with the accumulator bound to `acc`. An empty iterable yields nothing. -/// - Chains always splice (the result is iterable). -/// - Multiple chains can be chained, e.g. `.map(...).reduce_left(...)`. -/// /// Can be called with an explicit context or using the implicit context /// from an enclosing `rule!`: /// diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index 6e4de57a141..2ab6236fdac 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -430,37 +430,16 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result = #chained.collect(); - }); - // An empty pipeline means the field is absent — skip it - // entirely rather than emitting an empty named field. - field_args.push(quote! { - if !#temp.is_empty() { __fields.push((#field_str, #temp)); } - }); - continue; - } - - // Plain `{expr}` — trait-dispatched extend. let group = expect_group(tokens, Delimiter::Brace)?; let expr = group.stream(); stmts.push(quote! { let mut #temp: Vec = Vec::new(); yeast::IntoFieldIds::extend_into({ #expr }, &mut #temp); }); + // An empty `{expr}` means the field is absent — skip it + // entirely rather than emitting an empty named field. field_args.push(quote! { if !#temp.is_empty() { __fields.push((#field_str, #temp)); } }); @@ -492,93 +471,6 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result template) -- iterator map: produces Vec -/// ``` -/// -/// The chain may be empty (returns `base` unchanged). Multiple chained calls -/// are supported, e.g. `.map(p -> ...).map(q -> ...)`. -/// -/// Each call expects the receiver to be an iterator. The `base` argument -/// should therefore already be an iterator (use `.into_iter()` on it before -/// calling this function). -fn parse_chain_suffix(tokens: &mut Tokens, ctx: &Ident, base: TokenStream) -> Result { - let mut current = base; - while matches!(tokens.peek(), Some(TokenTree::Punct(p)) if p.as_char() == '.') { - tokens.next(); // consume . - let method = expect_ident(tokens, "expected method name after `.`")?; - let method_str = method.to_string(); - let args_group = expect_group(tokens, Delimiter::Parenthesis)?; - match method_str.as_str() { - "map" => { - let mut inner = args_group.stream().into_iter().peekable(); - let param = expect_ident(&mut inner, "expected lambda parameter name")?; - expect_punct(&mut inner, '-', "expected `->` after lambda parameter")?; - expect_punct(&mut inner, '>', "expected `->` after lambda parameter")?; - let body = parse_direct_node(&mut inner, ctx)?; - if let Some(tok) = inner.next() { - return Err(syn::Error::new_spanned( - tok, - "unexpected token after lambda body", - )); - } - current = quote! { - #current.map(|#param| #body) - }; - } - "reduce_left" => { - // Syntax: reduce_left(first -> init_tpl, acc, elem -> fold_tpl) - // - first -> init_tpl : converts the first element to the initial accumulator - // - acc, elem -> fold_tpl : fold step (acc = current accumulator, elem = next element) - // Empty iterator produces an empty iterator; non-empty produces a single-element iterator. - let mut inner = args_group.stream().into_iter().peekable(); - let init_param = expect_ident(&mut inner, "expected initial lambda parameter")?; - expect_punct(&mut inner, '-', "expected `->` after init parameter")?; - expect_punct(&mut inner, '>', "expected `->` after init parameter")?; - let init_body = parse_direct_node(&mut inner, ctx)?; - expect_punct(&mut inner, ',', "expected `,` after init template")?; - let acc_param = expect_ident(&mut inner, "expected accumulator parameter")?; - expect_punct(&mut inner, ',', "expected `,` after accumulator parameter")?; - let elem_param = expect_ident(&mut inner, "expected element parameter")?; - expect_punct(&mut inner, '-', "expected `->` after element parameter")?; - expect_punct(&mut inner, '>', "expected `->` after element parameter")?; - let fold_body = parse_direct_node(&mut inner, ctx)?; - if let Some(tok) = inner.next() { - return Err(syn::Error::new_spanned( - tok, - "unexpected token after fold template", - )); - } - current = quote! { - { - let mut __iter = #current; - let __result: Option = if let Some(#init_param) = __iter.next() { - let mut __acc: yeast::Id = #init_body; - for #elem_param in __iter { - let #acc_param: yeast::Id = __acc; - __acc = #fold_body; - } - Some(__acc) - } else { - None - }; - __result.into_iter() - } - }; - } - _ => { - return Err(syn::Error::new_spanned( - method, - format!("unknown builtin method `.{method_str}()`"), - )); - } - } - } - Ok(current) -} - /// Parse the top-level list of a `trees!` template. /// Each item is a node template or `{expr}` splice. fn parse_direct_list(tokens: &mut Tokens, ctx: &Ident) -> Result> { @@ -599,25 +491,14 @@ fn parse_direct_list(tokens: &mut Tokens, ctx: &Ident) -> Result