@@ -41,6 +41,12 @@ pub struct AnnotationConfig {
4141 pub annotate_references : bool ,
4242 pub annotate_method_references : bool ,
4343 pub annotate_enum_variant_references : bool ,
44+ pub annotation_location : AnnotationLocation ,
45+ }
46+
47+ pub enum AnnotationLocation {
48+ AboveName ,
49+ AboveWholeItem ,
4450}
4551
4652pub ( crate ) fn annotations (
@@ -65,10 +71,10 @@ pub(crate) fn annotations(
6571 visit_file_defs ( & Semantics :: new ( db) , file_id, & mut |def| {
6672 let range = match def {
6773 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) )
6975 }
7076 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) )
7278 }
7379 Definition :: Adt ( adt) => match adt {
7480 hir:: Adt :: Enum ( enum_) => {
@@ -77,7 +83,9 @@ pub(crate) fn annotations(
7783 . variants ( db)
7884 . into_iter ( )
7985 . 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) )
8189 } )
8290 . flatten ( )
8391 . for_each ( |range| {
@@ -88,14 +96,14 @@ pub(crate) fn annotations(
8896 } )
8997 }
9098 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) )
92100 } else {
93101 None
94102 }
95103 }
96104 _ => {
97105 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) )
99107 } else {
100108 None
101109 }
@@ -113,6 +121,7 @@ pub(crate) fn annotations(
113121 annotations
114122 . push ( Annotation { range, kind : AnnotationKind :: HasImpls { file_id, data : None } } ) ;
115123 }
124+
116125 if config. annotate_references {
117126 annotations. push ( Annotation {
118127 range,
@@ -122,12 +131,18 @@ pub(crate) fn annotations(
122131
123132 fn name_range < T : HasName > (
124133 db : & RootDatabase ,
134+ config : & AnnotationConfig ,
125135 node : InFile < T > ,
126136 source_file_id : FileId ,
127137 ) -> Option < TextRange > {
128138 if let Some ( InFile { file_id, value } ) = node. original_ast_node ( db) {
129139 if file_id == source_file_id. into ( ) {
130- return value. name ( ) . map ( |it| it. syntax ( ) . text_range ( ) ) ;
140+ return match config. annotation_location {
141+ AnnotationLocation :: AboveName => {
142+ value. name ( ) . map ( |name| name. syntax ( ) . text_range ( ) )
143+ }
144+ AnnotationLocation :: AboveWholeItem => Some ( value. syntax ( ) . text_range ( ) ) ,
145+ } ;
131146 }
132147 }
133148 None
@@ -188,21 +203,23 @@ mod tests {
188203
189204 use crate :: { fixture, Annotation , AnnotationConfig } ;
190205
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+ annotation_location : AnnotationLocation :: AboveName ,
216+ } ;
217+
218+ fn check ( ra_fixture : & str , expect : Expect , config : & AnnotationConfig ) {
192219 let ( analysis, file_id) = fixture:: file ( ra_fixture) ;
193220
194221 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)
206223 . unwrap ( )
207224 . into_iter ( )
208225 . map ( |annotation| analysis. resolve_annotation ( annotation) . unwrap ( ) )
@@ -286,6 +303,7 @@ fn main() {
286303 },
287304 ]
288305 "# ] ] ,
306+ & DEFAULT_CONFIG ,
289307 ) ;
290308 }
291309
@@ -362,6 +380,7 @@ fn main() {
362380 },
363381 ]
364382 "# ] ] ,
383+ & DEFAULT_CONFIG ,
365384 ) ;
366385 }
367386
@@ -497,6 +516,7 @@ fn main() {
497516 },
498517 ]
499518 "# ] ] ,
519+ & DEFAULT_CONFIG ,
500520 ) ;
501521 }
502522
@@ -540,6 +560,7 @@ fn main() {}
540560 },
541561 ]
542562 "# ] ] ,
563+ & DEFAULT_CONFIG ,
543564 ) ;
544565 }
545566
@@ -654,6 +675,7 @@ fn main() {
654675 },
655676 ]
656677 "# ] ] ,
678+ & DEFAULT_CONFIG ,
657679 ) ;
658680 }
659681
@@ -750,6 +772,7 @@ mod tests {
750772 },
751773 ]
752774 "# ] ] ,
775+ & DEFAULT_CONFIG ,
753776 ) ;
754777 }
755778
@@ -765,6 +788,7 @@ struct Foo;
765788 expect ! [ [ r#"
766789 []
767790 "# ] ] ,
791+ & DEFAULT_CONFIG ,
768792 ) ;
769793 }
770794
@@ -784,6 +808,46 @@ m!();
784808 expect ! [ [ r#"
785809 []
786810 "# ] ] ,
811+ & DEFAULT_CONFIG ,
812+ ) ;
813+ }
814+
815+ #[ test]
816+ fn test_annotations_appear_above_whole_item_when_configured_to_do_so ( ) {
817+ check (
818+ r#"
819+ /// This is a struct named Foo, obviously.
820+ #[derive(Clone)]
821+ struct Foo;
822+ "# ,
823+ expect ! [ [ r#"
824+ [
825+ Annotation {
826+ range: 0..71,
827+ kind: HasImpls {
828+ file_id: FileId(
829+ 0,
830+ ),
831+ data: Some(
832+ [],
833+ ),
834+ },
835+ },
836+ Annotation {
837+ range: 0..71,
838+ kind: HasReferences {
839+ file_id: FileId(
840+ 0,
841+ ),
842+ data: None,
843+ },
844+ },
845+ ]
846+ "# ] ] ,
847+ & AnnotationConfig {
848+ annotation_location : AnnotationLocation :: AboveWholeItem ,
849+ ..DEFAULT_CONFIG
850+ } ,
787851 ) ;
788852 }
789853}
0 commit comments