Unnamed repository; edit this file 'description' to name the repository.
Simplify
Lukas Wirth 2023-09-02
parent b157552 · commit 8eddc64
-rw-r--r--crates/hir/src/attrs.rs96
-rw-r--r--crates/hir/src/lib.rs9
-rw-r--r--crates/ide-db/src/documentation.rs204
-rw-r--r--crates/ide/src/doc_links.rs2
-rw-r--r--crates/ide/src/hover/render.rs2
5 files changed, 157 insertions, 156 deletions
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 2e3c46fdd4..796490abd7 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -6,33 +6,22 @@ use hir_def::{
path::{ModPath, Path},
per_ns::Namespace,
resolver::{HasResolver, Resolver, TypeNs},
- AssocItemId, AttrDefId, GenericParamId, ModuleDefId,
+ AssocItemId, AttrDefId, ModuleDefId,
};
use hir_expand::{hygiene::Hygiene, name::Name};
use hir_ty::db::HirDatabase;
use syntax::{ast, AstNode};
use crate::{
- Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, Enum, ExternCrateDecl, Field,
- Function, GenericParam, Impl, LifetimeParam, Macro, Module, ModuleDef, Static, Struct, Trait,
- TraitAlias, TypeAlias, TypeParam, Union, Variant, VariantDef,
+ Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl,
+ Field, Function, GenericParam, Impl, LifetimeParam, Macro, Module, ModuleDef, Static, Struct,
+ Trait, TraitAlias, TypeAlias, TypeParam, Union, Variant, VariantDef,
};
pub trait HasAttrs {
fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner;
- fn resolve_doc_path(
- self,
- db: &dyn HirDatabase,
- link: &str,
- ns: Option<Namespace>,
- ) -> Option<DocLinkDef>;
-}
-
-/// Subset of `ide_db::Definition` that doc links can resolve to.
-pub enum DocLinkDef {
- ModuleDef(ModuleDef),
- Field(Field),
- SelfType(Trait),
+ #[doc(hidden)]
+ fn attr_id(self) -> AttrDefId;
}
macro_rules! impl_has_attrs {
@@ -42,14 +31,8 @@ macro_rules! impl_has_attrs {
let def = AttrDefId::$def_id(self.into());
db.attrs_with_owner(def)
}
- fn resolve_doc_path(
- self,
- db: &dyn HirDatabase,
- link: &str,
- ns: Option<Namespace>
- ) -> Option<DocLinkDef> {
- let def = AttrDefId::$def_id(self.into());
- resolve_doc_path(db, def, link, ns)
+ fn attr_id(self) -> AttrDefId {
+ AttrDefId::$def_id(self.into())
}
}
)*};
@@ -69,6 +52,7 @@ impl_has_attrs![
(Module, ModuleId),
(GenericParam, GenericParamId),
(Impl, ImplId),
+ (ExternCrateDecl, ExternCrateId),
];
macro_rules! impl_has_attrs_enum {
@@ -77,13 +61,8 @@ macro_rules! impl_has_attrs_enum {
fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner {
$enum::$variant(self).attrs(db)
}
- fn resolve_doc_path(
- self,
- db: &dyn HirDatabase,
- link: &str,
- ns: Option<Namespace>
- ) -> Option<DocLinkDef> {
- $enum::$variant(self).resolve_doc_path(db, link, ns)
+ fn attr_id(self) -> AttrDefId {
+ $enum::$variant(self).attr_id()
}
}
)*};
@@ -100,45 +79,35 @@ impl HasAttrs for AssocItem {
AssocItem::TypeAlias(it) => it.attrs(db),
}
}
-
- fn resolve_doc_path(
- self,
- db: &dyn HirDatabase,
- link: &str,
- ns: Option<Namespace>,
- ) -> Option<DocLinkDef> {
+ fn attr_id(self) -> AttrDefId {
match self {
- AssocItem::Function(it) => it.resolve_doc_path(db, link, ns),
- AssocItem::Const(it) => it.resolve_doc_path(db, link, ns),
- AssocItem::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
+ AssocItem::Function(it) => it.attr_id(),
+ AssocItem::Const(it) => it.attr_id(),
+ AssocItem::TypeAlias(it) => it.attr_id(),
}
}
}
-impl HasAttrs for ExternCrateDecl {
- fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner {
- let def = AttrDefId::ExternCrateId(self.into());
- db.attrs_with_owner(def)
- }
- fn resolve_doc_path(
- self,
- db: &dyn HirDatabase,
- link: &str,
- ns: Option<Namespace>,
- ) -> Option<DocLinkDef> {
- let def = AttrDefId::ExternCrateId(self.into());
- resolve_doc_path(db, def, link, ns)
- }
+/// Resolves the item `link` points to in the scope of `def`.
+pub fn resolve_doc_path_on(
+ db: &dyn HirDatabase,
+ def: impl HasAttrs,
+ link: &str,
+ ns: Option<Namespace>,
+) -> Option<DocLinkDef> {
+ // AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
+ // AttrDefId::EnumVariantId(it) => it.parent.resolver(db.upcast()),
+
+ resolve_doc_path_on_(db, link, def.attr_id(), ns)
}
-/// Resolves the item `link` points to in the scope of `def`.
-fn resolve_doc_path(
+fn resolve_doc_path_on_(
db: &dyn HirDatabase,
- def: AttrDefId,
link: &str,
+ attr_id: AttrDefId,
ns: Option<Namespace>,
) -> Option<DocLinkDef> {
- let resolver = match def {
+ let resolver = match attr_id {
AttrDefId::ModuleId(it) => it.resolver(db.upcast()),
AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
AttrDefId::AdtId(it) => it.resolver(db.upcast()),
@@ -154,12 +123,7 @@ fn resolve_doc_path(
AttrDefId::UseId(it) => it.resolver(db.upcast()),
AttrDefId::MacroId(it) => it.resolver(db.upcast()),
AttrDefId::ExternCrateId(it) => it.resolver(db.upcast()),
- AttrDefId::GenericParamId(it) => match it {
- GenericParamId::TypeParamId(it) => it.parent(),
- GenericParamId::ConstParamId(it) => it.parent(),
- GenericParamId::LifetimeParamId(it) => it.parent,
- }
- .resolver(db.upcast()),
+ AttrDefId::GenericParamId(_) => return None,
};
let mut modpath = modpath_from_str(db, link)?;
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4123b235a7..91443238c6 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -88,7 +88,7 @@ use triomphe::Arc;
use crate::db::{DefDatabase, HirDatabase};
pub use crate::{
- attrs::{DocLinkDef, HasAttrs},
+ attrs::{resolve_doc_path_on, HasAttrs},
diagnostics::{
AnyDiagnostic, BreakOutsideOfLoop, CaseType, ExpectedFunction, InactiveCode,
IncoherentImpl, IncorrectCase, InvalidDeriveTarget, MacroDefError, MacroError,
@@ -4839,3 +4839,10 @@ pub enum ItemContainer {
ExternBlock(),
Crate(CrateId),
}
+
+/// Subset of `ide_db::Definition` that doc links can resolve to.
+pub enum DocLinkDef {
+ ModuleDef(ModuleDef),
+ Field(Field),
+ SelfType(Trait),
+}
diff --git a/crates/ide-db/src/documentation.rs b/crates/ide-db/src/documentation.rs
index 3e6b1cbc36..aa8a374218 100644
--- a/crates/ide-db/src/documentation.rs
+++ b/crates/ide-db/src/documentation.rs
@@ -1,7 +1,7 @@
use either::Either;
use hir::{
db::{DefDatabase, HirDatabase},
- AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile,
+ resolve_doc_path_on, AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile,
};
use itertools::Itertools;
use syntax::{
@@ -32,77 +32,13 @@ impl From<Documentation> for String {
pub trait HasDocs: HasAttrs {
fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>;
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>,
+ ) -> Option<hir::DocLinkDef>;
}
-
-macro_rules! impl_has_docs {
- ($($def:ident,)*) => {$(
- impl HasDocs for hir::$def {
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
- docs_from_attrs(&self.attrs(db)).map(Documentation)
- }
- }
- )*};
-}
-
-impl_has_docs![
- Field,
- Variant,
- Static,
- Const,
- Trait,
- TraitAlias,
- TypeAlias,
- Macro,
- Function,
- Adt,
- Module,
- GenericParam,
- Impl,
-];
-
-macro_rules! impl_has_docs_enum {
- ($($variant:ident),* for $enum:ident) => {$(
- impl HasDocs for hir::$variant {
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
- hir::$enum::$variant(self).docs(db)
- }
- }
- )*};
-}
-
-impl_has_docs_enum![Struct, Union, Enum for Adt];
-impl_has_docs_enum![TypeParam, ConstParam, LifetimeParam for GenericParam];
-
-impl HasDocs for hir::AssocItem {
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
- match self {
- hir::AssocItem::Function(it) => it.docs(db),
- hir::AssocItem::Const(it) => it.docs(db),
- hir::AssocItem::TypeAlias(it) => it.docs(db),
- }
- }
-}
-
-impl HasDocs for hir::ExternCrateDecl {
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
- let crate_docs =
- docs_from_attrs(&self.resolved_crate(db)?.root_module().attrs(db)).map(String::from);
- let decl_docs = docs_from_attrs(&self.attrs(db)).map(String::from);
- match (decl_docs, crate_docs) {
- (None, None) => None,
- (Some(decl_docs), None) => Some(decl_docs),
- (None, Some(crate_docs)) => Some(crate_docs),
- (Some(mut decl_docs), Some(crate_docs)) => {
- decl_docs.push('\n');
- decl_docs.push('\n');
- decl_docs += &crate_docs;
- Some(decl_docs)
- }
- }
- .map(Documentation::new)
- }
-}
-
/// A struct to map text ranges from [`Documentation`] back to TextRanges in the syntax tree.
#[derive(Debug)]
pub struct DocsRangeMap {
@@ -150,22 +86,6 @@ impl DocsRangeMap {
}
}
-fn get_doc_string_in_attr(it: &ast::Attr) -> Option<ast::String> {
- match it.expr() {
- // #[doc = lit]
- Some(ast::Expr::Literal(lit)) => match lit.kind() {
- ast::LiteralKind::String(it) => Some(it),
- _ => None,
- },
- // #[cfg_attr(..., doc = "", ...)]
- None => {
- // FIXME: See highlight injection for what to do here
- None
- }
- _ => None,
- }
-}
-
pub fn docs_with_rangemap(
db: &dyn DefDatabase,
attrs: &AttrsWithOwner,
@@ -237,6 +157,116 @@ pub fn docs_from_attrs(attrs: &hir::Attrs) -> Option<String> {
}
}
+macro_rules! impl_has_docs {
+ ($($def:ident,)*) => {$(
+ impl HasDocs for hir::$def {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
+ docs_from_attrs(&self.attrs(db)).map(Documentation)
+ }
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>
+ ) -> Option<hir::DocLinkDef> {
+ resolve_doc_path_on(db, self, link, ns)
+ }
+ }
+ )*};
+}
+
+impl_has_docs![
+ Variant, Field, Static, Const, Trait, TraitAlias, TypeAlias, Macro, Function, Adt, Module,
+ Impl,
+];
+
+macro_rules! impl_has_docs_enum {
+ ($($variant:ident),* for $enum:ident) => {$(
+ impl HasDocs for hir::$variant {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
+ hir::$enum::$variant(self).docs(db)
+ }
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>
+ ) -> Option<hir::DocLinkDef> {
+ hir::$enum::$variant(self).resolve_doc_path(db, link, ns)
+ }
+ }
+ )*};
+}
+
+impl_has_docs_enum![Struct, Union, Enum for Adt];
+
+impl HasDocs for hir::AssocItem {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
+ match self {
+ hir::AssocItem::Function(it) => it.docs(db),
+ hir::AssocItem::Const(it) => it.docs(db),
+ hir::AssocItem::TypeAlias(it) => it.docs(db),
+ }
+ }
+
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>,
+ ) -> Option<hir::DocLinkDef> {
+ match self {
+ hir::AssocItem::Function(it) => it.resolve_doc_path(db, link, ns),
+ hir::AssocItem::Const(it) => it.resolve_doc_path(db, link, ns),
+ hir::AssocItem::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
+ }
+ }
+}
+
+impl HasDocs for hir::ExternCrateDecl {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
+ let crate_docs =
+ docs_from_attrs(&self.resolved_crate(db)?.root_module().attrs(db)).map(String::from);
+ let decl_docs = docs_from_attrs(&self.attrs(db)).map(String::from);
+ match (decl_docs, crate_docs) {
+ (None, None) => None,
+ (Some(decl_docs), None) => Some(decl_docs),
+ (None, Some(crate_docs)) => Some(crate_docs),
+ (Some(mut decl_docs), Some(crate_docs)) => {
+ decl_docs.push('\n');
+ decl_docs.push('\n');
+ decl_docs += &crate_docs;
+ Some(decl_docs)
+ }
+ }
+ .map(Documentation::new)
+ }
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>,
+ ) -> Option<hir::DocLinkDef> {
+ resolve_doc_path_on(db, self, link, ns)
+ }
+}
+
+fn get_doc_string_in_attr(it: &ast::Attr) -> Option<ast::String> {
+ match it.expr() {
+ // #[doc = lit]
+ Some(ast::Expr::Literal(lit)) => match lit.kind() {
+ ast::LiteralKind::String(it) => Some(it),
+ _ => None,
+ },
+ // #[cfg_attr(..., doc = "", ...)]
+ None => {
+ // FIXME: See highlight injection for what to do here
+ None
+ }
+ _ => None,
+ }
+}
+
fn doc_indent(attrs: &hir::Attrs) -> usize {
attrs
.by_key("doc")
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index f714bb7d1d..37a1776221 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -16,7 +16,7 @@ use hir::{db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, HasA
use ide_db::{
base_db::{CrateOrigin, LangCrateOrigin, ReleaseChannel, SourceDatabase},
defs::{Definition, NameClass, NameRefClass},
- documentation::{docs_with_rangemap, Documentation},
+ documentation::{docs_with_rangemap, Documentation, HasDocs},
helpers::pick_best_token,
RootDatabase,
};
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index 59423396ce..f72ce37d1d 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -471,7 +471,7 @@ pub(super) fn definition(
Definition::SelfType(impl_def) => {
impl_def.self_ty(db).as_adt().map(|adt| label_and_docs(db, adt))?
}
- Definition::GenericParam(it) => label_and_docs(db, it),
+ Definition::GenericParam(it) => (it.display(db).to_string(), None),
Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db).display(db))),
Definition::ExternCrateDecl(it) => label_and_docs(db, it),
// FIXME: We should be able to show more info about these