use base_db::FileId;
use hir_def::{
+ attr::AttrId,
child_by_source::ChildBySource,
dyn_map::DynMap,
expr::{LabelId, PatId},
pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> {
let _p = profile::span("module_to_def");
- let parent_declaration = src
- .syntax()
- .cloned()
- .ancestors_with_macros_skip_attr_item(self.db.upcast())
- .skip(1)
- .find_map(|it| {
- let m = ast::Module::cast(it.value.clone())?;
- Some(it.with_value(m))
- });
+ let parent_declaration =
+ src.syntax().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1).find_map(
+ |it| {
+ let m = ast::Module::cast(it.value.clone())?;
+ Some(it.with_value(m))
+ },
+ );
let parent_module = match parent_declaration {
Some(parent_declaration) => self.module_to_def(parent_declaration),
pub(super) fn item_to_macro_call(&mut self, src: InFile<ast::Item>) -> Option<MacroCallId> {
let map = self.dyn_map(src.as_ref())?;
- map[keys::ATTR_MACRO].get(&src).copied()
+ map[keys::ATTR_MACRO_CALL].get(&src.value).copied()
}
pub(super) fn attr_to_derive_macro_call(
&mut self,
- item: InFile<&ast::Item>,
+ item: InFile<&ast::Adt>,
src: InFile<ast::Attr>,
- ) -> Option<&[MacroCallId]> {
+ ) -> Option<(AttrId, MacroCallId, &[Option<MacroCallId>])> {
let map = self.dyn_map(item)?;
- map[keys::DERIVE_MACRO].get(&src).map(AsRef::as_ref)
+ map[keys::DERIVE_MACRO_CALL]
+ .get(&src.value)
+ .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids))
+ }
+ pub(super) fn has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool {
+ self.dyn_map(adt).as_ref().map_or(false, |map| !map[keys::DERIVE_MACRO_CALL].is_empty())
}
fn to_def<Ast: AstNode + 'static, ID: Copy + 'static>(
src: InFile<Ast>,
key: Key<Ast, ID>,
) -> Option<ID> {
- self.dyn_map(src.as_ref())?[key].get(&src).copied()
+ self.dyn_map(src.as_ref())?[key].get(&src.value).copied()
}
fn dyn_map<Ast: AstNode + 'static>(&mut self, src: InFile<&Ast>) -> Option<&DynMap> {
pub(super) fn type_param_to_def(&mut self, src: InFile<ast::TypeParam>) -> Option<TypeParamId> {
let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into();
let dyn_map = self.cache_for(container, src.file_id);
- dyn_map[keys::TYPE_PARAM].get(&src).copied()
+ dyn_map[keys::TYPE_PARAM].get(&src.value).copied()
}
pub(super) fn lifetime_param_to_def(
) -> Option<LifetimeParamId> {
let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into();
let dyn_map = self.cache_for(container, src.file_id);
- dyn_map[keys::LIFETIME_PARAM].get(&src).copied()
+ dyn_map[keys::LIFETIME_PARAM].get(&src.value).copied()
}
pub(super) fn const_param_to_def(
) -> Option<ConstParamId> {
let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into();
let dyn_map = self.cache_for(container, src.file_id);
- dyn_map[keys::CONST_PARAM].get(&src).copied()
+ dyn_map[keys::CONST_PARAM].get(&src.value).copied()
}
pub(super) fn generic_param_to_def(
}
pub(super) fn macro_to_def(&mut self, src: InFile<ast::Macro>) -> Option<MacroDefId> {
- let makro = self.dyn_map(src.as_ref()).and_then(|it| it[keys::MACRO].get(&src).copied());
- if let res @ Some(_) = makro {
- return res;
+ let makro = self.dyn_map(src.as_ref()).and_then(|it| it[keys::MACRO].get(&src.value));
+ if let Some(&makro) = makro {
+ return Some(makro);
}
// Not all macros are recorded in the dyn map, only the ones behaving like items, so fall back
}
pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
- for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1)
- {
+ for container in src.ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) {
if let Some(res) = self.container_to_def(container) {
return Some(res);
}
}
fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option<GenericDefId> {
- for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1)
- {
+ for container in src.ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) {
let res: GenericDefId = match_ast! {
match (container.value) {
ast::Fn(it) => self.fn_to_def(container.with_value(it))?.into(),
}
fn find_pat_or_label_container(&mut self, src: InFile<&SyntaxNode>) -> Option<DefWithBodyId> {
- for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1)
- {
+ for container in src.ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) {
let res: DefWithBodyId = match_ast! {
match (container.value) {
ast::Const(it) => self.const_to_def(container.with_value(it))?.into(),