@@ -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 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. 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+ location : AnnotationLocation :: AboveName ,
216+ } ;
217+
218+ fn check_with_config ( 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 ( ) )
@@ -211,6 +228,10 @@ mod tests {
211228 expect. assert_debug_eq ( & annotations) ;
212229 }
213230
231+ fn check ( ra_fixture : & str , expect : Expect ) {
232+ check_with_config ( ra_fixture, expect, & DEFAULT_CONFIG ) ;
233+ }
234+
214235 #[ test]
215236 fn const_annotations ( ) {
216237 check (
@@ -786,4 +807,40 @@ m!();
786807 "# ] ] ,
787808 ) ;
788809 }
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+ }
789846}
0 commit comments