diff options
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/runnables.rs | 70 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 3 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlighting.html | 6 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 6 |
4 files changed, 82 insertions, 3 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index eb82456ad..2bd0e86e5 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -102,6 +102,7 @@ pub(crate) fn runnable( | |||
102 | ) -> Option<Runnable> { | 102 | ) -> Option<Runnable> { |
103 | match_ast! { | 103 | match_ast! { |
104 | match item { | 104 | match item { |
105 | ast::Struct(it) => runnable_struct(sema, it, file_id), | ||
105 | ast::Fn(it) => runnable_fn(sema, it, file_id), | 106 | ast::Fn(it) => runnable_fn(sema, it, file_id), |
106 | ast::Module(it) => runnable_mod(sema, it, file_id), | 107 | ast::Module(it) => runnable_mod(sema, it, file_id), |
107 | _ => None, | 108 | _ => None, |
@@ -182,6 +183,43 @@ fn runnable_fn( | |||
182 | Some(Runnable { nav, kind, cfg }) | 183 | Some(Runnable { nav, kind, cfg }) |
183 | } | 184 | } |
184 | 185 | ||
186 | fn runnable_struct( | ||
187 | sema: &Semantics<RootDatabase>, | ||
188 | struct_def: ast::Struct, | ||
189 | file_id: FileId, | ||
190 | ) -> Option<Runnable> { | ||
191 | if !has_runnable_doc_test(&struct_def) { | ||
192 | return None; | ||
193 | } | ||
194 | let name_string = struct_def.name()?.text().to_string(); | ||
195 | |||
196 | let attrs = | ||
197 | Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &struct_def)); | ||
198 | let cfg = attrs.cfg(); | ||
199 | |||
200 | let test_id = match sema.to_def(&struct_def).map(|def| def.module(sema.db)) { | ||
201 | Some(module) => { | ||
202 | let path_iter = module | ||
203 | .path_to_root(sema.db) | ||
204 | .into_iter() | ||
205 | .rev() | ||
206 | .filter_map(|it| it.name(sema.db)) | ||
207 | .map(|name| name.to_string()); | ||
208 | let path = path_iter.chain(std::iter::once(name_string)).join("::"); | ||
209 | |||
210 | TestId::Path(path) | ||
211 | } | ||
212 | None => TestId::Name(name_string), | ||
213 | }; | ||
214 | |||
215 | let nav = NavigationTarget::from_doc_commented( | ||
216 | sema.db, | ||
217 | InFile::new(file_id.into(), &struct_def), | ||
218 | InFile::new(file_id.into(), &struct_def), | ||
219 | ); | ||
220 | Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg }) | ||
221 | } | ||
222 | |||
185 | #[derive(Debug, Copy, Clone)] | 223 | #[derive(Debug, Copy, Clone)] |
186 | pub struct TestAttr { | 224 | pub struct TestAttr { |
187 | pub ignore: bool, | 225 | pub ignore: bool, |
@@ -215,8 +253,8 @@ const RUSTDOC_FENCE: &str = "```"; | |||
215 | const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] = | 253 | const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] = |
216 | &["", "rust", "should_panic", "edition2015", "edition2018"]; | 254 | &["", "rust", "should_panic", "edition2015", "edition2018"]; |
217 | 255 | ||
218 | fn has_runnable_doc_test(fn_def: &ast::Fn) -> bool { | 256 | fn has_runnable_doc_test(def: &dyn DocCommentsOwner) -> bool { |
219 | fn_def.doc_comment_text().map_or(false, |comments_text| { | 257 | def.doc_comment_text().map_or(false, |comments_text| { |
220 | let mut in_code_block = false; | 258 | let mut in_code_block = false; |
221 | 259 | ||
222 | for line in comments_text.lines() { | 260 | for line in comments_text.lines() { |
@@ -487,8 +525,14 @@ fn should_have_no_runnable_5() {} | |||
487 | /// let z = 55; | 525 | /// let z = 55; |
488 | /// ``` | 526 | /// ``` |
489 | fn should_have_no_runnable_6() {} | 527 | fn should_have_no_runnable_6() {} |
528 | |||
529 | /// ``` | ||
530 | /// let x = 5; | ||
531 | /// ``` | ||
532 | struct StructWithRunnable(String); | ||
533 | |||
490 | "#, | 534 | "#, |
491 | &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST], | 535 | &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST], |
492 | expect![[r#" | 536 | expect![[r#" |
493 | [ | 537 | [ |
494 | Runnable { | 538 | Runnable { |
@@ -569,6 +613,26 @@ fn should_have_no_runnable_6() {} | |||
569 | }, | 613 | }, |
570 | cfg: None, | 614 | cfg: None, |
571 | }, | 615 | }, |
616 | Runnable { | ||
617 | nav: NavigationTarget { | ||
618 | file_id: FileId( | ||
619 | 0, | ||
620 | ), | ||
621 | full_range: 756..821, | ||
622 | focus_range: None, | ||
623 | name: "StructWithRunnable", | ||
624 | kind: STRUCT, | ||
625 | container_name: None, | ||
626 | description: None, | ||
627 | docs: None, | ||
628 | }, | ||
629 | kind: DocTest { | ||
630 | test_id: Path( | ||
631 | "StructWithRunnable", | ||
632 | ), | ||
633 | }, | ||
634 | cfg: None, | ||
635 | }, | ||
572 | ] | 636 | ] |
573 | "#]], | 637 | "#]], |
574 | ); | 638 | ); |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 9f864179e..624a63075 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -562,6 +562,9 @@ fn highlight_element( | |||
562 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { | 562 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { |
563 | HighlightTag::Macro.into() | 563 | HighlightTag::Macro.into() |
564 | } | 564 | } |
565 | T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { | ||
566 | HighlightTag::BuiltinType.into() | ||
567 | } | ||
565 | T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => { | 568 | T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => { |
566 | HighlightTag::Keyword.into() | 569 | HighlightTag::Keyword.into() |
567 | } | 570 | } |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index ee115972b..5eb222ee2 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -110,6 +110,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
110 | <span class="function">foo</span><span class="operator">::</span><span class="punctuation"><</span><span class="lifetime">'a</span><span class="punctuation">,</span> <span class="builtin_type">i32</span><span class="punctuation">></span><span class="punctuation">(</span><span class="punctuation">)</span> | 110 | <span class="function">foo</span><span class="operator">::</span><span class="punctuation"><</span><span class="lifetime">'a</span><span class="punctuation">,</span> <span class="builtin_type">i32</span><span class="punctuation">></span><span class="punctuation">(</span><span class="punctuation">)</span> |
111 | <span class="punctuation">}</span> | 111 | <span class="punctuation">}</span> |
112 | 112 | ||
113 | <span class="keyword">fn</span> <span class="function declaration">never</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">!</span> <span class="punctuation">{</span> | ||
114 | <span class="keyword control">loop</span> <span class="punctuation">{</span><span class="punctuation">}</span> | ||
115 | <span class="punctuation">}</span> | ||
116 | |||
113 | <span class="keyword">use</span> <span class="module">ops</span><span class="operator">::</span><span class="trait">Fn</span><span class="punctuation">;</span> | 117 | <span class="keyword">use</span> <span class="module">ops</span><span class="operator">::</span><span class="trait">Fn</span><span class="punctuation">;</span> |
114 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation"><</span><span class="type_param declaration">F</span><span class="punctuation">:</span> <span class="trait">Fn</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">></span><span class="punctuation">(</span><span class="value_param declaration callable">f</span><span class="punctuation">:</span> <span class="type_param">F</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 118 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation"><</span><span class="type_param declaration">F</span><span class="punctuation">:</span> <span class="trait">Fn</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">></span><span class="punctuation">(</span><span class="value_param declaration callable">f</span><span class="punctuation">:</span> <span class="type_param">F</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
115 | <span class="value_param callable">f</span><span class="punctuation">(</span><span class="punctuation">)</span> | 119 | <span class="value_param callable">f</span><span class="punctuation">(</span><span class="punctuation">)</span> |
@@ -185,6 +189,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
185 | 189 | ||
186 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="punctuation">;</span> | 190 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="punctuation">;</span> |
187 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="punctuation">;</span> | 191 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="punctuation">;</span> |
192 | |||
193 | <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="operator">!</span><span class="bool_literal">true</span><span class="punctuation">;</span> | ||
188 | <span class="punctuation">}</span> | 194 | <span class="punctuation">}</span> |
189 | 195 | ||
190 | <span class="keyword">enum</span> <span class="enum declaration">Option</span><span class="punctuation"><</span><span class="type_param declaration">T</span><span class="punctuation">></span> <span class="punctuation">{</span> | 196 | <span class="keyword">enum</span> <span class="enum declaration">Option</span><span class="punctuation"><</span><span class="type_param declaration">T</span><span class="punctuation">></span> <span class="punctuation">{</span> |
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 5ea712cf5..2b667b0d4 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -84,6 +84,10 @@ fn foo<'a, T>() -> T { | |||
84 | foo::<'a, i32>() | 84 | foo::<'a, i32>() |
85 | } | 85 | } |
86 | 86 | ||
87 | fn never() -> ! { | ||
88 | loop {} | ||
89 | } | ||
90 | |||
87 | use ops::Fn; | 91 | use ops::Fn; |
88 | fn baz<F: Fn() -> ()>(f: F) { | 92 | fn baz<F: Fn() -> ()>(f: F) { |
89 | f() | 93 | f() |
@@ -159,6 +163,8 @@ fn main() { | |||
159 | 163 | ||
160 | let baz = -42; | 164 | let baz = -42; |
161 | let baz = -baz; | 165 | let baz = -baz; |
166 | |||
167 | let _ = !true; | ||
162 | } | 168 | } |
163 | 169 | ||
164 | enum Option<T> { | 170 | enum Option<T> { |