Skip to content

Commit e7da581

Browse files
bors[bot]matklad
andauthored
Merge #5895
5895: Tease apart orthogonal concerns in markdown link rewriting r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents 7e012ae + f8a59ad commit e7da581

File tree

9 files changed

+297
-337
lines changed

9 files changed

+297
-337
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/hir/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ rustc-hash = "1.1.0"
1515
either = "1.5.3"
1616
arrayvec = "0.5.1"
1717
itertools = "0.9.0"
18-
url = "2.1.1"
1918

2019
stdx = { path = "../stdx", version = "0.0.0" }
2120
syntax = { path = "../syntax", version = "0.0.0" }

crates/hir/src/attrs.rs

Lines changed: 54 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
//! Attributes & documentation for hir types.
22
use hir_def::{
3-
attr::Attrs,
4-
docs::Documentation,
5-
resolver::{HasResolver, Resolver},
6-
AdtId, AttrDefId, FunctionId, GenericDefId, ModuleId, StaticId, TraitId, VariantId,
3+
attr::Attrs, docs::Documentation, path::ModPath, resolver::HasResolver, AttrDefId, ModuleDefId,
74
};
5+
use hir_expand::hygiene::Hygiene;
86
use hir_ty::db::HirDatabase;
7+
use syntax::ast;
98

109
use crate::{
11-
doc_links::Resolvable, Adt, Const, Enum, EnumVariant, Field, Function, GenericDef, ImplDef,
12-
Local, MacroDef, Module, ModuleDef, Static, Struct, Trait, TypeAlias, TypeParam, Union,
10+
Adt, Const, Enum, EnumVariant, Field, Function, MacroDef, Module, ModuleDef, Static, Struct,
11+
Trait, TypeAlias, Union,
1312
};
1413

1514
pub trait HasAttrs {
1615
fn attrs(self, db: &dyn HirDatabase) -> Attrs;
1716
fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>;
17+
fn resolve_doc_path(
18+
self,
19+
db: &dyn HirDatabase,
20+
link: &str,
21+
ns: Option<Namespace>,
22+
) -> Option<ModuleDef>;
23+
}
24+
25+
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
26+
pub enum Namespace {
27+
Types,
28+
Values,
29+
Macros,
1830
}
1931

2032
macro_rules! impl_has_attrs {
@@ -28,6 +40,10 @@ macro_rules! impl_has_attrs {
2840
let def = AttrDefId::$def_id(self.into());
2941
db.documentation(def)
3042
}
43+
fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
44+
let def = AttrDefId::$def_id(self.into());
45+
resolve_doc_path(db, def, link, ns).map(ModuleDef::from)
46+
}
3147
}
3248
)*};
3349
}
@@ -54,83 +70,42 @@ macro_rules! impl_has_attrs_adt {
5470
fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
5571
Adt::$adt(self).docs(db)
5672
}
73+
fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
74+
Adt::$adt(self).resolve_doc_path(db, link, ns)
75+
}
5776
}
5877
)*};
5978
}
6079

6180
impl_has_attrs_adt![Struct, Union, Enum];
6281

63-
impl Resolvable for ModuleDef {
64-
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
65-
Some(match self {
66-
ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db.upcast()),
67-
ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db.upcast()),
68-
ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db.upcast()),
69-
ModuleDef::EnumVariant(ev) => {
70-
GenericDefId::from(GenericDef::from(ev.clone())).resolver(db.upcast())
71-
}
72-
ModuleDef::Const(c) => {
73-
GenericDefId::from(GenericDef::from(c.clone())).resolver(db.upcast())
74-
}
75-
ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db.upcast()),
76-
ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db.upcast()),
77-
ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db.upcast()),
78-
// FIXME: This should be a resolver relative to `std/core`
79-
ModuleDef::BuiltinType(_t) => None?,
80-
})
81-
}
82-
83-
fn try_into_module_def(self) -> Option<ModuleDef> {
84-
Some(self)
85-
}
86-
}
87-
88-
impl Resolvable for TypeParam {
89-
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
90-
Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
91-
}
92-
93-
fn try_into_module_def(self) -> Option<ModuleDef> {
94-
None
95-
}
96-
}
97-
98-
impl Resolvable for MacroDef {
99-
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
100-
Some(ModuleId::from(self.module(db)?).resolver(db.upcast()))
101-
}
102-
103-
fn try_into_module_def(self) -> Option<ModuleDef> {
104-
None
105-
}
106-
}
107-
108-
impl Resolvable for Field {
109-
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
110-
Some(VariantId::from(self.parent_def(db)).resolver(db.upcast()))
111-
}
112-
113-
fn try_into_module_def(self) -> Option<ModuleDef> {
114-
None
115-
}
116-
}
117-
118-
impl Resolvable for ImplDef {
119-
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
120-
Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
121-
}
122-
123-
fn try_into_module_def(self) -> Option<ModuleDef> {
124-
None
125-
}
126-
}
127-
128-
impl Resolvable for Local {
129-
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
130-
Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
131-
}
132-
133-
fn try_into_module_def(self) -> Option<ModuleDef> {
134-
None
135-
}
82+
fn resolve_doc_path(
83+
db: &dyn HirDatabase,
84+
def: AttrDefId,
85+
link: &str,
86+
ns: Option<Namespace>,
87+
) -> Option<ModuleDefId> {
88+
let resolver = match def {
89+
AttrDefId::ModuleId(it) => it.resolver(db.upcast()),
90+
AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
91+
AttrDefId::AdtId(it) => it.resolver(db.upcast()),
92+
AttrDefId::FunctionId(it) => it.resolver(db.upcast()),
93+
AttrDefId::EnumVariantId(it) => it.parent.resolver(db.upcast()),
94+
AttrDefId::StaticId(it) => it.resolver(db.upcast()),
95+
AttrDefId::ConstId(it) => it.resolver(db.upcast()),
96+
AttrDefId::TraitId(it) => it.resolver(db.upcast()),
97+
AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()),
98+
AttrDefId::ImplId(it) => it.resolver(db.upcast()),
99+
AttrDefId::MacroDefId(_) => return None,
100+
};
101+
let path = ast::Path::parse(link).ok()?;
102+
let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
103+
let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
104+
let def = match ns {
105+
Some(Namespace::Types) => resolved.take_types()?,
106+
Some(Namespace::Values) => resolved.take_values()?,
107+
Some(Namespace::Macros) => return None,
108+
None => resolved.iter_items().find_map(|it| it.as_module_def_id())?,
109+
};
110+
Some(def.into())
136111
}

crates/hir/src/code_model.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,16 @@ impl ModuleDef {
196196
}
197197
}
198198

199+
pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> {
200+
let mut segments = Vec::new();
201+
segments.push(self.name(db)?.to_string());
202+
for m in self.module(db)?.path_to_root(db) {
203+
segments.extend(m.name(db).map(|it| it.to_string()))
204+
}
205+
segments.reverse();
206+
Some(segments.join("::"))
207+
}
208+
199209
pub fn definition_visibility(&self, db: &dyn HirDatabase) -> Option<Visibility> {
200210
let module = match self {
201211
ModuleDef::Module(it) => it.parent(db)?,

0 commit comments

Comments
 (0)