aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/annotations.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/annotations.rs')
-rw-r--r--crates/ide/src/annotations.rs87
1 files changed, 59 insertions, 28 deletions
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs
index 8e0a8fd8d..72492f826 100644
--- a/crates/ide/src/annotations.rs
+++ b/crates/ide/src/annotations.rs
@@ -1,17 +1,18 @@
1use hir::Semantics; 1use either::Either;
2use hir::{HasSource, Semantics};
2use ide_db::{ 3use ide_db::{
3 base_db::{FileId, FilePosition, FileRange, SourceDatabase}, 4 base_db::{FileId, FilePosition, FileRange},
4 RootDatabase, SymbolKind, 5 helpers::visit_file_defs,
6 RootDatabase,
5}; 7};
6use syntax::TextRange; 8use syntax::{ast::NameOwner, AstNode, TextRange, TextSize};
7 9
8use crate::{ 10use crate::{
9 file_structure::file_structure,
10 fn_references::find_all_methods, 11 fn_references::find_all_methods,
11 goto_implementation::goto_implementation, 12 goto_implementation::goto_implementation,
12 references::find_all_refs, 13 references::find_all_refs,
13 runnables::{runnables, Runnable}, 14 runnables::{runnables, Runnable},
14 NavigationTarget, RunnableKind, StructureNodeKind, 15 NavigationTarget, RunnableKind,
15}; 16};
16 17
17// Feature: Annotations 18// Feature: Annotations
@@ -75,41 +76,56 @@ pub(crate) fn annotations(
75 } 76 }
76 } 77 }
77 78
78 file_structure(&db.parse(file_id).tree()) 79 visit_file_defs(&Semantics::new(db), file_id, &mut |def| match def {
79 .into_iter() 80 Either::Left(def) => {
80 .filter(|node| { 81 let node = match def {
81 matches!( 82 hir::ModuleDef::Const(konst) => {
82 node.kind, 83 konst.source(db).and_then(|node| range_and_position_of(&node.value))
83 StructureNodeKind::SymbolKind(SymbolKind::Trait) 84 }
84 | StructureNodeKind::SymbolKind(SymbolKind::Struct) 85 hir::ModuleDef::Trait(trait_) => {
85 | StructureNodeKind::SymbolKind(SymbolKind::Enum) 86 trait_.source(db).and_then(|node| range_and_position_of(&node.value))
86 | StructureNodeKind::SymbolKind(SymbolKind::Union) 87 }
87 | StructureNodeKind::SymbolKind(SymbolKind::Const) 88 hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => {
88 ) 89 strukt.source(db).and_then(|node| range_and_position_of(&node.value))
89 }) 90 }
90 .for_each(|node| { 91 hir::ModuleDef::Adt(hir::Adt::Enum(enum_)) => {
91 if config.annotate_impls 92 enum_.source(db).and_then(|node| range_and_position_of(&node.value))
92 && node.kind != StructureNodeKind::SymbolKind(SymbolKind::Const) 93 }
93 { 94 hir::ModuleDef::Adt(hir::Adt::Union(union)) => {
95 union.source(db).and_then(|node| range_and_position_of(&node.value))
96 }
97 _ => None,
98 };
99 let (offset, range) = match node {
100 Some(node) => node,
101 None => return,
102 };
103
104 if config.annotate_impls && !matches!(def, hir::ModuleDef::Const(_)) {
94 annotations.push(Annotation { 105 annotations.push(Annotation {
95 range: node.node_range, 106 range,
96 kind: AnnotationKind::HasImpls { 107 kind: AnnotationKind::HasImpls {
97 position: FilePosition { file_id, offset: node.navigation_range.start() }, 108 position: FilePosition { file_id, offset },
98 data: None, 109 data: None,
99 }, 110 },
100 }); 111 });
101 } 112 }
102
103 if config.annotate_references { 113 if config.annotate_references {
104 annotations.push(Annotation { 114 annotations.push(Annotation {
105 range: node.node_range, 115 range,
106 kind: AnnotationKind::HasReferences { 116 kind: AnnotationKind::HasReferences {
107 position: FilePosition { file_id, offset: node.navigation_range.start() }, 117 position: FilePosition { file_id, offset },
108 data: None, 118 data: None,
109 }, 119 },
110 }); 120 });
111 } 121 }
112 }); 122
123 fn range_and_position_of(node: &dyn NameOwner) -> Option<(TextSize, TextRange)> {
124 Some((node.name()?.syntax().text_range().start(), node.syntax().text_range()))
125 }
126 }
127 Either::Right(_) => (),
128 });
113 129
114 if config.annotate_method_references { 130 if config.annotate_method_references {
115 annotations.extend(find_all_methods(db, file_id).into_iter().map(|method| Annotation { 131 annotations.extend(find_all_methods(db, file_id).into_iter().map(|method| Annotation {
@@ -936,4 +952,19 @@ mod tests {
936 "#]], 952 "#]],
937 ); 953 );
938 } 954 }
955
956 #[test]
957 fn test_no_annotations_outside_module_tree() {
958 check(
959 r#"
960//- /foo.rs
961struct Foo;
962//- /lib.rs
963// this file comes last since `check` checks the first file only
964"#,
965 expect![[r#"
966 []
967 "#]],
968 );
969 }
939} 970}