From bde9cab66ec04b185679a39ded69d0ab857aec33 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 23 May 2019 21:01:08 +0300 Subject: remove references --- crates/ra_hir/src/code_model_api.rs | 162 +++++++++++++++++++++++------------- 1 file changed, 105 insertions(+), 57 deletions(-) (limited to 'crates/ra_hir/src/code_model_api.rs') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 637ebb7ec..4447c608a 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -1,10 +1,10 @@ use std::sync::Arc; -use ra_db::{CrateId, SourceRootId, Edition}; +use ra_db::{CrateId, SourceRootId, Edition, FileId}; use ra_syntax::{ast::self, TreeArc}; use crate::{ - Name, AsName, Ty, HirFileId, Either, + Name, AsName, AstId, Ty, HirFileId, Either, HirDatabase, DefDatabase, type_ref::TypeRef, nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, @@ -107,29 +107,66 @@ pub enum ModuleSource { Module(TreeArc), } +impl ModuleSource { + pub(crate) fn new( + db: &impl DefDatabase, + file_id: Option, + decl_id: Option>, + ) -> ModuleSource { + match (file_id, decl_id) { + (Some(file_id), _) => { + let source_file = db.parse(file_id); + ModuleSource::SourceFile(source_file) + } + (None, Some(item_id)) => { + let module = item_id.to_node(db); + assert!(module.item_list().is_some(), "expected inline module"); + ModuleSource::Module(module.to_owned()) + } + (None, None) => panic!(), + } + } +} + impl Module { /// Name of this module. - pub fn name(&self, db: &impl HirDatabase) -> Option { - self.name_impl(db) + pub fn name(self, db: &impl HirDatabase) -> Option { + let def_map = db.crate_def_map(self.krate); + let parent = def_map[self.module_id].parent?; + def_map[parent].children.iter().find_map(|(name, module_id)| { + if *module_id == self.module_id { + Some(name.clone()) + } else { + None + } + }) } /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. - pub fn definition_source(&self, db: &impl DefDatabase) -> (HirFileId, ModuleSource) { - self.definition_source_impl(db) + pub fn definition_source(self, db: &impl DefDatabase) -> (HirFileId, ModuleSource) { + let def_map = db.crate_def_map(self.krate); + let decl_id = def_map[self.module_id].declaration; + let file_id = def_map[self.module_id].definition; + let module_source = ModuleSource::new(db, file_id, decl_id); + let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); + (file_id, module_source) } /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. /// `None` for the crate root. pub fn declaration_source( - &self, + self, db: &impl HirDatabase, ) -> Option<(HirFileId, TreeArc)> { - self.declaration_source_impl(db) + let def_map = db.crate_def_map(self.krate); + let decl = def_map[self.module_id].declaration?; + let ast = decl.to_node(db); + Some((decl.file_id(), ast)) } /// Returns the syntax of the last path segment corresponding to this import pub fn import_source( - &self, + self, db: &impl HirDatabase, import: ImportId, ) -> Either, TreeArc> { @@ -139,33 +176,44 @@ impl Module { } /// Returns the crate this module is part of. - pub fn krate(&self, _db: &impl DefDatabase) -> Option { + pub fn krate(self, _db: &impl DefDatabase) -> Option { Some(self.krate) } /// Topmost parent of this module. Every module has a `crate_root`, but some /// might be missing `krate`. This can happen if a module's file is not included /// in the module tree of any target in `Cargo.toml`. - pub fn crate_root(&self, db: &impl DefDatabase) -> Module { - self.crate_root_impl(db) + pub fn crate_root(self, db: &impl DefDatabase) -> Module { + let def_map = db.crate_def_map(self.krate); + self.with_module_id(def_map.root()) } /// Finds a child module with the specified name. - pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Option { - self.child_impl(db, name) + pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option { + let def_map = db.crate_def_map(self.krate); + let child_id = def_map[self.module_id].children.get(name)?; + Some(self.with_module_id(*child_id)) } /// Iterates over all child modules. - pub fn children(&self, db: &impl DefDatabase) -> impl Iterator { - self.children_impl(db) + pub fn children(self, db: &impl DefDatabase) -> impl Iterator { + let def_map = db.crate_def_map(self.krate); + let children = def_map[self.module_id] + .children + .iter() + .map(|(_, module_id)| self.with_module_id(*module_id)) + .collect::>(); + children.into_iter() } /// Finds a parent module. - pub fn parent(&self, db: &impl DefDatabase) -> Option { - self.parent_impl(db) + pub fn parent(self, db: &impl DefDatabase) -> Option { + let def_map = db.crate_def_map(self.krate); + let parent_id = def_map[self.module_id].parent?; + Some(self.with_module_id(parent_id)) } - pub fn path_to_root(&self, db: &impl HirDatabase) -> Vec { + pub fn path_to_root(self, db: &impl HirDatabase) -> Vec { let mut res = vec![self.clone()]; let mut curr = self.clone(); while let Some(next) = curr.parent(db) { @@ -176,11 +224,11 @@ impl Module { } /// Returns a `ModuleScope`: a set of items, visible in this module. - pub fn scope(&self, db: &impl HirDatabase) -> ModuleScope { + pub fn scope(self, db: &impl HirDatabase) -> ModuleScope { db.crate_def_map(self.krate)[self.module_id].scope.clone() } - pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { + pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); for decl in self.declarations(db) { match decl { @@ -200,7 +248,7 @@ impl Module { } } - pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { + pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { let def_map = db.crate_def_map(self.krate); Resolver::default().push_module_scope(def_map, self.module_id) } @@ -225,6 +273,10 @@ impl Module { .map(|(impl_id, _)| ImplBlock::from_id(self, impl_id)) .collect() } + + fn with_module_id(&self, module_id: CrateModuleId) -> Module { + Module { module_id, krate: self.krate } + } } impl Docs for Module { @@ -278,49 +330,49 @@ pub struct Struct { } impl Struct { - pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { self.id.source(db) } - pub fn module(&self, db: &impl HirDatabase) -> Module { + pub fn module(self, db: &impl HirDatabase) -> Module { self.id.module(db) } - pub fn name(&self, db: &impl HirDatabase) -> Option { - db.struct_data(*self).name.clone() + pub fn name(self, db: &impl HirDatabase) -> Option { + db.struct_data(self).name.clone() } - pub fn fields(&self, db: &impl HirDatabase) -> Vec { - db.struct_data(*self) + pub fn fields(self, db: &impl HirDatabase) -> Vec { + db.struct_data(self) .variant_data .fields() .into_iter() .flat_map(|it| it.iter()) - .map(|(id, _)| StructField { parent: (*self).into(), id }) + .map(|(id, _)| StructField { parent: self.into(), id }) .collect() } - pub fn field(&self, db: &impl HirDatabase, name: &Name) -> Option { - db.struct_data(*self) + pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option { + db.struct_data(self) .variant_data .fields() .into_iter() .flat_map(|it| it.iter()) .find(|(_id, data)| data.name == *name) - .map(|(id, _)| StructField { parent: (*self).into(), id }) + .map(|(id, _)| StructField { parent: self.into(), id }) } - pub fn ty(&self, db: &impl HirDatabase) -> Ty { - db.type_for_def((*self).into(), Namespace::Types) + pub fn ty(self, db: &impl HirDatabase) -> Ty { + db.type_for_def(self.into(), Namespace::Types) } - pub fn constructor_ty(&self, db: &impl HirDatabase) -> Ty { - db.type_for_def((*self).into(), Namespace::Values) + pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { + db.type_for_def(self.into(), Namespace::Values) } // FIXME move to a more general type /// Builds a resolver for type references inside this struct. - pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { + pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { // take the outer scope... let r = self.module(db).resolver(db); // ...and add generic params, if present @@ -342,21 +394,21 @@ pub struct Union { } impl Union { - pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { self.id.source(db) } - pub fn name(&self, db: &impl HirDatabase) -> Option { + pub fn name(self, db: &impl HirDatabase) -> Option { db.struct_data(Struct { id: self.id }).name.clone() } - pub fn module(&self, db: &impl HirDatabase) -> Module { + pub fn module(self, db: &impl HirDatabase) -> Module { self.id.module(db) } // FIXME move to a more general type /// Builds a resolver for type references inside this union. - pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { + pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { // take the outer scope... let r = self.module(db).resolver(db); // ...and add generic params, if present @@ -378,41 +430,37 @@ pub struct Enum { } impl Enum { - pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { self.id.source(db) } - pub fn module(&self, db: &impl HirDatabase) -> Module { + pub fn module(self, db: &impl HirDatabase) -> Module { self.id.module(db) } - pub fn name(&self, db: &impl HirDatabase) -> Option { - db.enum_data(*self).name.clone() + pub fn name(self, db: &impl HirDatabase) -> Option { + db.enum_data(self).name.clone() } - pub fn variants(&self, db: &impl DefDatabase) -> Vec { - db.enum_data(*self) - .variants - .iter() - .map(|(id, _)| EnumVariant { parent: *self, id }) - .collect() + pub fn variants(self, db: &impl DefDatabase) -> Vec { + db.enum_data(self).variants.iter().map(|(id, _)| EnumVariant { parent: self, id }).collect() } - pub fn variant(&self, db: &impl DefDatabase, name: &Name) -> Option { - db.enum_data(*self) + pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option { + db.enum_data(self) .variants .iter() .find(|(_id, data)| data.name.as_ref() == Some(name)) - .map(|(id, _)| EnumVariant { parent: *self, id }) + .map(|(id, _)| EnumVariant { parent: self, id }) } - pub fn ty(&self, db: &impl HirDatabase) -> Ty { - db.type_for_def((*self).into(), Namespace::Types) + pub fn ty(self, db: &impl HirDatabase) -> Ty { + db.type_for_def(self.into(), Namespace::Types) } // FIXME: move to a more general type /// Builds a resolver for type references inside this struct. - pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { + pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { // take the outer scope... let r = self.module(db).resolver(db); // ...and add generic params, if present -- cgit v1.2.3