diff options
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/runnables.rs | 108 |
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 | ||
214 | const RUSTDOC_FENCE: &str = "```"; | ||
215 | const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] = | ||
216 | &["", "rust", "should_panic", "edition2015", "edition2018"]; | ||
217 | |||
214 | fn has_runnable_doc_test(fn_def: &ast::Fn) -> bool { | 218 | fn 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 | /// ``` |
424 | fn foo() {} | 441 | fn should_have_runnable() {} |
442 | |||
443 | /// ```edition2018 | ||
444 | /// let x = 5; | ||
445 | /// ``` | ||
446 | fn should_have_runnable_1() {} | ||
447 | |||
448 | /// ``` | ||
449 | /// let z = 55; | ||
450 | /// ``` | ||
451 | /// | ||
452 | /// ```ignore | ||
453 | /// let z = 56; | ||
454 | /// ``` | ||
455 | fn 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 | /// ``` |
439 | fn should_have_no_runnable_3() {} | 470 | fn should_have_no_runnable_3() {} |
471 | |||
472 | /// ```text | ||
473 | /// arbitrary plain text | ||
474 | /// ``` | ||
475 | fn should_have_no_runnable_4() {} | ||
476 | |||
477 | /// ```text | ||
478 | /// arbitrary plain text | ||
479 | /// ``` | ||
480 | /// | ||
481 | /// ```sh | ||
482 | /// $ shell code | ||
483 | /// ``` | ||
484 | fn should_have_no_runnable_5() {} | ||
485 | |||
486 | /// ```rust,no_run | ||
487 | /// let z = 55; | ||
488 | /// ``` | ||
489 | fn 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: [], |