diff options
Diffstat (limited to 'crates/ide/src/annotations.rs')
-rw-r--r-- | crates/ide/src/annotations.rs | 83 |
1 files changed, 58 insertions, 25 deletions
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs index 2e8e82b70..72492f826 100644 --- a/crates/ide/src/annotations.rs +++ b/crates/ide/src/annotations.rs | |||
@@ -1,12 +1,13 @@ | |||
1 | use hir::Semantics; | 1 | use either::Either; |
2 | use hir::{HasSource, Semantics}; | ||
2 | use ide_db::{ | 3 | use 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 | }; |
6 | use syntax::TextRange; | 8 | use syntax::{ast::NameOwner, AstNode, TextRange, TextSize}; |
7 | 9 | ||
8 | use crate::{ | 10 | use 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, |
@@ -75,39 +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 | SymbolKind::Trait | 84 | } |
84 | | SymbolKind::Struct | 85 | hir::ModuleDef::Trait(trait_) => { |
85 | | SymbolKind::Enum | 86 | trait_.source(db).and_then(|node| range_and_position_of(&node.value)) |
86 | | SymbolKind::Union | 87 | } |
87 | | 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 && node.kind != SymbolKind::Const { | 92 | enum_.source(db).and_then(|node| range_and_position_of(&node.value)) |
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(_)) { | ||
92 | annotations.push(Annotation { | 105 | annotations.push(Annotation { |
93 | range: node.node_range, | 106 | range, |
94 | kind: AnnotationKind::HasImpls { | 107 | kind: AnnotationKind::HasImpls { |
95 | position: FilePosition { file_id, offset: node.navigation_range.start() }, | 108 | position: FilePosition { file_id, offset }, |
96 | data: None, | 109 | data: None, |
97 | }, | 110 | }, |
98 | }); | 111 | }); |
99 | } | 112 | } |
100 | |||
101 | if config.annotate_references { | 113 | if config.annotate_references { |
102 | annotations.push(Annotation { | 114 | annotations.push(Annotation { |
103 | range: node.node_range, | 115 | range, |
104 | kind: AnnotationKind::HasReferences { | 116 | kind: AnnotationKind::HasReferences { |
105 | position: FilePosition { file_id, offset: node.navigation_range.start() }, | 117 | position: FilePosition { file_id, offset }, |
106 | data: None, | 118 | data: None, |
107 | }, | 119 | }, |
108 | }); | 120 | }); |
109 | } | 121 | } |
110 | }); | 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 | }); | ||
111 | 129 | ||
112 | if config.annotate_method_references { | 130 | if config.annotate_method_references { |
113 | 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 { |
@@ -934,4 +952,19 @@ mod tests { | |||
934 | "#]], | 952 | "#]], |
935 | ); | 953 | ); |
936 | } | 954 | } |
955 | |||
956 | #[test] | ||
957 | fn test_no_annotations_outside_module_tree() { | ||
958 | check( | ||
959 | r#" | ||
960 | //- /foo.rs | ||
961 | struct Foo; | ||
962 | //- /lib.rs | ||
963 | // this file comes last since `check` checks the first file only | ||
964 | "#, | ||
965 | expect![[r#" | ||
966 | [] | ||
967 | "#]], | ||
968 | ); | ||
969 | } | ||
937 | } | 970 | } |