From 6b8358d4d9317c13593ae15e6065d67eecb85296 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 29 Mar 2021 20:11:28 +0200 Subject: [PATCH] Remove code duplication in highlight injection --- crates/ide/src/doc_links.rs | 63 ++++++++++---------- crates/ide/src/syntax_highlighting/inject.rs | 32 +--------- 2 files changed, 35 insertions(+), 60 deletions(-) diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 9301cdeffe..99276168fb 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -98,6 +98,29 @@ pub(crate) fn remove_links(markdown: &str) -> String { out } +/// Retrieve a link to documentation for the given symbol. +pub(crate) fn external_docs( + db: &RootDatabase, + position: &FilePosition, +) -> Option { + 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( markdown: &str, ) -> Vec<(Range, String, Option)> { @@ -178,15 +201,15 @@ pub(crate) fn resolve_doc_path_for_def( ) -> Option { match def { Definition::ModuleDef(def) => match def { - ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns), - ModuleDef::Function(it) => it.resolve_doc_path(db, &link, ns), - ModuleDef::Adt(it) => it.resolve_doc_path(db, &link, ns), - ModuleDef::Variant(it) => it.resolve_doc_path(db, &link, ns), - ModuleDef::Const(it) => it.resolve_doc_path(db, &link, ns), - ModuleDef::Static(it) => it.resolve_doc_path(db, &link, ns), - ModuleDef::Trait(it) => it.resolve_doc_path(db, &link, ns), - ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, &link, ns), - ModuleDef::BuiltinType(_) => None, + 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), @@ -328,28 +351,6 @@ fn rewrite_url_link(db: &RootDatabase, def: ModuleDef, target: &str) -> Option Option { - 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. fn map_links<'e>( events: impl Iterator>, diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index 963c3fb594..b62d43256c 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs @@ -11,7 +11,8 @@ use syntax::{ }; 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}; @@ -190,7 +191,7 @@ pub(super) fn doc_comment( extract_definitions_from_markdown(line) .into_iter() .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)| { ( @@ -283,33 +284,6 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option, -) -> Option { - 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 { let symbol = match def { hir::ModuleDef::Module(_) => SymbolKind::Module,