diff options
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/diagnostics/fixes.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/doc_links.rs | 9 | ||||
-rw-r--r-- | crates/ide/src/file_structure.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 129 | ||||
-rw-r--r-- | crates/ide/src/join_lines.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/lib.rs | 14 | ||||
-rw-r--r-- | crates/ide/src/markdown_remove.rs | 3 | ||||
-rw-r--r-- | crates/ide/src/matching_brace.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/references.rs | 8 | ||||
-rw-r--r-- | crates/ide/src/runnables.rs | 70 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 12 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlighting.html | 12 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 12 |
13 files changed, 245 insertions, 32 deletions
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index 0c950003e..02e17ba43 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs | |||
@@ -25,7 +25,7 @@ use crate::{diagnostics::Fix, references::rename::rename_with_semantics, FilePos | |||
25 | /// A [Diagnostic] that potentially has a fix available. | 25 | /// A [Diagnostic] that potentially has a fix available. |
26 | /// | 26 | /// |
27 | /// [Diagnostic]: hir::diagnostics::Diagnostic | 27 | /// [Diagnostic]: hir::diagnostics::Diagnostic |
28 | pub trait DiagnosticWithFix: Diagnostic { | 28 | pub(crate) trait DiagnosticWithFix: Diagnostic { |
29 | fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix>; | 29 | fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix>; |
30 | } | 30 | } |
31 | 31 | ||
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 250f10f9f..10263537a 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | //! Resolves and rewrites links in markdown documentation. | 1 | //! Resolves and rewrites links in markdown documentation. |
2 | 2 | ||
3 | use std::convert::TryFrom; | 3 | use std::{convert::TryFrom, iter::once}; |
4 | use std::iter::once; | ||
5 | 4 | ||
6 | use itertools::Itertools; | 5 | use itertools::Itertools; |
7 | use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; | 6 | use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; |
@@ -21,10 +20,10 @@ use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, | |||
21 | 20 | ||
22 | use crate::{FilePosition, Semantics}; | 21 | use crate::{FilePosition, Semantics}; |
23 | 22 | ||
24 | pub type DocumentationLink = String; | 23 | pub(crate) type DocumentationLink = String; |
25 | 24 | ||
26 | /// Rewrite documentation links in markdown to point to an online host (e.g. docs.rs) | 25 | /// Rewrite documentation links in markdown to point to an online host (e.g. docs.rs) |
27 | pub fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) -> String { | 26 | pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) -> String { |
28 | let mut cb = |link: BrokenLink| { | 27 | let mut cb = |link: BrokenLink| { |
29 | Some(( | 28 | Some(( |
30 | /*url*/ link.reference.to_owned().into(), | 29 | /*url*/ link.reference.to_owned().into(), |
@@ -63,7 +62,7 @@ pub fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) | |||
63 | } | 62 | } |
64 | 63 | ||
65 | /// Remove all links in markdown documentation. | 64 | /// Remove all links in markdown documentation. |
66 | pub fn remove_links(markdown: &str) -> String { | 65 | pub(crate) fn remove_links(markdown: &str) -> String { |
67 | let mut drop_link = false; | 66 | let mut drop_link = false; |
68 | 67 | ||
69 | let mut opts = Options::empty(); | 68 | let mut opts = Options::empty(); |
diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs index 6168fb837..415795e8c 100644 --- a/crates/ide/src/file_structure.rs +++ b/crates/ide/src/file_structure.rs | |||
@@ -27,7 +27,7 @@ pub struct StructureNode { | |||
27 | // | 27 | // |
28 | // | VS Code | kbd:[Ctrl+Shift+O] | 28 | // | VS Code | kbd:[Ctrl+Shift+O] |
29 | // |=== | 29 | // |=== |
30 | pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { | 30 | pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> { |
31 | let mut res = Vec::new(); | 31 | let mut res = Vec::new(); |
32 | let mut stack = Vec::new(); | 32 | let mut stack = Vec::new(); |
33 | 33 | ||
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 49d8e4ae1..ac704ae21 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use assists::utils::FamousDefs; | 1 | use assists::utils::FamousDefs; |
2 | use either::Either; | 2 | use either::Either; |
3 | use hir::{known, HirDisplay, Semantics}; | 3 | use hir::{known, Callable, HirDisplay, Semantics}; |
4 | use ide_db::RootDatabase; | 4 | use ide_db::RootDatabase; |
5 | use stdx::to_lower_snake_case; | 5 | use stdx::to_lower_snake_case; |
6 | use syntax::{ | 6 | use syntax::{ |
@@ -170,7 +170,7 @@ fn get_param_name_hints( | |||
170 | }; | 170 | }; |
171 | Some((param_name, arg)) | 171 | Some((param_name, arg)) |
172 | }) | 172 | }) |
173 | .filter(|(param_name, arg)| should_show_param_name_hint(sema, &callable, ¶m_name, &arg)) | 173 | .filter(|(param_name, arg)| should_show_param_name_hint(sema, &callable, param_name, &arg)) |
174 | .map(|(param_name, arg)| InlayHint { | 174 | .map(|(param_name, arg)| InlayHint { |
175 | range: arg.syntax().text_range(), | 175 | range: arg.syntax().text_range(), |
176 | kind: InlayKind::ParameterHint, | 176 | kind: InlayKind::ParameterHint, |
@@ -334,9 +334,11 @@ fn should_show_param_name_hint( | |||
334 | | hir::CallableKind::TupleEnumVariant(_) | 334 | | hir::CallableKind::TupleEnumVariant(_) |
335 | | hir::CallableKind::Closure => None, | 335 | | hir::CallableKind::Closure => None, |
336 | }; | 336 | }; |
337 | |||
337 | if param_name.is_empty() | 338 | if param_name.is_empty() |
338 | || Some(param_name) == fn_name.as_ref().map(|s| s.trim_start_matches('_')) | 339 | || Some(param_name) == fn_name.as_ref().map(|s| s.trim_start_matches('_')) |
339 | || is_argument_similar_to_param_name(sema, argument, param_name) | 340 | || is_argument_similar_to_param_name(sema, argument, param_name) |
341 | || is_param_name_similar_to_fn_name(param_name, callable, fn_name.as_ref()) | ||
340 | || param_name.starts_with("ra_fixture") | 342 | || param_name.starts_with("ra_fixture") |
341 | { | 343 | { |
342 | return false; | 344 | return false; |
@@ -364,6 +366,26 @@ fn is_argument_similar_to_param_name( | |||
364 | } | 366 | } |
365 | } | 367 | } |
366 | 368 | ||
369 | fn is_param_name_similar_to_fn_name( | ||
370 | param_name: &str, | ||
371 | callable: &Callable, | ||
372 | fn_name: Option<&String>, | ||
373 | ) -> bool { | ||
374 | // if it's the only parameter, don't show it if: | ||
375 | // - is the same as the function name, or | ||
376 | // - the function ends with '_' + param_name | ||
377 | |||
378 | match (callable.n_params(), fn_name) { | ||
379 | (1, Some(function)) => { | ||
380 | function == param_name | ||
381 | || (function.len() > param_name.len() | ||
382 | && function.ends_with(param_name) | ||
383 | && function[..function.len() - param_name.len()].ends_with('_')) | ||
384 | } | ||
385 | _ => false, | ||
386 | } | ||
387 | } | ||
388 | |||
367 | fn is_enum_name_similar_to_param_name( | 389 | fn is_enum_name_similar_to_param_name( |
368 | sema: &Semantics<RootDatabase>, | 390 | sema: &Semantics<RootDatabase>, |
369 | argument: &ast::Expr, | 391 | argument: &ast::Expr, |
@@ -457,6 +479,88 @@ fn main() { | |||
457 | } | 479 | } |
458 | 480 | ||
459 | #[test] | 481 | #[test] |
482 | fn param_name_similar_to_fn_name_still_hints() { | ||
483 | check_with_config( | ||
484 | InlayHintsConfig { | ||
485 | parameter_hints: true, | ||
486 | type_hints: false, | ||
487 | chaining_hints: false, | ||
488 | max_length: None, | ||
489 | }, | ||
490 | r#" | ||
491 | fn max(x: i32, y: i32) -> i32 { x + y } | ||
492 | fn main() { | ||
493 | let _x = max( | ||
494 | 4, | ||
495 | //^ x | ||
496 | 4, | ||
497 | //^ y | ||
498 | ); | ||
499 | }"#, | ||
500 | ); | ||
501 | } | ||
502 | |||
503 | #[test] | ||
504 | fn param_name_similar_to_fn_name() { | ||
505 | check_with_config( | ||
506 | InlayHintsConfig { | ||
507 | parameter_hints: true, | ||
508 | type_hints: false, | ||
509 | chaining_hints: false, | ||
510 | max_length: None, | ||
511 | }, | ||
512 | r#" | ||
513 | fn param_with_underscore(with_underscore: i32) -> i32 { with_underscore } | ||
514 | fn main() { | ||
515 | let _x = param_with_underscore( | ||
516 | 4, | ||
517 | ); | ||
518 | }"#, | ||
519 | ); | ||
520 | } | ||
521 | |||
522 | #[test] | ||
523 | fn param_name_same_as_fn_name() { | ||
524 | check_with_config( | ||
525 | InlayHintsConfig { | ||
526 | parameter_hints: true, | ||
527 | type_hints: false, | ||
528 | chaining_hints: false, | ||
529 | max_length: None, | ||
530 | }, | ||
531 | r#" | ||
532 | fn foo(foo: i32) -> i32 { foo } | ||
533 | fn main() { | ||
534 | let _x = foo( | ||
535 | 4, | ||
536 | ); | ||
537 | }"#, | ||
538 | ); | ||
539 | } | ||
540 | |||
541 | #[test] | ||
542 | fn never_hide_param_when_multiple_params() { | ||
543 | check_with_config( | ||
544 | InlayHintsConfig { | ||
545 | parameter_hints: true, | ||
546 | type_hints: false, | ||
547 | chaining_hints: false, | ||
548 | max_length: None, | ||
549 | }, | ||
550 | r#" | ||
551 | fn foo(bar: i32, baz: i32) -> i32 { bar + baz } | ||
552 | fn main() { | ||
553 | let _x = foo( | ||
554 | 4, | ||
555 | //^ bar | ||
556 | 8, | ||
557 | //^ baz | ||
558 | ); | ||
559 | }"#, | ||
560 | ); | ||
561 | } | ||
562 | |||
563 | #[test] | ||
460 | fn hints_disabled() { | 564 | fn hints_disabled() { |
461 | check_with_config( | 565 | check_with_config( |
462 | InlayHintsConfig { | 566 | InlayHintsConfig { |
@@ -1235,4 +1339,25 @@ fn main() { | |||
1235 | "#, | 1339 | "#, |
1236 | ); | 1340 | ); |
1237 | } | 1341 | } |
1342 | |||
1343 | #[test] | ||
1344 | fn infer_call_method_return_associated_types_with_generic() { | ||
1345 | check( | ||
1346 | r#" | ||
1347 | pub trait Default { | ||
1348 | fn default() -> Self; | ||
1349 | } | ||
1350 | pub trait Foo { | ||
1351 | type Bar: Default; | ||
1352 | } | ||
1353 | |||
1354 | pub fn quux<T: Foo>() -> T::Bar { | ||
1355 | let y = Default::default(); | ||
1356 | //^ <T as Foo>::Bar | ||
1357 | |||
1358 | y | ||
1359 | } | ||
1360 | "#, | ||
1361 | ); | ||
1362 | } | ||
1238 | } | 1363 | } |
diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs index e37702acd..b5a6f66fd 100644 --- a/crates/ide/src/join_lines.rs +++ b/crates/ide/src/join_lines.rs | |||
@@ -18,7 +18,7 @@ use text_edit::{TextEdit, TextEditBuilder}; | |||
18 | // | 18 | // |
19 | // | VS Code | **Rust Analyzer: Join lines** | 19 | // | VS Code | **Rust Analyzer: Join lines** |
20 | // |=== | 20 | // |=== |
21 | pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit { | 21 | pub(crate) fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit { |
22 | let range = if range.is_empty() { | 22 | let range = if range.is_empty() { |
23 | let syntax = file.syntax(); | 23 | let syntax = file.syntax(); |
24 | let text = syntax.text().slice(range.start()..); | 24 | let text = syntax.text().slice(range.start()..); |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 4bc733b70..6288f7ea7 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -72,18 +72,20 @@ pub use crate::{ | |||
72 | inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, | 72 | inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, |
73 | markup::Markup, | 73 | markup::Markup, |
74 | prime_caches::PrimeCachesProgress, | 74 | prime_caches::PrimeCachesProgress, |
75 | references::{ | 75 | references::{rename::RenameError, Declaration, ReferenceSearchResult}, |
76 | Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, RenameError, | ||
77 | }, | ||
78 | runnables::{Runnable, RunnableKind, TestId}, | 76 | runnables::{Runnable, RunnableKind, TestId}, |
79 | syntax_highlighting::{ | 77 | syntax_highlighting::{ |
80 | Highlight, HighlightModifier, HighlightModifiers, HighlightTag, HighlightedRange, | 78 | tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag}, |
79 | HighlightedRange, | ||
81 | }, | 80 | }, |
82 | }; | 81 | }; |
83 | pub use completion::{ | 82 | pub use completion::{ |
84 | CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat, | 83 | CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat, |
85 | }; | 84 | }; |
86 | pub use ide_db::call_info::CallInfo; | 85 | pub use ide_db::{ |
86 | call_info::CallInfo, | ||
87 | search::{Reference, ReferenceAccess, ReferenceKind}, | ||
88 | }; | ||
87 | 89 | ||
88 | pub use assists::{ | 90 | pub use assists::{ |
89 | utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist, | 91 | utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist, |
@@ -503,7 +505,7 @@ impl Analysis { | |||
503 | position: FilePosition, | 505 | position: FilePosition, |
504 | new_name: &str, | 506 | new_name: &str, |
505 | ) -> Cancelable<Result<RangeInfo<SourceChange>, RenameError>> { | 507 | ) -> Cancelable<Result<RangeInfo<SourceChange>, RenameError>> { |
506 | self.with_db(|db| references::rename(db, position, new_name)) | 508 | self.with_db(|db| references::rename::rename(db, position, new_name)) |
507 | } | 509 | } |
508 | 510 | ||
509 | pub fn structural_search_replace( | 511 | pub fn structural_search_replace( |
diff --git a/crates/ide/src/markdown_remove.rs b/crates/ide/src/markdown_remove.rs index 02ad39dfb..3ec5c629e 100644 --- a/crates/ide/src/markdown_remove.rs +++ b/crates/ide/src/markdown_remove.rs | |||
@@ -1,11 +1,10 @@ | |||
1 | //! Removes markdown from strings. | 1 | //! Removes markdown from strings. |
2 | |||
3 | use pulldown_cmark::{Event, Parser, Tag}; | 2 | use pulldown_cmark::{Event, Parser, Tag}; |
4 | 3 | ||
5 | /// Removes all markdown, keeping the text and code blocks | 4 | /// Removes all markdown, keeping the text and code blocks |
6 | /// | 5 | /// |
7 | /// Currently limited in styling, i.e. no ascii tables or lists | 6 | /// Currently limited in styling, i.e. no ascii tables or lists |
8 | pub fn remove_markdown(markdown: &str) -> String { | 7 | pub(crate) fn remove_markdown(markdown: &str) -> String { |
9 | let mut out = String::new(); | 8 | let mut out = String::new(); |
10 | let parser = Parser::new(markdown); | 9 | let parser = Parser::new(markdown); |
11 | 10 | ||
diff --git a/crates/ide/src/matching_brace.rs b/crates/ide/src/matching_brace.rs index cb6abb0db..d70248afe 100644 --- a/crates/ide/src/matching_brace.rs +++ b/crates/ide/src/matching_brace.rs | |||
@@ -15,7 +15,7 @@ use test_utils::mark; | |||
15 | // | 15 | // |
16 | // | VS Code | **Rust Analyzer: Find matching brace** | 16 | // | VS Code | **Rust Analyzer: Find matching brace** |
17 | // |=== | 17 | // |=== |
18 | pub fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> { | 18 | pub(crate) fn matching_brace(file: &SourceFile, offset: TextSize) -> Option<TextSize> { |
19 | const BRACES: &[SyntaxKind] = | 19 | const BRACES: &[SyntaxKind] = |
20 | &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>], T![|], T![|]]; | 20 | &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>], T![|], T![|]]; |
21 | let (brace_token, brace_idx) = file | 21 | let (brace_token, brace_idx) = file |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index a517081d5..e05465b32 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -14,7 +14,8 @@ pub(crate) mod rename; | |||
14 | use hir::Semantics; | 14 | use hir::Semantics; |
15 | use ide_db::{ | 15 | use ide_db::{ |
16 | defs::{Definition, NameClass, NameRefClass}, | 16 | defs::{Definition, NameClass, NameRefClass}, |
17 | search::SearchScope, | 17 | search::Reference, |
18 | search::{ReferenceAccess, ReferenceKind, SearchScope}, | ||
18 | RootDatabase, | 19 | RootDatabase, |
19 | }; | 20 | }; |
20 | use syntax::{ | 21 | use syntax::{ |
@@ -25,11 +26,6 @@ use syntax::{ | |||
25 | 26 | ||
26 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; | 27 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; |
27 | 28 | ||
28 | pub(crate) use self::rename::rename; | ||
29 | pub use self::rename::RenameError; | ||
30 | |||
31 | pub use ide_db::search::{Reference, ReferenceAccess, ReferenceKind}; | ||
32 | |||
33 | #[derive(Debug, Clone)] | 29 | #[derive(Debug, Clone)] |
34 | pub struct ReferenceSearchResult { | 30 | pub struct ReferenceSearchResult { |
35 | declaration: Declaration, | 31 | declaration: Declaration, |
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..efcc8ecfe 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -2,7 +2,7 @@ mod format; | |||
2 | mod html; | 2 | mod html; |
3 | mod injection; | 3 | mod injection; |
4 | mod macro_rules; | 4 | mod macro_rules; |
5 | mod tags; | 5 | pub(crate) mod tags; |
6 | #[cfg(test)] | 6 | #[cfg(test)] |
7 | mod tests; | 7 | mod tests; |
8 | 8 | ||
@@ -20,12 +20,13 @@ use syntax::{ | |||
20 | }; | 20 | }; |
21 | 21 | ||
22 | use crate::{ | 22 | use crate::{ |
23 | syntax_highlighting::{format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter}, | 23 | syntax_highlighting::{ |
24 | FileId, | 24 | format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight, |
25 | }, | ||
26 | FileId, HighlightModifier, HighlightTag, | ||
25 | }; | 27 | }; |
26 | 28 | ||
27 | pub(crate) use html::highlight_as_html; | 29 | pub(crate) use html::highlight_as_html; |
28 | pub use tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag}; | ||
29 | 30 | ||
30 | #[derive(Debug, Clone)] | 31 | #[derive(Debug, Clone)] |
31 | pub struct HighlightedRange { | 32 | pub struct HighlightedRange { |
@@ -562,6 +563,9 @@ fn highlight_element( | |||
562 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { | 563 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { |
563 | HighlightTag::Macro.into() | 564 | HighlightTag::Macro.into() |
564 | } | 565 | } |
566 | T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { | ||
567 | HighlightTag::BuiltinType.into() | ||
568 | } | ||
565 | T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => { | 569 | T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => { |
566 | HighlightTag::Keyword.into() | 570 | HighlightTag::Keyword.into() |
567 | } | 571 | } |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index c6b4f5a00..5eb222ee2 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -110,11 +110,21 @@ 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> |
116 | <span class="punctuation">}</span> | 120 | <span class="punctuation">}</span> |
117 | 121 | ||
122 | <span class="keyword">fn</span> <span class="function declaration">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="keyword">impl</span> <span class="unresolved_reference">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span> | ||
123 | |||
124 | <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | ||
125 | <span class="keyword">let</span> <span class="variable declaration">bar</span> <span class="operator">=</span> <span class="function">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | ||
126 | <span class="punctuation">}</span> | ||
127 | |||
118 | <span class="macro">macro_rules!</span> <span class="macro declaration">def_fn</span> <span class="punctuation">{</span> | 128 | <span class="macro">macro_rules!</span> <span class="macro declaration">def_fn</span> <span class="punctuation">{</span> |
119 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>tt<span class="punctuation">:</span>tt<span class="punctuation">)</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="punctuation">$</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">}</span> | 129 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>tt<span class="punctuation">:</span>tt<span class="punctuation">)</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="punctuation">$</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">}</span> |
120 | <span class="punctuation">}</span> | 130 | <span class="punctuation">}</span> |
@@ -179,6 +189,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
179 | 189 | ||
180 | <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> |
181 | <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> | ||
182 | <span class="punctuation">}</span> | 194 | <span class="punctuation">}</span> |
183 | 195 | ||
184 | <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 dd43f9dd9..2b667b0d4 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -84,11 +84,21 @@ 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() |
90 | } | 94 | } |
91 | 95 | ||
96 | fn foobar() -> impl Copy {} | ||
97 | |||
98 | fn foo() { | ||
99 | let bar = foobar(); | ||
100 | } | ||
101 | |||
92 | macro_rules! def_fn { | 102 | macro_rules! def_fn { |
93 | ($($tt:tt)*) => {$($tt)*} | 103 | ($($tt:tt)*) => {$($tt)*} |
94 | } | 104 | } |
@@ -153,6 +163,8 @@ fn main() { | |||
153 | 163 | ||
154 | let baz = -42; | 164 | let baz = -42; |
155 | let baz = -baz; | 165 | let baz = -baz; |
166 | |||
167 | let _ = !true; | ||
156 | } | 168 | } |
157 | 169 | ||
158 | enum Option<T> { | 170 | enum Option<T> { |