Skip to content

Commit 5c47eb6

Browse files
bors[bot]Veykril
andauthored
Merge #11216
11216: internal: Support registered tools and attributes in ide layer r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents c574cf3 + dc135cc commit 5c47eb6

File tree

4 files changed

+76
-19
lines changed

4 files changed

+76
-19
lines changed

crates/hir/src/lib.rs

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,37 +2064,75 @@ impl Local {
20642064
}
20652065
}
20662066

2067+
// FIXME: Wrong name? This is could also be a registered attribute
20672068
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2068-
pub struct BuiltinAttr(usize);
2069+
pub struct BuiltinAttr {
2070+
krate: Option<CrateId>,
2071+
idx: usize,
2072+
}
20692073

20702074
impl BuiltinAttr {
2071-
pub(crate) fn by_name(name: &str) -> Option<Self> {
2072-
// FIXME: def maps registered attrs?
2073-
hir_def::builtin_attr::find_builtin_attr_idx(name).map(Self)
2075+
// FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs?
2076+
pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
2077+
if let builtin @ Some(_) = Self::builtin(name) {
2078+
return builtin;
2079+
}
2080+
let idx = db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)?;
2081+
Some(BuiltinAttr { krate: Some(krate.id), idx })
2082+
}
2083+
2084+
pub(crate) fn builtin(name: &str) -> Option<Self> {
2085+
hir_def::builtin_attr::INERT_ATTRIBUTES
2086+
.iter()
2087+
.position(|tool| tool.name == name)
2088+
.map(|idx| BuiltinAttr { krate: None, idx })
20742089
}
20752090

2076-
pub fn name(&self, _: &dyn HirDatabase) -> &str {
2091+
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
20772092
// FIXME: Return a `Name` here
2078-
hir_def::builtin_attr::INERT_ATTRIBUTES[self.0].name
2093+
match self.krate {
2094+
Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx].clone(),
2095+
None => SmolStr::new(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].name),
2096+
}
20792097
}
20802098

2081-
pub fn template(&self, _: &dyn HirDatabase) -> AttributeTemplate {
2082-
hir_def::builtin_attr::INERT_ATTRIBUTES[self.0].template
2099+
pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
2100+
match self.krate {
2101+
Some(_) => None,
2102+
None => Some(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].template),
2103+
}
20832104
}
20842105
}
20852106

20862107
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2087-
pub struct ToolModule(usize);
2108+
pub struct ToolModule {
2109+
krate: Option<CrateId>,
2110+
idx: usize,
2111+
}
20882112

20892113
impl ToolModule {
2090-
pub(crate) fn by_name(name: &str) -> Option<Self> {
2091-
// FIXME: def maps registered tools
2092-
hir_def::builtin_attr::TOOL_MODULES.iter().position(|&tool| tool == name).map(Self)
2114+
// FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs?
2115+
pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
2116+
if let builtin @ Some(_) = Self::builtin(name) {
2117+
return builtin;
2118+
}
2119+
let idx = db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)?;
2120+
Some(ToolModule { krate: Some(krate.id), idx })
20932121
}
20942122

2095-
pub fn name(&self, _: &dyn HirDatabase) -> &str {
2123+
pub(crate) fn builtin(name: &str) -> Option<Self> {
2124+
hir_def::builtin_attr::TOOL_MODULES
2125+
.iter()
2126+
.position(|&tool| tool == name)
2127+
.map(|idx| ToolModule { krate: None, idx })
2128+
}
2129+
2130+
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
20962131
// FIXME: Return a `Name` here
2097-
hir_def::builtin_attr::TOOL_MODULES[self.0]
2132+
match self.krate {
2133+
Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx].clone(),
2134+
None => SmolStr::new(hir_def::builtin_attr::TOOL_MODULES[self.idx]),
2135+
}
20982136
}
20992137
}
21002138

crates/hir/src/source_analyzer.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,11 @@ impl SourceAnalyzer {
346346
return match resolve_hir_path_qualifier(db, &self.resolver, &hir_path) {
347347
None if is_path_of_attr => {
348348
path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
349-
ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
349+
match self.resolver.krate() {
350+
Some(krate) => ToolModule::by_name(db, krate.into(), &name_ref.text()),
351+
None => ToolModule::builtin(&name_ref.text()),
352+
}
353+
.map(PathResolution::ToolModule)
350354
})
351355
}
352356
res => res,
@@ -356,8 +360,10 @@ impl SourceAnalyzer {
356360
// in this case we have to check for inert/builtin attributes and tools and prioritize
357361
// resolution of attributes over other namespaces
358362
let name_ref = path.as_single_name_ref();
359-
let builtin =
360-
name_ref.as_ref().map(ast::NameRef::text).as_deref().and_then(BuiltinAttr::by_name);
363+
let builtin = name_ref.as_ref().and_then(|name_ref| match self.resolver.krate() {
364+
Some(krate) => BuiltinAttr::by_name(db, krate.into(), &name_ref.text()),
365+
None => BuiltinAttr::builtin(&name_ref.text()),
366+
});
361367
if let builtin @ Some(_) = builtin {
362368
return builtin.map(PathResolution::BuiltinAttr);
363369
}
@@ -366,7 +372,11 @@ impl SourceAnalyzer {
366372
// this labels any path that starts with a tool module as the tool itself, this is technically wrong
367373
// but there is no benefit in differentiating these two cases for the time being
368374
_ => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
369-
ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
375+
match self.resolver.krate() {
376+
Some(krate) => ToolModule::by_name(db, krate.into(), &name_ref.text()),
377+
None => ToolModule::builtin(&name_ref.text()),
378+
}
379+
.map(PathResolution::ToolModule)
370380
}),
371381
};
372382
}

crates/hir_def/src/nameres.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@ impl DefMap {
296296
pub fn exported_proc_macros(&self) -> impl Iterator<Item = (MacroDefId, Name)> + '_ {
297297
self.exported_proc_macros.iter().map(|(id, def)| (*id, def.name.clone()))
298298
}
299+
pub fn registered_tools(&self) -> &[SmolStr] {
300+
&self.registered_tools
301+
}
302+
pub fn registered_attrs(&self) -> &[SmolStr] {
303+
&self.registered_attrs
304+
}
299305
pub fn root(&self) -> LocalModuleId {
300306
self.root
301307
}

crates/ide/src/hover/render.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,10 @@ fn render_builtin_attr(db: &RootDatabase, attr: hir::BuiltinAttr) -> Option<Mark
393393
let name = attr.name(db);
394394
let desc = format!("#[{}]", name);
395395

396-
let AttributeTemplate { word, list, name_value_str } = attr.template(db);
396+
let AttributeTemplate { word, list, name_value_str } = match attr.template(db) {
397+
Some(template) => template,
398+
None => return Some(Markup::fenced_block(&attr.name(db))),
399+
};
397400
let mut docs = "Valid forms are:".to_owned();
398401
if word {
399402
format_to!(docs, "\n - #\\[{}]", name);

0 commit comments

Comments
 (0)