From a1c96e04be55b3412e5510fc8d09cd82675dd4cd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 14 Mar 2021 16:12:38 +0100 Subject: Introduce Semantics::visit_file_defs --- crates/ide/src/annotations.rs | 86 +++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 28 deletions(-) (limited to 'crates/ide/src/annotations.rs') 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 @@ -use hir::Semantics; +use either::Either; +use hir::{HasSource, Semantics}; use ide_db::{ - base_db::{FileId, FilePosition, FileRange, SourceDatabase}, - RootDatabase, SymbolKind, + base_db::{FileId, FilePosition, FileRange}, + RootDatabase, }; -use syntax::TextRange; +use syntax::{ast::NameOwner, AstNode, TextRange, TextSize}; use crate::{ - file_structure::file_structure, fn_references::find_all_methods, goto_implementation::goto_implementation, references::find_all_refs, runnables::{runnables, Runnable}, - NavigationTarget, RunnableKind, StructureNodeKind, + NavigationTarget, RunnableKind, }; // Feature: Annotations @@ -75,41 +75,56 @@ pub(crate) fn annotations( } } - file_structure(&db.parse(file_id).tree()) - .into_iter() - .filter(|node| { - matches!( - node.kind, - StructureNodeKind::SymbolKind(SymbolKind::Trait) - | StructureNodeKind::SymbolKind(SymbolKind::Struct) - | StructureNodeKind::SymbolKind(SymbolKind::Enum) - | StructureNodeKind::SymbolKind(SymbolKind::Union) - | StructureNodeKind::SymbolKind(SymbolKind::Const) - ) - }) - .for_each(|node| { - if config.annotate_impls - && node.kind != StructureNodeKind::SymbolKind(SymbolKind::Const) - { + Semantics::new(db).visit_file_defs(file_id, &mut |def| match def { + Either::Left(def) => { + let node = match def { + hir::ModuleDef::Const(konst) => { + konst.source(db).and_then(|node| range_and_position_of(&node.value)) + } + hir::ModuleDef::Trait(trait_) => { + trait_.source(db).and_then(|node| range_and_position_of(&node.value)) + } + hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => { + strukt.source(db).and_then(|node| range_and_position_of(&node.value)) + } + hir::ModuleDef::Adt(hir::Adt::Enum(enum_)) => { + enum_.source(db).and_then(|node| range_and_position_of(&node.value)) + } + hir::ModuleDef::Adt(hir::Adt::Union(union)) => { + union.source(db).and_then(|node| range_and_position_of(&node.value)) + } + _ => None, + }; + let (offset, range) = match node { + Some(node) => node, + None => return, + }; + + if config.annotate_impls && !matches!(def, hir::ModuleDef::Const(_)) { annotations.push(Annotation { - range: node.node_range, + range, kind: AnnotationKind::HasImpls { - position: FilePosition { file_id, offset: node.navigation_range.start() }, + position: FilePosition { file_id, offset }, data: None, }, }); } - if config.annotate_references { annotations.push(Annotation { - range: node.node_range, + range, kind: AnnotationKind::HasReferences { - position: FilePosition { file_id, offset: node.navigation_range.start() }, + position: FilePosition { file_id, offset }, data: None, }, }); } - }); + + fn range_and_position_of(node: &dyn NameOwner) -> Option<(TextSize, TextRange)> { + Some((node.name()?.syntax().text_range().start(), node.syntax().text_range())) + } + } + Either::Right(_) => (), + }); if config.annotate_method_references { annotations.extend(find_all_methods(db, file_id).into_iter().map(|method| Annotation { @@ -936,4 +951,19 @@ mod tests { "#]], ); } + + #[test] + fn test_no_annotations_outside_module_tree() { + check( + r#" +//- /foo.rs +struct Foo; +//- /lib.rs +// this file comes last since `check` checks the first file only +"#, + expect![[r#" + [] + "#]], + ); + } } -- cgit v1.2.3