Merge #11216
11216: internal: Support registered tools and attributes in ide layer r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
5c47eb6bf8
@ -2064,37 +2064,75 @@ impl Local {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Wrong name? This is could also be a registered attribute
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct BuiltinAttr(usize);
|
||||
pub struct BuiltinAttr {
|
||||
krate: Option<CrateId>,
|
||||
idx: usize,
|
||||
}
|
||||
|
||||
impl BuiltinAttr {
|
||||
pub(crate) fn by_name(name: &str) -> Option<Self> {
|
||||
// FIXME: def maps registered attrs?
|
||||
hir_def::builtin_attr::find_builtin_attr_idx(name).map(Self)
|
||||
// FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs?
|
||||
pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
|
||||
if let builtin @ Some(_) = Self::builtin(name) {
|
||||
return builtin;
|
||||
}
|
||||
let idx = db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)?;
|
||||
Some(BuiltinAttr { krate: Some(krate.id), idx })
|
||||
}
|
||||
|
||||
pub fn name(&self, _: &dyn HirDatabase) -> &str {
|
||||
pub(crate) fn builtin(name: &str) -> Option<Self> {
|
||||
hir_def::builtin_attr::INERT_ATTRIBUTES
|
||||
.iter()
|
||||
.position(|tool| tool.name == name)
|
||||
.map(|idx| BuiltinAttr { krate: None, idx })
|
||||
}
|
||||
|
||||
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
|
||||
// FIXME: Return a `Name` here
|
||||
hir_def::builtin_attr::INERT_ATTRIBUTES[self.0].name
|
||||
match self.krate {
|
||||
Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx].clone(),
|
||||
None => SmolStr::new(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].name),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn template(&self, _: &dyn HirDatabase) -> AttributeTemplate {
|
||||
hir_def::builtin_attr::INERT_ATTRIBUTES[self.0].template
|
||||
pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
|
||||
match self.krate {
|
||||
Some(_) => None,
|
||||
None => Some(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].template),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ToolModule(usize);
|
||||
pub struct ToolModule {
|
||||
krate: Option<CrateId>,
|
||||
idx: usize,
|
||||
}
|
||||
|
||||
impl ToolModule {
|
||||
pub(crate) fn by_name(name: &str) -> Option<Self> {
|
||||
// FIXME: def maps registered tools
|
||||
hir_def::builtin_attr::TOOL_MODULES.iter().position(|&tool| tool == name).map(Self)
|
||||
// FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs?
|
||||
pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
|
||||
if let builtin @ Some(_) = Self::builtin(name) {
|
||||
return builtin;
|
||||
}
|
||||
let idx = db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)?;
|
||||
Some(ToolModule { krate: Some(krate.id), idx })
|
||||
}
|
||||
|
||||
pub fn name(&self, _: &dyn HirDatabase) -> &str {
|
||||
pub(crate) fn builtin(name: &str) -> Option<Self> {
|
||||
hir_def::builtin_attr::TOOL_MODULES
|
||||
.iter()
|
||||
.position(|&tool| tool == name)
|
||||
.map(|idx| ToolModule { krate: None, idx })
|
||||
}
|
||||
|
||||
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
|
||||
// FIXME: Return a `Name` here
|
||||
hir_def::builtin_attr::TOOL_MODULES[self.0]
|
||||
match self.krate {
|
||||
Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx].clone(),
|
||||
None => SmolStr::new(hir_def::builtin_attr::TOOL_MODULES[self.idx]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,7 +346,11 @@ impl SourceAnalyzer {
|
||||
return match resolve_hir_path_qualifier(db, &self.resolver, &hir_path) {
|
||||
None if is_path_of_attr => {
|
||||
path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
|
||||
ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
|
||||
match self.resolver.krate() {
|
||||
Some(krate) => ToolModule::by_name(db, krate.into(), &name_ref.text()),
|
||||
None => ToolModule::builtin(&name_ref.text()),
|
||||
}
|
||||
.map(PathResolution::ToolModule)
|
||||
})
|
||||
}
|
||||
res => res,
|
||||
@ -356,8 +360,10 @@ impl SourceAnalyzer {
|
||||
// in this case we have to check for inert/builtin attributes and tools and prioritize
|
||||
// resolution of attributes over other namespaces
|
||||
let name_ref = path.as_single_name_ref();
|
||||
let builtin =
|
||||
name_ref.as_ref().map(ast::NameRef::text).as_deref().and_then(BuiltinAttr::by_name);
|
||||
let builtin = name_ref.as_ref().and_then(|name_ref| match self.resolver.krate() {
|
||||
Some(krate) => BuiltinAttr::by_name(db, krate.into(), &name_ref.text()),
|
||||
None => BuiltinAttr::builtin(&name_ref.text()),
|
||||
});
|
||||
if let builtin @ Some(_) = builtin {
|
||||
return builtin.map(PathResolution::BuiltinAttr);
|
||||
}
|
||||
@ -366,7 +372,11 @@ impl SourceAnalyzer {
|
||||
// this labels any path that starts with a tool module as the tool itself, this is technically wrong
|
||||
// but there is no benefit in differentiating these two cases for the time being
|
||||
_ => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
|
||||
ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
|
||||
match self.resolver.krate() {
|
||||
Some(krate) => ToolModule::by_name(db, krate.into(), &name_ref.text()),
|
||||
None => ToolModule::builtin(&name_ref.text()),
|
||||
}
|
||||
.map(PathResolution::ToolModule)
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
@ -296,6 +296,12 @@ impl DefMap {
|
||||
pub fn exported_proc_macros(&self) -> impl Iterator<Item = (MacroDefId, Name)> + '_ {
|
||||
self.exported_proc_macros.iter().map(|(id, def)| (*id, def.name.clone()))
|
||||
}
|
||||
pub fn registered_tools(&self) -> &[SmolStr] {
|
||||
&self.registered_tools
|
||||
}
|
||||
pub fn registered_attrs(&self) -> &[SmolStr] {
|
||||
&self.registered_attrs
|
||||
}
|
||||
pub fn root(&self) -> LocalModuleId {
|
||||
self.root
|
||||
}
|
||||
|
@ -393,7 +393,10 @@ fn render_builtin_attr(db: &RootDatabase, attr: hir::BuiltinAttr) -> Option<Mark
|
||||
let name = attr.name(db);
|
||||
let desc = format!("#[{}]", name);
|
||||
|
||||
let AttributeTemplate { word, list, name_value_str } = attr.template(db);
|
||||
let AttributeTemplate { word, list, name_value_str } = match attr.template(db) {
|
||||
Some(template) => template,
|
||||
None => return Some(Markup::fenced_block(&attr.name(db))),
|
||||
};
|
||||
let mut docs = "Valid forms are:".to_owned();
|
||||
if word {
|
||||
format_to!(docs, "\n - #\\[{}]", name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user