Repository: rust-analyzer/rust-analyzer
Pull request #8086 (2021-03-18 14:23:14)

Use a highlight modifier for intra doc links

Veykril: Called the modifier things `IntraDocLink` and the like but maybe dropping the `Intra` to be more general is better for the future?

r? @matklad 

Patch:
diff --git a/crates/ide/src/syntax_highlighting/html.rs b/crates/ide/src/syntax_highlighting/html.rs
index 1d34731ab9..5327af845c 100644
--- a/crates/ide/src/syntax_highlighting/html.rs
+++ b/crates/ide/src/syntax_highlighting/html.rs
@@ -59,7 +59,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index e6dbd307ec..f359eacf2a 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -4,7 +4,7 @@ use std::{mem, ops::Range};
 
 use either::Either;
 use hir::{HasAttrs, InFile, Semantics};
-use ide_db::{call_info::ActiveParameter, defs::Definition};
+use ide_db::{call_info::ActiveParameter, defs::Definition, SymbolKind};
 use syntax::{
     ast::{self, AstNode, AttrsOwner, DocCommentsOwner},
     match_ast, AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize,
@@ -225,13 +225,16 @@ pub(super) fn doc_comment(
                     intra_doc_links.extend(
                         extract_definitions_from_markdown(line)
                             .into_iter()
-                            .filter(|(link, ns, _)| {
-                                validate_intra_doc_link(sema.db, &def, link, *ns)
+                            .filter_map(|(link, ns, range)| {
+                                validate_intra_doc_link(sema.db, &def, &link, ns).zip(Some(range))
                             })
-                            .map(|(.., Range { start, end })| {
-                                TextRange::at(
-                                    prev_range_start + TextSize::from(start as u32),
-                                    TextSize::from((end - start) as u32),
+                            .map(|(def, Range { start, end })| {
+                                (
+                                    def,
+                                    TextRange::at(
+                                        prev_range_start + TextSize::from(start as u32),
+                                        TextSize::from((end - start) as u32),
+                                    ),
                                 )
                             }),
                     );
@@ -255,10 +258,13 @@ pub(super) fn doc_comment(
         }
     }
 
-    for range in intra_doc_links {
+    for (def, range) in intra_doc_links {
         hl.add(HlRange {
             range,
-            highlight: HlTag::IntraDocLink | HlMod::Documentation,
+            highlight: module_def_to_hl_tag(def)
+                | HlMod::Documentation
+                | HlMod::Injected
+                | HlMod::IntraDocLink,
             binding_hash: None,
         });
     }
@@ -317,7 +323,7 @@ fn validate_intra_doc_link(
     def: &Definition,
     link: &str,
     ns: Option<hir::Namespace>,
-) -> bool {
+) -> Option<hir::ModuleDef> {
     match def {
         Definition::ModuleDef(def) => match def {
             hir::ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns),
@@ -337,5 +343,21 @@ fn validate_intra_doc_link(
         | Definition::GenericParam(_)
         | Definition::Label(_) => None,
     }
-    .is_some()
+}
+
+fn module_def_to_hl_tag(def: hir::ModuleDef) -> HlTag {
+    let symbol = match def {
+        hir::ModuleDef::Module(_) => SymbolKind::Module,
+        hir::ModuleDef::Function(_) => SymbolKind::Function,
+        hir::ModuleDef::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct,
+        hir::ModuleDef::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum,
+        hir::ModuleDef::Adt(hir::Adt::Union(_)) => SymbolKind::Union,
+        hir::ModuleDef::Variant(_) => SymbolKind::Variant,
+        hir::ModuleDef::Const(_) => SymbolKind::Const,
+        hir::ModuleDef::Static(_) => SymbolKind::Static,
+        hir::ModuleDef::Trait(_) => SymbolKind::Trait,
+        hir::ModuleDef::TypeAlias(_) => SymbolKind::TypeAlias,
+        hir::ModuleDef::BuiltinType(_) => return HlTag::BuiltinType,
+    };
+    HlTag::Symbol(symbol)
 }
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index ce46e5127a..93db79b895 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -26,7 +26,6 @@ pub enum HlTag {
     Comment,
     EscapeSequence,
     FormatSpecifier,
-    IntraDocLink,
     Keyword,
     NumericLiteral,
     Operator,
@@ -57,6 +56,8 @@ pub enum HlMod {
     Static,
     /// Used for items in impls&traits.
     Associated,
+    /// Used for intra doc links in doc injection.
+    IntraDocLink,
 
     /// Keep this last!
     Unsafe,
@@ -117,7 +118,6 @@ impl HlTag {
             HlTag::Comment => "comment",
             HlTag::EscapeSequence => "escape_sequence",
             HlTag::FormatSpecifier => "format_specifier",
-            HlTag::IntraDocLink => "intra_doc_link",
             HlTag::Keyword => "keyword",
             HlTag::Punctuation(punct) => match punct {
                 HlPunct::Bracket => "bracket",
@@ -151,6 +151,7 @@ impl HlMod {
         HlMod::ControlFlow,
         HlMod::Definition,
         HlMod::Documentation,
+        HlMod::IntraDocLink,
         HlMod::Injected,
         HlMod::Mutable,
         HlMod::Consuming,
@@ -162,17 +163,18 @@ impl HlMod {
 
     fn as_str(self) -> &'static str {
         match self {
+            HlMod::Associated => "associated",
             HlMod::Attribute => "attribute",
+            HlMod::Callable => "callable",
+            HlMod::Consuming => "consuming",
             HlMod::ControlFlow => "control",
             HlMod::Definition => "declaration",
             HlMod::Documentation => "documentation",
             HlMod::Injected => "injected",
+            HlMod::IntraDocLink => "intra_doc_link",
             HlMod::Mutable => "mutable",
-            HlMod::Consuming => "consuming",
-            HlMod::Unsafe => "unsafe",
-            HlMod::Callable => "callable",
             HlMod::Static => "static",
-            HlMod::Associated => "associated",
+            HlMod::Unsafe => "unsafe",
         }
     }
 
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index 0cb7d12a76..a3c5e9ccf4 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -52,7 +52,6 @@ define_semantic_token_types![
     (ESCAPE_SEQUENCE, "escapeSequence"),
     (FORMAT_SPECIFIER, "formatSpecifier"),
     (GENERIC, "generic"),
-    (INTRA_DOC_LINK, "intraDocLink"),
     (LABEL, "label"),
     (LIFETIME, "lifetime"),
     (PARENTHESIS, "parenthesis"),
@@ -90,6 +89,7 @@ define_semantic_token_modifiers![
     (UNSAFE, "unsafe"),
     (ATTRIBUTE_MODIFIER, "attribute"),
     (CALLABLE, "callable"),
+    (INTRA_DOC_LINK, "intraDocLink"),
 ];
 
 #[derive(Default)]
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 70501618e8..1ddea92788 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -443,7 +443,6 @@ fn semantic_token_type_and_modifiers(
         HlTag::Comment => lsp_types::SemanticTokenType::COMMENT,
         HlTag::EscapeSequence => semantic_tokens::ESCAPE_SEQUENCE,
         HlTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER,
-        HlTag::IntraDocLink => semantic_tokens::INTRA_DOC_LINK,
         HlTag::Keyword => lsp_types::SemanticTokenType::KEYWORD,
         HlTag::None => semantic_tokens::GENERIC,
         HlTag::Operator => lsp_types::SemanticTokenType::OPERATOR,
@@ -474,6 +473,7 @@ fn semantic_token_type_and_modifiers(
             HlMod::Unsafe => semantic_tokens::UNSAFE,
             HlMod::Callable => semantic_tokens::CALLABLE,
             HlMod::Static => lsp_types::SemanticTokenModifier::STATIC,
+            HlMod::IntraDocLink => semantic_tokens::INTRA_DOC_LINK,
             HlMod::Associated => continue,
         };
         mods |= modifier;


Test patch:
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
index 60c7518af8..4635ea9276 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index 5d802a6470..045162eb83 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
@@ -99,8 +99,8 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="brace">}</span>
 <span class="brace">}</span>
 
-<span class="comment documentation">/// </span><span class="intra_doc_link documentation">[`Foo`](Foo)</span><span class="comment documentation"> is a struct</span>
-<span class="comment documentation">/// </span><span class="intra_doc_link documentation">[`all_the_links`](all_the_links)</span><span class="comment documentation"> is this function</span>
+<span class="comment documentation">/// </span><span class="struct documentation intra_doc_link injected">[`Foo`](Foo)</span><span class="comment documentation"> is a struct</span>
+<span class="comment documentation">/// </span><span class="function documentation intra_doc_link injected">[`all_the_links`](all_the_links)</span><span class="comment documentation"> is this function</span>
 <span class="comment documentation">/// [`noop`](noop) is a macro below</span>
 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">all_the_links</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
index 4e312765c0..ca9bb1e7d2 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
index 57dfe75096..9215ddd9e3 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index 75dbd0f142..e860d713e0 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
index 423256a202..6a6555208c 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index fffe8c0f57..8b2dd3b70e 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/injection.html b/crates/ide/src/syntax_highlighting/test_data/injection.html
index 34d8deb684..9ab46d05c0 100644
--- a/crates/ide/src/syntax_highlighting/test_data/injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/injection.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html b/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
index d9ca3a4c46..666b0b228d 100644
--- a/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
@@ -7,7 +7,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .label              { color: #DFAF8F; font-style: italic; }
 .comment            { color: #7F9F7F; }
 .documentation      { color: #629755; }
-.intra_doc_link     { color: #A9C577; }
+.intra_doc_link     { font-style: italic; }
 .injected           { opacity: 0.65 ; }
 .struct, .enum      { color: #7CB8BB; }
 .enum_variant       { color: #BDE0F3; }