mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 17:28:09 +00:00
Make FromSource private
This commit is contained in:
parent
f4eeff2c82
commit
81a45ca1b3
8 changed files with 84 additions and 41 deletions
|
@ -1,6 +1,6 @@
|
|||
//! This module defines `AssistCtx` -- the API surface that is exposed to assists.
|
||||
use either::Either;
|
||||
use hir::{db::HirDatabase, InFile, SourceAnalyzer};
|
||||
use hir::{db::HirDatabase, InFile, SourceAnalyzer, SourceBinder};
|
||||
use ra_db::FileRange;
|
||||
use ra_fmt::{leading_indent, reindent};
|
||||
use ra_syntax::{
|
||||
|
@ -142,12 +142,16 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> {
|
|||
pub(crate) fn covering_element(&self) -> SyntaxElement {
|
||||
find_covering_element(self.source_file.syntax(), self.frange.range)
|
||||
}
|
||||
pub(crate) fn source_binder(&self) -> SourceBinder<'a, DB> {
|
||||
SourceBinder::new(self.db)
|
||||
}
|
||||
pub(crate) fn source_analyzer(
|
||||
&self,
|
||||
node: &SyntaxNode,
|
||||
offset: Option<TextUnit>,
|
||||
) -> SourceAnalyzer {
|
||||
SourceAnalyzer::new(self.db, InFile::new(self.frange.file_id.into(), node), offset)
|
||||
let src = InFile::new(self.frange.file_id.into(), node);
|
||||
self.source_binder().analyze(src, offset)
|
||||
}
|
||||
|
||||
pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use format_buf::format;
|
||||
use hir::{db::HirDatabase, FromSource, InFile};
|
||||
use hir::{db::HirDatabase, InFile};
|
||||
use join_to_string::join;
|
||||
use ra_syntax::{
|
||||
ast::{
|
||||
|
@ -136,15 +136,16 @@ fn find_struct_impl(
|
|||
let module = strukt.syntax().ancestors().find(|node| {
|
||||
ast::Module::can_cast(node.kind()) || ast::SourceFile::can_cast(node.kind())
|
||||
})?;
|
||||
let mut sb = ctx.source_binder();
|
||||
|
||||
let struct_ty = {
|
||||
let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() };
|
||||
hir::Struct::from_source(db, src)?.ty(db)
|
||||
sb.to_def::<hir::Struct, _>(src)?.ty(db)
|
||||
};
|
||||
|
||||
let block = module.descendants().filter_map(ast::ImplBlock::cast).find_map(|impl_blk| {
|
||||
let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() };
|
||||
let blk = hir::ImplBlock::from_source(db, src)?;
|
||||
let blk = sb.to_def::<hir::ImplBlock, _>(src)?;
|
||||
|
||||
let same_ty = blk.target_ty(db) == struct_ty;
|
||||
let not_trait_impl = blk.target_trait(db).is_none();
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
|||
MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union,
|
||||
};
|
||||
|
||||
pub trait FromSource: Sized {
|
||||
pub(crate) trait FromSource: Sized {
|
||||
type Ast;
|
||||
fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self>;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ pub use crate::{
|
|||
MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias,
|
||||
TypeParam, Union, VariantDef,
|
||||
},
|
||||
from_source::FromSource,
|
||||
has_source::HasSource,
|
||||
source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
|
||||
source_binder::SourceBinder,
|
||||
|
|
|
@ -11,7 +11,7 @@ use hir_def::{
|
|||
ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, ImplId, ModuleId, StaticId,
|
||||
StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
|
||||
};
|
||||
use hir_expand::InFile;
|
||||
use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind};
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
@ -62,18 +62,7 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
|
|||
}
|
||||
|
||||
fn to_id<T: ToId>(&mut self, src: InFile<T>) -> Option<T::ID> {
|
||||
let container = self.find_container(src.as_ref().map(|it| it.syntax()))?;
|
||||
let db = self.db;
|
||||
let dyn_map =
|
||||
&*self.child_by_source_cache.entry(container).or_insert_with(|| match container {
|
||||
ChildContainer::DefWithBodyId(it) => it.child_by_source(db),
|
||||
ChildContainer::ModuleId(it) => it.child_by_source(db),
|
||||
ChildContainer::TraitId(it) => it.child_by_source(db),
|
||||
ChildContainer::ImplId(it) => it.child_by_source(db),
|
||||
ChildContainer::EnumId(it) => it.child_by_source(db),
|
||||
ChildContainer::VariantId(it) => it.child_by_source(db),
|
||||
});
|
||||
dyn_map[T::KEY].get(&src).copied()
|
||||
T::to_id(self, src)
|
||||
}
|
||||
|
||||
fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
|
||||
|
@ -145,20 +134,47 @@ impl_froms! {
|
|||
}
|
||||
|
||||
pub trait ToId: Sized + AstNode + 'static {
|
||||
type ID: Sized + Copy + 'static;
|
||||
fn to_id<DB: HirDatabase>(sb: &mut SourceBinder<'_, DB>, src: InFile<Self>)
|
||||
-> Option<Self::ID>;
|
||||
}
|
||||
|
||||
pub trait ToIdByKey: Sized + AstNode + 'static {
|
||||
type ID: Sized + Copy + 'static;
|
||||
const KEY: Key<Self, Self::ID>;
|
||||
}
|
||||
|
||||
macro_rules! to_id_impls {
|
||||
impl<T: ToIdByKey> ToId for T {
|
||||
type ID = <T as ToIdByKey>::ID;
|
||||
fn to_id<DB: HirDatabase>(
|
||||
sb: &mut SourceBinder<'_, DB>,
|
||||
src: InFile<Self>,
|
||||
) -> Option<Self::ID> {
|
||||
let container = sb.find_container(src.as_ref().map(|it| it.syntax()))?;
|
||||
let db = sb.db;
|
||||
let dyn_map =
|
||||
&*sb.child_by_source_cache.entry(container).or_insert_with(|| match container {
|
||||
ChildContainer::DefWithBodyId(it) => it.child_by_source(db),
|
||||
ChildContainer::ModuleId(it) => it.child_by_source(db),
|
||||
ChildContainer::TraitId(it) => it.child_by_source(db),
|
||||
ChildContainer::ImplId(it) => it.child_by_source(db),
|
||||
ChildContainer::EnumId(it) => it.child_by_source(db),
|
||||
ChildContainer::VariantId(it) => it.child_by_source(db),
|
||||
});
|
||||
dyn_map[T::KEY].get(&src).copied()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! to_id_key_impls {
|
||||
($(($id:ident, $ast:path, $key:path)),* ,) => {$(
|
||||
impl ToId for $ast {
|
||||
impl ToIdByKey for $ast {
|
||||
type ID = $id;
|
||||
const KEY: Key<Self, Self::ID> = $key;
|
||||
}
|
||||
)*}
|
||||
}
|
||||
|
||||
to_id_impls![
|
||||
to_id_key_impls![
|
||||
(StructId, ast::StructDef, keys::STRUCT),
|
||||
(UnionId, ast::UnionDef, keys::UNION),
|
||||
(EnumId, ast::EnumDef, keys::ENUM),
|
||||
|
@ -171,3 +187,23 @@ to_id_impls![
|
|||
(StructFieldId, ast::RecordFieldDef, keys::RECORD_FIELD),
|
||||
(EnumVariantId, ast::EnumVariant, keys::ENUM_VARIANT),
|
||||
];
|
||||
|
||||
// FIXME: use DynMap as well?
|
||||
impl ToId for ast::MacroCall {
|
||||
type ID = MacroDefId;
|
||||
fn to_id<DB: HirDatabase>(
|
||||
sb: &mut SourceBinder<'_, DB>,
|
||||
src: InFile<Self>,
|
||||
) -> Option<Self::ID> {
|
||||
let kind = MacroDefKind::Declarative;
|
||||
|
||||
let module_src = ModuleSource::from_child_node(sb.db, src.as_ref().map(|it| it.syntax()));
|
||||
let module = crate::Module::from_definition(sb.db, InFile::new(src.file_id, module_src))?;
|
||||
let krate = Some(module.krate().id);
|
||||
|
||||
let ast_id =
|
||||
Some(AstId::new(src.file_id, sb.db.ast_id_map(src.file_id).ast_id(&src.value)));
|
||||
|
||||
Some(MacroDefId { krate, ast_id, kind })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use hir_expand::InFile;
|
||||
use hir_expand::{InFile, MacroDefId};
|
||||
use ra_syntax::{ast, AstNode, AstPtr};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
|
@ -29,6 +29,8 @@ pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new();
|
|||
pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new();
|
||||
pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new();
|
||||
|
||||
pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new();
|
||||
|
||||
/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
|
||||
/// equal if they point to exactly the same object.
|
||||
///
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! FIXME: write short doc here
|
||||
|
||||
use hir::{FromSource, ImplBlock};
|
||||
use hir::{ImplBlock, SourceBinder};
|
||||
use ra_db::SourceDatabase;
|
||||
use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
|
||||
|
||||
|
@ -12,6 +12,7 @@ pub(crate) fn goto_implementation(
|
|||
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
|
||||
let parse = db.parse(position.file_id);
|
||||
let syntax = parse.tree().syntax().clone();
|
||||
let mut sb = SourceBinder::new(db);
|
||||
|
||||
let src = hir::ModuleSource::from_position(db, position);
|
||||
let module = hir::Module::from_definition(
|
||||
|
@ -22,12 +23,12 @@ pub(crate) fn goto_implementation(
|
|||
if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) {
|
||||
return Some(RangeInfo::new(
|
||||
nominal_def.syntax().text_range(),
|
||||
impls_for_def(db, position, &nominal_def, module)?,
|
||||
impls_for_def(&mut sb, position, &nominal_def, module)?,
|
||||
));
|
||||
} else if let Some(trait_def) = find_node_at_offset::<ast::TraitDef>(&syntax, position.offset) {
|
||||
return Some(RangeInfo::new(
|
||||
trait_def.syntax().text_range(),
|
||||
impls_for_trait(db, position, &trait_def, module)?,
|
||||
impls_for_trait(&mut sb, position, &trait_def, module)?,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -35,7 +36,7 @@ pub(crate) fn goto_implementation(
|
|||
}
|
||||
|
||||
fn impls_for_def(
|
||||
db: &RootDatabase,
|
||||
sb: &mut SourceBinder<RootDatabase>,
|
||||
position: FilePosition,
|
||||
node: &ast::NominalDef,
|
||||
module: hir::Module,
|
||||
|
@ -43,43 +44,43 @@ fn impls_for_def(
|
|||
let ty = match node {
|
||||
ast::NominalDef::StructDef(def) => {
|
||||
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
|
||||
hir::Struct::from_source(db, src)?.ty(db)
|
||||
sb.to_def::<hir::Struct, _>(src)?.ty(sb.db)
|
||||
}
|
||||
ast::NominalDef::EnumDef(def) => {
|
||||
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
|
||||
hir::Enum::from_source(db, src)?.ty(db)
|
||||
sb.to_def::<hir::Enum, _>(src)?.ty(sb.db)
|
||||
}
|
||||
ast::NominalDef::UnionDef(def) => {
|
||||
let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
|
||||
hir::Union::from_source(db, src)?.ty(db)
|
||||
sb.to_def::<hir::Union, _>(src)?.ty(sb.db)
|
||||
}
|
||||
};
|
||||
|
||||
let krate = module.krate();
|
||||
let impls = ImplBlock::all_in_crate(db, krate);
|
||||
let impls = ImplBlock::all_in_crate(sb.db, krate);
|
||||
|
||||
Some(
|
||||
impls
|
||||
.into_iter()
|
||||
.filter(|impl_block| ty.is_equal_for_find_impls(&impl_block.target_ty(db)))
|
||||
.map(|imp| imp.to_nav(db))
|
||||
.filter(|impl_block| ty.is_equal_for_find_impls(&impl_block.target_ty(sb.db)))
|
||||
.map(|imp| imp.to_nav(sb.db))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn impls_for_trait(
|
||||
db: &RootDatabase,
|
||||
sb: &mut SourceBinder<RootDatabase>,
|
||||
position: FilePosition,
|
||||
node: &ast::TraitDef,
|
||||
module: hir::Module,
|
||||
) -> Option<Vec<NavigationTarget>> {
|
||||
let src = hir::InFile { file_id: position.file_id.into(), value: node.clone() };
|
||||
let tr = hir::Trait::from_source(db, src)?;
|
||||
let tr = sb.to_def(src)?;
|
||||
|
||||
let krate = module.krate();
|
||||
let impls = ImplBlock::for_trait(db, krate, tr);
|
||||
let impls = ImplBlock::for_trait(sb.db, krate, tr);
|
||||
|
||||
Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect())
|
||||
Some(impls.into_iter().map(|imp| imp.to_nav(sb.db)).collect())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -210,7 +211,7 @@ mod tests {
|
|||
"
|
||||
//- /lib.rs
|
||||
#[derive(Copy)]
|
||||
struct Foo<|>;
|
||||
struct Foo<|>;
|
||||
",
|
||||
&["impl IMPL_BLOCK FileId(1) [0; 15)"],
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Functions that are used to classify an element from its definition or reference.
|
||||
|
||||
use hir::{FromSource, InFile, Module, ModuleSource, PathResolution, SourceBinder};
|
||||
use hir::{InFile, Module, ModuleSource, PathResolution, SourceBinder};
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::{ast, match_ast, AstNode};
|
||||
use test_utils::tested_by;
|
||||
|
@ -101,7 +101,7 @@ pub(crate) fn classify_name(
|
|||
},
|
||||
ast::MacroCall(it) => {
|
||||
let src = name.with_value(it);
|
||||
let def = hir::MacroDef::from_source(sb.db, src.clone())?;
|
||||
let def = sb.to_def(src.clone())?;
|
||||
|
||||
let module_src = ModuleSource::from_child_node(sb.db, src.as_ref().map(|it| it.syntax()));
|
||||
let module = Module::from_definition(sb.db, src.with_value(module_src))?;
|
||||
|
|
Loading…
Reference in a new issue