Allow name querying for derive helpers
This commit is contained in:
parent
aa1491ecde
commit
ddad2847ab
@ -12,7 +12,7 @@
|
||||
db::DefDatabase,
|
||||
intern::Interned,
|
||||
item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, ModItem, Param, TreeId},
|
||||
nameres::{attr_resolution::ResolvedAttr, DefMap},
|
||||
nameres::{attr_resolution::ResolvedAttr, proc_macro::ProcMacroKind, DefMap},
|
||||
type_ref::{TraitRef, TypeBound, TypeRef},
|
||||
visibility::RawVisibility,
|
||||
AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
|
||||
@ -348,7 +348,8 @@ pub(crate) fn macro_rules_data_query(
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ProcMacroData {
|
||||
pub name: Name,
|
||||
// FIXME: Record deriver helper here?
|
||||
/// Derive helpers, if this is a derive
|
||||
pub helpers: Option<Box<[Name]>>,
|
||||
}
|
||||
|
||||
impl ProcMacroData {
|
||||
@ -360,17 +361,23 @@ pub(crate) fn proc_macro_data_query(
|
||||
let item_tree = loc.id.item_tree(db);
|
||||
let makro = &item_tree[loc.id.value];
|
||||
|
||||
let name = if let Some(def) = item_tree
|
||||
let (name, helpers) = if let Some(def) = item_tree
|
||||
.attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
|
||||
.parse_proc_macro_decl(&makro.name)
|
||||
{
|
||||
def.name
|
||||
(
|
||||
def.name,
|
||||
match def.kind {
|
||||
ProcMacroKind::CustomDerive { helpers } => Some(helpers),
|
||||
ProcMacroKind::FnLike | ProcMacroKind::Attr => None,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
// eeeh...
|
||||
stdx::never!("proc macro declaration is not a proc macro");
|
||||
makro.name.clone()
|
||||
(makro.name.clone(), None)
|
||||
};
|
||||
Arc::new(ProcMacroData { name })
|
||||
Arc::new(ProcMacroData { name, helpers })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,11 @@
|
||||
//! the result
|
||||
|
||||
pub mod attr_resolution;
|
||||
mod collector;
|
||||
pub mod proc_macro;
|
||||
pub mod diagnostics;
|
||||
mod collector;
|
||||
mod mod_resolution;
|
||||
mod path_resolution;
|
||||
mod proc_macro;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
@ -2255,12 +2255,27 @@ pub fn source(self, db: &dyn HirDatabase) -> InFile<Either<ast::IdentPat, ast::S
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct DeriveHelper {
|
||||
pub(crate) derive: MacroId,
|
||||
pub(crate) idx: usize,
|
||||
}
|
||||
|
||||
impl DeriveHelper {
|
||||
pub fn derive(&self) -> Macro {
|
||||
Macro { id: self.derive.into() }
|
||||
}
|
||||
|
||||
pub fn name(&self, db: &dyn HirDatabase) -> Name {
|
||||
match self.derive {
|
||||
MacroId::Macro2Id(_) => None,
|
||||
MacroId::MacroRulesId(_) => None,
|
||||
MacroId::ProcMacroId(proc_macro) => db
|
||||
.proc_macro_data(proc_macro)
|
||||
.helpers
|
||||
.as_ref()
|
||||
.and_then(|it| it.get(self.idx))
|
||||
.cloned(),
|
||||
}
|
||||
.unwrap_or_else(|| Name::missing())
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Wrong name? This is could also be a registered attribute
|
||||
|
@ -35,6 +35,7 @@
|
||||
method_resolution, Adjust, Adjustment, AutoBorrow, InferenceResult, Interner, Substitution,
|
||||
TyExt, TyKind, TyLoweringContext,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use smallvec::SmallVec;
|
||||
use syntax::{
|
||||
ast::{self, AstNode},
|
||||
@ -487,10 +488,16 @@ pub(crate) fn resolve_path(
|
||||
{
|
||||
// FIXME: Multiple derives can have the same helper
|
||||
let name_ref = name_ref.as_name();
|
||||
if let Some(&(_, derive, _)) =
|
||||
helpers.iter().find(|(name, ..)| *name == name_ref)
|
||||
for (macro_id, mut helpers) in
|
||||
helpers.iter().group_by(|(_, macro_id, ..)| macro_id).into_iter()
|
||||
{
|
||||
return Some(PathResolution::DeriveHelper(DeriveHelper { derive }));
|
||||
if let Some(idx) = helpers.position(|(name, ..)| *name == name_ref)
|
||||
{
|
||||
return Some(PathResolution::DeriveHelper(DeriveHelper {
|
||||
derive: *macro_id,
|
||||
idx,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ pub fn name(&self, db: &RootDatabase) -> Option<Name> {
|
||||
Definition::Label(it) => it.name(db),
|
||||
Definition::BuiltinAttr(_) => return None, // FIXME
|
||||
Definition::ToolModule(_) => return None, // FIXME
|
||||
Definition::DeriveHelper(_) => return None, // FIXME
|
||||
Definition::DeriveHelper(it) => it.name(db),
|
||||
};
|
||||
Some(name)
|
||||
}
|
||||
|
@ -278,16 +278,16 @@ fn search_scope(&self, db: &RootDatabase) -> SearchScope {
|
||||
}
|
||||
}
|
||||
hir::MacroKind::BuiltIn => SearchScope::crate_graph(db),
|
||||
// FIXME: We don't actually see derives in derive attributes as these do not
|
||||
// expand to something that references the derive macro in the output.
|
||||
// We could get around this by doing pseudo expansions for proc_macro_derive like we
|
||||
// do for the derive attribute
|
||||
hir::MacroKind::Derive | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => {
|
||||
SearchScope::reverse_dependencies(db, module.krate())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if let Definition::DeriveHelper(_) = self {
|
||||
return SearchScope::reverse_dependencies(db, module.krate());
|
||||
}
|
||||
|
||||
let vis = self.visibility(db);
|
||||
if let Some(Visibility::Public) = vis {
|
||||
return SearchScope::reverse_dependencies(db, module.krate());
|
||||
|
@ -370,8 +370,7 @@ pub(super) fn definition(
|
||||
// FIXME: We should be able to show more info about these
|
||||
Definition::BuiltinAttr(it) => return render_builtin_attr(db, it),
|
||||
Definition::ToolModule(it) => return Some(Markup::fenced_block(&it.name(db))),
|
||||
// FIXME: it.name(db)
|
||||
Definition::DeriveHelper(_it) => ("derive-helper".to_owned(), None),
|
||||
Definition::DeriveHelper(it) => (format!("derive_helper {}", it.name(db)), None),
|
||||
};
|
||||
|
||||
let docs = match config.documentation {
|
||||
|
@ -432,6 +432,13 @@ fn item(&self) -> &ast::Item {
|
||||
// let the editor do its highlighting for these tokens instead
|
||||
continue;
|
||||
}
|
||||
if highlight.tag == HlTag::UnresolvedReference
|
||||
&& matches!(attr_or_derive_item, Some(AttrOrDerive::Derive(_)) if inside_attribute)
|
||||
{
|
||||
// do not emit unresolved references in derive helpers if the token mapping maps to
|
||||
// something unresolvable. FIXME: There should be a way to prevent that
|
||||
continue;
|
||||
}
|
||||
if inside_attribute {
|
||||
highlight |= HlMod::Attribute
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user