From dbd02546b9cea2a2633cd0414040980f8e4a29e1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 23 May 2019 20:25:55 +0300 Subject: fix signature --- crates/ra_hir/src/code_model_api.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 970b78412..e4089afe7 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -35,19 +35,19 @@ pub struct CrateDependency { } impl Crate { - pub fn crate_id(&self) -> CrateId { + pub fn crate_id(self) -> CrateId { self.crate_id } - pub fn dependencies(&self, db: &impl DefDatabase) -> Vec { + pub fn dependencies(self, db: &impl DefDatabase) -> Vec { self.dependencies_impl(db) } - pub fn root_module(&self, db: &impl DefDatabase) -> Option { + pub fn root_module(self, db: &impl DefDatabase) -> Option { self.root_module_impl(db) } - pub fn edition(&self, db: &impl DefDatabase) -> Edition { + pub fn edition(self, db: &impl DefDatabase) -> Edition { let crate_graph = db.crate_graph(); crate_graph.edition(self.crate_id) } -- cgit v1.2.3 From 7f22f905037f4a6c15195263e9bb6bcb022d65b6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 23 May 2019 20:30:09 +0300 Subject: kill krate_impl --- crates/ra_hir/src/code_model_api.rs | 15 ++++++++++++--- crates/ra_hir/src/code_model_impl.rs | 1 - crates/ra_hir/src/code_model_impl/krate.rs | 22 ---------------------- 3 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 crates/ra_hir/src/code_model_impl/krate.rs (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index e4089afe7..637ebb7ec 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -4,7 +4,7 @@ use ra_db::{CrateId, SourceRootId, Edition}; use ra_syntax::{ast::self, TreeArc}; use crate::{ - Name, Ty, HirFileId, Either, + Name, AsName, Ty, HirFileId, Either, HirDatabase, DefDatabase, type_ref::TypeRef, nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, @@ -40,11 +40,20 @@ impl Crate { } pub fn dependencies(self, db: &impl DefDatabase) -> Vec { - self.dependencies_impl(db) + db.crate_graph() + .dependencies(self.crate_id) + .map(|dep| { + let krate = Crate { crate_id: dep.crate_id() }; + let name = dep.as_name(); + CrateDependency { krate, name } + }) + .collect() } pub fn root_module(self, db: &impl DefDatabase) -> Option { - self.root_module_impl(db) + let module_id = db.crate_def_map(self).root(); + let module = Module { krate: self, module_id }; + Some(module) } pub fn edition(self, db: &impl DefDatabase) -> Edition { diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs index 24df9a113..991533b5b 100644 --- a/crates/ra_hir/src/code_model_impl.rs +++ b/crates/ra_hir/src/code_model_impl.rs @@ -1,4 +1,3 @@ -mod krate; // `crate` is invalid ident :( mod konst; // `const` is invalid ident :( mod module; pub(crate) mod function; diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs deleted file mode 100644 index 914414fc3..000000000 --- a/crates/ra_hir/src/code_model_impl/krate.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::{ - Crate, CrateDependency, AsName, Module, DefDatabase, -}; - -impl Crate { - pub(crate) fn dependencies_impl(&self, db: &impl DefDatabase) -> Vec { - let crate_graph = db.crate_graph(); - crate_graph - .dependencies(self.crate_id) - .map(|dep| { - let krate = Crate { crate_id: dep.crate_id() }; - let name = dep.as_name(); - CrateDependency { krate, name } - }) - .collect() - } - pub(crate) fn root_module_impl(&self, db: &impl DefDatabase) -> Option { - let module_id = db.crate_def_map(*self).root(); - let module = Module { krate: *self, module_id }; - Some(module) - } -} -- cgit v1.2.3 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 ++++++++++++++++++---------- crates/ra_hir/src/code_model_impl.rs | 1 - crates/ra_hir/src/code_model_impl/module.rs | 99 ----------------- 3 files changed, 105 insertions(+), 157 deletions(-) delete mode 100644 crates/ra_hir/src/code_model_impl/module.rs (limited to 'crates/ra_hir/src') 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 diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs index 991533b5b..7bdd86eae 100644 --- a/crates/ra_hir/src/code_model_impl.rs +++ b/crates/ra_hir/src/code_model_impl.rs @@ -1,3 +1,2 @@ mod konst; // `const` is invalid ident :( -mod module; pub(crate) mod function; diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs deleted file mode 100644 index 5c2ea73ce..000000000 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ /dev/null @@ -1,99 +0,0 @@ -use ra_db::FileId; -use ra_syntax::{ast, TreeArc}; - -use crate::{ - Module, ModuleSource, Name, AstId, - nameres::CrateModuleId, - HirDatabase, DefDatabase, - HirFileId, -}; - -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 { - fn with_module_id(&self, module_id: CrateModuleId) -> Module { - Module { module_id, krate: self.krate } - } - - pub(crate) fn name_impl(&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 - } - }) - } - - pub(crate) fn definition_source_impl( - &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) - } - - pub(crate) fn declaration_source_impl( - &self, - db: &impl HirDatabase, - ) -> Option<(HirFileId, TreeArc)> { - 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)) - } - - pub(crate) fn crate_root_impl(&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(crate) fn child_impl(&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(crate) fn children_impl(&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() - } - - pub(crate) fn parent_impl(&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)) - } -} -- cgit v1.2.3 From ce82fbfc44edff633d7f6a2d383b64bfd10d21c4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 23 May 2019 21:08:10 +0300 Subject: remove more references --- crates/ra_hir/src/code_model_api.rs | 112 ++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 56 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 4447c608a..b6834bc25 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -533,16 +533,16 @@ pub enum DefWithBody { impl_froms!(DefWithBody: Function, Const, Static); impl DefWithBody { - pub fn infer(&self, db: &impl HirDatabase) -> Arc { - db.infer(*self) + pub fn infer(self, db: &impl HirDatabase) -> Arc { + db.infer(self) } - pub fn body(&self, db: &impl HirDatabase) -> Arc { - db.body_hir(*self) + pub fn body(self, db: &impl HirDatabase) -> Arc { + db.body_hir(self) } - pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc { - db.body_with_source_map(*self).1 + pub fn body_source_map(self, db: &impl HirDatabase) -> Arc { + db.body_with_source_map(self).1 } /// Builds a resolver for code inside this item. @@ -592,50 +592,50 @@ impl FnSignature { } impl Function { - 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 DefDatabase) -> Module { + pub fn module(self, db: &impl DefDatabase) -> Module { self.id.module(db) } - pub fn name(&self, db: &impl HirDatabase) -> Name { + pub fn name(self, db: &impl HirDatabase) -> Name { self.signature(db).name.clone() } - pub(crate) fn body_source_map(&self, db: &impl HirDatabase) -> Arc { - db.body_with_source_map((*self).into()).1 + pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc { + db.body_with_source_map(self.into()).1 } - pub fn body(&self, db: &impl HirDatabase) -> Arc { - db.body_hir((*self).into()) + pub fn body(self, db: &impl HirDatabase) -> Arc { + db.body_hir(self.into()) } - pub fn ty(&self, db: &impl HirDatabase) -> Ty { - db.type_for_def((*self).into(), Namespace::Values) + pub fn ty(self, db: &impl HirDatabase) -> Ty { + db.type_for_def(self.into(), Namespace::Values) } - pub fn signature(&self, db: &impl HirDatabase) -> Arc { - db.fn_signature(*self) + pub fn signature(self, db: &impl HirDatabase) -> Arc { + db.fn_signature(self) } - pub fn infer(&self, db: &impl HirDatabase) -> Arc { - db.infer((*self).into()) + pub fn infer(self, db: &impl HirDatabase) -> Arc { + db.infer(self.into()) } /// The containing impl block, if this is a method. - pub fn impl_block(&self, db: &impl DefDatabase) -> Option { + pub fn impl_block(self, db: &impl DefDatabase) -> Option { let module_impls = db.impls_in_module(self.module(db)); - ImplBlock::containing(module_impls, (*self).into()) + ImplBlock::containing(module_impls, self.into()) } /// The containing trait, if this is a trait method definition. - pub fn parent_trait(&self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db)).get_parent_trait((*self).into()) + pub fn parent_trait(self, db: &impl DefDatabase) -> Option { + db.trait_items_index(self.module(db)).get_parent_trait(self.into()) } - pub fn container(&self, db: &impl DefDatabase) -> Option { + pub fn container(self, db: &impl DefDatabase) -> Option { if let Some(impl_block) = self.impl_block(db) { Some(impl_block.into()) } else if let Some(trait_) = self.parent_trait(db) { @@ -647,7 +647,7 @@ impl Function { // FIXME: move to a more general type for 'body-having' items /// Builds a resolver for code inside this item. - 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.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); // ...and add generic params, if present @@ -656,10 +656,10 @@ impl Function { r } - pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { + pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { let infer = self.infer(db); - infer.add_diagnostics(db, *self, sink); - let mut validator = ExprValidator::new(*self, infer, sink); + infer.add_diagnostics(db, self, sink); + let mut validator = ExprValidator::new(self, infer, sink); validator.validate_body(db); } } @@ -676,31 +676,31 @@ pub struct Const { } impl Const { - 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 DefDatabase) -> Module { + pub fn module(self, db: &impl DefDatabase) -> Module { self.id.module(db) } - pub fn signature(&self, db: &impl HirDatabase) -> Arc { - db.const_signature(*self) + pub fn signature(self, db: &impl HirDatabase) -> Arc { + db.const_signature(self) } - pub fn infer(&self, db: &impl HirDatabase) -> Arc { - db.infer((*self).into()) + pub fn infer(self, db: &impl HirDatabase) -> Arc { + db.infer(self.into()) } /// The containing impl block, if this is a method. - pub fn impl_block(&self, db: &impl DefDatabase) -> Option { + pub fn impl_block(self, db: &impl DefDatabase) -> Option { let module_impls = db.impls_in_module(self.module(db)); - ImplBlock::containing(module_impls, (*self).into()) + ImplBlock::containing(module_impls, self.into()) } // FIXME: move to a more general type for 'body-having' items /// Builds a resolver for code inside this item. - 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 .impl_block(db) @@ -739,26 +739,26 @@ pub struct Static { } impl Static { - 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 DefDatabase) -> Module { + pub fn module(self, db: &impl DefDatabase) -> Module { self.id.module(db) } - pub fn signature(&self, db: &impl HirDatabase) -> Arc { - db.static_signature(*self) + pub fn signature(self, db: &impl HirDatabase) -> Arc { + db.static_signature(self) } /// Builds a resolver for code inside this item. - pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { + pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { // take the outer scope... self.module(db).resolver(db) } - pub fn infer(&self, db: &impl HirDatabase) -> Arc { - db.infer((*self).into()) + pub fn infer(self, db: &impl HirDatabase) -> Arc { + db.infer(self.into()) } } @@ -774,11 +774,11 @@ pub struct Trait { } impl Trait { - 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 DefDatabase) -> Module { + pub fn module(self, db: &impl DefDatabase) -> Module { self.id.module(db) } @@ -802,7 +802,7 @@ impl Trait { self.trait_data(db).is_auto() } - pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { + pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { let r = self.module(db).resolver(db); // add generic params, if present let p = self.generic_params(db); @@ -823,26 +823,26 @@ pub struct TypeAlias { } impl TypeAlias { - 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 DefDatabase) -> Module { + pub fn module(self, db: &impl DefDatabase) -> Module { self.id.module(db) } /// The containing impl block, if this is a method. - pub fn impl_block(&self, db: &impl DefDatabase) -> Option { + pub fn impl_block(self, db: &impl DefDatabase) -> Option { let module_impls = db.impls_in_module(self.module(db)); - ImplBlock::containing(module_impls, (*self).into()) + ImplBlock::containing(module_impls, self.into()) } /// The containing trait, if this is a trait method definition. - pub fn parent_trait(&self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db)).get_parent_trait((*self).into()) + pub fn parent_trait(self, db: &impl DefDatabase) -> Option { + db.trait_items_index(self.module(db)).get_parent_trait(self.into()) } - pub fn container(&self, db: &impl DefDatabase) -> Option { + pub fn container(self, db: &impl DefDatabase) -> Option { if let Some(impl_block) = self.impl_block(db) { Some(impl_block.into()) } else if let Some(trait_) = self.parent_trait(db) { @@ -857,7 +857,7 @@ impl TypeAlias { } /// Builds a resolver for the type references in this type alias. - 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 .impl_block(db) @@ -883,7 +883,7 @@ pub enum Container { impl_froms!(Container: Trait, ImplBlock); impl Container { - pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { + pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { match self { Container::Trait(trait_) => trait_.resolver(db), Container::ImplBlock(impl_block) => impl_block.resolver(db), -- cgit v1.2.3 From 0e57d58dd086e2d114ccc82261b5396a5f828901 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 23 May 2019 21:13:22 +0300 Subject: kill code_model_impl --- crates/ra_hir/src/code_model_api.rs | 66 ++++++++++++++++++++++++++- crates/ra_hir/src/code_model_impl.rs | 2 - crates/ra_hir/src/code_model_impl/function.rs | 50 -------------------- crates/ra_hir/src/code_model_impl/konst.rs | 34 -------------- crates/ra_hir/src/lib.rs | 1 - 5 files changed, 64 insertions(+), 89 deletions(-) delete mode 100644 crates/ra_hir/src/code_model_impl.rs delete mode 100644 crates/ra_hir/src/code_model_impl/function.rs delete mode 100644 crates/ra_hir/src/code_model_impl/konst.rs (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index b6834bc25..49030ce67 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use ra_db::{CrateId, SourceRootId, Edition, FileId}; -use ra_syntax::{ast::self, TreeArc}; +use ra_syntax::{ast::{self, NameOwner, TypeAscriptionOwner}, TreeArc}; use crate::{ Name, AsName, AstId, Ty, HirFileId, Either, @@ -9,7 +9,7 @@ use crate::{ type_ref::TypeRef, nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, expr::{Body, BodySourceMap, validation::ExprValidator}, - ty::{ TraitRef, InferenceResult}, + ty::{TraitRef, InferenceResult}, adt::{EnumVariantId, StructFieldId, VariantDef}, generics::HasGenericParams, docs::{Documentation, Docs, docs_from_ast}, @@ -18,6 +18,7 @@ use crate::{ resolve::Resolver, diagnostics::{DiagnosticSink}, traits::{TraitItem, TraitData}, + type_ref::Mutability, }; /// hir::Crate describes a single crate. It's the main interface with which @@ -572,6 +573,44 @@ pub struct FnSignature { } impl FnSignature { + pub(crate) fn fn_signature_query(db: &impl DefDatabase, func: Function) -> Arc { + let (_, node) = func.source(db); + let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); + let mut params = Vec::new(); + let mut has_self_param = false; + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + let self_type = if let Some(type_ref) = self_param.ascribed_type() { + TypeRef::from_ast(type_ref) + } else { + let self_type = TypeRef::Path(Name::self_type().into()); + match self_param.kind() { + ast::SelfParamKind::Owned => self_type, + ast::SelfParamKind::Ref => { + TypeRef::Reference(Box::new(self_type), Mutability::Shared) + } + ast::SelfParamKind::MutRef => { + TypeRef::Reference(Box::new(self_type), Mutability::Mut) + } + } + }; + params.push(self_type); + has_self_param = true; + } + for param in param_list.params() { + let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); + params.push(type_ref); + } + } + let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { + TypeRef::from_ast(type_ref) + } else { + TypeRef::unit() + }; + + let sig = FnSignature { name, params, ret_type, has_self_param }; + Arc::new(sig) + } pub fn name(&self) -> &Name { &self.name } @@ -731,6 +770,29 @@ impl ConstSignature { pub fn type_ref(&self) -> &TypeRef { &self.type_ref } + + pub(crate) fn const_signature_query( + db: &impl DefDatabase, + konst: Const, + ) -> Arc { + let (_, node) = konst.source(db); + const_signature_for(&*node) + } + + pub(crate) fn static_signature_query( + db: &impl DefDatabase, + konst: Static, + ) -> Arc { + let (_, node) = konst.source(db); + const_signature_for(&*node) + } +} + +fn const_signature_for(node: &N) -> Arc { + let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); + let type_ref = TypeRef::from_ast_opt(node.ascribed_type()); + let sig = ConstSignature { name, type_ref }; + Arc::new(sig) } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs deleted file mode 100644 index 7bdd86eae..000000000 --- a/crates/ra_hir/src/code_model_impl.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod konst; // `const` is invalid ident :( -pub(crate) mod function; diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs deleted file mode 100644 index f8bd0f784..000000000 --- a/crates/ra_hir/src/code_model_impl/function.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::sync::Arc; - -use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; - -use crate::{ - Name, AsName, Function, FnSignature, - type_ref::{TypeRef, Mutability}, - DefDatabase, -}; - -impl FnSignature { - pub(crate) fn fn_signature_query(db: &impl DefDatabase, func: Function) -> Arc { - let (_, node) = func.source(db); - let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); - let mut params = Vec::new(); - let mut has_self_param = false; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - let self_type = if let Some(type_ref) = self_param.ascribed_type() { - TypeRef::from_ast(type_ref) - } else { - let self_type = TypeRef::Path(Name::self_type().into()); - match self_param.kind() { - ast::SelfParamKind::Owned => self_type, - ast::SelfParamKind::Ref => { - TypeRef::Reference(Box::new(self_type), Mutability::Shared) - } - ast::SelfParamKind::MutRef => { - TypeRef::Reference(Box::new(self_type), Mutability::Mut) - } - } - }; - params.push(self_type); - has_self_param = true; - } - for param in param_list.params() { - let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); - params.push(type_ref); - } - } - let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { - TypeRef::from_ast(type_ref) - } else { - TypeRef::unit() - }; - - let sig = FnSignature { name, params, ret_type, has_self_param }; - Arc::new(sig) - } -} diff --git a/crates/ra_hir/src/code_model_impl/konst.rs b/crates/ra_hir/src/code_model_impl/konst.rs deleted file mode 100644 index db4e5ce5c..000000000 --- a/crates/ra_hir/src/code_model_impl/konst.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::sync::Arc; - -use ra_syntax::ast::{NameOwner, TypeAscriptionOwner}; - -use crate::{ - Name, AsName, Const, ConstSignature, Static, - type_ref::{TypeRef}, - DefDatabase, -}; - -fn const_signature_for(node: &N) -> Arc { - let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); - let type_ref = TypeRef::from_ast_opt(node.ascribed_type()); - let sig = ConstSignature { name, type_ref }; - Arc::new(sig) -} - -impl ConstSignature { - pub(crate) fn const_signature_query( - db: &impl DefDatabase, - konst: Const, - ) -> Arc { - let (_, node) = konst.source(db); - const_signature_for(&*node) - } - - pub(crate) fn static_signature_query( - db: &impl DefDatabase, - konst: Static, - ) -> Arc { - let (_, node) = konst.source(db); - const_signature_for(&*node) - } -} diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 0135644db..556828946 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -43,7 +43,6 @@ mod resolve; pub mod diagnostics; mod code_model_api; -mod code_model_impl; #[cfg(test)] mod marks; -- cgit v1.2.3 From ef3169a33a5204c940cc9e0486954b4b35dc3d4d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 23 May 2019 21:14:19 +0300 Subject: rename code_model_api -> code_model --- crates/ra_hir/src/code_model.rs | 954 ++++++++++++++++++++++++++++++++++++ crates/ra_hir/src/code_model_api.rs | 954 ------------------------------------ crates/ra_hir/src/impl_block.rs | 2 +- crates/ra_hir/src/lib.rs | 4 +- crates/ra_hir/src/resolve.rs | 2 +- 5 files changed, 958 insertions(+), 958 deletions(-) create mode 100644 crates/ra_hir/src/code_model.rs delete mode 100644 crates/ra_hir/src/code_model_api.rs (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs new file mode 100644 index 000000000..49030ce67 --- /dev/null +++ b/crates/ra_hir/src/code_model.rs @@ -0,0 +1,954 @@ +use std::sync::Arc; + +use ra_db::{CrateId, SourceRootId, Edition, FileId}; +use ra_syntax::{ast::{self, NameOwner, TypeAscriptionOwner}, TreeArc}; + +use crate::{ + Name, AsName, AstId, Ty, HirFileId, Either, + HirDatabase, DefDatabase, + type_ref::TypeRef, + nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, + expr::{Body, BodySourceMap, validation::ExprValidator}, + ty::{TraitRef, InferenceResult}, + adt::{EnumVariantId, StructFieldId, VariantDef}, + generics::HasGenericParams, + docs::{Documentation, Docs, docs_from_ast}, + ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeAliasId}, + impl_block::ImplBlock, + resolve::Resolver, + diagnostics::{DiagnosticSink}, + traits::{TraitItem, TraitData}, + type_ref::Mutability, +}; + +/// hir::Crate describes a single crate. It's the main interface with which +/// a crate's dependencies interact. Mostly, it should be just a proxy for the +/// root module. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Crate { + pub(crate) crate_id: CrateId, +} + +#[derive(Debug)] +pub struct CrateDependency { + pub krate: Crate, + pub name: Name, +} + +impl Crate { + pub fn crate_id(self) -> CrateId { + self.crate_id + } + + pub fn dependencies(self, db: &impl DefDatabase) -> Vec { + db.crate_graph() + .dependencies(self.crate_id) + .map(|dep| { + let krate = Crate { crate_id: dep.crate_id() }; + let name = dep.as_name(); + CrateDependency { krate, name } + }) + .collect() + } + + pub fn root_module(self, db: &impl DefDatabase) -> Option { + let module_id = db.crate_def_map(self).root(); + let module = Module { krate: self, module_id }; + Some(module) + } + + pub fn edition(self, db: &impl DefDatabase) -> Edition { + let crate_graph = db.crate_graph(); + crate_graph.edition(self.crate_id) + } + + // FIXME: should this be in source_binder? + pub fn source_root_crates(db: &impl DefDatabase, source_root: SourceRootId) -> Vec { + let crate_ids = db.source_root_crates(source_root); + crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect() + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Module { + pub(crate) krate: Crate, + pub(crate) module_id: CrateModuleId, +} + +/// The defs which can be visible in the module. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ModuleDef { + Module(Module), + Function(Function), + Struct(Struct), + Union(Union), + Enum(Enum), + // Can't be directly declared, but can be imported. + EnumVariant(EnumVariant), + Const(Const), + Static(Static), + Trait(Trait), + TypeAlias(TypeAlias), +} +impl_froms!( + ModuleDef: Module, + Function, + Struct, + Union, + Enum, + EnumVariant, + Const, + Static, + Trait, + TypeAlias +); + +pub enum ModuleSource { + SourceFile(TreeArc), + 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 { + 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) { + 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, + db: &impl HirDatabase, + ) -> Option<(HirFileId, TreeArc)> { + 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, + db: &impl HirDatabase, + import: ImportId, + ) -> Either, TreeArc> { + let (file_id, source) = self.definition_source(db); + let (_, source_map) = db.raw_items_with_source_map(file_id); + source_map.get(&source, import) + } + + /// Returns the crate this module is part of. + 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 { + 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 { + 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 { + 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 { + 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 { + let mut res = vec![self.clone()]; + let mut curr = self.clone(); + while let Some(next) = curr.parent(db) { + res.push(next.clone()); + curr = next + } + res + } + + /// Returns a `ModuleScope`: a set of items, visible in this module. + 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) { + db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); + for decl in self.declarations(db) { + match decl { + crate::ModuleDef::Function(f) => f.diagnostics(db, sink), + crate::ModuleDef::Module(f) => f.diagnostics(db, sink), + _ => (), + } + } + + for impl_block in self.impl_blocks(db) { + for item in impl_block.items(db) { + match item { + crate::ImplItem::Method(f) => f.diagnostics(db, sink), + _ => (), + } + } + } + } + + 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) + } + + pub fn declarations(self, db: &impl DefDatabase) -> Vec { + let def_map = db.crate_def_map(self.krate); + def_map[self.module_id] + .scope + .entries() + .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) + .flat_map(|per_ns| { + per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) + }) + .collect() + } + + pub fn impl_blocks(self, db: &impl HirDatabase) -> Vec { + let module_impl_blocks = db.impls_in_module(self); + module_impl_blocks + .impls + .iter() + .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 { + fn docs(&self, db: &impl HirDatabase) -> Option { + self.declaration_source(db).and_then(|it| docs_from_ast(&*it.1)) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct StructField { + pub(crate) parent: VariantDef, + pub(crate) id: StructFieldId, +} + +#[derive(Debug)] +pub enum FieldSource { + Named(TreeArc), + Pos(TreeArc), +} + +impl StructField { + pub fn name(&self, db: &impl HirDatabase) -> Name { + self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() + } + + pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, FieldSource) { + self.source_impl(db) + } + + pub fn ty(&self, db: &impl HirDatabase) -> Ty { + db.type_for_field(*self) + } + + pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { + self.parent + } +} + +impl Docs for StructField { + fn docs(&self, db: &impl HirDatabase) -> Option { + match self.source(db).1 { + FieldSource::Named(named) => docs_from_ast(&*named), + FieldSource::Pos(..) => return None, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Struct { + pub(crate) id: StructId, +} + +impl Struct { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.id.source(db) + } + + 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 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 }) + .collect() + } + + 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 }) + } + + 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) + } + + // 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 { + // take the outer scope... + let r = self.module(db).resolver(db); + // ...and add generic params, if present + let p = self.generic_params(db); + let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; + r + } +} + +impl Docs for Struct { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Union { + pub(crate) id: StructId, +} + +impl Union { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.id.source(db) + } + + 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 { + 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 { + // take the outer scope... + let r = self.module(db).resolver(db); + // ...and add generic params, if present + let p = self.generic_params(db); + let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; + r + } +} + +impl Docs for Union { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Enum { + pub(crate) id: EnumId, +} + +impl Enum { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.id.source(db) + } + + 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 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) + .variants + .iter() + .find(|(_id, data)| data.name.as_ref() == Some(name)) + .map(|(id, _)| EnumVariant { parent: self, id }) + } + + 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 { + // take the outer scope... + let r = self.module(db).resolver(db); + // ...and add generic params, if present + let p = self.generic_params(db); + let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; + r + } +} + +impl Docs for Enum { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct EnumVariant { + pub(crate) parent: Enum, + pub(crate) id: EnumVariantId, +} + +impl EnumVariant { + pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.source_impl(db) + } + pub fn module(&self, db: &impl HirDatabase) -> Module { + self.parent.module(db) + } + pub fn parent_enum(&self, _db: &impl DefDatabase) -> Enum { + self.parent + } + + pub fn name(&self, db: &impl DefDatabase) -> Option { + db.enum_data(self.parent).variants[self.id].name.clone() + } + + pub fn fields(&self, db: &impl HirDatabase) -> Vec { + self.variant_data(db) + .fields() + .into_iter() + .flat_map(|it| it.iter()) + .map(|(id, _)| StructField { parent: (*self).into(), id }) + .collect() + } + + pub fn field(&self, db: &impl HirDatabase, name: &Name) -> Option { + self.variant_data(db) + .fields() + .into_iter() + .flat_map(|it| it.iter()) + .find(|(_id, data)| data.name == *name) + .map(|(id, _)| StructField { parent: (*self).into(), id }) + } +} + +impl Docs for EnumVariant { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +/// The defs which have a body. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum DefWithBody { + Function(Function), + Static(Static), + Const(Const), +} + +impl_froms!(DefWithBody: Function, Const, Static); + +impl DefWithBody { + pub fn infer(self, db: &impl HirDatabase) -> Arc { + db.infer(self) + } + + pub fn body(self, db: &impl HirDatabase) -> Arc { + db.body_hir(self) + } + + pub fn body_source_map(self, db: &impl HirDatabase) -> Arc { + db.body_with_source_map(self).1 + } + + /// Builds a resolver for code inside this item. + pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { + match *self { + DefWithBody::Const(ref c) => c.resolver(db), + DefWithBody::Function(ref f) => f.resolver(db), + DefWithBody::Static(ref s) => s.resolver(db), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Function { + pub(crate) id: FunctionId, +} + +/// The declared signature of a function. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FnSignature { + pub(crate) name: Name, + pub(crate) params: Vec, + pub(crate) ret_type: TypeRef, + /// True if the first param is `self`. This is relevant to decide whether this + /// can be called as a method. + pub(crate) has_self_param: bool, +} + +impl FnSignature { + pub(crate) fn fn_signature_query(db: &impl DefDatabase, func: Function) -> Arc { + let (_, node) = func.source(db); + let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); + let mut params = Vec::new(); + let mut has_self_param = false; + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + let self_type = if let Some(type_ref) = self_param.ascribed_type() { + TypeRef::from_ast(type_ref) + } else { + let self_type = TypeRef::Path(Name::self_type().into()); + match self_param.kind() { + ast::SelfParamKind::Owned => self_type, + ast::SelfParamKind::Ref => { + TypeRef::Reference(Box::new(self_type), Mutability::Shared) + } + ast::SelfParamKind::MutRef => { + TypeRef::Reference(Box::new(self_type), Mutability::Mut) + } + } + }; + params.push(self_type); + has_self_param = true; + } + for param in param_list.params() { + let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); + params.push(type_ref); + } + } + let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { + TypeRef::from_ast(type_ref) + } else { + TypeRef::unit() + }; + + let sig = FnSignature { name, params, ret_type, has_self_param }; + Arc::new(sig) + } + pub fn name(&self) -> &Name { + &self.name + } + + pub fn params(&self) -> &[TypeRef] { + &self.params + } + + pub fn ret_type(&self) -> &TypeRef { + &self.ret_type + } + + /// True if the first arg is `self`. This is relevant to decide whether this + /// can be called as a method. + pub fn has_self_param(&self) -> bool { + self.has_self_param + } +} + +impl Function { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.id.source(db) + } + + pub fn module(self, db: &impl DefDatabase) -> Module { + self.id.module(db) + } + + pub fn name(self, db: &impl HirDatabase) -> Name { + self.signature(db).name.clone() + } + + pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc { + db.body_with_source_map(self.into()).1 + } + + pub fn body(self, db: &impl HirDatabase) -> Arc { + db.body_hir(self.into()) + } + + pub fn ty(self, db: &impl HirDatabase) -> Ty { + db.type_for_def(self.into(), Namespace::Values) + } + + pub fn signature(self, db: &impl HirDatabase) -> Arc { + db.fn_signature(self) + } + + pub fn infer(self, db: &impl HirDatabase) -> Arc { + db.infer(self.into()) + } + + /// The containing impl block, if this is a method. + pub fn impl_block(self, db: &impl DefDatabase) -> Option { + let module_impls = db.impls_in_module(self.module(db)); + ImplBlock::containing(module_impls, self.into()) + } + + /// The containing trait, if this is a trait method definition. + pub fn parent_trait(self, db: &impl DefDatabase) -> Option { + db.trait_items_index(self.module(db)).get_parent_trait(self.into()) + } + + pub fn container(self, db: &impl DefDatabase) -> Option { + if let Some(impl_block) = self.impl_block(db) { + Some(impl_block.into()) + } else if let Some(trait_) = self.parent_trait(db) { + Some(trait_.into()) + } else { + None + } + } + + // FIXME: move to a more general type for 'body-having' items + /// Builds a resolver for code inside this item. + pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { + // take the outer scope... + let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); + // ...and add generic params, if present + let p = self.generic_params(db); + let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; + r + } + + pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { + let infer = self.infer(db); + infer.add_diagnostics(db, self, sink); + let mut validator = ExprValidator::new(self, infer, sink); + validator.validate_body(db); + } +} + +impl Docs for Function { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Const { + pub(crate) id: ConstId, +} + +impl Const { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.id.source(db) + } + + pub fn module(self, db: &impl DefDatabase) -> Module { + self.id.module(db) + } + + pub fn signature(self, db: &impl HirDatabase) -> Arc { + db.const_signature(self) + } + + pub fn infer(self, db: &impl HirDatabase) -> Arc { + db.infer(self.into()) + } + + /// The containing impl block, if this is a method. + pub fn impl_block(self, db: &impl DefDatabase) -> Option { + let module_impls = db.impls_in_module(self.module(db)); + ImplBlock::containing(module_impls, self.into()) + } + + // FIXME: move to a more general type for 'body-having' items + /// Builds a resolver for code inside this item. + pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { + // take the outer scope... + let r = self + .impl_block(db) + .map(|ib| ib.resolver(db)) + .unwrap_or_else(|| self.module(db).resolver(db)); + r + } +} + +impl Docs for Const { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +/// The declared signature of a const. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ConstSignature { + pub(crate) name: Name, + pub(crate) type_ref: TypeRef, +} + +impl ConstSignature { + pub fn name(&self) -> &Name { + &self.name + } + + pub fn type_ref(&self) -> &TypeRef { + &self.type_ref + } + + pub(crate) fn const_signature_query( + db: &impl DefDatabase, + konst: Const, + ) -> Arc { + let (_, node) = konst.source(db); + const_signature_for(&*node) + } + + pub(crate) fn static_signature_query( + db: &impl DefDatabase, + konst: Static, + ) -> Arc { + let (_, node) = konst.source(db); + const_signature_for(&*node) + } +} + +fn const_signature_for(node: &N) -> Arc { + let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); + let type_ref = TypeRef::from_ast_opt(node.ascribed_type()); + let sig = ConstSignature { name, type_ref }; + Arc::new(sig) +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Static { + pub(crate) id: StaticId, +} + +impl Static { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.id.source(db) + } + + pub fn module(self, db: &impl DefDatabase) -> Module { + self.id.module(db) + } + + pub fn signature(self, db: &impl HirDatabase) -> Arc { + db.static_signature(self) + } + + /// Builds a resolver for code inside this item. + pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { + // take the outer scope... + self.module(db).resolver(db) + } + + pub fn infer(self, db: &impl HirDatabase) -> Arc { + db.infer(self.into()) + } +} + +impl Docs for Static { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Trait { + pub(crate) id: TraitId, +} + +impl Trait { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.id.source(db) + } + + pub fn module(self, db: &impl DefDatabase) -> Module { + self.id.module(db) + } + + pub fn name(self, db: &impl DefDatabase) -> Option { + self.trait_data(db).name().clone() + } + + pub fn items(self, db: &impl DefDatabase) -> Vec { + self.trait_data(db).items().to_vec() + } + + pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc { + db.trait_data(self) + } + + pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { + TraitRef::for_trait(db, self) + } + + pub fn is_auto(self, db: &impl DefDatabase) -> bool { + self.trait_data(db).is_auto() + } + + pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { + let r = self.module(db).resolver(db); + // add generic params, if present + let p = self.generic_params(db); + let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; + r + } +} + +impl Docs for Trait { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct TypeAlias { + pub(crate) id: TypeAliasId, +} + +impl TypeAlias { + pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { + self.id.source(db) + } + + pub fn module(self, db: &impl DefDatabase) -> Module { + self.id.module(db) + } + + /// The containing impl block, if this is a method. + pub fn impl_block(self, db: &impl DefDatabase) -> Option { + let module_impls = db.impls_in_module(self.module(db)); + ImplBlock::containing(module_impls, self.into()) + } + + /// The containing trait, if this is a trait method definition. + pub fn parent_trait(self, db: &impl DefDatabase) -> Option { + db.trait_items_index(self.module(db)).get_parent_trait(self.into()) + } + + pub fn container(self, db: &impl DefDatabase) -> Option { + if let Some(impl_block) = self.impl_block(db) { + Some(impl_block.into()) + } else if let Some(trait_) = self.parent_trait(db) { + Some(trait_.into()) + } else { + None + } + } + + pub fn type_ref(self, db: &impl DefDatabase) -> Arc { + db.type_alias_ref(self) + } + + /// Builds a resolver for the type references in this type alias. + pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { + // take the outer scope... + let r = self + .impl_block(db) + .map(|ib| ib.resolver(db)) + .unwrap_or_else(|| self.module(db).resolver(db)); + // ...and add generic params, if present + let p = self.generic_params(db); + let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; + r + } +} + +impl Docs for TypeAlias { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + +pub enum Container { + Trait(Trait), + ImplBlock(ImplBlock), +} +impl_froms!(Container: Trait, ImplBlock); + +impl Container { + pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + Container::Trait(trait_) => trait_.resolver(db), + Container::ImplBlock(impl_block) => impl_block.resolver(db), + } + } +} diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs deleted file mode 100644 index 49030ce67..000000000 --- a/crates/ra_hir/src/code_model_api.rs +++ /dev/null @@ -1,954 +0,0 @@ -use std::sync::Arc; - -use ra_db::{CrateId, SourceRootId, Edition, FileId}; -use ra_syntax::{ast::{self, NameOwner, TypeAscriptionOwner}, TreeArc}; - -use crate::{ - Name, AsName, AstId, Ty, HirFileId, Either, - HirDatabase, DefDatabase, - type_ref::TypeRef, - nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, - expr::{Body, BodySourceMap, validation::ExprValidator}, - ty::{TraitRef, InferenceResult}, - adt::{EnumVariantId, StructFieldId, VariantDef}, - generics::HasGenericParams, - docs::{Documentation, Docs, docs_from_ast}, - ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeAliasId}, - impl_block::ImplBlock, - resolve::Resolver, - diagnostics::{DiagnosticSink}, - traits::{TraitItem, TraitData}, - type_ref::Mutability, -}; - -/// hir::Crate describes a single crate. It's the main interface with which -/// a crate's dependencies interact. Mostly, it should be just a proxy for the -/// root module. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Crate { - pub(crate) crate_id: CrateId, -} - -#[derive(Debug)] -pub struct CrateDependency { - pub krate: Crate, - pub name: Name, -} - -impl Crate { - pub fn crate_id(self) -> CrateId { - self.crate_id - } - - pub fn dependencies(self, db: &impl DefDatabase) -> Vec { - db.crate_graph() - .dependencies(self.crate_id) - .map(|dep| { - let krate = Crate { crate_id: dep.crate_id() }; - let name = dep.as_name(); - CrateDependency { krate, name } - }) - .collect() - } - - pub fn root_module(self, db: &impl DefDatabase) -> Option { - let module_id = db.crate_def_map(self).root(); - let module = Module { krate: self, module_id }; - Some(module) - } - - pub fn edition(self, db: &impl DefDatabase) -> Edition { - let crate_graph = db.crate_graph(); - crate_graph.edition(self.crate_id) - } - - // FIXME: should this be in source_binder? - pub fn source_root_crates(db: &impl DefDatabase, source_root: SourceRootId) -> Vec { - let crate_ids = db.source_root_crates(source_root); - crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Module { - pub(crate) krate: Crate, - pub(crate) module_id: CrateModuleId, -} - -/// The defs which can be visible in the module. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum ModuleDef { - Module(Module), - Function(Function), - Struct(Struct), - Union(Union), - Enum(Enum), - // Can't be directly declared, but can be imported. - EnumVariant(EnumVariant), - Const(Const), - Static(Static), - Trait(Trait), - TypeAlias(TypeAlias), -} -impl_froms!( - ModuleDef: Module, - Function, - Struct, - Union, - Enum, - EnumVariant, - Const, - Static, - Trait, - TypeAlias -); - -pub enum ModuleSource { - SourceFile(TreeArc), - 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 { - 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) { - 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, - db: &impl HirDatabase, - ) -> Option<(HirFileId, TreeArc)> { - 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, - db: &impl HirDatabase, - import: ImportId, - ) -> Either, TreeArc> { - let (file_id, source) = self.definition_source(db); - let (_, source_map) = db.raw_items_with_source_map(file_id); - source_map.get(&source, import) - } - - /// Returns the crate this module is part of. - 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 { - 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 { - 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 { - 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 { - 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 { - let mut res = vec![self.clone()]; - let mut curr = self.clone(); - while let Some(next) = curr.parent(db) { - res.push(next.clone()); - curr = next - } - res - } - - /// Returns a `ModuleScope`: a set of items, visible in this module. - 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) { - db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); - for decl in self.declarations(db) { - match decl { - crate::ModuleDef::Function(f) => f.diagnostics(db, sink), - crate::ModuleDef::Module(f) => f.diagnostics(db, sink), - _ => (), - } - } - - for impl_block in self.impl_blocks(db) { - for item in impl_block.items(db) { - match item { - crate::ImplItem::Method(f) => f.diagnostics(db, sink), - _ => (), - } - } - } - } - - 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) - } - - pub fn declarations(self, db: &impl DefDatabase) -> Vec { - let def_map = db.crate_def_map(self.krate); - def_map[self.module_id] - .scope - .entries() - .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) - .flat_map(|per_ns| { - per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) - }) - .collect() - } - - pub fn impl_blocks(self, db: &impl HirDatabase) -> Vec { - let module_impl_blocks = db.impls_in_module(self); - module_impl_blocks - .impls - .iter() - .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 { - fn docs(&self, db: &impl HirDatabase) -> Option { - self.declaration_source(db).and_then(|it| docs_from_ast(&*it.1)) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct StructField { - pub(crate) parent: VariantDef, - pub(crate) id: StructFieldId, -} - -#[derive(Debug)] -pub enum FieldSource { - Named(TreeArc), - Pos(TreeArc), -} - -impl StructField { - pub fn name(&self, db: &impl HirDatabase) -> Name { - self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() - } - - pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, FieldSource) { - self.source_impl(db) - } - - pub fn ty(&self, db: &impl HirDatabase) -> Ty { - db.type_for_field(*self) - } - - pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { - self.parent - } -} - -impl Docs for StructField { - fn docs(&self, db: &impl HirDatabase) -> Option { - match self.source(db).1 { - FieldSource::Named(named) => docs_from_ast(&*named), - FieldSource::Pos(..) => return None, - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Struct { - pub(crate) id: StructId, -} - -impl Struct { - pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.id.source(db) - } - - 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 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 }) - .collect() - } - - 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 }) - } - - 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) - } - - // 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 { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r - } -} - -impl Docs for Struct { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Union { - pub(crate) id: StructId, -} - -impl Union { - pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.id.source(db) - } - - 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 { - 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 { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r - } -} - -impl Docs for Union { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Enum { - pub(crate) id: EnumId, -} - -impl Enum { - pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.id.source(db) - } - - 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 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) - .variants - .iter() - .find(|(_id, data)| data.name.as_ref() == Some(name)) - .map(|(id, _)| EnumVariant { parent: self, id }) - } - - 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 { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r - } -} - -impl Docs for Enum { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct EnumVariant { - pub(crate) parent: Enum, - pub(crate) id: EnumVariantId, -} - -impl EnumVariant { - pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.source_impl(db) - } - pub fn module(&self, db: &impl HirDatabase) -> Module { - self.parent.module(db) - } - pub fn parent_enum(&self, _db: &impl DefDatabase) -> Enum { - self.parent - } - - pub fn name(&self, db: &impl DefDatabase) -> Option { - db.enum_data(self.parent).variants[self.id].name.clone() - } - - pub fn fields(&self, db: &impl HirDatabase) -> Vec { - self.variant_data(db) - .fields() - .into_iter() - .flat_map(|it| it.iter()) - .map(|(id, _)| StructField { parent: (*self).into(), id }) - .collect() - } - - pub fn field(&self, db: &impl HirDatabase, name: &Name) -> Option { - self.variant_data(db) - .fields() - .into_iter() - .flat_map(|it| it.iter()) - .find(|(_id, data)| data.name == *name) - .map(|(id, _)| StructField { parent: (*self).into(), id }) - } -} - -impl Docs for EnumVariant { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -/// The defs which have a body. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum DefWithBody { - Function(Function), - Static(Static), - Const(Const), -} - -impl_froms!(DefWithBody: Function, Const, Static); - -impl DefWithBody { - pub fn infer(self, db: &impl HirDatabase) -> Arc { - db.infer(self) - } - - pub fn body(self, db: &impl HirDatabase) -> Arc { - db.body_hir(self) - } - - pub fn body_source_map(self, db: &impl HirDatabase) -> Arc { - db.body_with_source_map(self).1 - } - - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { - match *self { - DefWithBody::Const(ref c) => c.resolver(db), - DefWithBody::Function(ref f) => f.resolver(db), - DefWithBody::Static(ref s) => s.resolver(db), - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Function { - pub(crate) id: FunctionId, -} - -/// The declared signature of a function. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FnSignature { - pub(crate) name: Name, - pub(crate) params: Vec, - pub(crate) ret_type: TypeRef, - /// True if the first param is `self`. This is relevant to decide whether this - /// can be called as a method. - pub(crate) has_self_param: bool, -} - -impl FnSignature { - pub(crate) fn fn_signature_query(db: &impl DefDatabase, func: Function) -> Arc { - let (_, node) = func.source(db); - let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); - let mut params = Vec::new(); - let mut has_self_param = false; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - let self_type = if let Some(type_ref) = self_param.ascribed_type() { - TypeRef::from_ast(type_ref) - } else { - let self_type = TypeRef::Path(Name::self_type().into()); - match self_param.kind() { - ast::SelfParamKind::Owned => self_type, - ast::SelfParamKind::Ref => { - TypeRef::Reference(Box::new(self_type), Mutability::Shared) - } - ast::SelfParamKind::MutRef => { - TypeRef::Reference(Box::new(self_type), Mutability::Mut) - } - } - }; - params.push(self_type); - has_self_param = true; - } - for param in param_list.params() { - let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); - params.push(type_ref); - } - } - let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { - TypeRef::from_ast(type_ref) - } else { - TypeRef::unit() - }; - - let sig = FnSignature { name, params, ret_type, has_self_param }; - Arc::new(sig) - } - pub fn name(&self) -> &Name { - &self.name - } - - pub fn params(&self) -> &[TypeRef] { - &self.params - } - - pub fn ret_type(&self) -> &TypeRef { - &self.ret_type - } - - /// True if the first arg is `self`. This is relevant to decide whether this - /// can be called as a method. - pub fn has_self_param(&self) -> bool { - self.has_self_param - } -} - -impl Function { - pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.id.source(db) - } - - pub fn module(self, db: &impl DefDatabase) -> Module { - self.id.module(db) - } - - pub fn name(self, db: &impl HirDatabase) -> Name { - self.signature(db).name.clone() - } - - pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc { - db.body_with_source_map(self.into()).1 - } - - pub fn body(self, db: &impl HirDatabase) -> Arc { - db.body_hir(self.into()) - } - - pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Values) - } - - pub fn signature(self, db: &impl HirDatabase) -> Arc { - db.fn_signature(self) - } - - pub fn infer(self, db: &impl HirDatabase) -> Arc { - db.infer(self.into()) - } - - /// The containing impl block, if this is a method. - pub fn impl_block(self, db: &impl DefDatabase) -> Option { - let module_impls = db.impls_in_module(self.module(db)); - ImplBlock::containing(module_impls, self.into()) - } - - /// The containing trait, if this is a trait method definition. - pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db)).get_parent_trait(self.into()) - } - - pub fn container(self, db: &impl DefDatabase) -> Option { - if let Some(impl_block) = self.impl_block(db) { - Some(impl_block.into()) - } else if let Some(trait_) = self.parent_trait(db) { - Some(trait_.into()) - } else { - None - } - } - - // FIXME: move to a more general type for 'body-having' items - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); - // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r - } - - pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { - let infer = self.infer(db); - infer.add_diagnostics(db, self, sink); - let mut validator = ExprValidator::new(self, infer, sink); - validator.validate_body(db); - } -} - -impl Docs for Function { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Const { - pub(crate) id: ConstId, -} - -impl Const { - pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.id.source(db) - } - - pub fn module(self, db: &impl DefDatabase) -> Module { - self.id.module(db) - } - - pub fn signature(self, db: &impl HirDatabase) -> Arc { - db.const_signature(self) - } - - pub fn infer(self, db: &impl HirDatabase) -> Arc { - db.infer(self.into()) - } - - /// The containing impl block, if this is a method. - pub fn impl_block(self, db: &impl DefDatabase) -> Option { - let module_impls = db.impls_in_module(self.module(db)); - ImplBlock::containing(module_impls, self.into()) - } - - // FIXME: move to a more general type for 'body-having' items - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self - .impl_block(db) - .map(|ib| ib.resolver(db)) - .unwrap_or_else(|| self.module(db).resolver(db)); - r - } -} - -impl Docs for Const { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -/// The declared signature of a const. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ConstSignature { - pub(crate) name: Name, - pub(crate) type_ref: TypeRef, -} - -impl ConstSignature { - pub fn name(&self) -> &Name { - &self.name - } - - pub fn type_ref(&self) -> &TypeRef { - &self.type_ref - } - - pub(crate) fn const_signature_query( - db: &impl DefDatabase, - konst: Const, - ) -> Arc { - let (_, node) = konst.source(db); - const_signature_for(&*node) - } - - pub(crate) fn static_signature_query( - db: &impl DefDatabase, - konst: Static, - ) -> Arc { - let (_, node) = konst.source(db); - const_signature_for(&*node) - } -} - -fn const_signature_for(node: &N) -> Arc { - let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); - let type_ref = TypeRef::from_ast_opt(node.ascribed_type()); - let sig = ConstSignature { name, type_ref }; - Arc::new(sig) -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Static { - pub(crate) id: StaticId, -} - -impl Static { - pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.id.source(db) - } - - pub fn module(self, db: &impl DefDatabase) -> Module { - self.id.module(db) - } - - pub fn signature(self, db: &impl HirDatabase) -> Arc { - db.static_signature(self) - } - - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - self.module(db).resolver(db) - } - - pub fn infer(self, db: &impl HirDatabase) -> Arc { - db.infer(self.into()) - } -} - -impl Docs for Static { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Trait { - pub(crate) id: TraitId, -} - -impl Trait { - pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.id.source(db) - } - - pub fn module(self, db: &impl DefDatabase) -> Module { - self.id.module(db) - } - - pub fn name(self, db: &impl DefDatabase) -> Option { - self.trait_data(db).name().clone() - } - - pub fn items(self, db: &impl DefDatabase) -> Vec { - self.trait_data(db).items().to_vec() - } - - pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc { - db.trait_data(self) - } - - pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { - TraitRef::for_trait(db, self) - } - - pub fn is_auto(self, db: &impl DefDatabase) -> bool { - self.trait_data(db).is_auto() - } - - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - let r = self.module(db).resolver(db); - // add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r - } -} - -impl Docs for Trait { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TypeAlias { - pub(crate) id: TypeAliasId, -} - -impl TypeAlias { - pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - self.id.source(db) - } - - pub fn module(self, db: &impl DefDatabase) -> Module { - self.id.module(db) - } - - /// The containing impl block, if this is a method. - pub fn impl_block(self, db: &impl DefDatabase) -> Option { - let module_impls = db.impls_in_module(self.module(db)); - ImplBlock::containing(module_impls, self.into()) - } - - /// The containing trait, if this is a trait method definition. - pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db)).get_parent_trait(self.into()) - } - - pub fn container(self, db: &impl DefDatabase) -> Option { - if let Some(impl_block) = self.impl_block(db) { - Some(impl_block.into()) - } else if let Some(trait_) = self.parent_trait(db) { - Some(trait_.into()) - } else { - None - } - } - - pub fn type_ref(self, db: &impl DefDatabase) -> Arc { - db.type_alias_ref(self) - } - - /// Builds a resolver for the type references in this type alias. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self - .impl_block(db) - .map(|ib| ib.resolver(db)) - .unwrap_or_else(|| self.module(db).resolver(db)); - // ...and add generic params, if present - let p = self.generic_params(db); - let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; - r - } -} - -impl Docs for TypeAlias { - fn docs(&self, db: &impl HirDatabase) -> Option { - docs_from_ast(&*self.source(db).1) - } -} - -pub enum Container { - Trait(Trait), - ImplBlock(ImplBlock), -} -impl_froms!(Container: Trait, ImplBlock); - -impl Container { - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - match self { - Container::Trait(trait_) => trait_.resolver(db), - Container::ImplBlock(impl_block) => impl_block.resolver(db), - } - } -} diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 51fa491c3..637f6ab83 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -15,7 +15,7 @@ use crate::{ resolve::Resolver, ty::Ty, generics::HasGenericParams, - code_model_api::{Module, ModuleSource} + code_model::{Module, ModuleSource} }; #[derive(Debug, Default, PartialEq, Eq)] diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 556828946..fe2d4adee 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -42,7 +42,7 @@ mod docs; mod resolve; pub mod diagnostics; -mod code_model_api; +mod code_model; #[cfg(test)] mod marks; @@ -72,7 +72,7 @@ pub use self::{ source_binder::{SourceAnalyzer, PathResolution, ScopeEntryWithSyntax,MacroByExampleDef}, }; -pub use self::code_model_api::{ +pub use self::code_model::{ Crate, CrateDependency, DefWithBody, Module, ModuleDef, ModuleSource, diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 3874e28bf..fedfe2fee 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -5,7 +5,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use crate::{ ModuleDef, Trait, - code_model_api::Crate, + code_model::Crate, MacroDefId, db::HirDatabase, name::{Name, KnownName}, -- cgit v1.2.3