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