derive_builder_core/
change_span.rs

1use std::iter::FromIterator;
2
3use proc_macro2::{Group, Span, TokenStream, TokenTree};
4
5/// Deeply change the span of some tokens, ensuring that the output only references `span`.
6///
7/// Macros such as `quote_spanned` preserve the spans of interpolated tokens, which is useful.
8/// However, in some very specific scenarios it is desirable to suppress the original span
9/// information in favor of a different one.
10///
11/// For more information, see [dtolnay/syn#309](https://github.com/dtolnay/syn/issues/309).
12pub(crate) fn change_span(tokens: TokenStream, span: Span) -> TokenStream {
13    let mut result = vec![];
14    for mut token in tokens {
15        match token {
16            TokenTree::Group(group) => {
17                let mut new_group =
18                    Group::new(group.delimiter(), change_span(group.stream(), span));
19                new_group.set_span(span);
20                result.push(TokenTree::Group(new_group));
21            }
22            _ => {
23                token.set_span(span);
24                result.push(token);
25            }
26        }
27    }
28    FromIterator::from_iter(result)
29}