mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Remove code duplication in highlight injection
This commit is contained in:
parent
5dd6b93138
commit
6b8358d4d9
2 changed files with 35 additions and 60 deletions
|
@ -98,6 +98,29 @@ pub(crate) fn remove_links(markdown: &str) -> String {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve a link to documentation for the given symbol.
|
||||||
|
pub(crate) fn external_docs(
|
||||||
|
db: &RootDatabase,
|
||||||
|
position: &FilePosition,
|
||||||
|
) -> Option<DocumentationLink> {
|
||||||
|
let sema = Semantics::new(db);
|
||||||
|
let file = sema.parse(position.file_id).syntax().clone();
|
||||||
|
let token = pick_best(file.token_at_offset(position.offset))?;
|
||||||
|
let token = sema.descend_into_macros(token);
|
||||||
|
|
||||||
|
let node = token.parent()?;
|
||||||
|
let definition = match_ast! {
|
||||||
|
match node {
|
||||||
|
ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)),
|
||||||
|
ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined(sema.db)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
get_doc_link(db, definition?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts all links from a given markdown text.
|
||||||
pub(crate) fn extract_definitions_from_markdown(
|
pub(crate) fn extract_definitions_from_markdown(
|
||||||
markdown: &str,
|
markdown: &str,
|
||||||
) -> Vec<(Range<usize>, String, Option<hir::Namespace>)> {
|
) -> Vec<(Range<usize>, String, Option<hir::Namespace>)> {
|
||||||
|
@ -178,15 +201,15 @@ pub(crate) fn resolve_doc_path_for_def(
|
||||||
) -> Option<hir::ModuleDef> {
|
) -> Option<hir::ModuleDef> {
|
||||||
match def {
|
match def {
|
||||||
Definition::ModuleDef(def) => match def {
|
Definition::ModuleDef(def) => match def {
|
||||||
ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns),
|
hir::ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
ModuleDef::Function(it) => it.resolve_doc_path(db, &link, ns),
|
hir::ModuleDef::Function(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
ModuleDef::Adt(it) => it.resolve_doc_path(db, &link, ns),
|
hir::ModuleDef::Adt(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
ModuleDef::Variant(it) => it.resolve_doc_path(db, &link, ns),
|
hir::ModuleDef::Variant(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
ModuleDef::Const(it) => it.resolve_doc_path(db, &link, ns),
|
hir::ModuleDef::Const(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
ModuleDef::Static(it) => it.resolve_doc_path(db, &link, ns),
|
hir::ModuleDef::Static(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
ModuleDef::Trait(it) => it.resolve_doc_path(db, &link, ns),
|
hir::ModuleDef::Trait(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, &link, ns),
|
hir::ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
ModuleDef::BuiltinType(_) => None,
|
hir::ModuleDef::BuiltinType(_) => None,
|
||||||
},
|
},
|
||||||
Definition::Macro(it) => it.resolve_doc_path(db, &link, ns),
|
Definition::Macro(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
Definition::Field(it) => it.resolve_doc_path(db, &link, ns),
|
Definition::Field(it) => it.resolve_doc_path(db, &link, ns),
|
||||||
|
@ -328,28 +351,6 @@ fn rewrite_url_link(db: &RootDatabase, def: ModuleDef, target: &str) -> Option<S
|
||||||
.map(|url| url.into_string())
|
.map(|url| url.into_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a link to documentation for the given symbol.
|
|
||||||
pub(crate) fn external_docs(
|
|
||||||
db: &RootDatabase,
|
|
||||||
position: &FilePosition,
|
|
||||||
) -> Option<DocumentationLink> {
|
|
||||||
let sema = Semantics::new(db);
|
|
||||||
let file = sema.parse(position.file_id).syntax().clone();
|
|
||||||
let token = pick_best(file.token_at_offset(position.offset))?;
|
|
||||||
let token = sema.descend_into_macros(token);
|
|
||||||
|
|
||||||
let node = token.parent()?;
|
|
||||||
let definition = match_ast! {
|
|
||||||
match node {
|
|
||||||
ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)),
|
|
||||||
ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined(sema.db)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
get_doc_link(db, definition?)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Rewrites a markdown document, applying 'callback' to each link.
|
/// Rewrites a markdown document, applying 'callback' to each link.
|
||||||
fn map_links<'e>(
|
fn map_links<'e>(
|
||||||
events: impl Iterator<Item = Event<'e>>,
|
events: impl Iterator<Item = Event<'e>>,
|
||||||
|
|
|
@ -11,7 +11,8 @@ use syntax::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
doc_links::extract_definitions_from_markdown, Analysis, HlMod, HlRange, HlTag, RootDatabase,
|
doc_links::{extract_definitions_from_markdown, resolve_doc_path_for_def},
|
||||||
|
Analysis, HlMod, HlRange, HlTag, RootDatabase,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{highlights::Highlights, injector::Injector};
|
use super::{highlights::Highlights, injector::Injector};
|
||||||
|
@ -190,7 +191,7 @@ pub(super) fn doc_comment(
|
||||||
extract_definitions_from_markdown(line)
|
extract_definitions_from_markdown(line)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(range, link, ns)| {
|
.filter_map(|(range, link, ns)| {
|
||||||
Some(range).zip(validate_intra_doc_link(sema.db, &def, &link, ns))
|
Some(range).zip(resolve_doc_path_for_def(sema.db, def, &link, ns))
|
||||||
})
|
})
|
||||||
.map(|(Range { start, end }, def)| {
|
.map(|(Range { start, end }, def)| {
|
||||||
(
|
(
|
||||||
|
@ -283,33 +284,6 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::Stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_intra_doc_link(
|
|
||||||
db: &RootDatabase,
|
|
||||||
def: &Definition,
|
|
||||||
link: &str,
|
|
||||||
ns: Option<hir::Namespace>,
|
|
||||||
) -> Option<hir::ModuleDef> {
|
|
||||||
match def {
|
|
||||||
Definition::ModuleDef(def) => match def {
|
|
||||||
hir::ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
hir::ModuleDef::Function(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
hir::ModuleDef::Adt(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
hir::ModuleDef::Variant(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
hir::ModuleDef::Const(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
hir::ModuleDef::Static(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
hir::ModuleDef::Trait(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
hir::ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
hir::ModuleDef::BuiltinType(_) => None,
|
|
||||||
},
|
|
||||||
Definition::Macro(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
Definition::Field(it) => it.resolve_doc_path(db, &link, ns),
|
|
||||||
Definition::SelfType(_)
|
|
||||||
| Definition::Local(_)
|
|
||||||
| Definition::GenericParam(_)
|
|
||||||
| Definition::Label(_) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn module_def_to_hl_tag(def: hir::ModuleDef) -> HlTag {
|
fn module_def_to_hl_tag(def: hir::ModuleDef) -> HlTag {
|
||||||
let symbol = match def {
|
let symbol = match def {
|
||||||
hir::ModuleDef::Module(_) => SymbolKind::Module,
|
hir::ModuleDef::Module(_) => SymbolKind::Module,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue