mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
Move module to SourceBinder
This commit is contained in:
parent
16cfc8d50c
commit
9a6c26e348
5 changed files with 69 additions and 55 deletions
|
@ -2,46 +2,22 @@
|
||||||
//! file.
|
//! file.
|
||||||
|
|
||||||
use hir_def::{nameres::ModuleSource, ModuleId};
|
use hir_def::{nameres::ModuleSource, ModuleId};
|
||||||
use hir_expand::name::AsName;
|
|
||||||
use ra_db::FileId;
|
use ra_db::FileId;
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::ast::{self, AstNode, NameOwner};
|
|
||||||
|
|
||||||
use crate::{db::DefDatabase, InFile, Module};
|
use crate::{
|
||||||
|
db::{DefDatabase, HirDatabase},
|
||||||
|
InFile, Module,
|
||||||
|
};
|
||||||
|
|
||||||
impl Module {
|
impl Module {
|
||||||
pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> {
|
pub fn from_definition(db: &impl HirDatabase, src: InFile<ModuleSource>) -> Option<Self> {
|
||||||
let _p = profile("Module::from_declaration");
|
|
||||||
let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
|
|
||||||
|
|
||||||
let parent_module = match parent_declaration {
|
|
||||||
Some(parent_declaration) => {
|
|
||||||
let src_parent = InFile { file_id: src.file_id, value: parent_declaration };
|
|
||||||
Module::from_declaration(db, src_parent)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let source_file = db.parse(src.file_id.original_file(db)).tree();
|
|
||||||
let src_parent =
|
|
||||||
InFile { file_id: src.file_id, value: ModuleSource::SourceFile(source_file) };
|
|
||||||
Module::from_definition(db, src_parent)
|
|
||||||
}
|
|
||||||
}?;
|
|
||||||
|
|
||||||
let child_name = src.value.name()?.as_name();
|
|
||||||
let def_map = db.crate_def_map(parent_module.id.krate);
|
|
||||||
let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?;
|
|
||||||
Some(parent_module.with_module_id(*child_id))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> {
|
|
||||||
let _p = profile("Module::from_definition");
|
let _p = profile("Module::from_definition");
|
||||||
|
let mut sb = crate::SourceBinder::new(db);
|
||||||
match src.value {
|
match src.value {
|
||||||
ModuleSource::Module(ref module) => {
|
ModuleSource::Module(ref module) => {
|
||||||
assert!(!module.has_semi());
|
assert!(!module.has_semi());
|
||||||
return Module::from_declaration(
|
return sb.to_def(InFile { file_id: src.file_id, value: module.clone() });
|
||||||
db,
|
|
||||||
InFile { file_id: src.file_id, value: module.clone() },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
ModuleSource::SourceFile(_) => (),
|
ModuleSource::SourceFile(_) => (),
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,12 +11,15 @@ use hir_def::{
|
||||||
ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId,
|
ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId,
|
||||||
StaticId, StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
|
StaticId, StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind};
|
use hir_expand::{name::AsName, AstId, InFile, MacroDefId, MacroDefKind};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit};
|
use ra_syntax::{
|
||||||
|
ast::{self, NameOwner},
|
||||||
|
match_ast, AstNode, SyntaxNode, TextUnit,
|
||||||
|
};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::{db::HirDatabase, Local, ModuleSource, SourceAnalyzer, TypeParam};
|
use crate::{db::HirDatabase, Local, Module, ModuleSource, SourceAnalyzer, TypeParam};
|
||||||
|
|
||||||
pub struct SourceBinder<'a, DB> {
|
pub struct SourceBinder<'a, DB> {
|
||||||
pub db: &'a DB,
|
pub db: &'a DB,
|
||||||
|
@ -306,3 +309,38 @@ impl ToDef for ast::TypeParam {
|
||||||
Some(TypeParam { id })
|
Some(TypeParam { id })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToDef for ast::Module {
|
||||||
|
type Def = Module;
|
||||||
|
|
||||||
|
fn to_def<DB: HirDatabase>(
|
||||||
|
sb: &mut SourceBinder<'_, DB>,
|
||||||
|
src: InFile<ast::Module>,
|
||||||
|
) -> Option<Module> {
|
||||||
|
{
|
||||||
|
let _p = profile("ast::Module::to_def");
|
||||||
|
let parent_declaration =
|
||||||
|
src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
|
||||||
|
|
||||||
|
let parent_module = match parent_declaration {
|
||||||
|
Some(parent_declaration) => {
|
||||||
|
let src_parent = InFile { file_id: src.file_id, value: parent_declaration };
|
||||||
|
sb.to_def(src_parent)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let source_file = sb.db.parse(src.file_id.original_file(sb.db)).tree();
|
||||||
|
let src_parent = InFile {
|
||||||
|
file_id: src.file_id,
|
||||||
|
value: ModuleSource::SourceFile(source_file),
|
||||||
|
};
|
||||||
|
Module::from_definition(sb.db, src_parent)
|
||||||
|
}
|
||||||
|
}?;
|
||||||
|
|
||||||
|
let child_name = src.value.name()?.as_name();
|
||||||
|
let def_map = sb.db.crate_def_map(parent_module.id.krate);
|
||||||
|
let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?;
|
||||||
|
Some(parent_module.with_module_id(*child_id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,13 +24,14 @@ pub(crate) fn goto_definition(
|
||||||
let original_token = pick_best(file.token_at_offset(position.offset))?;
|
let original_token = pick_best(file.token_at_offset(position.offset))?;
|
||||||
let token = descend_into_macros(db, position.file_id, original_token.clone());
|
let token = descend_into_macros(db, position.file_id, original_token.clone());
|
||||||
|
|
||||||
|
let mut sb = SourceBinder::new(db);
|
||||||
let nav_targets = match_ast! {
|
let nav_targets = match_ast! {
|
||||||
match (token.value.parent()) {
|
match (token.value.parent()) {
|
||||||
ast::NameRef(name_ref) => {
|
ast::NameRef(name_ref) => {
|
||||||
reference_definition(db, token.with_value(&name_ref)).to_vec()
|
reference_definition(&mut sb, token.with_value(&name_ref)).to_vec()
|
||||||
},
|
},
|
||||||
ast::Name(name) => {
|
ast::Name(name) => {
|
||||||
name_definition(db, token.with_value(&name))?
|
name_definition(&mut sb, token.with_value(&name))?
|
||||||
},
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
|
@ -67,20 +68,19 @@ impl ReferenceResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn reference_definition(
|
pub(crate) fn reference_definition(
|
||||||
db: &RootDatabase,
|
sb: &mut SourceBinder<RootDatabase>,
|
||||||
name_ref: InFile<&ast::NameRef>,
|
name_ref: InFile<&ast::NameRef>,
|
||||||
) -> ReferenceResult {
|
) -> ReferenceResult {
|
||||||
use self::ReferenceResult::*;
|
use self::ReferenceResult::*;
|
||||||
|
|
||||||
let mut sb = SourceBinder::new(db);
|
let name_kind = classify_name_ref(sb, name_ref).map(|d| d.kind);
|
||||||
let name_kind = classify_name_ref(&mut sb, name_ref).map(|d| d.kind);
|
|
||||||
match name_kind {
|
match name_kind {
|
||||||
Some(Macro(it)) => return Exact(it.to_nav(db)),
|
Some(Macro(it)) => return Exact(it.to_nav(sb.db)),
|
||||||
Some(Field(it)) => return Exact(it.to_nav(db)),
|
Some(Field(it)) => return Exact(it.to_nav(sb.db)),
|
||||||
Some(TypeParam(it)) => return Exact(it.to_nav(db)),
|
Some(TypeParam(it)) => return Exact(it.to_nav(sb.db)),
|
||||||
Some(AssocItem(it)) => return Exact(it.to_nav(db)),
|
Some(AssocItem(it)) => return Exact(it.to_nav(sb.db)),
|
||||||
Some(Local(it)) => return Exact(it.to_nav(db)),
|
Some(Local(it)) => return Exact(it.to_nav(sb.db)),
|
||||||
Some(Def(def)) => match NavigationTarget::from_def(db, def) {
|
Some(Def(def)) => match NavigationTarget::from_def(sb.db, def) {
|
||||||
Some(nav) => return Exact(nav),
|
Some(nav) => return Exact(nav),
|
||||||
None => return Approximate(vec![]),
|
None => return Approximate(vec![]),
|
||||||
},
|
},
|
||||||
|
@ -88,21 +88,21 @@ pub(crate) fn reference_definition(
|
||||||
// FIXME: ideally, this should point to the type in the impl, and
|
// FIXME: ideally, this should point to the type in the impl, and
|
||||||
// not at the whole impl. And goto **type** definition should bring
|
// not at the whole impl. And goto **type** definition should bring
|
||||||
// us to the actual type
|
// us to the actual type
|
||||||
return Exact(imp.to_nav(db));
|
return Exact(imp.to_nav(sb.db));
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fallback index based approach:
|
// Fallback index based approach:
|
||||||
let navs = crate::symbol_index::index_resolve(db, name_ref.value)
|
let navs = crate::symbol_index::index_resolve(sb.db, name_ref.value)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|s| s.to_nav(db))
|
.map(|s| s.to_nav(sb.db))
|
||||||
.collect();
|
.collect();
|
||||||
Approximate(navs)
|
Approximate(navs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn name_definition(
|
fn name_definition(
|
||||||
db: &RootDatabase,
|
sb: &mut SourceBinder<RootDatabase>,
|
||||||
name: InFile<&ast::Name>,
|
name: InFile<&ast::Name>,
|
||||||
) -> Option<Vec<NavigationTarget>> {
|
) -> Option<Vec<NavigationTarget>> {
|
||||||
let parent = name.value.syntax().parent()?;
|
let parent = name.value.syntax().parent()?;
|
||||||
|
@ -110,14 +110,14 @@ pub(crate) fn name_definition(
|
||||||
if let Some(module) = ast::Module::cast(parent.clone()) {
|
if let Some(module) = ast::Module::cast(parent.clone()) {
|
||||||
if module.has_semi() {
|
if module.has_semi() {
|
||||||
let src = name.with_value(module);
|
let src = name.with_value(module);
|
||||||
if let Some(child_module) = hir::Module::from_declaration(db, src) {
|
if let Some(child_module) = sb.to_def(src) {
|
||||||
let nav = child_module.to_nav(db);
|
let nav = child_module.to_nav(sb.db);
|
||||||
return Some(vec![nav]);
|
return Some(vec![nav]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(nav) = named_target(db, name.with_value(&parent)) {
|
if let Some(nav) = named_target(sb.db, name.with_value(&parent)) {
|
||||||
return Some(vec![nav]);
|
return Some(vec![nav]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub(crate) fn classify_name(
|
||||||
hir::Module::from_definition(sb.db, src)
|
hir::Module::from_definition(sb.db, src)
|
||||||
} else {
|
} else {
|
||||||
let src = name.with_value(it);
|
let src = name.with_value(it);
|
||||||
hir::Module::from_declaration(sb.db, src)
|
sb.to_def(src)
|
||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
Some(from_module_def(sb.db, def.into(), None))
|
Some(from_module_def(sb.db, def.into(), None))
|
||||||
|
|
|
@ -63,7 +63,7 @@ fn rename_mod(
|
||||||
let mut source_file_edits = Vec::new();
|
let mut source_file_edits = Vec::new();
|
||||||
let mut file_system_edits = Vec::new();
|
let mut file_system_edits = Vec::new();
|
||||||
let module_src = hir::InFile { file_id: position.file_id.into(), value: ast_module.clone() };
|
let module_src = hir::InFile { file_id: position.file_id.into(), value: ast_module.clone() };
|
||||||
if let Some(module) = hir::Module::from_declaration(db, module_src) {
|
if let Some(module) = hir::SourceBinder::new(db).to_def(module_src) {
|
||||||
let src = module.definition_source(db);
|
let src = module.definition_source(db);
|
||||||
let file_id = src.file_id.original_file(db);
|
let file_id = src.file_id.original_file(db);
|
||||||
match src.value {
|
match src.value {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue