diff options
author | Lukas Wirth <[email protected]> | 2021-03-30 16:20:43 +0100 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-03-30 16:20:43 +0100 |
commit | 9a327311e4a9b9102528751e052c63266c00c6bd (patch) | |
tree | 6cddc362ef8237570c0ce1f8fef73d9dcc9eec8a /crates/ide | |
parent | 9df78ec4a4e41ca94b25f292aba90e266f104f02 (diff) |
Implement basic Documentation source to syntax range mapping
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/goto_definition.rs | 1 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/inject.rs | 55 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html | 10 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 10 |
4 files changed, 42 insertions, 34 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 4e4d1b200..1951c599f 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -32,6 +32,7 @@ pub(crate) fn goto_definition( | |||
32 | let parent = token.parent()?; | 32 | let parent = token.parent()?; |
33 | if let Some(comment) = ast::Comment::cast(token) { | 33 | if let Some(comment) = ast::Comment::cast(token) { |
34 | let docs = doc_owner_to_def(&sema, &parent)?.docs(db)?; | 34 | let docs = doc_owner_to_def(&sema, &parent)?.docs(db)?; |
35 | |||
35 | let (_, link, ns) = extract_positioned_link_from_comment(position.offset, &comment, docs)?; | 36 | let (_, link, ns) = extract_positioned_link_from_comment(position.offset, &comment, docs)?; |
36 | let def = doc_owner_to_def(&sema, &parent)?; | 37 | let def = doc_owner_to_def(&sema, &parent)?; |
37 | let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?; | 38 | let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?; |
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index b62d43256..504783f31 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! "Recursive" Syntax highlighting for code in doctests and fixtures. | 1 | //! "Recursive" Syntax highlighting for code in doctests and fixtures. |
2 | 2 | ||
3 | use std::{mem, ops::Range}; | 3 | use std::mem; |
4 | 4 | ||
5 | use either::Either; | 5 | use either::Either; |
6 | use hir::{HasAttrs, InFile, Semantics}; | 6 | use hir::{HasAttrs, InFile, Semantics}; |
@@ -139,8 +139,28 @@ pub(super) fn doc_comment( | |||
139 | // Replace the original, line-spanning comment ranges by new, only comment-prefix | 139 | // Replace the original, line-spanning comment ranges by new, only comment-prefix |
140 | // spanning comment ranges. | 140 | // spanning comment ranges. |
141 | let mut new_comments = Vec::new(); | 141 | let mut new_comments = Vec::new(); |
142 | let mut intra_doc_links = Vec::new(); | ||
143 | let mut string; | 142 | let mut string; |
143 | |||
144 | if let Some((docs, doc_mapping)) = attributes.docs_with_rangemap(sema.db) { | ||
145 | extract_definitions_from_markdown(docs.as_str()) | ||
146 | .into_iter() | ||
147 | .filter_map(|(range, link, ns)| { | ||
148 | let def = resolve_doc_path_for_def(sema.db, def, &link, ns)?; | ||
149 | let InFile { file_id, value: range } = doc_mapping.map(range)?; | ||
150 | (file_id == node.file_id).then(|| (range, def)) | ||
151 | }) | ||
152 | .for_each(|(range, def)| { | ||
153 | hl.add(HlRange { | ||
154 | range, | ||
155 | highlight: module_def_to_hl_tag(def) | ||
156 | | HlMod::Documentation | ||
157 | | HlMod::Injected | ||
158 | | HlMod::IntraDocLink, | ||
159 | binding_hash: None, | ||
160 | }) | ||
161 | }); | ||
162 | } | ||
163 | |||
144 | for attr in attributes.by_key("doc").attrs() { | 164 | for attr in attributes.by_key("doc").attrs() { |
145 | let InFile { file_id, value: src } = attrs_source_map.source_of(&attr); | 165 | let InFile { file_id, value: src } = attrs_source_map.source_of(&attr); |
146 | if file_id != node.file_id { | 166 | if file_id != node.file_id { |
@@ -186,25 +206,7 @@ pub(super) fn doc_comment( | |||
186 | is_doctest = is_codeblock && is_rust; | 206 | is_doctest = is_codeblock && is_rust; |
187 | continue; | 207 | continue; |
188 | } | 208 | } |
189 | None if !is_doctest => { | 209 | None if !is_doctest => continue, |
190 | intra_doc_links.extend( | ||
191 | extract_definitions_from_markdown(line) | ||
192 | .into_iter() | ||
193 | .filter_map(|(range, link, ns)| { | ||
194 | Some(range).zip(resolve_doc_path_for_def(sema.db, def, &link, ns)) | ||
195 | }) | ||
196 | .map(|(Range { start, end }, def)| { | ||
197 | ( | ||
198 | def, | ||
199 | TextRange::at( | ||
200 | prev_range_start + TextSize::from(start as u32), | ||
201 | TextSize::from((end - start) as u32), | ||
202 | ), | ||
203 | ) | ||
204 | }), | ||
205 | ); | ||
206 | continue; | ||
207 | } | ||
208 | None => (), | 210 | None => (), |
209 | } | 211 | } |
210 | 212 | ||
@@ -223,17 +225,6 @@ pub(super) fn doc_comment( | |||
223 | } | 225 | } |
224 | } | 226 | } |
225 | 227 | ||
226 | for (def, range) in intra_doc_links { | ||
227 | hl.add(HlRange { | ||
228 | range, | ||
229 | highlight: module_def_to_hl_tag(def) | ||
230 | | HlMod::Documentation | ||
231 | | HlMod::Injected | ||
232 | | HlMod::IntraDocLink, | ||
233 | binding_hash: None, | ||
234 | }); | ||
235 | } | ||
236 | |||
237 | if new_comments.is_empty() { | 228 | if new_comments.is_empty() { |
238 | return; // no need to run an analysis on an empty file | 229 | return; // no need to run an analysis on an empty file |
239 | } | 230 | } |
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 045162eb8..b6d1cac4e 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html | |||
@@ -100,10 +100,18 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
100 | <span class="brace">}</span> | 100 | <span class="brace">}</span> |
101 | 101 | ||
102 | <span class="comment documentation">/// </span><span class="struct documentation intra_doc_link injected">[`Foo`](Foo)</span><span class="comment documentation"> is a struct</span> | 102 | <span class="comment documentation">/// </span><span class="struct documentation intra_doc_link injected">[`Foo`](Foo)</span><span class="comment documentation"> is a struct</span> |
103 | <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> | 103 | <span class="comment documentation">/// This function is > </span><span class="function documentation intra_doc_link injected">[`all_the_links`](all_the_links)</span><span class="comment documentation"> <</span> |
104 | <span class="comment documentation">/// [`noop`](noop) is a macro below</span> | 104 | <span class="comment documentation">/// [`noop`](noop) is a macro below</span> |
105 | <span class="comment documentation">/// </span><span class="struct documentation intra_doc_link injected">[`Item`]</span><span class="comment documentation"> is a struct in the module </span><span class="module documentation intra_doc_link injected">[`module`]</span> | ||
106 | <span class="comment documentation">///</span> | ||
107 | <span class="comment documentation">/// [`Item`]: module::Item</span> | ||
108 | <span class="comment documentation">/// [mix_and_match]: ThisShouldntResolve</span> | ||
105 | <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> | 109 | <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> |
106 | 110 | ||
111 | <span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">module</span> <span class="brace">{</span> | ||
112 | <span class="keyword">pub</span> <span class="keyword">struct</span> <span class="struct declaration">Item</span><span class="semicolon">;</span> | ||
113 | <span class="brace">}</span> | ||
114 | |||
107 | <span class="comment documentation">/// ```</span> | 115 | <span class="comment documentation">/// ```</span> |
108 | <span class="comment documentation">/// </span><span class="macro injected">noop!</span><span class="parenthesis injected">(</span><span class="numeric_literal injected">1</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> | 116 | <span class="comment documentation">/// </span><span class="macro injected">noop!</span><span class="parenthesis injected">(</span><span class="numeric_literal injected">1</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
109 | <span class="comment documentation">/// ```</span> | 117 | <span class="comment documentation">/// ```</span> |
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 369ae0972..1b02857ec 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -544,10 +544,18 @@ impl Foo { | |||
544 | } | 544 | } |
545 | 545 | ||
546 | /// [`Foo`](Foo) is a struct | 546 | /// [`Foo`](Foo) is a struct |
547 | /// [`all_the_links`](all_the_links) is this function | 547 | /// This function is > [`all_the_links`](all_the_links) < |
548 | /// [`noop`](noop) is a macro below | 548 | /// [`noop`](noop) is a macro below |
549 | /// [`Item`] is a struct in the module [`module`] | ||
550 | /// | ||
551 | /// [`Item`]: module::Item | ||
552 | /// [mix_and_match]: ThisShouldntResolve | ||
549 | pub fn all_the_links() {} | 553 | pub fn all_the_links() {} |
550 | 554 | ||
555 | pub mod module { | ||
556 | pub struct Item; | ||
557 | } | ||
558 | |||
551 | /// ``` | 559 | /// ``` |
552 | /// noop!(1); | 560 | /// noop!(1); |
553 | /// ``` | 561 | /// ``` |