aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/runnables.rs108
1 files changed, 99 insertions, 9 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index dd59d9e70..989a63c09 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -211,12 +211,29 @@ fn has_test_related_attribute(fn_def: &ast::Fn) -> bool {
211 .any(|attribute_text| attribute_text.contains("test")) 211 .any(|attribute_text| attribute_text.contains("test"))
212} 212}
213 213
214const RUSTDOC_FENCE: &str = "```";
215const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] =
216 &["", "rust", "should_panic", "edition2015", "edition2018"];
217
214fn has_runnable_doc_test(fn_def: &ast::Fn) -> bool { 218fn has_runnable_doc_test(fn_def: &ast::Fn) -> bool {
215 fn_def.doc_comment_text().map_or(false, |comments_text| { 219 fn_def.doc_comment_text().map_or(false, |comments_text| {
216 comments_text.contains("```") 220 let mut in_code_block = false;
217 && !comments_text.contains("```ignore") 221
218 && !comments_text.contains("```no_run") 222 for line in comments_text.lines() {
219 && !comments_text.contains("```compile_fail") 223 if let Some(header) = line.strip_prefix(RUSTDOC_FENCE) {
224 in_code_block = !in_code_block;
225
226 if in_code_block
227 && header
228 .split(',')
229 .all(|sub| RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE.contains(&sub.trim()))
230 {
231 return true;
232 }
233 }
234 }
235
236 false
220 }) 237 })
221} 238}
222 239
@@ -421,7 +438,21 @@ fn main() {}
421/// ``` 438/// ```
422/// let x = 5; 439/// let x = 5;
423/// ``` 440/// ```
424fn foo() {} 441fn should_have_runnable() {}
442
443/// ```edition2018
444/// let x = 5;
445/// ```
446fn should_have_runnable_1() {}
447
448/// ```
449/// let z = 55;
450/// ```
451///
452/// ```ignore
453/// let z = 56;
454/// ```
455fn should_have_runnable_2() {}
425 456
426/// ```no_run 457/// ```no_run
427/// let z = 55; 458/// let z = 55;
@@ -437,8 +468,27 @@ fn should_have_no_runnable_2() {}
437/// let z = 55; 468/// let z = 55;
438/// ``` 469/// ```
439fn should_have_no_runnable_3() {} 470fn should_have_no_runnable_3() {}
471
472/// ```text
473/// arbitrary plain text
474/// ```
475fn should_have_no_runnable_4() {}
476
477/// ```text
478/// arbitrary plain text
479/// ```
480///
481/// ```sh
482/// $ shell code
483/// ```
484fn should_have_no_runnable_5() {}
485
486/// ```rust,no_run
487/// let z = 55;
488/// ```
489fn should_have_no_runnable_6() {}
440"#, 490"#,
441 &[&BIN, &DOCTEST], 491 &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST],
442 expect![[r#" 492 expect![[r#"
443 [ 493 [
444 Runnable { 494 Runnable {
@@ -464,9 +514,49 @@ fn should_have_no_runnable_3() {}
464 file_id: FileId( 514 file_id: FileId(
465 1, 515 1,
466 ), 516 ),
467 full_range: 15..57, 517 full_range: 15..74,
468 focus_range: None, 518 focus_range: None,
469 name: "foo", 519 name: "should_have_runnable",
520 kind: FN,
521 container_name: None,
522 description: None,
523 docs: None,
524 },
525 kind: DocTest {
526 test_id: Path(
527 "should_have_runnable",
528 ),
529 },
530 cfg_exprs: [],
531 },
532 Runnable {
533 nav: NavigationTarget {
534 file_id: FileId(
535 1,
536 ),
537 full_range: 76..148,
538 focus_range: None,
539 name: "should_have_runnable_1",
540 kind: FN,
541 container_name: None,
542 description: None,
543 docs: None,
544 },
545 kind: DocTest {
546 test_id: Path(
547 "should_have_runnable_1",
548 ),
549 },
550 cfg_exprs: [],
551 },
552 Runnable {
553 nav: NavigationTarget {
554 file_id: FileId(
555 1,
556 ),
557 full_range: 150..254,
558 focus_range: None,
559 name: "should_have_runnable_2",
470 kind: FN, 560 kind: FN,
471 container_name: None, 561 container_name: None,
472 description: None, 562 description: None,
@@ -474,7 +564,7 @@ fn should_have_no_runnable_3() {}
474 }, 564 },
475 kind: DocTest { 565 kind: DocTest {
476 test_id: Path( 566 test_id: Path(
477 "foo", 567 "should_have_runnable_2",
478 ), 568 ),
479 }, 569 },
480 cfg_exprs: [], 570 cfg_exprs: [],