remove references
This commit is contained in:
parent
7f22f90503
commit
bde9cab66e
@ -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<ast::Module>),
|
||||
}
|
||||
|
||||
impl ModuleSource {
|
||||
pub(crate) fn new(
|
||||
db: &impl DefDatabase,
|
||||
file_id: Option<FileId>,
|
||||
decl_id: Option<AstId<ast::Module>>,
|
||||
) -> 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<Name> {
|
||||
self.name_impl(db)
|
||||
pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
|
||||
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<ast::Module>)> {
|
||||
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<ast::UseTree>, TreeArc<ast::ExternCrateItem>> {
|
||||
@ -139,33 +176,44 @@ impl Module {
|
||||
}
|
||||
|
||||
/// Returns the crate this module is part of.
|
||||
pub fn krate(&self, _db: &impl DefDatabase) -> Option<Crate> {
|
||||
pub fn krate(self, _db: &impl DefDatabase) -> Option<Crate> {
|
||||
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<Module> {
|
||||
self.child_impl(db, name)
|
||||
pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
|
||||
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<Item = Module> {
|
||||
self.children_impl(db)
|
||||
pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
|
||||
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::<Vec<_>>();
|
||||
children.into_iter()
|
||||
}
|
||||
|
||||
/// Finds a parent module.
|
||||
pub fn parent(&self, db: &impl DefDatabase) -> Option<Module> {
|
||||
self.parent_impl(db)
|
||||
pub fn parent(self, db: &impl DefDatabase) -> Option<Module> {
|
||||
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<Module> {
|
||||
pub fn path_to_root(self, db: &impl HirDatabase) -> Vec<Module> {
|
||||
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<ast::StructDef>) {
|
||||
pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
|
||||
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<Name> {
|
||||
db.struct_data(*self).name.clone()
|
||||
pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
|
||||
db.struct_data(self).name.clone()
|
||||
}
|
||||
|
||||
pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> {
|
||||
db.struct_data(*self)
|
||||
pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
|
||||
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<StructField> {
|
||||
db.struct_data(*self)
|
||||
pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
|
||||
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<ast::StructDef>) {
|
||||
pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
|
||||
self.id.source(db)
|
||||
}
|
||||
|
||||
pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
|
||||
pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
|
||||
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<ast::EnumDef>) {
|
||||
pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) {
|
||||
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<Name> {
|
||||
db.enum_data(*self).name.clone()
|
||||
pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
|
||||
db.enum_data(self).name.clone()
|
||||
}
|
||||
|
||||
pub fn variants(&self, db: &impl DefDatabase) -> Vec<EnumVariant> {
|
||||
db.enum_data(*self)
|
||||
.variants
|
||||
.iter()
|
||||
.map(|(id, _)| EnumVariant { parent: *self, id })
|
||||
.collect()
|
||||
pub fn variants(self, db: &impl DefDatabase) -> Vec<EnumVariant> {
|
||||
db.enum_data(self).variants.iter().map(|(id, _)| EnumVariant { parent: self, id }).collect()
|
||||
}
|
||||
|
||||
pub fn variant(&self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
|
||||
db.enum_data(*self)
|
||||
pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
|
||||
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
|
||||
|
@ -1,3 +1,2 @@
|
||||
mod konst; // `const` is invalid ident :(
|
||||
mod module;
|
||||
pub(crate) mod function;
|
||||
|
@ -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<FileId>,
|
||||
decl_id: Option<AstId<ast::Module>>,
|
||||
) -> 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<Name> {
|
||||
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<ast::Module>)> {
|
||||
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<Module> {
|
||||
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<Item = Module> {
|
||||
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::<Vec<_>>();
|
||||
children.into_iter()
|
||||
}
|
||||
|
||||
pub(crate) fn parent_impl(&self, db: &impl DefDatabase) -> Option<Module> {
|
||||
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))
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user