@@ -23,6 +23,11 @@ pub enum StructureNodeKind {
23
23
Region ,
24
24
}
25
25
26
+ #[ derive( Debug , Clone ) ]
27
+ pub struct FileStructureConfig {
28
+ pub exclude_locals : bool ,
29
+ }
30
+
26
31
// Feature: File Structure
27
32
//
28
33
// Provides a tree of the symbols defined in the file. Can be used to
@@ -36,21 +41,24 @@ pub enum StructureNodeKind {
36
41
// | VS Code | <kbd>Ctrl+Shift+O</kbd> |
37
42
//
38
43
// 
39
- pub ( crate ) fn file_structure ( file : & SourceFile ) -> Vec < StructureNode > {
44
+ pub ( crate ) fn file_structure (
45
+ file : & SourceFile ,
46
+ config : & FileStructureConfig ,
47
+ ) -> Vec < StructureNode > {
40
48
let mut res = Vec :: new ( ) ;
41
49
let mut stack = Vec :: new ( ) ;
42
50
43
51
for event in file. syntax ( ) . preorder_with_tokens ( ) {
44
52
match event {
45
53
WalkEvent :: Enter ( NodeOrToken :: Node ( node) ) => {
46
- if let Some ( mut symbol) = structure_node ( & node) {
54
+ if let Some ( mut symbol) = structure_node ( & node, config ) {
47
55
symbol. parent = stack. last ( ) . copied ( ) ;
48
56
stack. push ( res. len ( ) ) ;
49
57
res. push ( symbol) ;
50
58
}
51
59
}
52
60
WalkEvent :: Leave ( NodeOrToken :: Node ( node) ) => {
53
- if structure_node ( & node) . is_some ( ) {
61
+ if structure_node ( & node, config ) . is_some ( ) {
54
62
stack. pop ( ) . unwrap ( ) ;
55
63
}
56
64
}
@@ -71,7 +79,7 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
71
79
res
72
80
}
73
81
74
- fn structure_node ( node : & SyntaxNode ) -> Option < StructureNode > {
82
+ fn structure_node ( node : & SyntaxNode , config : & FileStructureConfig ) -> Option < StructureNode > {
75
83
fn decl < N : HasName + HasAttrs > ( node : N , kind : StructureNodeKind ) -> Option < StructureNode > {
76
84
decl_with_detail ( & node, None , kind)
77
85
}
@@ -187,6 +195,10 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
187
195
Some ( node)
188
196
} ,
189
197
ast:: LetStmt ( it) => {
198
+ if config. exclude_locals {
199
+ return None ;
200
+ }
201
+
190
202
let pat = it. pat( ) ?;
191
203
192
204
let mut label = String :: new( ) ;
@@ -254,9 +266,19 @@ mod tests {
254
266
255
267
use super :: * ;
256
268
269
+ const DEFAULT_CONFIG : FileStructureConfig = FileStructureConfig { exclude_locals : true } ;
270
+
257
271
fn check ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str , expect : Expect ) {
272
+ check_with_config ( ra_fixture, & DEFAULT_CONFIG , expect) ;
273
+ }
274
+
275
+ fn check_with_config (
276
+ #[ rust_analyzer:: rust_fixture] ra_fixture : & str ,
277
+ config : & FileStructureConfig ,
278
+ expect : Expect ,
279
+ ) {
258
280
let file = SourceFile :: parse ( ra_fixture, span:: Edition :: CURRENT ) . ok ( ) . unwrap ( ) ;
259
- let structure = file_structure ( & file) ;
281
+ let structure = file_structure ( & file, config ) ;
260
282
expect. assert_debug_eq ( & structure)
261
283
}
262
284
@@ -701,13 +723,264 @@ fn let_statements() {
701
723
),
702
724
deprecated: false,
703
725
},
726
+ ]
727
+ "# ] ] ,
728
+ ) ;
729
+ }
730
+
731
+ #[ test]
732
+ fn test_file_structure_include_locals ( ) {
733
+ check_with_config (
734
+ r#"
735
+ struct Foo {
736
+ x: i32
737
+ }
738
+
739
+ mod m {
740
+ fn bar1() {}
741
+ fn bar2<T>(t: T) -> T {}
742
+ fn bar3<A,
743
+ B>(a: A,
744
+ b: B) -> Vec<
745
+ u32
746
+ > {}
747
+ }
748
+
749
+ enum E { X, Y(i32) }
750
+ type T = ();
751
+ static S: i32 = 42;
752
+ const C: i32 = 42;
753
+ trait Tr {}
754
+ trait Alias = Tr;
755
+
756
+ macro_rules! mc {
757
+ () => {}
758
+ }
759
+
760
+ fn let_statements() {
761
+ let x = 42;
762
+ let mut y = x;
763
+ let Foo {
764
+ ..
765
+ } = Foo { x };
766
+ _ = ();
767
+ let _ = g();
768
+ }
769
+ "# ,
770
+ & FileStructureConfig { exclude_locals : false } ,
771
+ expect ! [ [ r#"
772
+ [
773
+ StructureNode {
774
+ parent: None,
775
+ label: "Foo",
776
+ navigation_range: 8..11,
777
+ node_range: 1..26,
778
+ kind: SymbolKind(
779
+ Struct,
780
+ ),
781
+ detail: None,
782
+ deprecated: false,
783
+ },
784
+ StructureNode {
785
+ parent: Some(
786
+ 0,
787
+ ),
788
+ label: "x",
789
+ navigation_range: 18..19,
790
+ node_range: 18..24,
791
+ kind: SymbolKind(
792
+ Field,
793
+ ),
794
+ detail: Some(
795
+ "i32",
796
+ ),
797
+ deprecated: false,
798
+ },
799
+ StructureNode {
800
+ parent: None,
801
+ label: "m",
802
+ navigation_range: 32..33,
803
+ node_range: 28..158,
804
+ kind: SymbolKind(
805
+ Module,
806
+ ),
807
+ detail: None,
808
+ deprecated: false,
809
+ },
810
+ StructureNode {
811
+ parent: Some(
812
+ 2,
813
+ ),
814
+ label: "bar1",
815
+ navigation_range: 43..47,
816
+ node_range: 40..52,
817
+ kind: SymbolKind(
818
+ Function,
819
+ ),
820
+ detail: Some(
821
+ "fn()",
822
+ ),
823
+ deprecated: false,
824
+ },
825
+ StructureNode {
826
+ parent: Some(
827
+ 2,
828
+ ),
829
+ label: "bar2",
830
+ navigation_range: 60..64,
831
+ node_range: 57..81,
832
+ kind: SymbolKind(
833
+ Function,
834
+ ),
835
+ detail: Some(
836
+ "fn<T>(t: T) -> T",
837
+ ),
838
+ deprecated: false,
839
+ },
840
+ StructureNode {
841
+ parent: Some(
842
+ 2,
843
+ ),
844
+ label: "bar3",
845
+ navigation_range: 89..93,
846
+ node_range: 86..156,
847
+ kind: SymbolKind(
848
+ Function,
849
+ ),
850
+ detail: Some(
851
+ "fn<A, B>(a: A, b: B) -> Vec< u32 >",
852
+ ),
853
+ deprecated: false,
854
+ },
855
+ StructureNode {
856
+ parent: None,
857
+ label: "E",
858
+ navigation_range: 165..166,
859
+ node_range: 160..180,
860
+ kind: SymbolKind(
861
+ Enum,
862
+ ),
863
+ detail: None,
864
+ deprecated: false,
865
+ },
866
+ StructureNode {
867
+ parent: Some(
868
+ 6,
869
+ ),
870
+ label: "X",
871
+ navigation_range: 169..170,
872
+ node_range: 169..170,
873
+ kind: SymbolKind(
874
+ Variant,
875
+ ),
876
+ detail: None,
877
+ deprecated: false,
878
+ },
879
+ StructureNode {
880
+ parent: Some(
881
+ 6,
882
+ ),
883
+ label: "Y",
884
+ navigation_range: 172..173,
885
+ node_range: 172..178,
886
+ kind: SymbolKind(
887
+ Variant,
888
+ ),
889
+ detail: None,
890
+ deprecated: false,
891
+ },
892
+ StructureNode {
893
+ parent: None,
894
+ label: "T",
895
+ navigation_range: 186..187,
896
+ node_range: 181..193,
897
+ kind: SymbolKind(
898
+ TypeAlias,
899
+ ),
900
+ detail: Some(
901
+ "()",
902
+ ),
903
+ deprecated: false,
904
+ },
905
+ StructureNode {
906
+ parent: None,
907
+ label: "S",
908
+ navigation_range: 201..202,
909
+ node_range: 194..213,
910
+ kind: SymbolKind(
911
+ Static,
912
+ ),
913
+ detail: Some(
914
+ "i32",
915
+ ),
916
+ deprecated: false,
917
+ },
918
+ StructureNode {
919
+ parent: None,
920
+ label: "C",
921
+ navigation_range: 220..221,
922
+ node_range: 214..232,
923
+ kind: SymbolKind(
924
+ Const,
925
+ ),
926
+ detail: Some(
927
+ "i32",
928
+ ),
929
+ deprecated: false,
930
+ },
931
+ StructureNode {
932
+ parent: None,
933
+ label: "Tr",
934
+ navigation_range: 239..241,
935
+ node_range: 233..244,
936
+ kind: SymbolKind(
937
+ Trait,
938
+ ),
939
+ detail: None,
940
+ deprecated: false,
941
+ },
942
+ StructureNode {
943
+ parent: None,
944
+ label: "Alias",
945
+ navigation_range: 251..256,
946
+ node_range: 245..262,
947
+ kind: SymbolKind(
948
+ TraitAlias,
949
+ ),
950
+ detail: None,
951
+ deprecated: false,
952
+ },
953
+ StructureNode {
954
+ parent: None,
955
+ label: "mc",
956
+ navigation_range: 277..279,
957
+ node_range: 264..296,
958
+ kind: SymbolKind(
959
+ Macro,
960
+ ),
961
+ detail: None,
962
+ deprecated: false,
963
+ },
964
+ StructureNode {
965
+ parent: None,
966
+ label: "let_statements",
967
+ navigation_range: 301..315,
968
+ node_range: 298..429,
969
+ kind: SymbolKind(
970
+ Function,
971
+ ),
972
+ detail: Some(
973
+ "fn()",
974
+ ),
975
+ deprecated: false,
976
+ },
704
977
StructureNode {
705
978
parent: Some(
706
- 27 ,
979
+ 15 ,
707
980
),
708
981
label: "x",
709
- navigation_range: 684..685 ,
710
- node_range: 680..691 ,
982
+ navigation_range: 328..329 ,
983
+ node_range: 324..335 ,
711
984
kind: SymbolKind(
712
985
Local,
713
986
),
@@ -716,11 +989,11 @@ fn let_statements() {
716
989
},
717
990
StructureNode {
718
991
parent: Some(
719
- 27 ,
992
+ 15 ,
720
993
),
721
994
label: "mut y",
722
- navigation_range: 700..705 ,
723
- node_range: 696..710 ,
995
+ navigation_range: 344..349 ,
996
+ node_range: 340..354 ,
724
997
kind: SymbolKind(
725
998
Local,
726
999
),
@@ -729,11 +1002,11 @@ fn let_statements() {
729
1002
},
730
1003
StructureNode {
731
1004
parent: Some(
732
- 27 ,
1005
+ 15 ,
733
1006
),
734
1007
label: "Foo { .. }",
735
- navigation_range: 719..741 ,
736
- node_range: 715..754 ,
1008
+ navigation_range: 363..385 ,
1009
+ node_range: 359..398 ,
737
1010
kind: SymbolKind(
738
1011
Local,
739
1012
),
@@ -742,11 +1015,11 @@ fn let_statements() {
742
1015
},
743
1016
StructureNode {
744
1017
parent: Some(
745
- 27 ,
1018
+ 15 ,
746
1019
),
747
1020
label: "_",
748
- navigation_range: 804..805 ,
749
- node_range: 800..812 ,
1021
+ navigation_range: 419..420 ,
1022
+ node_range: 415..427 ,
750
1023
kind: SymbolKind(
751
1024
Local,
752
1025
),
0 commit comments