@@ -41,6 +41,12 @@ pub struct AnnotationConfig {
41
41
pub annotate_references : bool ,
42
42
pub annotate_method_references : bool ,
43
43
pub annotate_enum_variant_references : bool ,
44
+ pub location : AnnotationLocation ,
45
+ }
46
+
47
+ pub enum AnnotationLocation {
48
+ AboveName ,
49
+ AboveWholeItem ,
44
50
}
45
51
46
52
pub ( crate ) fn annotations (
@@ -65,10 +71,10 @@ pub(crate) fn annotations(
65
71
visit_file_defs ( & Semantics :: new ( db) , file_id, & mut |def| {
66
72
let range = match def {
67
73
Definition :: Const ( konst) if config. annotate_references => {
68
- konst. source ( db) . and_then ( |node| name_range ( db, node, file_id) )
74
+ konst. source ( db) . and_then ( |node| name_range ( db, config , node, file_id) )
69
75
}
70
76
Definition :: Trait ( trait_) if config. annotate_references || config. annotate_impls => {
71
- trait_. source ( db) . and_then ( |node| name_range ( db, node, file_id) )
77
+ trait_. source ( db) . and_then ( |node| name_range ( db, config , node, file_id) )
72
78
}
73
79
Definition :: Adt ( adt) => match adt {
74
80
hir:: Adt :: Enum ( enum_) => {
@@ -77,7 +83,9 @@ pub(crate) fn annotations(
77
83
. variants ( db)
78
84
. into_iter ( )
79
85
. map ( |variant| {
80
- variant. source ( db) . and_then ( |node| name_range ( db, node, file_id) )
86
+ variant
87
+ . source ( db)
88
+ . and_then ( |node| name_range ( db, config, node, file_id) )
81
89
} )
82
90
. flatten ( )
83
91
. for_each ( |range| {
@@ -88,14 +96,14 @@ pub(crate) fn annotations(
88
96
} )
89
97
}
90
98
if config. annotate_references || config. annotate_impls {
91
- enum_. source ( db) . and_then ( |node| name_range ( db, node, file_id) )
99
+ enum_. source ( db) . and_then ( |node| name_range ( db, config , node, file_id) )
92
100
} else {
93
101
None
94
102
}
95
103
}
96
104
_ => {
97
105
if config. annotate_references || config. annotate_impls {
98
- adt. source ( db) . and_then ( |node| name_range ( db, node, file_id) )
106
+ adt. source ( db) . and_then ( |node| name_range ( db, config , node, file_id) )
99
107
} else {
100
108
None
101
109
}
@@ -113,6 +121,7 @@ pub(crate) fn annotations(
113
121
annotations
114
122
. push ( Annotation { range, kind : AnnotationKind :: HasImpls { file_id, data : None } } ) ;
115
123
}
124
+
116
125
if config. annotate_references {
117
126
annotations. push ( Annotation {
118
127
range,
@@ -122,12 +131,18 @@ pub(crate) fn annotations(
122
131
123
132
fn name_range < T : HasName > (
124
133
db : & RootDatabase ,
134
+ config : & AnnotationConfig ,
125
135
node : InFile < T > ,
126
136
source_file_id : FileId ,
127
137
) -> Option < TextRange > {
128
138
if let Some ( InFile { file_id, value } ) = node. original_ast_node ( db) {
129
139
if file_id == source_file_id. into ( ) {
130
- return value. name ( ) . map ( |it| it. syntax ( ) . text_range ( ) ) ;
140
+ return match config. location {
141
+ AnnotationLocation :: AboveName => {
142
+ value. name ( ) . map ( |name| name. syntax ( ) . text_range ( ) )
143
+ }
144
+ AnnotationLocation :: AboveWholeItem => Some ( value. syntax ( ) . text_range ( ) ) ,
145
+ } ;
131
146
}
132
147
}
133
148
None
@@ -188,21 +203,23 @@ mod tests {
188
203
189
204
use crate :: { fixture, Annotation , AnnotationConfig } ;
190
205
191
- fn check ( ra_fixture : & str , expect : Expect ) {
206
+ use super :: AnnotationLocation ;
207
+
208
+ const DEFAULT_CONFIG : AnnotationConfig = AnnotationConfig {
209
+ binary_target : true ,
210
+ annotate_runnables : true ,
211
+ annotate_impls : true ,
212
+ annotate_references : true ,
213
+ annotate_method_references : true ,
214
+ annotate_enum_variant_references : true ,
215
+ location : AnnotationLocation :: AboveName ,
216
+ } ;
217
+
218
+ fn check_with_config ( ra_fixture : & str , expect : Expect , config : & AnnotationConfig ) {
192
219
let ( analysis, file_id) = fixture:: file ( ra_fixture) ;
193
220
194
221
let annotations: Vec < Annotation > = analysis
195
- . annotations (
196
- & AnnotationConfig {
197
- binary_target : true ,
198
- annotate_runnables : true ,
199
- annotate_impls : true ,
200
- annotate_references : true ,
201
- annotate_method_references : true ,
202
- annotate_enum_variant_references : true ,
203
- } ,
204
- file_id,
205
- )
222
+ . annotations ( config, file_id)
206
223
. unwrap ( )
207
224
. into_iter ( )
208
225
. map ( |annotation| analysis. resolve_annotation ( annotation) . unwrap ( ) )
@@ -211,6 +228,10 @@ mod tests {
211
228
expect. assert_debug_eq ( & annotations) ;
212
229
}
213
230
231
+ fn check ( ra_fixture : & str , expect : Expect ) {
232
+ check_with_config ( ra_fixture, expect, & DEFAULT_CONFIG ) ;
233
+ }
234
+
214
235
#[ test]
215
236
fn const_annotations ( ) {
216
237
check (
@@ -786,4 +807,40 @@ m!();
786
807
"# ] ] ,
787
808
) ;
788
809
}
810
+
811
+ #[ test]
812
+ fn test_annotations_appear_above_whole_item_when_configured_to_do_so ( ) {
813
+ check_with_config (
814
+ r#"
815
+ /// This is a struct named Foo, obviously.
816
+ #[derive(Clone)]
817
+ struct Foo;
818
+ "# ,
819
+ expect ! [ [ r#"
820
+ [
821
+ Annotation {
822
+ range: 0..71,
823
+ kind: HasImpls {
824
+ file_id: FileId(
825
+ 0,
826
+ ),
827
+ data: Some(
828
+ [],
829
+ ),
830
+ },
831
+ },
832
+ Annotation {
833
+ range: 0..71,
834
+ kind: HasReferences {
835
+ file_id: FileId(
836
+ 0,
837
+ ),
838
+ data: None,
839
+ },
840
+ },
841
+ ]
842
+ "# ] ] ,
843
+ & AnnotationConfig { location : AnnotationLocation :: AboveWholeItem , ..DEFAULT_CONFIG } ,
844
+ ) ;
845
+ }
789
846
}
0 commit comments