diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index c38dbfd0e7a3..49417d945ce0 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -51,7 +51,7 @@ use hir_def::{ per_ns::PerNs, resolver::{HasResolver, Resolver}, src::HasSource as _, - AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, + AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, @@ -119,11 +119,9 @@ pub use { path::{ModPath, PathKind}, type_ref::{Mutability, TypeRef}, visibility::Visibility, - // FIXME: This is here since it is input of a method in `HirWrite` - // and things outside of hir need to implement that trait. We probably - // should move whole `hir_ty::display` to this crate so we will become - // able to use `ModuleDef` or `Definition` instead of `ModuleDefId`. - ModuleDefId, + // FIXME: This is here since some queries take it as input that are used + // outside of hir. + {AdtId, ModuleDefId}, }, hir_expand::{ attrs::Attr, @@ -4429,3 +4427,90 @@ impl HasCrate for Module { Module::krate(*self) } } + +pub trait HasContainer { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer; +} + +impl HasContainer for Module { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + // FIXME: handle block expressions as modules (their parent is in a different DefMap) + let def_map = self.id.def_map(db.upcast()); + match def_map[self.id.local_id].parent { + Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }), + None => ItemContainer::Crate(def_map.krate()), + } + } +} + +impl HasContainer for Function { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + container_id_to_hir(self.id.lookup(db.upcast()).container) + } +} + +impl HasContainer for Struct { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container }) + } +} + +impl HasContainer for Union { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container }) + } +} + +impl HasContainer for Enum { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container }) + } +} + +impl HasContainer for TypeAlias { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + container_id_to_hir(self.id.lookup(db.upcast()).container) + } +} + +impl HasContainer for Const { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + container_id_to_hir(self.id.lookup(db.upcast()).container) + } +} + +impl HasContainer for Static { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + container_id_to_hir(self.id.lookup(db.upcast()).container) + } +} + +impl HasContainer for Trait { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container }) + } +} + +impl HasContainer for TraitAlias { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container }) + } +} + +fn container_id_to_hir(c: ItemContainerId) -> ItemContainer { + match c { + ItemContainerId::ExternBlockId(_id) => ItemContainer::ExternBlock(), + ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }), + ItemContainerId::ImplId(id) => ItemContainer::Impl(Impl { id }), + ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }), + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ItemContainer { + Trait(Trait), + Impl(Impl), + Module(Module), + ExternBlock(), + Crate(CrateId), +} diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index da5aaf22570b..386758ccab4c 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -1,89 +1,20 @@ //! File symbol extraction. -use base_db::FileRange; use hir_def::{ - item_tree::ItemTreeNode, src::HasSource, AdtId, AssocItemId, AssocItemLoc, DefWithBodyId, - HasModule, ImplId, ItemContainerId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, + AdtId, AssocItemId, DefWithBodyId, HasModule, ImplId, MacroId, ModuleDefId, ModuleId, TraitId, }; -use hir_expand::{HirFileId, InFile}; use hir_ty::db::HirDatabase; -use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr}; +use syntax::SmolStr; -use crate::{Module, Semantics}; +use crate::{Module, ModuleDef}; /// The actual data that is stored in the index. It should be as compact as /// possible. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FileSymbol { + // even though name can be derived from the def, we store it for efficiency pub name: SmolStr, - pub loc: DeclarationLocation, - pub kind: FileSymbolKind, - pub container_name: Option, -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct DeclarationLocation { - /// The file id for both the `ptr` and `name_ptr`. - pub hir_file_id: HirFileId, - /// This points to the whole syntax node of the declaration. - pub ptr: SyntaxNodePtr, - /// This points to the [`syntax::ast::Name`] identifier of the declaration. - pub name_ptr: SyntaxNodePtr, -} - -impl DeclarationLocation { - pub fn syntax(&self, sema: &Semantics<'_, DB>) -> SyntaxNode { - let root = sema.parse_or_expand(self.hir_file_id); - self.ptr.to_node(&root) - } - - pub fn original_range(&self, db: &dyn HirDatabase) -> FileRange { - let node = resolve_node(db, self.hir_file_id, &self.ptr); - node.as_ref().original_file_range(db.upcast()) - } - - pub fn original_name_range(&self, db: &dyn HirDatabase) -> Option { - let node = resolve_node(db, self.hir_file_id, &self.name_ptr); - node.as_ref().original_file_range_opt(db.upcast()) - } -} - -fn resolve_node( - db: &dyn HirDatabase, - file_id: HirFileId, - ptr: &SyntaxNodePtr, -) -> InFile { - let root = db.parse_or_expand(file_id); - let node = ptr.to_node(&root); - InFile::new(file_id, node) -} - -#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] -pub enum FileSymbolKind { - Const, - Enum, - Function, - Macro, - Module, - Static, - Struct, - Trait, - TraitAlias, - TypeAlias, - Union, -} - -impl FileSymbolKind { - pub fn is_type(self: FileSymbolKind) -> bool { - matches!( - self, - FileSymbolKind::Struct - | FileSymbolKind::Enum - | FileSymbolKind::Trait - | FileSymbolKind::TypeAlias - | FileSymbolKind::Union - ) - } + pub def: ModuleDef, } /// Represents an outstanding module that the symbol collector must collect symbols from. @@ -146,36 +77,34 @@ impl<'a> SymbolCollector<'a> { match module_def_id { ModuleDefId::ModuleId(id) => self.push_module(id), ModuleDefId::FunctionId(id) => { - self.push_decl_assoc(id, FileSymbolKind::Function); + self.push_decl(id); self.collect_from_body(id); } - ModuleDefId::AdtId(AdtId::StructId(id)) => { - self.push_decl(id, FileSymbolKind::Struct) - } - ModuleDefId::AdtId(AdtId::EnumId(id)) => self.push_decl(id, FileSymbolKind::Enum), - ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id, FileSymbolKind::Union), + ModuleDefId::AdtId(AdtId::StructId(id)) => self.push_decl(id), + ModuleDefId::AdtId(AdtId::EnumId(id)) => self.push_decl(id), + ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id), ModuleDefId::ConstId(id) => { - self.push_decl_assoc(id, FileSymbolKind::Const); + self.push_decl(id); self.collect_from_body(id); } ModuleDefId::StaticId(id) => { - self.push_decl_assoc(id, FileSymbolKind::Static); + self.push_decl(id); self.collect_from_body(id); } ModuleDefId::TraitId(id) => { - self.push_decl(id, FileSymbolKind::Trait); + self.push_decl(id); self.collect_from_trait(id); } ModuleDefId::TraitAliasId(id) => { - self.push_decl(id, FileSymbolKind::TraitAlias); + self.push_decl(id); } ModuleDefId::TypeAliasId(id) => { - self.push_decl_assoc(id, FileSymbolKind::TypeAlias); + self.push_decl(id); } ModuleDefId::MacroId(id) => match id { - MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro), - MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro), - MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro), + MacroId::Macro2Id(id) => self.push_decl(id), + MacroId::MacroRulesId(id) => self.push_decl(id), + MacroId::ProcMacroId(id) => self.push_decl(id), }, // Don't index these. ModuleDefId::BuiltinType(_) => {} @@ -195,9 +124,9 @@ impl<'a> SymbolCollector<'a> { for &id in id { if id.module(self.db.upcast()) == module_id { match id { - MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro), - MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro), - MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro), + MacroId::Macro2Id(id) => self.push_decl(id), + MacroId::MacroRulesId(id) => self.push_decl(id), + MacroId::ProcMacroId(id) => self.push_decl(id), } } } @@ -245,124 +174,36 @@ impl<'a> SymbolCollector<'a> { } } - fn current_container_name(&self) -> Option { - self.current_container_name.clone() - } - fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option { match body_id { - DefWithBodyId::FunctionId(id) => Some( - id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(), - ), - DefWithBodyId::StaticId(id) => Some( - id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(), - ), - DefWithBodyId::ConstId(id) => Some( - id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(), - ), - DefWithBodyId::VariantId(id) => Some({ - let db = self.db.upcast(); - id.parent.lookup(db).source(db).value.name()?.text().into() - }), + DefWithBodyId::FunctionId(id) => Some(self.db.function_data(id).name.to_smol_str()), + DefWithBodyId::StaticId(id) => Some(self.db.static_data(id).name.to_smol_str()), + DefWithBodyId::ConstId(id) => Some(self.db.const_data(id).name.as_ref()?.to_smol_str()), + DefWithBodyId::VariantId(id) => { + Some(self.db.enum_data(id.parent).variants[id.local_id].name.to_smol_str()) + } } } fn push_assoc_item(&mut self, assoc_item_id: AssocItemId) { match assoc_item_id { - AssocItemId::FunctionId(id) => self.push_decl_assoc(id, FileSymbolKind::Function), - AssocItemId::ConstId(id) => self.push_decl_assoc(id, FileSymbolKind::Const), - AssocItemId::TypeAliasId(id) => self.push_decl_assoc(id, FileSymbolKind::TypeAlias), + AssocItemId::FunctionId(id) => self.push_decl(id), + AssocItemId::ConstId(id) => self.push_decl(id), + AssocItemId::TypeAliasId(id) => self.push_decl(id), } } - fn push_decl_assoc(&mut self, id: L, kind: FileSymbolKind) - where - L: Lookup>, - T: ItemTreeNode, - ::Source: HasName, - { - fn container_name(db: &dyn HirDatabase, container: ItemContainerId) -> Option { - match container { - ItemContainerId::ModuleId(module_id) => { - let module = Module::from(module_id); - module.name(db).and_then(|name| name.as_text()) - } - ItemContainerId::TraitId(trait_id) => { - let trait_data = db.trait_data(trait_id); - trait_data.name.as_text() - } - ItemContainerId::ImplId(_) | ItemContainerId::ExternBlockId(_) => None, - } + fn push_decl(&mut self, id: impl Into) { + let def = ModuleDef::from(id.into()); + if let Some(name) = def.name(self.db) { + self.symbols.push(FileSymbol { name: name.to_smol_str(), def }); } - - self.push_file_symbol(|s| { - let loc = id.lookup(s.db.upcast()); - let source = loc.source(s.db.upcast()); - let name_node = source.value.name()?; - let container_name = - container_name(s.db, loc.container).or_else(|| s.current_container_name()); - - Some(FileSymbol { - name: name_node.text().into(), - kind, - container_name, - loc: DeclarationLocation { - hir_file_id: source.file_id, - ptr: SyntaxNodePtr::new(source.value.syntax()), - name_ptr: SyntaxNodePtr::new(name_node.syntax()), - }, - }) - }) - } - - fn push_decl(&mut self, id: L, kind: FileSymbolKind) - where - L: Lookup, - ::Data: HasSource, - <::Data as HasSource>::Value: HasName, - { - self.push_file_symbol(|s| { - let loc = id.lookup(s.db.upcast()); - let source = loc.source(s.db.upcast()); - let name_node = source.value.name()?; - - Some(FileSymbol { - name: name_node.text().into(), - kind, - container_name: s.current_container_name(), - loc: DeclarationLocation { - hir_file_id: source.file_id, - ptr: SyntaxNodePtr::new(source.value.syntax()), - name_ptr: SyntaxNodePtr::new(name_node.syntax()), - }, - }) - }) } fn push_module(&mut self, module_id: ModuleId) { - self.push_file_symbol(|s| { - let def_map = module_id.def_map(s.db.upcast()); - let module_data = &def_map[module_id.local_id]; - let declaration = module_data.origin.declaration()?; - let module = declaration.to_node(s.db.upcast()); - let name_node = module.name()?; - - Some(FileSymbol { - name: name_node.text().into(), - kind: FileSymbolKind::Module, - container_name: s.current_container_name(), - loc: DeclarationLocation { - hir_file_id: declaration.file_id, - ptr: SyntaxNodePtr::new(module.syntax()), - name_ptr: SyntaxNodePtr::new(name_node.syntax()), - }, - }) - }) - } - - fn push_file_symbol(&mut self, f: impl FnOnce(&Self) -> Option) { - if let Some(file_symbol) = f(self) { - self.symbols.push(file_symbol); + let def = Module::from(module_id); + if let Some(name) = def.name(self.db) { + self.symbols.push(FileSymbol { name: name.to_smol_str(), def: ModuleDef::Module(def) }); } } } diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs index 4071c490b7fc..760834bfafc7 100644 --- a/crates/ide-db/src/defs.rs +++ b/crates/ide-db/src/defs.rs @@ -8,8 +8,8 @@ use arrayvec::ArrayVec; use hir::{ Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper, Field, - Function, GenericParam, HasVisibility, Impl, ItemInNs, Label, Local, Macro, Module, ModuleDef, - Name, PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias, TypeAlias, Variant, + Function, GenericParam, HasVisibility, Impl, Label, Local, Macro, Module, ModuleDef, Name, + PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias, TypeAlias, Variant, Visibility, }; use stdx::impl_from; @@ -622,22 +622,3 @@ impl From for Definition { } } } - -impl From for Option { - fn from(def: Definition) -> Self { - let item = match def { - Definition::Module(it) => ModuleDef::Module(it), - Definition::Function(it) => ModuleDef::Function(it), - Definition::Adt(it) => ModuleDef::Adt(it), - Definition::Variant(it) => ModuleDef::Variant(it), - Definition::Const(it) => ModuleDef::Const(it), - Definition::Static(it) => ModuleDef::Static(it), - Definition::Trait(it) => ModuleDef::Trait(it), - Definition::TraitAlias(it) => ModuleDef::TraitAlias(it), - Definition::TypeAlias(it) => ModuleDef::TypeAlias(it), - Definition::BuiltinType(it) => ModuleDef::BuiltinType(it), - _ => return None, - }; - Some(ItemInNs::from(item)) - } -} diff --git a/crates/ide-db/src/items_locator.rs b/crates/ide-db/src/items_locator.rs index 5631741e1e87..46f1353e2e1b 100644 --- a/crates/ide-db/src/items_locator.rs +++ b/crates/ide-db/src/items_locator.rs @@ -5,17 +5,11 @@ use either::Either; use hir::{ import_map::{self, ImportKind}, - symbols::FileSymbol, AsAssocItem, Crate, ItemInNs, Semantics, }; use limit::Limit; -use syntax::{ast, AstNode, SyntaxKind::NAME}; -use crate::{ - defs::{Definition, NameClass}, - imports::import_assets::NameToImport, - symbol_index, RootDatabase, -}; +use crate::{imports::import_assets::NameToImport, symbol_index, RootDatabase}; /// A value to use, when uncertain which limit to pick. pub static DEFAULT_QUERY_SEARCH_LIMIT: Limit = Limit::new(40); @@ -118,10 +112,9 @@ fn find_items<'a>( let local_results = local_query .search(&symbol_index::crate_symbols(db, krate)) .into_iter() - .filter_map(move |local_candidate| get_name_definition(sema, &local_candidate)) - .filter_map(|name_definition_to_import| match name_definition_to_import { - Definition::Macro(macro_def) => Some(ItemInNs::from(macro_def)), - def => >::from(def), + .filter_map(|local_candidate| match local_candidate.def { + hir::ModuleDef::Macro(macro_def) => Some(ItemInNs::Macros(macro_def)), + def => Some(ItemInNs::from(def)), }); external_importables.chain(local_results).filter(move |&item| match assoc_item_search { @@ -131,22 +124,6 @@ fn find_items<'a>( }) } -fn get_name_definition( - sema: &Semantics<'_, RootDatabase>, - import_candidate: &FileSymbol, -) -> Option { - let _p = profile::span("get_name_definition"); - - let candidate_node = import_candidate.loc.syntax(sema); - let candidate_name_node = if candidate_node.kind() != NAME { - candidate_node.children().find(|it| it.kind() == NAME)? - } else { - candidate_node - }; - let name = ast::Name::cast(candidate_name_node)?; - NameClass::classify(sema, &name)?.defined() -} - fn is_assoc_item(item: ItemInNs, db: &RootDatabase) -> bool { item.as_module_def().and_then(|module_def| module_def.as_assoc_item(db)).is_some() } diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs index b0c5820fb091..0c6b0f20cf51 100644 --- a/crates/ide-db/src/lib.rs +++ b/crates/ide-db/src/lib.rs @@ -49,10 +49,7 @@ use base_db::{ salsa::{self, Durability}, AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, }; -use hir::{ - db::{DefDatabase, ExpandDatabase, HirDatabase}, - symbols::FileSymbolKind, -}; +use hir::db::{DefDatabase, ExpandDatabase, HirDatabase}; use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase}; pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; @@ -378,20 +375,22 @@ impl From for SymbolKind { } } -impl From for SymbolKind { - fn from(it: FileSymbolKind) -> Self { +impl From for SymbolKind { + fn from(it: hir::ModuleDefId) -> Self { match it { - FileSymbolKind::Const => SymbolKind::Const, - FileSymbolKind::Enum => SymbolKind::Enum, - FileSymbolKind::Function => SymbolKind::Function, - FileSymbolKind::Macro => SymbolKind::Macro, - FileSymbolKind::Module => SymbolKind::Module, - FileSymbolKind::Static => SymbolKind::Static, - FileSymbolKind::Struct => SymbolKind::Struct, - FileSymbolKind::Trait => SymbolKind::Trait, - FileSymbolKind::TraitAlias => SymbolKind::TraitAlias, - FileSymbolKind::TypeAlias => SymbolKind::TypeAlias, - FileSymbolKind::Union => SymbolKind::Union, + hir::ModuleDefId::ConstId(..) => SymbolKind::Const, + hir::ModuleDefId::EnumVariantId(..) => SymbolKind::Variant, + hir::ModuleDefId::FunctionId(..) => SymbolKind::Function, + hir::ModuleDefId::MacroId(..) => SymbolKind::Macro, + hir::ModuleDefId::ModuleId(..) => SymbolKind::Module, + hir::ModuleDefId::StaticId(..) => SymbolKind::Static, + hir::ModuleDefId::AdtId(hir::AdtId::StructId(..)) => SymbolKind::Struct, + hir::ModuleDefId::AdtId(hir::AdtId::EnumId(..)) => SymbolKind::Enum, + hir::ModuleDefId::AdtId(hir::AdtId::UnionId(..)) => SymbolKind::Union, + hir::ModuleDefId::TraitId(..) => SymbolKind::Trait, + hir::ModuleDefId::TraitAliasId(..) => SymbolKind::TraitAlias, + hir::ModuleDefId::TypeAliasId(..) => SymbolKind::TypeAlias, + hir::ModuleDefId::BuiltinType(..) => SymbolKind::TypeAlias, } } } diff --git a/crates/ide-db/src/symbol_index.rs b/crates/ide-db/src/symbol_index.rs index 6f953dba0c35..a6f86c83df7a 100644 --- a/crates/ide-db/src/symbol_index.rs +++ b/crates/ide-db/src/symbol_index.rs @@ -317,7 +317,14 @@ impl Query { let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value); for symbol in &symbol_index.symbols[start..end] { - if self.only_types && !symbol.kind.is_type() { + if self.only_types + && !matches!( + symbol.def, + hir::ModuleDef::Adt(..) + | hir::ModuleDef::TypeAlias(..) + | hir::ModuleDef::BuiltinType(..) + ) + { continue; } if self.exact { diff --git a/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 7bda07ace2db..1223e8d6b69e 100644 --- a/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -10,368 +10,226 @@ [ FileSymbol { name: "Alias", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: TYPE_ALIAS, - range: 397..417, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 402..407, + def: TypeAlias( + TypeAlias { + id: TypeAliasId( + 0, + ), }, - }, - kind: TypeAlias, - container_name: None, + ), }, FileSymbol { name: "CONST", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: CONST, - range: 340..361, + def: Const( + Const { + id: ConstId( + 0, + ), }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 346..351, - }, - }, - kind: Const, - container_name: None, + ), }, FileSymbol { name: "CONST_WITH_INNER", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: CONST, - range: 520..592, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 526..542, + def: Const( + Const { + id: ConstId( + 2, + ), }, - }, - kind: Const, - container_name: None, + ), }, FileSymbol { name: "Enum", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, + def: Adt( + Enum( + Enum { + id: EnumId( + 0, + ), + }, ), - ptr: SyntaxNodePtr { - kind: ENUM, - range: 185..207, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 190..194, - }, - }, - kind: Enum, - container_name: None, + ), }, FileSymbol { name: "Macro", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: MACRO_DEF, - range: 153..168, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 159..164, + def: Macro( + Macro { + id: Macro2Id( + Macro2Id( + 0, + ), + ), }, - }, - kind: Macro, - container_name: None, + ), }, FileSymbol { name: "STATIC", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: STATIC, - range: 362..396, + def: Static( + Static { + id: StaticId( + 0, + ), }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 369..375, - }, - }, - kind: Static, - container_name: None, + ), }, FileSymbol { name: "Struct", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, + def: Adt( + Struct( + Struct { + id: StructId( + 1, + ), + }, ), - ptr: SyntaxNodePtr { - kind: STRUCT, - range: 170..184, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 177..183, - }, - }, - kind: Struct, - container_name: None, + ), }, FileSymbol { name: "StructFromMacro", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 2147483648, + def: Adt( + Struct( + Struct { + id: StructId( + 0, + ), + }, ), - ptr: SyntaxNodePtr { - kind: STRUCT, - range: 0..22, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 6..21, - }, - }, - kind: Struct, - container_name: None, + ), }, FileSymbol { name: "StructInFn", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, + def: Adt( + Struct( + Struct { + id: StructId( + 4, + ), + }, ), - ptr: SyntaxNodePtr { - kind: STRUCT, - range: 318..336, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 325..335, - }, - }, - kind: Struct, - container_name: Some( - "main", ), }, FileSymbol { name: "StructInNamedConst", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, + def: Adt( + Struct( + Struct { + id: StructId( + 5, + ), + }, ), - ptr: SyntaxNodePtr { - kind: STRUCT, - range: 555..581, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 562..580, - }, - }, - kind: Struct, - container_name: Some( - "CONST_WITH_INNER", ), }, FileSymbol { name: "StructInUnnamedConst", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, + def: Adt( + Struct( + Struct { + id: StructId( + 6, + ), + }, ), - ptr: SyntaxNodePtr { - kind: STRUCT, - range: 479..507, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 486..506, - }, - }, - kind: Struct, - container_name: None, + ), }, FileSymbol { name: "Trait", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: TRAIT, - range: 261..300, + def: Trait( + Trait { + id: TraitId( + 0, + ), }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 267..272, - }, - }, - kind: Trait, - container_name: None, + ), }, FileSymbol { name: "Union", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, + def: Adt( + Union( + Union { + id: UnionId( + 0, + ), + }, ), - ptr: SyntaxNodePtr { - kind: UNION, - range: 208..222, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 214..219, - }, - }, - kind: Union, - container_name: None, + ), }, FileSymbol { name: "a_mod", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: MODULE, - range: 419..457, + def: Module( + Module { + id: ModuleId { + krate: Idx::(0), + block: None, + local_id: Idx::(1), + }, }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 423..428, - }, - }, - kind: Module, - container_name: None, + ), }, FileSymbol { name: "b_mod", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: MODULE, - range: 594..604, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 598..603, + def: Module( + Module { + id: ModuleId { + krate: Idx::(0), + block: None, + local_id: Idx::(2), + }, }, - }, - kind: Module, - container_name: None, + ), }, FileSymbol { name: "define_struct", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: MACRO_RULES, - range: 51..131, + def: Macro( + Macro { + id: MacroRulesId( + MacroRulesId( + 1, + ), + ), }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 64..77, - }, - }, - kind: Macro, - container_name: None, + ), }, FileSymbol { name: "impl_fn", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: FN, - range: 242..257, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 245..252, + def: Function( + Function { + id: FunctionId( + 2, + ), }, - }, - kind: Function, - container_name: None, + ), }, FileSymbol { name: "macro_rules_macro", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: MACRO_RULES, - range: 1..48, + def: Macro( + Macro { + id: MacroRulesId( + MacroRulesId( + 0, + ), + ), }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 14..31, - }, - }, - kind: Macro, - container_name: None, + ), }, FileSymbol { name: "main", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: FN, - range: 302..338, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 305..309, + def: Function( + Function { + id: FunctionId( + 0, + ), }, - }, - kind: Function, - container_name: None, + ), }, FileSymbol { name: "trait_fn", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, - ), - ptr: SyntaxNodePtr { - kind: FN, - range: 279..298, + def: Function( + Function { + id: FunctionId( + 1, + ), }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 282..290, - }, - }, - kind: Function, - container_name: Some( - "Trait", ), }, ], @@ -387,21 +245,15 @@ [ FileSymbol { name: "StructInModA", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 0, + def: Adt( + Struct( + Struct { + id: StructId( + 2, + ), + }, ), - ptr: SyntaxNodePtr { - kind: STRUCT, - range: 435..455, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 442..454, - }, - }, - kind: Struct, - container_name: None, + ), }, ], ), @@ -416,21 +268,15 @@ [ FileSymbol { name: "StructInModB", - loc: DeclarationLocation { - hir_file_id: HirFileId( - 1, + def: Adt( + Struct( + Struct { + id: StructId( + 3, + ), + }, ), - ptr: SyntaxNodePtr { - kind: STRUCT, - range: 0..20, - }, - name_ptr: SyntaxNodePtr { - kind: NAME, - range: 7..19, - }, - }, - kind: Struct, - container_name: None, + ), }, ], ), diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs index 48bcd37b62c6..dd1d0d75c63e 100644 --- a/crates/ide/src/call_hierarchy.rs +++ b/crates/ide/src/call_hierarchy.rs @@ -263,7 +263,7 @@ mod tests { expect![["callee Function FileId(0) 0..14 3..9"]], expect![[r#" caller1 Function FileId(0) 15..45 18..25 : [34..40] - test_caller Function FileId(0) 95..149 110..121 : [134..140]"#]], + test_caller Function FileId(0) 95..149 110..121 tests : [134..140]"#]], expect![[]], ); } @@ -283,7 +283,7 @@ fn caller() { //- /foo/mod.rs pub fn callee() {} "#, - expect![["callee Function FileId(1) 0..18 7..13"]], + expect!["callee Function FileId(1) 0..18 7..13 foo"], expect![["caller Function FileId(0) 27..56 30..36 : [45..51]"]], expect![[]], ); @@ -323,7 +323,7 @@ pub fn callee() {} "#, expect![["caller Function FileId(0) 27..56 30..36"]], expect![[]], - expect![["callee Function FileId(1) 0..18 7..13 : [45..51]"]], + expect!["callee Function FileId(1) 0..18 7..13 foo : [45..51]"], ); } @@ -477,7 +477,7 @@ fn caller() { S1::callee(); } "#, - expect![["callee Function FileId(0) 15..27 18..24"]], + expect!["callee Function FileId(0) 15..27 18..24 T1"], expect![["caller Function FileId(0) 82..115 85..91 : [104..110]"]], expect![[]], ); diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 64df511e46e0..0d9b4d8505fd 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -2170,52 +2170,53 @@ mod M { fn main() { let s$0t = (A(1), B(2), M::C(3) ); } "#, expect![[r#" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "test::A", - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 0..14, - focus_range: 7..8, - name: "A", - kind: Struct, - description: "struct A", - }, + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "test::A", + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 0..14, + focus_range: 7..8, + name: "A", + kind: Struct, + description: "struct A", }, - HoverGotoTypeData { - mod_path: "test::B", - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 15..29, - focus_range: 22..23, - name: "B", - kind: Struct, - description: "struct B", - }, + }, + HoverGotoTypeData { + mod_path: "test::B", + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 15..29, + focus_range: 22..23, + name: "B", + kind: Struct, + description: "struct B", }, - HoverGotoTypeData { - mod_path: "test::M::C", - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 42..60, - focus_range: 53..54, - name: "C", - kind: Struct, - description: "pub struct C", - }, + }, + HoverGotoTypeData { + mod_path: "test::M::C", + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 42..60, + focus_range: 53..54, + name: "C", + kind: Struct, + container_name: "M", + description: "pub struct C", }, - ], - ), - ] - "#]], + }, + ], + ), + ] + "#]], ); } @@ -2544,6 +2545,7 @@ pub mod future { focus_range: 60..66, name: "Future", kind: Trait, + container_name: "future", description: "pub trait Future", }, }, diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 3509dee0c96e..e3900fa0d63b 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -398,7 +398,7 @@ impl Analysis { self.with_db(|db| { symbol_index::world_symbols(db, query) .into_iter() // xx: should we make this a par iter? - .filter_map(|s| s.try_to_nav(db)) + .filter_map(|s| s.def.try_to_nav(db)) .collect::>() }) } diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index c1a775136f6b..b5e410eaeb9e 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -4,8 +4,8 @@ use std::fmt; use either::Either; use hir::{ - symbols::FileSymbol, AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay, - InFile, LocalSource, ModuleSource, Semantics, + AssocItem, Documentation, FieldSource, HasAttrs, HasContainer, HasSource, HirDisplay, InFile, + LocalSource, ModuleSource, }; use ide_db::{ base_db::{FileId, FileRange}, @@ -15,7 +15,7 @@ use ide_db::{defs::Definition, RootDatabase}; use stdx::never; use syntax::{ ast::{self, HasName}, - match_ast, AstNode, SmolStr, SyntaxNode, TextRange, + AstNode, SmolStr, SyntaxNode, TextRange, }; /// `NavigationTarget` represents an element in the editor's UI which you can @@ -158,24 +158,6 @@ impl NavigationTarget { } } -impl TryToNav for FileSymbol { - fn try_to_nav(&self, db: &RootDatabase) -> Option { - let full_range = self.loc.original_range(db); - let name_range = self.loc.original_name_range(db)?; - - Some(NavigationTarget { - file_id: full_range.file_id, - name: self.name.clone(), - kind: Some(self.kind.into()), - full_range: full_range.range, - focus_range: Some(name_range.range), - container_name: self.container_name.clone(), - description: description_from_symbol(db, self), - docs: None, - }) - } -} - impl TryToNav for Definition { fn try_to_nav(&self, db: &RootDatabase) -> Option { match self { @@ -221,38 +203,80 @@ impl TryToNav for hir::ModuleDef { } } -pub(crate) trait ToNavFromAst { +pub(crate) trait ToNavFromAst: Sized { const KIND: SymbolKind; + fn container_name(self, db: &RootDatabase) -> Option { + _ = db; + None + } } + +fn container_name(db: &RootDatabase, t: impl HasContainer) -> Option { + match t.container(db) { + hir::ItemContainer::Trait(it) => Some(it.name(db).to_smol_str()), + // FIXME: Handle owners of blocks correctly here + hir::ItemContainer::Module(it) => it.name(db).map(|name| name.to_smol_str()), + _ => None, + } +} + impl ToNavFromAst for hir::Function { const KIND: SymbolKind = SymbolKind::Function; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } + impl ToNavFromAst for hir::Const { const KIND: SymbolKind = SymbolKind::Const; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } impl ToNavFromAst for hir::Static { const KIND: SymbolKind = SymbolKind::Static; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } impl ToNavFromAst for hir::Struct { const KIND: SymbolKind = SymbolKind::Struct; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } impl ToNavFromAst for hir::Enum { const KIND: SymbolKind = SymbolKind::Enum; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } impl ToNavFromAst for hir::Variant { const KIND: SymbolKind = SymbolKind::Variant; } impl ToNavFromAst for hir::Union { const KIND: SymbolKind = SymbolKind::Union; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } impl ToNavFromAst for hir::TypeAlias { const KIND: SymbolKind = SymbolKind::TypeAlias; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } impl ToNavFromAst for hir::Trait { const KIND: SymbolKind = SymbolKind::Trait; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } impl ToNavFromAst for hir::TraitAlias { const KIND: SymbolKind = SymbolKind::TraitAlias; + fn container_name(self, db: &RootDatabase) -> Option { + container_name(db, self) + } } impl TryToNav for D @@ -269,6 +293,7 @@ where ); res.docs = self.docs(db); res.description = Some(self.display(db).to_string()); + res.container_name = self.container_name(db); Some(res) } } @@ -544,32 +569,6 @@ impl TryToNav for hir::ConstParam { } } -/// Get a description of a symbol. -/// -/// e.g. `struct Name`, `enum Name`, `fn Name` -pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option { - let sema = Semantics::new(db); - let node = symbol.loc.syntax(&sema); - - match_ast! { - match node { - ast::Fn(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::Struct(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::Enum(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::Trait(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::TraitAlias(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::Module(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::TypeAlias(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::Const(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::Static(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::RecordField(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::Variant(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - ast::Union(it) => sema.to_def(&it).map(|it| it.display(db).to_string()), - _ => None, - } - } -} - fn orig_focus_range( db: &RootDatabase, file_id: hir::HirFileId, @@ -614,7 +613,6 @@ fn foo() { enum FooInner { } } focus_range: 34..42, name: "FooInner", kind: Enum, - container_name: "foo", description: "enum FooInner", }, ] diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 3684c1033f32..b8e05d4f6256 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -715,7 +715,7 @@ fn f() { } "#, expect![[r#" - Foo Struct FileId(1) 17..51 28..31 + Foo Struct FileId(1) 17..51 28..31 foo FileId(0) 53..56 FileId(2) 79..82 @@ -803,7 +803,7 @@ pub(super) struct Foo$0 { } "#, expect![[r#" - Foo Struct FileId(2) 0..41 18..21 + Foo Struct FileId(2) 0..41 18..21 some FileId(1) 20..23 Import FileId(1) 47..50 @@ -1542,7 +1542,7 @@ fn f() { FileId(0) 161..165 - func Function FileId(0) 137..146 140..144 + func Function FileId(0) 137..146 140..144 module FileId(0) 181..185 "#]], @@ -1581,7 +1581,7 @@ trait Trait { } "#, expect![[r#" - func Function FileId(0) 48..87 51..55 + func Function FileId(0) 48..87 51..55 Trait FileId(0) 74..78 "#]], @@ -1692,7 +1692,7 @@ fn f() { } "#, expect![[r#" - CONST Const FileId(0) 18..37 24..29 + CONST Const FileId(0) 18..37 24..29 Trait FileId(0) 71..76 FileId(0) 125..130 @@ -1721,7 +1721,7 @@ fn f() { } "#, expect![[r#" - TypeAlias TypeAlias FileId(0) 18..33 23..32 + TypeAlias TypeAlias FileId(0) 18..33 23..32 Trait FileId(0) 66..75 FileId(0) 117..126 @@ -1750,7 +1750,7 @@ fn f() { } "#, expect![[r#" - function Function FileId(0) 18..34 21..29 + function Function FileId(0) 18..34 21..29 Trait FileId(0) 65..73 FileId(0) 112..120 @@ -1894,7 +1894,7 @@ fn f() { } "#, expect![[r#" - TypeAlias TypeAlias FileId(0) 18..33 23..32 + TypeAlias TypeAlias FileId(0) 18..33 23..32 Trait FileId(0) 66..75 FileId(0) 117..126 @@ -1950,7 +1950,7 @@ impl Foo for Bar { fn method() {} "#, expect![[r#" - method Function FileId(0) 16..39 19..25 + method Function FileId(0) 16..39 19..25 Foo FileId(0) 101..107 "#]], diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 8a8a9151c425..64150cc2f7fd 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -2579,6 +2579,7 @@ mod r#mod { ), full_range: 47..84, name: "r#for", + container_name: "r#mod", }, kind: DocTest { test_id: Path( @@ -2595,6 +2596,7 @@ mod r#mod { ), full_range: 90..146, name: "r#struct", + container_name: "r#mod", }, kind: DocTest { test_id: Path(