ide/
file_structure.rs

1use ide_db::SymbolKind;
2use syntax::{
3    AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, TextRange, WalkEvent,
4    ast::{self, HasAttrs, HasGenericParams, HasName},
5    match_ast,
6};
7
8#[derive(Debug, Clone)]
9pub struct StructureNode {
10    pub parent: Option<usize>,
11    pub label: String,
12    pub navigation_range: TextRange,
13    pub node_range: TextRange,
14    pub kind: StructureNodeKind,
15    pub detail: Option<String>,
16    pub deprecated: bool,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
20pub enum StructureNodeKind {
21    SymbolKind(SymbolKind),
22    ExternBlock,
23    Region,
24}
25
26#[derive(Debug, Clone)]
27pub struct FileStructureConfig {
28    pub exclude_locals: bool,
29}
30
31// Feature: File Structure
32//
33// Provides a tree of the symbols defined in the file. Can be used to
34//
35// * fuzzy search symbol in a file (super useful)
36// * draw breadcrumbs to describe the context around the cursor
37// * draw outline of the file
38//
39// | Editor  | Shortcut |
40// |---------|----------|
41// | VS Code | <kbd>Ctrl+Shift+O</kbd> |
42//
43// ![File Structure](https://user-images.githubusercontent.com/48062697/113020654-b42fc800-917a-11eb-8388-e7dc4d92b02e.gif)
44pub(crate) fn file_structure(
45    file: &SourceFile,
46    config: &FileStructureConfig,
47) -> Vec<StructureNode> {
48    let mut res = Vec::new();
49    let mut stack = Vec::new();
50
51    for event in file.syntax().preorder_with_tokens() {
52        match event {
53            WalkEvent::Enter(NodeOrToken::Node(node)) => {
54                if let Some(mut symbol) = structure_node(&node, config) {
55                    symbol.parent = stack.last().copied();
56                    stack.push(res.len());
57                    res.push(symbol);
58                }
59            }
60            WalkEvent::Leave(NodeOrToken::Node(node)) => {
61                if structure_node(&node, config).is_some() {
62                    stack.pop().unwrap();
63                }
64            }
65            WalkEvent::Enter(NodeOrToken::Token(token)) => {
66                if let Some(mut symbol) = structure_token(token) {
67                    symbol.parent = stack.last().copied();
68                    stack.push(res.len());
69                    res.push(symbol);
70                }
71            }
72            WalkEvent::Leave(NodeOrToken::Token(token)) => {
73                if structure_token(token).is_some() {
74                    stack.pop().unwrap();
75                }
76            }
77        }
78    }
79    res
80}
81
82fn structure_node(node: &SyntaxNode, config: &FileStructureConfig) -> Option<StructureNode> {
83    fn decl<N: HasName + HasAttrs>(node: N, kind: StructureNodeKind) -> Option<StructureNode> {
84        decl_with_detail(&node, None, kind)
85    }
86
87    fn decl_with_type_ref<N: HasName + HasAttrs>(
88        node: &N,
89        type_ref: Option<ast::Type>,
90        kind: StructureNodeKind,
91    ) -> Option<StructureNode> {
92        let detail = type_ref.map(|type_ref| {
93            let mut detail = String::new();
94            collapse_ws(type_ref.syntax(), &mut detail);
95            detail
96        });
97        decl_with_detail(node, detail, kind)
98    }
99
100    fn decl_with_detail<N: HasName + HasAttrs>(
101        node: &N,
102        detail: Option<String>,
103        kind: StructureNodeKind,
104    ) -> Option<StructureNode> {
105        let name = node.name()?;
106
107        Some(StructureNode {
108            parent: None,
109            label: name.text().to_string(),
110            navigation_range: name.syntax().text_range(),
111            node_range: node.syntax().text_range(),
112            kind,
113            detail,
114            deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"),
115        })
116    }
117
118    fn collapse_ws(node: &SyntaxNode, output: &mut String) {
119        let mut can_insert_ws = false;
120        node.text().for_each_chunk(|chunk| {
121            for line in chunk.lines() {
122                let line = line.trim();
123                if line.is_empty() {
124                    if can_insert_ws {
125                        output.push(' ');
126                        can_insert_ws = false;
127                    }
128                } else {
129                    output.push_str(line);
130                    can_insert_ws = true;
131                }
132            }
133        })
134    }
135
136    match_ast! {
137        match node {
138            ast::Fn(it) => {
139                let mut detail = String::from("fn");
140                if let Some(type_param_list) = it.generic_param_list() {
141                    collapse_ws(type_param_list.syntax(), &mut detail);
142                }
143                let has_self_param = if let Some(param_list) = it.param_list() {
144                    collapse_ws(param_list.syntax(), &mut detail);
145                    param_list.self_param().is_some()
146                } else {
147                    false
148                };
149                if let Some(ret_type) = it.ret_type() {
150                    detail.push(' ');
151                    collapse_ws(ret_type.syntax(), &mut detail);
152                }
153
154                decl_with_detail(&it, Some(detail), StructureNodeKind::SymbolKind(if has_self_param {
155                    SymbolKind::Method
156                } else {
157                    SymbolKind::Function
158                }))
159            },
160            ast::Struct(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Struct)),
161            ast::Union(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Union)),
162            ast::Enum(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Enum)),
163            ast::Variant(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Variant)),
164            ast::Trait(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Trait)),
165            ast::Module(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Module)),
166            ast::Macro(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Macro)),
167            ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty(), StructureNodeKind::SymbolKind(SymbolKind::TypeAlias)),
168            ast::RecordField(it) => decl_with_type_ref(&it, it.ty(), StructureNodeKind::SymbolKind(SymbolKind::Field)),
169            ast::Const(it) => decl_with_type_ref(&it, it.ty(), StructureNodeKind::SymbolKind(SymbolKind::Const)),
170            ast::Static(it) => decl_with_type_ref(&it, it.ty(), StructureNodeKind::SymbolKind(SymbolKind::Static)),
171            ast::Impl(it) => {
172                let target_type = it.self_ty()?;
173                let target_trait = it.trait_();
174                let label = match target_trait {
175                    None => format!("impl {}", target_type.syntax().text()),
176                    Some(t) => {
177                        format!("impl {}{} for {}",
178                            it.excl_token().map(|x| x.to_string()).unwrap_or_default(),
179                            t.syntax().text(),
180                            target_type.syntax().text(),
181                        )
182                    }
183                };
184
185                let node = StructureNode {
186                    parent: None,
187                    label,
188                    navigation_range: target_type.syntax().text_range(),
189                    node_range: it.syntax().text_range(),
190                    kind: StructureNodeKind::SymbolKind(SymbolKind::Impl),
191                    detail: None,
192                    deprecated: false,
193                };
194                Some(node)
195            },
196            ast::LetStmt(it) => {
197                if config.exclude_locals {
198                    return None;
199                }
200
201                let pat = it.pat()?;
202
203                let mut label = String::new();
204                collapse_ws(pat.syntax(), &mut label);
205
206                let node = StructureNode {
207                    parent: None,
208                    label,
209                    navigation_range: pat.syntax().text_range(),
210                    node_range: it.syntax().text_range(),
211                    kind: StructureNodeKind::SymbolKind(SymbolKind::Local),
212                    detail: it.ty().map(|ty| ty.to_string()),
213                    deprecated: false,
214                };
215                Some(node)
216            },
217            ast::ExternBlock(it) => {
218                let mut label = "extern".to_owned();
219                let abi = it.abi()?;
220                if let Some(abi) = abi.string_token() {
221                    label.push(' ');
222                    label.push_str(abi.text());
223                }
224                Some(StructureNode {
225                    parent: None,
226                    label,
227                    navigation_range: abi.syntax().text_range(),
228                    node_range: it.syntax().text_range(),
229                    kind: StructureNodeKind::ExternBlock,
230                    detail: None,
231                    deprecated: false,
232                })
233            },
234            _ => None,
235        }
236    }
237}
238
239fn structure_token(token: SyntaxToken) -> Option<StructureNode> {
240    if let Some(comment) = ast::Comment::cast(token) {
241        let text = comment.text().trim();
242
243        if let Some(region_name) =
244            text.strip_prefix("// region:").map(str::trim).filter(|it| !it.is_empty())
245        {
246            return Some(StructureNode {
247                parent: None,
248                label: region_name.to_owned(),
249                navigation_range: comment.syntax().text_range(),
250                node_range: comment.syntax().text_range(),
251                kind: StructureNodeKind::Region,
252                detail: None,
253                deprecated: false,
254            });
255        }
256    }
257
258    None
259}
260
261#[cfg(test)]
262mod tests {
263    use expect_test::{Expect, expect};
264
265    use super::*;
266
267    const DEFAULT_CONFIG: FileStructureConfig = FileStructureConfig { exclude_locals: true };
268
269    fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
270        check_with_config(ra_fixture, &DEFAULT_CONFIG, expect);
271    }
272
273    fn check_with_config(
274        #[rust_analyzer::rust_fixture] ra_fixture: &str,
275        config: &FileStructureConfig,
276        expect: Expect,
277    ) {
278        let file = SourceFile::parse(ra_fixture, span::Edition::CURRENT).ok().unwrap();
279        let structure = file_structure(&file, config);
280        expect.assert_debug_eq(&structure)
281    }
282
283    #[test]
284    fn test_negative_trait_bound() {
285        let txt = r#"impl !Unpin for Test {}"#;
286        check(
287            txt,
288            expect![[r#"
289        [
290            StructureNode {
291                parent: None,
292                label: "impl !Unpin for Test",
293                navigation_range: 16..20,
294                node_range: 0..23,
295                kind: SymbolKind(
296                    Impl,
297                ),
298                detail: None,
299                deprecated: false,
300            },
301        ]
302        "#]],
303        );
304    }
305
306    #[test]
307    fn test_file_structure() {
308        check(
309            r#"
310struct Foo {
311    x: i32
312}
313
314mod m {
315    fn bar1() {}
316    fn bar2<T>(t: T) -> T {}
317    fn bar3<A,
318        B>(a: A,
319        b: B) -> Vec<
320        u32
321    > {}
322}
323
324enum E { X, Y(i32) }
325type T = ();
326static S: i32 = 92;
327const C: i32 = 92;
328trait Tr {}
329trait Alias = Tr;
330
331impl E {}
332
333impl fmt::Debug for E {}
334
335macro_rules! mc {
336    () => {}
337}
338
339#[macro_export]
340macro_rules! mcexp {
341    () => {}
342}
343
344/// Doc comment
345macro_rules! mcexp {
346    () => {}
347}
348
349#[deprecated]
350fn obsolete() {}
351
352#[deprecated(note = "for a while")]
353fn very_obsolete() {}
354
355// region: Some region name
356// endregion
357
358// region: dontpanic
359mod m {
360fn f() {}
361// endregion
362fn g() {}
363}
364
365extern "C" {}
366
367fn let_statements() {
368    let x = 42;
369    let mut y = x;
370    let Foo {
371        ..
372    } = Foo { x };
373    if let None = Some(x) {}
374    _ = ();
375    let _ = g();
376}
377"#,
378            expect![[r#"
379                [
380                    StructureNode {
381                        parent: None,
382                        label: "Foo",
383                        navigation_range: 8..11,
384                        node_range: 1..26,
385                        kind: SymbolKind(
386                            Struct,
387                        ),
388                        detail: None,
389                        deprecated: false,
390                    },
391                    StructureNode {
392                        parent: Some(
393                            0,
394                        ),
395                        label: "x",
396                        navigation_range: 18..19,
397                        node_range: 18..24,
398                        kind: SymbolKind(
399                            Field,
400                        ),
401                        detail: Some(
402                            "i32",
403                        ),
404                        deprecated: false,
405                    },
406                    StructureNode {
407                        parent: None,
408                        label: "m",
409                        navigation_range: 32..33,
410                        node_range: 28..158,
411                        kind: SymbolKind(
412                            Module,
413                        ),
414                        detail: None,
415                        deprecated: false,
416                    },
417                    StructureNode {
418                        parent: Some(
419                            2,
420                        ),
421                        label: "bar1",
422                        navigation_range: 43..47,
423                        node_range: 40..52,
424                        kind: SymbolKind(
425                            Function,
426                        ),
427                        detail: Some(
428                            "fn()",
429                        ),
430                        deprecated: false,
431                    },
432                    StructureNode {
433                        parent: Some(
434                            2,
435                        ),
436                        label: "bar2",
437                        navigation_range: 60..64,
438                        node_range: 57..81,
439                        kind: SymbolKind(
440                            Function,
441                        ),
442                        detail: Some(
443                            "fn<T>(t: T) -> T",
444                        ),
445                        deprecated: false,
446                    },
447                    StructureNode {
448                        parent: Some(
449                            2,
450                        ),
451                        label: "bar3",
452                        navigation_range: 89..93,
453                        node_range: 86..156,
454                        kind: SymbolKind(
455                            Function,
456                        ),
457                        detail: Some(
458                            "fn<A, B>(a: A, b: B) -> Vec< u32 >",
459                        ),
460                        deprecated: false,
461                    },
462                    StructureNode {
463                        parent: None,
464                        label: "E",
465                        navigation_range: 165..166,
466                        node_range: 160..180,
467                        kind: SymbolKind(
468                            Enum,
469                        ),
470                        detail: None,
471                        deprecated: false,
472                    },
473                    StructureNode {
474                        parent: Some(
475                            6,
476                        ),
477                        label: "X",
478                        navigation_range: 169..170,
479                        node_range: 169..170,
480                        kind: SymbolKind(
481                            Variant,
482                        ),
483                        detail: None,
484                        deprecated: false,
485                    },
486                    StructureNode {
487                        parent: Some(
488                            6,
489                        ),
490                        label: "Y",
491                        navigation_range: 172..173,
492                        node_range: 172..178,
493                        kind: SymbolKind(
494                            Variant,
495                        ),
496                        detail: None,
497                        deprecated: false,
498                    },
499                    StructureNode {
500                        parent: None,
501                        label: "T",
502                        navigation_range: 186..187,
503                        node_range: 181..193,
504                        kind: SymbolKind(
505                            TypeAlias,
506                        ),
507                        detail: Some(
508                            "()",
509                        ),
510                        deprecated: false,
511                    },
512                    StructureNode {
513                        parent: None,
514                        label: "S",
515                        navigation_range: 201..202,
516                        node_range: 194..213,
517                        kind: SymbolKind(
518                            Static,
519                        ),
520                        detail: Some(
521                            "i32",
522                        ),
523                        deprecated: false,
524                    },
525                    StructureNode {
526                        parent: None,
527                        label: "C",
528                        navigation_range: 220..221,
529                        node_range: 214..232,
530                        kind: SymbolKind(
531                            Const,
532                        ),
533                        detail: Some(
534                            "i32",
535                        ),
536                        deprecated: false,
537                    },
538                    StructureNode {
539                        parent: None,
540                        label: "Tr",
541                        navigation_range: 239..241,
542                        node_range: 233..244,
543                        kind: SymbolKind(
544                            Trait,
545                        ),
546                        detail: None,
547                        deprecated: false,
548                    },
549                    StructureNode {
550                        parent: None,
551                        label: "Alias",
552                        navigation_range: 251..256,
553                        node_range: 245..262,
554                        kind: SymbolKind(
555                            Trait,
556                        ),
557                        detail: None,
558                        deprecated: false,
559                    },
560                    StructureNode {
561                        parent: None,
562                        label: "impl E",
563                        navigation_range: 269..270,
564                        node_range: 264..273,
565                        kind: SymbolKind(
566                            Impl,
567                        ),
568                        detail: None,
569                        deprecated: false,
570                    },
571                    StructureNode {
572                        parent: None,
573                        label: "impl fmt::Debug for E",
574                        navigation_range: 295..296,
575                        node_range: 275..299,
576                        kind: SymbolKind(
577                            Impl,
578                        ),
579                        detail: None,
580                        deprecated: false,
581                    },
582                    StructureNode {
583                        parent: None,
584                        label: "mc",
585                        navigation_range: 314..316,
586                        node_range: 301..333,
587                        kind: SymbolKind(
588                            Macro,
589                        ),
590                        detail: None,
591                        deprecated: false,
592                    },
593                    StructureNode {
594                        parent: None,
595                        label: "mcexp",
596                        navigation_range: 364..369,
597                        node_range: 335..386,
598                        kind: SymbolKind(
599                            Macro,
600                        ),
601                        detail: None,
602                        deprecated: false,
603                    },
604                    StructureNode {
605                        parent: None,
606                        label: "mcexp",
607                        navigation_range: 417..422,
608                        node_range: 388..439,
609                        kind: SymbolKind(
610                            Macro,
611                        ),
612                        detail: None,
613                        deprecated: false,
614                    },
615                    StructureNode {
616                        parent: None,
617                        label: "obsolete",
618                        navigation_range: 458..466,
619                        node_range: 441..471,
620                        kind: SymbolKind(
621                            Function,
622                        ),
623                        detail: Some(
624                            "fn()",
625                        ),
626                        deprecated: true,
627                    },
628                    StructureNode {
629                        parent: None,
630                        label: "very_obsolete",
631                        navigation_range: 512..525,
632                        node_range: 473..530,
633                        kind: SymbolKind(
634                            Function,
635                        ),
636                        detail: Some(
637                            "fn()",
638                        ),
639                        deprecated: true,
640                    },
641                    StructureNode {
642                        parent: None,
643                        label: "Some region name",
644                        navigation_range: 532..559,
645                        node_range: 532..559,
646                        kind: Region,
647                        detail: None,
648                        deprecated: false,
649                    },
650                    StructureNode {
651                        parent: None,
652                        label: "m",
653                        navigation_range: 599..600,
654                        node_range: 574..637,
655                        kind: SymbolKind(
656                            Module,
657                        ),
658                        detail: None,
659                        deprecated: false,
660                    },
661                    StructureNode {
662                        parent: Some(
663                            22,
664                        ),
665                        label: "dontpanic",
666                        navigation_range: 574..594,
667                        node_range: 574..594,
668                        kind: Region,
669                        detail: None,
670                        deprecated: false,
671                    },
672                    StructureNode {
673                        parent: Some(
674                            22,
675                        ),
676                        label: "f",
677                        navigation_range: 606..607,
678                        node_range: 603..612,
679                        kind: SymbolKind(
680                            Function,
681                        ),
682                        detail: Some(
683                            "fn()",
684                        ),
685                        deprecated: false,
686                    },
687                    StructureNode {
688                        parent: Some(
689                            22,
690                        ),
691                        label: "g",
692                        navigation_range: 629..630,
693                        node_range: 613..635,
694                        kind: SymbolKind(
695                            Function,
696                        ),
697                        detail: Some(
698                            "fn()",
699                        ),
700                        deprecated: false,
701                    },
702                    StructureNode {
703                        parent: None,
704                        label: "extern \"C\"",
705                        navigation_range: 639..649,
706                        node_range: 639..652,
707                        kind: ExternBlock,
708                        detail: None,
709                        deprecated: false,
710                    },
711                    StructureNode {
712                        parent: None,
713                        label: "let_statements",
714                        navigation_range: 657..671,
715                        node_range: 654..814,
716                        kind: SymbolKind(
717                            Function,
718                        ),
719                        detail: Some(
720                            "fn()",
721                        ),
722                        deprecated: false,
723                    },
724                ]
725            "#]],
726        );
727    }
728
729    #[test]
730    fn test_file_structure_include_locals() {
731        check_with_config(
732            r#"
733struct Foo {
734    x: i32
735}
736
737mod m {
738    fn bar1() {}
739    fn bar2<T>(t: T) -> T {}
740    fn bar3<A,
741        B>(a: A,
742        b: B) -> Vec<
743        u32
744    > {}
745}
746
747enum E { X, Y(i32) }
748type T = ();
749static S: i32 = 42;
750const C: i32 = 42;
751trait Tr {}
752trait Alias = Tr;
753
754macro_rules! mc {
755    () => {}
756}
757
758fn let_statements() {
759    let x = 42;
760    let mut y = x;
761    let Foo {
762        ..
763    } = Foo { x };
764    _ = ();
765    let _ = g();
766}
767"#,
768            &FileStructureConfig { exclude_locals: false },
769            expect![[r#"
770                [
771                    StructureNode {
772                        parent: None,
773                        label: "Foo",
774                        navigation_range: 8..11,
775                        node_range: 1..26,
776                        kind: SymbolKind(
777                            Struct,
778                        ),
779                        detail: None,
780                        deprecated: false,
781                    },
782                    StructureNode {
783                        parent: Some(
784                            0,
785                        ),
786                        label: "x",
787                        navigation_range: 18..19,
788                        node_range: 18..24,
789                        kind: SymbolKind(
790                            Field,
791                        ),
792                        detail: Some(
793                            "i32",
794                        ),
795                        deprecated: false,
796                    },
797                    StructureNode {
798                        parent: None,
799                        label: "m",
800                        navigation_range: 32..33,
801                        node_range: 28..158,
802                        kind: SymbolKind(
803                            Module,
804                        ),
805                        detail: None,
806                        deprecated: false,
807                    },
808                    StructureNode {
809                        parent: Some(
810                            2,
811                        ),
812                        label: "bar1",
813                        navigation_range: 43..47,
814                        node_range: 40..52,
815                        kind: SymbolKind(
816                            Function,
817                        ),
818                        detail: Some(
819                            "fn()",
820                        ),
821                        deprecated: false,
822                    },
823                    StructureNode {
824                        parent: Some(
825                            2,
826                        ),
827                        label: "bar2",
828                        navigation_range: 60..64,
829                        node_range: 57..81,
830                        kind: SymbolKind(
831                            Function,
832                        ),
833                        detail: Some(
834                            "fn<T>(t: T) -> T",
835                        ),
836                        deprecated: false,
837                    },
838                    StructureNode {
839                        parent: Some(
840                            2,
841                        ),
842                        label: "bar3",
843                        navigation_range: 89..93,
844                        node_range: 86..156,
845                        kind: SymbolKind(
846                            Function,
847                        ),
848                        detail: Some(
849                            "fn<A, B>(a: A, b: B) -> Vec< u32 >",
850                        ),
851                        deprecated: false,
852                    },
853                    StructureNode {
854                        parent: None,
855                        label: "E",
856                        navigation_range: 165..166,
857                        node_range: 160..180,
858                        kind: SymbolKind(
859                            Enum,
860                        ),
861                        detail: None,
862                        deprecated: false,
863                    },
864                    StructureNode {
865                        parent: Some(
866                            6,
867                        ),
868                        label: "X",
869                        navigation_range: 169..170,
870                        node_range: 169..170,
871                        kind: SymbolKind(
872                            Variant,
873                        ),
874                        detail: None,
875                        deprecated: false,
876                    },
877                    StructureNode {
878                        parent: Some(
879                            6,
880                        ),
881                        label: "Y",
882                        navigation_range: 172..173,
883                        node_range: 172..178,
884                        kind: SymbolKind(
885                            Variant,
886                        ),
887                        detail: None,
888                        deprecated: false,
889                    },
890                    StructureNode {
891                        parent: None,
892                        label: "T",
893                        navigation_range: 186..187,
894                        node_range: 181..193,
895                        kind: SymbolKind(
896                            TypeAlias,
897                        ),
898                        detail: Some(
899                            "()",
900                        ),
901                        deprecated: false,
902                    },
903                    StructureNode {
904                        parent: None,
905                        label: "S",
906                        navigation_range: 201..202,
907                        node_range: 194..213,
908                        kind: SymbolKind(
909                            Static,
910                        ),
911                        detail: Some(
912                            "i32",
913                        ),
914                        deprecated: false,
915                    },
916                    StructureNode {
917                        parent: None,
918                        label: "C",
919                        navigation_range: 220..221,
920                        node_range: 214..232,
921                        kind: SymbolKind(
922                            Const,
923                        ),
924                        detail: Some(
925                            "i32",
926                        ),
927                        deprecated: false,
928                    },
929                    StructureNode {
930                        parent: None,
931                        label: "Tr",
932                        navigation_range: 239..241,
933                        node_range: 233..244,
934                        kind: SymbolKind(
935                            Trait,
936                        ),
937                        detail: None,
938                        deprecated: false,
939                    },
940                    StructureNode {
941                        parent: None,
942                        label: "Alias",
943                        navigation_range: 251..256,
944                        node_range: 245..262,
945                        kind: SymbolKind(
946                            Trait,
947                        ),
948                        detail: None,
949                        deprecated: false,
950                    },
951                    StructureNode {
952                        parent: None,
953                        label: "mc",
954                        navigation_range: 277..279,
955                        node_range: 264..296,
956                        kind: SymbolKind(
957                            Macro,
958                        ),
959                        detail: None,
960                        deprecated: false,
961                    },
962                    StructureNode {
963                        parent: None,
964                        label: "let_statements",
965                        navigation_range: 301..315,
966                        node_range: 298..429,
967                        kind: SymbolKind(
968                            Function,
969                        ),
970                        detail: Some(
971                            "fn()",
972                        ),
973                        deprecated: false,
974                    },
975                    StructureNode {
976                        parent: Some(
977                            15,
978                        ),
979                        label: "x",
980                        navigation_range: 328..329,
981                        node_range: 324..335,
982                        kind: SymbolKind(
983                            Local,
984                        ),
985                        detail: None,
986                        deprecated: false,
987                    },
988                    StructureNode {
989                        parent: Some(
990                            15,
991                        ),
992                        label: "mut y",
993                        navigation_range: 344..349,
994                        node_range: 340..354,
995                        kind: SymbolKind(
996                            Local,
997                        ),
998                        detail: None,
999                        deprecated: false,
1000                    },
1001                    StructureNode {
1002                        parent: Some(
1003                            15,
1004                        ),
1005                        label: "Foo { .. }",
1006                        navigation_range: 363..385,
1007                        node_range: 359..398,
1008                        kind: SymbolKind(
1009                            Local,
1010                        ),
1011                        detail: None,
1012                        deprecated: false,
1013                    },
1014                    StructureNode {
1015                        parent: Some(
1016                            15,
1017                        ),
1018                        label: "_",
1019                        navigation_range: 419..420,
1020                        node_range: 415..427,
1021                        kind: SymbolKind(
1022                            Local,
1023                        ),
1024                        detail: None,
1025                        deprecated: false,
1026                    },
1027                ]
1028            "#]],
1029        );
1030    }
1031}