mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 13:25:09 +00:00
Move more stuff to SourceBinder
This commit is contained in:
parent
a3d6ddbe69
commit
7aa627fe58
3 changed files with 70 additions and 66 deletions
|
@ -1,66 +1,13 @@
|
||||||
//! Finds a corresponding hir data structure for a syntax node in a specific
|
//! Finds a corresponding hir data structure for a syntax node in a specific
|
||||||
//! file.
|
//! file.
|
||||||
|
|
||||||
use hir_def::{
|
use hir_def::{nameres::ModuleSource, ModuleId};
|
||||||
child_by_source::ChildBySource, keys, nameres::ModuleSource, GenericDefId, ModuleId,
|
|
||||||
};
|
|
||||||
use hir_expand::name::AsName;
|
use hir_expand::name::AsName;
|
||||||
use ra_db::FileId;
|
use ra_db::FileId;
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{
|
use ra_syntax::ast::{self, AstNode, NameOwner};
|
||||||
ast::{self, AstNode, NameOwner},
|
|
||||||
match_ast,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{db::DefDatabase, InFile, Module};
|
||||||
db::{DefDatabase, HirDatabase},
|
|
||||||
DefWithBody, InFile, Local, Module, SourceBinder, TypeParam,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Local {
|
|
||||||
pub fn from_source(db: &impl HirDatabase, src: InFile<ast::BindPat>) -> Option<Self> {
|
|
||||||
let mut sb = SourceBinder::new(db);
|
|
||||||
let file_id = src.file_id;
|
|
||||||
let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| {
|
|
||||||
let res = match_ast! {
|
|
||||||
match it {
|
|
||||||
ast::ConstDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
|
|
||||||
ast::StaticDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
|
|
||||||
ast::FnDef(value) => { sb.to_def(InFile { value, file_id})?.into() },
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Some(res)
|
|
||||||
})?;
|
|
||||||
let (_body, source_map) = db.body_with_source_map(parent.into());
|
|
||||||
let src = src.map(ast::Pat::from);
|
|
||||||
let pat_id = source_map.node_pat(src.as_ref())?;
|
|
||||||
Some(Local { parent, pat_id })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypeParam {
|
|
||||||
pub fn from_source(db: &impl HirDatabase, src: InFile<ast::TypeParam>) -> Option<Self> {
|
|
||||||
let mut sb = SourceBinder::new(db);
|
|
||||||
let file_id = src.file_id;
|
|
||||||
let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| {
|
|
||||||
let res = match_ast! {
|
|
||||||
match it {
|
|
||||||
ast::FnDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
|
||||||
ast::StructDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
|
||||||
ast::EnumDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
|
||||||
ast::TraitDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
|
||||||
ast::TypeAliasDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
|
||||||
ast::ImplBlock(value) => { sb.to_def(InFile { value, file_id})?.id.into() },
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Some(res)
|
|
||||||
})?;
|
|
||||||
let &id = parent.child_by_source(db)[keys::TYPE_PARAM].get(&src)?;
|
|
||||||
Some(TypeParam { id })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Module {
|
impl Module {
|
||||||
pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> {
|
pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> {
|
||||||
|
|
|
@ -8,15 +8,15 @@ use hir_def::{
|
||||||
dyn_map::DynMap,
|
dyn_map::DynMap,
|
||||||
keys::{self, Key},
|
keys::{self, Key},
|
||||||
resolver::{HasResolver, Resolver},
|
resolver::{HasResolver, Resolver},
|
||||||
ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, ImplId, ModuleId, StaticId,
|
ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId,
|
||||||
StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
|
StaticId, StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind};
|
use hir_expand::{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, match_ast, AstNode, SyntaxNode, TextUnit};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::{db::HirDatabase, ModuleSource, SourceAnalyzer};
|
use crate::{db::HirDatabase, Local, ModuleSource, SourceAnalyzer, TypeParam};
|
||||||
|
|
||||||
pub struct SourceBinder<'a, DB> {
|
pub struct SourceBinder<'a, DB> {
|
||||||
pub db: &'a DB,
|
pub db: &'a DB,
|
||||||
|
@ -53,8 +53,7 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_def<T: ToDef>(&mut self, src: InFile<T>) -> Option<T::Def> {
|
pub fn to_def<T: ToDef>(&mut self, src: InFile<T>) -> Option<T::Def> {
|
||||||
let id: T::ID = self.to_id(src)?;
|
T::to_def(self, src)
|
||||||
Some(id.into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_id<T: ToId>(&mut self, src: InFile<T>) -> Option<T::ID> {
|
fn to_id<T: ToId>(&mut self, src: InFile<T>) -> Option<T::ID> {
|
||||||
|
@ -110,20 +109,27 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToId: Sized + AstNode + 'static {
|
pub trait ToId: Sized {
|
||||||
type ID: Sized + Copy + 'static;
|
type ID: Sized + Copy + 'static;
|
||||||
fn to_id<DB: HirDatabase>(sb: &mut SourceBinder<'_, DB>, src: InFile<Self>)
|
fn to_id<DB: HirDatabase>(sb: &mut SourceBinder<'_, DB>, src: InFile<Self>)
|
||||||
-> Option<Self::ID>;
|
-> Option<Self::ID>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToDef: ToId {
|
pub trait ToDef: Sized + AstNode + 'static {
|
||||||
type Def: From<Self::ID>;
|
type Def;
|
||||||
|
fn to_def<DB: HirDatabase>(
|
||||||
|
sb: &mut SourceBinder<'_, DB>,
|
||||||
|
src: InFile<Self>,
|
||||||
|
) -> Option<Self::Def>;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! to_def_impls {
|
macro_rules! to_def_impls {
|
||||||
($(($def:path, $ast:path)),* ,) => {$(
|
($(($def:path, $ast:path)),* ,) => {$(
|
||||||
impl ToDef for $ast {
|
impl ToDef for $ast {
|
||||||
type Def = $def;
|
type Def = $def;
|
||||||
|
fn to_def<DB: HirDatabase>(sb: &mut SourceBinder<'_, DB>, src: InFile<Self>)
|
||||||
|
-> Option<Self::Def>
|
||||||
|
{ sb.to_id(src).map(Into::into) }
|
||||||
}
|
}
|
||||||
)*}
|
)*}
|
||||||
}
|
}
|
||||||
|
@ -230,3 +236,54 @@ impl ToId for ast::MacroCall {
|
||||||
Some(MacroDefId { krate, ast_id, kind })
|
Some(MacroDefId { krate, ast_id, kind })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToDef for ast::BindPat {
|
||||||
|
type Def = Local;
|
||||||
|
|
||||||
|
fn to_def<DB: HirDatabase>(sb: &mut SourceBinder<'_, DB>, src: InFile<Self>) -> Option<Local> {
|
||||||
|
let file_id = src.file_id;
|
||||||
|
let parent: DefWithBodyId = src.value.syntax().ancestors().find_map(|it| {
|
||||||
|
let res = match_ast! {
|
||||||
|
match it {
|
||||||
|
ast::ConstDef(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
ast::StaticDef(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
ast::FnDef(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(res)
|
||||||
|
})?;
|
||||||
|
let (_body, source_map) = sb.db.body_with_source_map(parent);
|
||||||
|
let src = src.map(ast::Pat::from);
|
||||||
|
let pat_id = source_map.node_pat(src.as_ref())?;
|
||||||
|
Some(Local { parent: parent.into(), pat_id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToDef for ast::TypeParam {
|
||||||
|
type Def = TypeParam;
|
||||||
|
|
||||||
|
fn to_def<DB: HirDatabase>(
|
||||||
|
sb: &mut SourceBinder<'_, DB>,
|
||||||
|
src: InFile<ast::TypeParam>,
|
||||||
|
) -> Option<TypeParam> {
|
||||||
|
let mut sb = SourceBinder::new(sb.db);
|
||||||
|
let file_id = src.file_id;
|
||||||
|
let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| {
|
||||||
|
let res = match_ast! {
|
||||||
|
match it {
|
||||||
|
ast::FnDef(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
ast::StructDef(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
ast::EnumDef(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
ast::TraitDef(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
ast::TypeAliasDef(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
ast::ImplBlock(value) => { sb.to_id(InFile { value, file_id})?.into() },
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(res)
|
||||||
|
})?;
|
||||||
|
let &id = parent.child_by_source(sb.db)[keys::TYPE_PARAM].get(&src)?;
|
||||||
|
Some(TypeParam { id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub(crate) fn classify_name(
|
||||||
match parent {
|
match parent {
|
||||||
ast::BindPat(it) => {
|
ast::BindPat(it) => {
|
||||||
let src = name.with_value(it);
|
let src = name.with_value(it);
|
||||||
let local = hir::Local::from_source(sb.db, src)?;
|
let local = sb.to_def(src)?;
|
||||||
Some(NameDefinition {
|
Some(NameDefinition {
|
||||||
visibility: None,
|
visibility: None,
|
||||||
container: local.module(sb.db),
|
container: local.module(sb.db),
|
||||||
|
@ -114,7 +114,7 @@ pub(crate) fn classify_name(
|
||||||
},
|
},
|
||||||
ast::TypeParam(it) => {
|
ast::TypeParam(it) => {
|
||||||
let src = name.with_value(it);
|
let src = name.with_value(it);
|
||||||
let def = hir::TypeParam::from_source(sb.db, src)?;
|
let def = sb.to_def(src)?;
|
||||||
Some(NameDefinition {
|
Some(NameDefinition {
|
||||||
visibility: None,
|
visibility: None,
|
||||||
container: def.module(sb.db),
|
container: def.module(sb.db),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue