aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/syntax_highlighting/inject.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/syntax_highlighting/inject.rs')
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs48
1 files changed, 43 insertions, 5 deletions
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index 086db40e5..0f1de4fb8 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -5,7 +5,7 @@ use hir::{HasAttrs, Semantics};
5use ide_db::call_info::ActiveParameter; 5use ide_db::call_info::ActiveParameter;
6use syntax::{ 6use syntax::{
7 ast::{self, AstNode, AttrsOwner, DocCommentsOwner}, 7 ast::{self, AstNode, AttrsOwner, DocCommentsOwner},
8 match_ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize, 8 match_ast, AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize,
9}; 9};
10 10
11use crate::{Analysis, HlMod, HlRange, HlTag, RootDatabase}; 11use crate::{Analysis, HlMod, HlRange, HlTag, RootDatabase};
@@ -153,7 +153,6 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
153 if attributes.docs().map_or(true, |docs| !String::from(docs).contains(RUSTDOC_FENCE)) { 153 if attributes.docs().map_or(true, |docs| !String::from(docs).contains(RUSTDOC_FENCE)) {
154 return; 154 return;
155 } 155 }
156 let doc_comments = attributes.by_key("doc").attrs().map(|attr| attr.to_src(&owner));
157 156
158 let mut inj = Injector::default(); 157 let mut inj = Injector::default();
159 inj.add_unmapped("fn doctest() {\n"); 158 inj.add_unmapped("fn doctest() {\n");
@@ -164,13 +163,28 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
164 // Replace the original, line-spanning comment ranges by new, only comment-prefix 163 // Replace the original, line-spanning comment ranges by new, only comment-prefix
165 // spanning comment ranges. 164 // spanning comment ranges.
166 let mut new_comments = Vec::new(); 165 let mut new_comments = Vec::new();
167 for comment in doc_comments { 166 let mut string;
168 let (line, range, prefix) = match &comment { 167 for attr in attributes.by_key("doc").attrs() {
169 Either::Left(_) => continue, // FIXME 168 let src = attr.to_src(&owner);
169 let (line, range, prefix) = match &src {
170 Either::Left(it) => {
171 string = match find_doc_string_in_attr(attr, it) {
172 Some(it) => it,
173 None => continue,
174 };
175 let text_range = string.syntax().text_range();
176 let text_range = TextRange::new(
177 text_range.start() + TextSize::from(1),
178 text_range.end() - TextSize::from(1),
179 );
180 let text = string.text();
181 (&text[1..text.len() - 1], text_range, "")
182 }
170 Either::Right(comment) => { 183 Either::Right(comment) => {
171 (comment.text(), comment.syntax().text_range(), comment.prefix()) 184 (comment.text(), comment.syntax().text_range(), comment.prefix())
172 } 185 }
173 }; 186 };
187
174 match line.find(RUSTDOC_FENCE) { 188 match line.find(RUSTDOC_FENCE) {
175 Some(idx) => { 189 Some(idx) => {
176 is_codeblock = !is_codeblock; 190 is_codeblock = !is_codeblock;
@@ -222,3 +236,27 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
222 }); 236 });
223 } 237 }
224} 238}
239
240fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::String> {
241 match it.literal() {
242 // #[doc = lit]
243 Some(lit) => match lit.kind() {
244 ast::LiteralKind::String(it) => Some(it),
245 _ => None,
246 },
247 // #[cfg_attr(..., doc = "", ...)]
248 None => {
249 // We gotta hunt the string token manually here
250 let text = attr.string_value()?;
251 // FIXME: We just pick the first string literal that has the same text as the doc attribute
252 // This means technically we might highlight the wrong one
253 it.syntax()
254 .descendants_with_tokens()
255 .filter_map(NodeOrToken::into_token)
256 .filter_map(ast::String::cast)
257 .find(|string| {
258 string.text().get(1..string.text().len() - 1).map_or(false, |it| it == text)
259 })
260 }
261 }
262}