aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/syntax_highlighting/injection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/syntax_highlighting/injection.rs')
-rw-r--r--crates/ra_ide/src/syntax_highlighting/injection.rs24
1 files changed, 19 insertions, 5 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs
index 3575a0fc6..415f24a6d 100644
--- a/crates/ra_ide/src/syntax_highlighting/injection.rs
+++ b/crates/ra_ide/src/syntax_highlighting/injection.rs
@@ -7,7 +7,10 @@ use hir::Semantics;
7use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; 7use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize};
8use stdx::SepBy; 8use stdx::SepBy;
9 9
10use crate::{call_info::ActiveParameter, Analysis, HighlightTag, HighlightedRange, RootDatabase}; 10use crate::{
11 call_info::ActiveParameter, Analysis, HighlightModifier, HighlightTag, HighlightedRange,
12 RootDatabase,
13};
11 14
12use super::HighlightedRangeStack; 15use super::HighlightedRangeStack;
13 16
@@ -53,6 +56,10 @@ pub(super) fn highlight_injection(
53/// Mapping from extracted documentation code to original code 56/// Mapping from extracted documentation code to original code
54type RangesMap = BTreeMap<TextSize, TextSize>; 57type RangesMap = BTreeMap<TextSize, TextSize>;
55 58
59const RUSTDOC_FENCE: &'static str = "```";
60const RUSTDOC_FENCE_TOKENS: &[&'static str] =
61 &["", "rust", "should_panic", "ignore", "no_run", "compile_fail", "edition2015", "edition2018"];
62
56/// Extracts Rust code from documentation comments as well as a mapping from 63/// Extracts Rust code from documentation comments as well as a mapping from
57/// the extracted source code back to the original source ranges. 64/// the extracted source code back to the original source ranges.
58/// Lastly, a vector of new comment highlight ranges (spanning only the 65/// Lastly, a vector of new comment highlight ranges (spanning only the
@@ -67,6 +74,7 @@ pub(super) fn extract_doc_comments(
67 // Mapping from extracted documentation code to original code 74 // Mapping from extracted documentation code to original code
68 let mut range_mapping: RangesMap = BTreeMap::new(); 75 let mut range_mapping: RangesMap = BTreeMap::new();
69 let mut line_start = TextSize::try_from(prefix.len()).unwrap(); 76 let mut line_start = TextSize::try_from(prefix.len()).unwrap();
77 let mut is_codeblock = false;
70 let mut is_doctest = false; 78 let mut is_doctest = false;
71 // Replace the original, line-spanning comment ranges by new, only comment-prefix 79 // Replace the original, line-spanning comment ranges by new, only comment-prefix
72 // spanning comment ranges. 80 // spanning comment ranges.
@@ -76,8 +84,13 @@ pub(super) fn extract_doc_comments(
76 .filter_map(|el| el.into_token().and_then(ast::Comment::cast)) 84 .filter_map(|el| el.into_token().and_then(ast::Comment::cast))
77 .filter(|comment| comment.kind().doc.is_some()) 85 .filter(|comment| comment.kind().doc.is_some())
78 .filter(|comment| { 86 .filter(|comment| {
79 if comment.text().contains("```") { 87 if let Some(idx) = comment.text().find(RUSTDOC_FENCE) {
80 is_doctest = !is_doctest; 88 is_codeblock = !is_codeblock;
89 // Check whether code is rust by inspecting fence guards
90 let guards = &comment.text()[idx + RUSTDOC_FENCE.len()..];
91 let is_rust =
92 guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim()));
93 is_doctest = is_codeblock && is_rust;
81 false 94 false
82 } else { 95 } else {
83 is_doctest 96 is_doctest
@@ -108,7 +121,7 @@ pub(super) fn extract_doc_comments(
108 range.start(), 121 range.start(),
109 range.start() + TextSize::try_from(pos).unwrap(), 122 range.start() + TextSize::try_from(pos).unwrap(),
110 ), 123 ),
111 highlight: HighlightTag::Comment.into(), 124 highlight: HighlightTag::Comment | HighlightModifier::Documentation,
112 binding_hash: None, 125 binding_hash: None,
113 }); 126 });
114 line_start += range.len() - TextSize::try_from(pos).unwrap(); 127 line_start += range.len() - TextSize::try_from(pos).unwrap();
@@ -137,7 +150,7 @@ pub(super) fn highlight_doc_comment(
137 let (analysis, tmp_file_id) = Analysis::from_single_file(text); 150 let (analysis, tmp_file_id) = Analysis::from_single_file(text);
138 151
139 stack.push(); 152 stack.push();
140 for mut h in analysis.highlight(tmp_file_id).unwrap() { 153 for mut h in analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap() {
141 // Determine start offset and end offset in case of multi-line ranges 154 // Determine start offset and end offset in case of multi-line ranges
142 let mut start_offset = None; 155 let mut start_offset = None;
143 let mut end_offset = None; 156 let mut end_offset = None;
@@ -154,6 +167,7 @@ pub(super) fn highlight_doc_comment(
154 h.range.start() + start_offset, 167 h.range.start() + start_offset,
155 h.range.end() + end_offset.unwrap_or(start_offset), 168 h.range.end() + end_offset.unwrap_or(start_offset),
156 ); 169 );
170
157 stack.add(h); 171 stack.add(h);
158 } 172 }
159 } 173 }