1use crate::anon_unions::AnonUnions;
2use crate::mk_syntax::{concat_doc, ident, lit_array, lit_str, modularize};
3use crate::queries::sexp::SExpSeq;
4use crate::queries::sexp_node_type::SExpNodeType;
5use crate::queries::GeneratedQueryTokens;
6use crate::NodeType;
7use crate::PrintCtx;
8use crate::{sexp_name_to_rust_names, unmake_reserved};
9use proc_macro2::TokenStream;
10use quote::{format_ident, quote};
11use slice_group_by::GroupBy;
12use syn::{Ident, Path};
13use tree_sitter::CaptureQuantifier;
14
15impl<'tree> SExpSeq<'tree> {
16 pub(crate) fn print(
39 &self,
40 query_str: &str,
41 ts_query: tree_sitter::Query,
42 def_ident: &Ident,
43 language_ident: &syn::Ident,
44 disabled_patterns: &[&str],
45 disabled_capture_names: &[&str],
46 disabled_capture_idxs: &[usize],
47 nodes: &Path,
48 use_yak_sitter: bool,
49 ctx @ PrintCtx {
50 tree_sitter,
51 type_sitter_lib,
52 ..
53 }: PrintCtx,
54 anon_unions: &mut AnonUnions,
55 ) -> TokenStream {
56 let disabled_captures = disabled_capture_idxs
57 .iter()
58 .copied()
59 .chain(disabled_capture_names.iter().flat_map(|&name| {
60 ts_query
61 .capture_names()
62 .iter()
63 .enumerate()
64 .filter(move |(_, n)| **n == name)
65 .map(|(idx, _)| idx)
66 }))
67 .collect::<Vec<_>>();
68 let capture_idxs_and_names = ts_query
69 .capture_names()
70 .iter()
71 .enumerate()
72 .filter(|(capture_idx, _)| !disabled_captures.contains(capture_idx))
73 .collect::<Vec<_>>();
74 let (capture_idxs, capture_names) = capture_idxs_and_names
75 .iter()
76 .map(|(idx, name)| (*idx, **name))
77 .unzip::<_, _, Vec<_>, Vec<_>>();
78
79 let def_name = def_ident.to_string();
80 let language_name = language_ident.to_string();
81 let query_parse_error = lit_str(&format!(
82 "query parsed at compile-time but failed at runtime. Is the language '{}' correct, and did \
83 you use the same tree-sitter / {} version?",
84 language_name, language_name
85 ));
86 let internal_query = format_ident!("__{}__", def_ident);
87 let query_matches = format_ident!("{}Matches", def_ident);
88 let query_captures = format_ident!("{}Captures", def_ident);
89 let query_match = format_ident!("{}Match", def_ident);
90 let query_capture = format_ident!("{}Capture", def_ident);
91 let disabled_patterns = disabled_patterns.iter().map(|p| lit_str(p));
92 let full_query_documentation = format!("\n\n```sexp\n{}\n```", query_str);
93 let def_doc = concat_doc!("Typed version of the query:", full_query_documentation);
94 let matches_doc = concat_doc!(
95 "Matches returned by a query cursor running the query [`",
96 def_name,
97 "`]:",
98 full_query_documentation
99 );
100 let query_match_doc = concat_doc!(
101 "A match returned by the query [`",
102 def_name,
103 "`]:",
104 full_query_documentation
105 );
106 let captures_doc = concat_doc!(
107 "Captures returned by a query cursor running the query [`",
108 def_name,
109 "`]:",
110 full_query_documentation
111 );
112 let query_capture_doc = concat_doc!(
113 "A capture returned by the query [`",
114 def_name,
115 "`]:",
116 full_query_documentation
117 );
118
119 let (tree_t, tree_fn, tree_query, tree_to_raws) = match use_yak_sitter {
120 false => (
121 quote! { , Text, I },
122 quote! {},
123 quote! {},
124 capture_idxs
125 .iter()
126 .map(|capture_idx| {
127 quote! {
128 #tree_sitter::QueryCapture {
129 index: #capture_idx as u32,
130 node: *node.raw()
131 }
132 }
133 })
134 .collect::<Vec<_>>(),
135 ),
136 true => (
137 quote! {},
138 quote! {
139 #[inline]
140 fn tree(&self) -> &'tree yak_sitter::Tree {
141 self.0.tree()
142 }
143 },
144 quote! { 'query, },
145 capture_idxs_and_names
146 .iter()
147 .map(|(i, c)| (*i, lit_str(c)))
148 .map(|(capture_idx, capture_name)| {
149 quote! {
150 yak_sitter::QueryCapture {
151 node: *node.raw(),
152 index: #capture_idx,
153 name: #capture_name
154 }
155 }
156 })
157 .collect::<Vec<_>>(),
158 ),
159 };
160
161 let capture_methods_and_variants = capture_idxs_and_names
165 .binary_group_by_key(|(_, capture_name)| *capture_name)
166 .map(|capture_idxs_and_name| {
167 let capture_idxs = capture_idxs_and_name
168 .iter()
169 .map(|(capture_idx, _)| *capture_idx)
170 .collect::<Vec<_>>();
171 let capture_name = capture_idxs_and_name[0].1;
172 self.print_capture_method_and_variant(
173 capture_name,
174 &capture_idxs,
175 query_str,
176 &ts_query,
177 nodes,
178 ctx,
179 anon_unions,
180 )
181 })
182 .collect::<Vec<_>>();
183 let capture_methods = capture_methods_and_variants
184 .iter()
185 .map(|x| x.0.clone())
186 .collect::<TokenStream>();
187 let capture_variant_extract_methods = capture_methods_and_variants
188 .iter()
189 .map(|x| x.1.clone())
190 .collect::<TokenStream>();
191 let capture_variants = capture_methods_and_variants
192 .iter()
193 .map(|x| &x.2)
194 .collect::<Vec<_>>();
195 let capture_variant_documentations = capture_methods_and_variants
196 .iter()
197 .map(|x| &x.3)
198 .collect::<Vec<_>>();
199 let capture_node_types = capture_methods_and_variants
200 .iter()
201 .map(|x| &x.4)
202 .collect::<Vec<_>>();
203 let non_existent_variant = match capture_methods_and_variants.is_empty() {
204 false => quote! {},
205 true => quote! {
206 __NonExistent(#type_sitter_lib::Never, std::marker::PhantomData<&'tree ()>)
210 },
211 };
212
213 quote! {
214 #[doc = #def_doc]
215 #[allow(non_camel_case_types)]
216 #[derive(Debug, Clone, Copy)]
217 pub struct #def_ident;
218
219 #[doc = #matches_doc]
220 #[allow(unused, non_camel_case_types)]
221 pub type #query_matches<'query, 'tree #tree_t> = #type_sitter_lib::QueryMatches<'query, 'tree, #def_ident #tree_t>;
222 #[doc = #captures_doc]
223 #[allow(unused, non_camel_case_types)]
224 pub type #query_captures<'query, 'tree #tree_t> = #type_sitter_lib::QueryCaptures<'query, 'tree, #def_ident #tree_t>;
225 #[doc = #query_match_doc]
226 #[repr(transparent)]
227 pub struct #query_match<'query, 'tree: 'query>(#tree_sitter::QueryMatch<'query, 'tree>);
228 #[doc = #query_capture_doc]
229 #[derive(Clone, Debug)]
230 pub enum #query_capture<'tree> {
231 #(#capture_variant_documentations #capture_variants(#capture_node_types),)*
232 #non_existent_variant
233 }
234
235 #[automatically_derived]
236 impl #type_sitter_lib::Query for #def_ident {
237 type Match<'query, 'tree: 'query> = #query_match<'query, 'tree>;
238 type Capture<'query, 'tree: 'query> = #query_capture<'tree>;
239
240 fn as_str(&self) -> &'static str {
241 #query_str
242 }
243
244 fn raw(&self) -> &'static #tree_sitter::Query {
245 #[allow(non_upper_case_globals)]
246 static #internal_query: std::sync::OnceLock<#tree_sitter::Query> = std::sync::OnceLock::new();
247
248 #internal_query.get_or_init(|| {
249 #[allow(unused_mut)]
250 let mut query = #tree_sitter::Query::new(
251 &#language_ident::LANGUAGE.into(),
252 #query_str
253 ).expect(#query_parse_error);
254 #(query.disable_capture(#disabled_captures);)*
255 #(query.disable_pattern(#disabled_patterns);)*
256 query
257 })
258 }
259
260 #[inline]
261 unsafe fn wrap_match<'query, 'tree>(
262 &self,
263 r#match: #tree_sitter::QueryMatch<'query, 'tree>
264 ) -> #query_match<'query, 'tree> {
265 #query_match(r#match)
266 }
267
268 #[inline]
269 unsafe fn wrap_match_ref<'m, 'query, 'tree>(
270 &self,
271 r#match: &'m #tree_sitter::QueryMatch<'query, 'tree>
272 ) -> &'m #query_match<'query, 'tree> {
273 &*(r#match as *const #tree_sitter::QueryMatch<'query, 'tree> as *const #query_match<'query, 'tree>)
275 }
276
277 #[inline]
278 unsafe fn wrap_capture<'query, 'tree: 'query>(
279 &self,
280 capture: #tree_sitter::QueryCapture<#tree_query 'tree>,
281 ) -> #query_capture<'tree> {
282 match capture.index as usize {
285 #(#capture_idxs => #query_capture::#capture_variants(
286 <#capture_node_types as #type_sitter_lib::Node<'tree>>::from_raw_unchecked(capture.node)
287 ),)*
288 capture_index => unreachable!("Invalid capture index: {}", capture_index)
289 }
290 }
291 }
292
293 #[automatically_derived]
294 #[allow(unused)]
295 impl<'query, 'tree: 'query> #query_match<'query, 'tree> {
296 #capture_methods
297 }
298
299 #[automatically_derived]
300 impl<'query, 'tree: 'query> std::fmt::Debug for #query_match<'query, 'tree> {
301 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
302 f.debug_tuple(stringify!(#query_match))
303 .field(&self.0)
304 .finish()
305 }
306 }
307
308 #[automatically_derived]
309 impl<'query, 'tree: 'query> #type_sitter_lib::QueryMatch<'query, 'tree> for #query_match<'query, 'tree> {
310 type Query = #def_ident;
311
312 #[inline]
313 fn query(&self) -> &'query Self::Query {
314 &#def_ident
315 }
316
317 #tree_fn
318
319 #[inline]
320 fn raw(&self) -> &#tree_sitter::QueryMatch<'query, 'tree> {
321 &self.0
322 }
323
324 #[inline]
325 fn into_raw(self) -> #tree_sitter::QueryMatch<'query, 'tree> {
326 self.0
327 }
328 }
329
330 #[automatically_derived]
331 #[allow(unused)]
332 impl<'tree> #query_capture<'tree> {
333 #capture_variant_extract_methods
334 }
335
336 #[automatically_derived]
337 impl<'query, 'tree: 'query> #type_sitter_lib::QueryCapture<'query, 'tree> for #query_capture<'tree> {
338 type Query = #def_ident;
339
340 #[inline]
341 fn query(&self) -> &'query Self::Query {
342 &#def_ident
343 }
344
345 #[inline]
346 fn raw(&self) -> #tree_sitter::QueryCapture<#tree_query 'tree> {
347 #[allow(unused_imports)]
348 use #type_sitter_lib::Node;
349 match self {
350 #(Self::#capture_variants(node) => #tree_to_raws,)*
351 #[allow(unreachable_patterns)]
353 _ => unreachable!()
354 }
355 }
356
357 #[inline]
358 fn node(&self) -> &#type_sitter_lib::UntypedNode<'tree> {
359 #[allow(unused_imports)]
360 use #type_sitter_lib::Node;
361 match self {
362 #(Self::#capture_variants(node) => #type_sitter_lib::UntypedNode::r#ref(node.raw()),)*
363 #[allow(unreachable_patterns)]
365 _ => unreachable!()
366 }
367 }
368
369 #[inline]
370 fn node_mut(&mut self) -> &mut #type_sitter_lib::UntypedNode<'tree> {
371 #[allow(unused_imports)]
372 use #type_sitter_lib::Node;
373 match self {
374 #(Self::#capture_variants(node) => #type_sitter_lib::UntypedNode::r#mut(node.raw_mut()),)*
375 #[allow(unreachable_patterns)]
377 _ => unreachable!()
378 }
379 }
380
381 #[inline]
382 fn name(&self) -> &'query str {
383 match self {
384 #(Self::#capture_variants { .. } => #capture_names,)*
385 #[allow(unreachable_patterns)]
387 _ => unreachable!()
388 }
389 }
390
391 #[inline]
392 fn index(&self) -> usize {
393 match self {
394 #(Self::#capture_variants { .. } => #capture_idxs,)*
395 #[allow(unreachable_patterns)]
397 _ => unreachable!()
398 }
399 }
400 }
401 }
402 }
403
404 fn print_capture_method_and_variant(
405 &self,
406 capture_name: &str,
407 capture_idxs: &[usize],
408 query_str: &str,
409 ts_query: &tree_sitter::Query,
410 nodes: &Path,
411 ctx @ PrintCtx {
412 all_types,
413 type_sitter_lib,
414 ..
415 }: PrintCtx,
416 anon_unions: &mut AnonUnions,
417 ) -> (TokenStream, TokenStream, Ident, TokenStream, TokenStream) {
418 let (capture_variant_name, capture_method_name) =
419 sexp_name_to_rust_names(&capture_name.replace(".", "_"));
420 let capture_method = ident!(capture_method_name, "capture name (capture method)")
421 .expect("ident should be valid because we get them from a names function");
422 let capture_variant = ident!(capture_variant_name, "capture name (capture variant)")
423 .expect("ident should be valid because we get them from a names function");
424
425 let mut capture_method_name = capture_method.to_string();
426 unmake_reserved(&mut capture_method_name);
429 let as_capture_method = format_ident!("as_{}", capture_method_name);
430
431 let mut captured_sexps = self.captured_patterns(capture_name).collect::<Vec<_>>();
432 captured_sexps.sort_by(|lhs, rhs| lhs.span().cmp(rhs.span()));
433 let captured_sexp_strs = captured_sexps.iter().map(|s| &query_str[s.span()]);
434 let capture_node_type = captured_sexps
435 .iter()
436 .map(|s| s.node_type(false, all_types))
437 .collect::<SExpNodeType>();
438 let capture_node_type_tokens =
439 capture_node_type.print(&capture_variant_name, nodes, ctx, anon_unions);
440
441 let capture_doc = format!(
442 "`{}` ([`{}`])",
443 capture_name,
444 capture_node_type.rust_type_path(nodes, &capture_variant_name)
445 );
446
447 let capture_quantifier = capture_idxs
448 .iter()
449 .flat_map(|capture_idx| {
450 (0..ts_query.pattern_count())
451 .map(|pattern_idx| &ts_query.capture_quantifiers(pattern_idx)[*capture_idx])
452 })
453 .copied()
454 .reduce(CaptureQuantifierExt::union)
455 .unwrap_or(CaptureQuantifier::Zero);
456 let captured_type = capture_quantifier.print_type(&capture_node_type_tokens);
457 let captured_nonempty_iterator_doc = capture_quantifier.print_nonempty_iterator_doc();
458 let capture_idxs_array = lit_array(capture_idxs.iter().map(|i| *i as u32));
459 let captured_expr = capture_quantifier.print_expr("e! {
460 #capture_idxs_array.into_iter().flat_map(|i| self.0.nodes_for_capture_index(i))
461 .map(|n| unsafe { <#capture_node_type_tokens as #type_sitter_lib::Node<'tree>>::from_raw_unchecked(n) })
463 });
464
465 let full_capture_pattern_doc = captured_sexp_strs
466 .map(|captured_sexp_str| {
467 let doc = concat_doc!(captured_sexp_str, " @", capture_name);
468 quote! { #[doc = #doc] }
469 })
470 .collect::<TokenStream>();
471 let full_capture_documentation = quote! {
472 #[doc = ""]
473 #[doc = "The full capture including pattern(s) is:"]
474 #[doc = "```sexp"]
475 #full_capture_pattern_doc
476 #[doc = "```"]
477 };
478
479 let capture_method_doc = concat_doc!(
480 "Returns an iterator over the nodes captured by ",
481 capture_doc
482 );
483 let capture_method = quote! {
484 #[doc = #capture_method_doc]
485 #captured_nonempty_iterator_doc
486 #full_capture_documentation
487 #[inline]
488 pub fn #capture_method(&self) -> #captured_type {
489 #captured_expr
490 }
491 };
492 let capture_variant_extract_method_doc =
493 concat_doc!("Try to interpret this capture as a ", capture_doc);
494 let capture_variant_extract_method = quote! {
495 #[doc = #capture_variant_extract_method_doc]
496 #full_capture_documentation
497 #[inline]
498 pub fn #as_capture_method(&self) -> ::std::option::Option<&#capture_node_type_tokens> {
499 #[allow(irrefutable_let_patterns)]
500 if let Self::#capture_variant(node) = self {
501 Some(node)
502 } else {
503 None
504 }
505 }
506 };
507 let capture_variant_main_doc = concat_doc!("A ", capture_doc);
508 let capture_variant_documentation = quote! {
509 #[doc = #capture_variant_main_doc]
510 #full_capture_documentation
511 };
512 (
513 capture_method,
514 capture_variant_extract_method,
515 capture_variant,
516 capture_variant_documentation,
517 capture_node_type_tokens,
518 )
519 }
520}
521
522impl SExpNodeType {
523 fn print(
524 &self,
525 capture_variant_name: &str,
526 nodes: &Path,
527 ctx @ PrintCtx {
528 type_sitter_lib, ..
529 }: PrintCtx,
530 anon_unions: &mut AnonUnions,
531 ) -> TokenStream {
532 match self {
533 Self::Single { r#type } => {
534 let type_ = r#type.print_rust_type();
535 quote! { #nodes::#type_ }
536 }
537 Self::Union { types, .. } => {
538 let mut types = types.iter().collect::<Vec<_>>();
539 types.sort_unstable_by(|lhs, rhs| lhs.name.cmp(&rhs.name));
541 types.dedup_by(|lhs, rhs| lhs.name == rhs.name);
542
543 NodeType::print_query_capture_sum_type(
544 capture_variant_name,
545 &types,
546 nodes,
547 ctx,
548 anon_unions,
549 )
550 }
551 Self::Untyped { is_named } => match is_named {
552 false => quote! { #type_sitter_lib::UntypedNode<'tree> },
553 true => quote! { #type_sitter_lib::UntypedNamedNode<'tree> },
554 },
555 }
556 }
557}
558
559trait CaptureQuantifierExt {
560 fn union(self, other: CaptureQuantifier) -> CaptureQuantifier;
561 fn print_type(&self, inner_type: &TokenStream) -> TokenStream;
562 fn print_nonempty_iterator_doc(&self) -> TokenStream;
563 fn print_expr(&self, iterator: &TokenStream) -> TokenStream;
564}
565
566impl CaptureQuantifierExt for CaptureQuantifier {
567 fn union(self, rhs: CaptureQuantifier) -> CaptureQuantifier {
568 match (self, rhs) {
569 (CaptureQuantifier::Zero, CaptureQuantifier::Zero) => CaptureQuantifier::Zero,
570 (CaptureQuantifier::Zero, CaptureQuantifier::ZeroOrOne) => CaptureQuantifier::ZeroOrOne,
571 (CaptureQuantifier::Zero, CaptureQuantifier::ZeroOrMore) => {
572 CaptureQuantifier::ZeroOrMore
573 }
574 (CaptureQuantifier::Zero, CaptureQuantifier::One) => CaptureQuantifier::ZeroOrOne,
575 (CaptureQuantifier::Zero, CaptureQuantifier::OneOrMore) => {
576 CaptureQuantifier::ZeroOrMore
577 }
578 (CaptureQuantifier::ZeroOrOne, CaptureQuantifier::Zero) => CaptureQuantifier::ZeroOrOne,
579 (CaptureQuantifier::ZeroOrOne, CaptureQuantifier::ZeroOrOne) => {
580 CaptureQuantifier::ZeroOrOne
581 }
582 (CaptureQuantifier::ZeroOrOne, CaptureQuantifier::ZeroOrMore) => {
583 CaptureQuantifier::ZeroOrMore
584 }
585 (CaptureQuantifier::ZeroOrOne, CaptureQuantifier::One) => CaptureQuantifier::ZeroOrOne,
586 (CaptureQuantifier::ZeroOrOne, CaptureQuantifier::OneOrMore) => {
587 CaptureQuantifier::ZeroOrMore
588 }
589 (CaptureQuantifier::ZeroOrMore, CaptureQuantifier::Zero) => {
590 CaptureQuantifier::ZeroOrMore
591 }
592 (CaptureQuantifier::ZeroOrMore, CaptureQuantifier::ZeroOrOne) => {
593 CaptureQuantifier::ZeroOrMore
594 }
595 (CaptureQuantifier::ZeroOrMore, CaptureQuantifier::ZeroOrMore) => {
596 CaptureQuantifier::ZeroOrMore
597 }
598 (CaptureQuantifier::ZeroOrMore, CaptureQuantifier::One) => {
599 CaptureQuantifier::ZeroOrMore
600 }
601 (CaptureQuantifier::ZeroOrMore, CaptureQuantifier::OneOrMore) => {
602 CaptureQuantifier::ZeroOrMore
603 }
604 (CaptureQuantifier::One, CaptureQuantifier::Zero) => CaptureQuantifier::ZeroOrOne,
605 (CaptureQuantifier::One, CaptureQuantifier::ZeroOrOne) => CaptureQuantifier::ZeroOrOne,
606 (CaptureQuantifier::One, CaptureQuantifier::ZeroOrMore) => {
607 CaptureQuantifier::ZeroOrMore
608 }
609 (CaptureQuantifier::One, CaptureQuantifier::One) => CaptureQuantifier::One,
610 (CaptureQuantifier::One, CaptureQuantifier::OneOrMore) => CaptureQuantifier::OneOrMore,
611 (CaptureQuantifier::OneOrMore, CaptureQuantifier::Zero) => {
612 CaptureQuantifier::ZeroOrMore
613 }
614 (CaptureQuantifier::OneOrMore, CaptureQuantifier::ZeroOrOne) => {
615 CaptureQuantifier::ZeroOrMore
616 }
617 (CaptureQuantifier::OneOrMore, CaptureQuantifier::ZeroOrMore) => {
618 CaptureQuantifier::ZeroOrMore
619 }
620 (CaptureQuantifier::OneOrMore, CaptureQuantifier::One) => CaptureQuantifier::OneOrMore,
621 (CaptureQuantifier::OneOrMore, CaptureQuantifier::OneOrMore) => {
622 CaptureQuantifier::OneOrMore
623 }
624 }
625 }
626
627 fn print_type(&self, inner_type: &TokenStream) -> TokenStream {
628 match self {
629 CaptureQuantifier::Zero => quote! { () },
630 CaptureQuantifier::ZeroOrOne => quote! { ::std::option::Option<#inner_type> },
631 CaptureQuantifier::ZeroOrMore => {
632 quote! { impl ::std::iter::Iterator<Item=#inner_type> + '_ }
633 }
634 CaptureQuantifier::One => quote! { #inner_type },
635 CaptureQuantifier::OneOrMore => {
636 quote! { impl ::std::iter::Iterator<Item=#inner_type> + '_ }
637 }
638 }
639 }
640
641 fn print_nonempty_iterator_doc(&self) -> TokenStream {
642 match self {
643 CaptureQuantifier::Zero => quote! {},
644 CaptureQuantifier::ZeroOrOne => quote! {},
645 CaptureQuantifier::ZeroOrMore => quote! {},
646 CaptureQuantifier::One => quote! {},
647 CaptureQuantifier::OneOrMore => {
648 quote! { #[doc = "\n\nThis is guaranteed to return at least one child"] }
649 }
650 }
651 }
652
653 fn print_expr(&self, iterator: &TokenStream) -> TokenStream {
654 let iterator = quote! {{ #iterator }};
655 match self {
656 CaptureQuantifier::Zero => {
657 quote! { ::std::debug_assert!(#iterator.next().is_none(), "zero quantifier returned an item") }
658 }
659 CaptureQuantifier::ZeroOrOne => quote! { #iterator.next() },
660 CaptureQuantifier::ZeroOrMore => quote! { #iterator },
661 CaptureQuantifier::One => quote! {
662 let mut iterator = #iterator;
663 let result = iterator.next().expect("one quantifier returned nothing");
664 ::std::debug_assert!(iterator.next().is_none(), "one quantifier returned more than one item");
665 result
666 },
667 CaptureQuantifier::OneOrMore => quote! { #iterator },
668 }
669 }
670}
671
672impl GeneratedQueryTokens {
673 pub fn collapse(self, nodes: &Path) -> TokenStream {
681 let nodes = match nodes
682 .segments
683 .first()
684 .map_or(false, |s| s.ident.to_string() == "super")
685 {
686 false => quote! { #nodes },
687 true => quote! { super::#nodes },
688 };
689 let GeneratedQueryTokens {
690 toplevel,
691 anon_unions,
692 } = self;
693 let anon_unions = anon_unions.into_values().collect::<TokenStream>();
694 let anon_unions = modularize!(anon_unions (use #nodes::*));
695 quote! {
696 #toplevel
697 #anon_unions
698 }
699 }
700}