diff options
-rw-r--r-- | crates/paths/src/lib.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/_match.rs | 77 | ||||
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs | 23 | ||||
-rw-r--r-- | crates/ra_ide/src/runnables.rs | 18 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlight_doctest.html | 76 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 9 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/injection.rs | 8 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tags.rs | 3 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 10 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 1 | ||||
-rw-r--r-- | crates/stdx/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/vfs/src/file_set.rs | 32 | ||||
-rw-r--r-- | crates/vfs/src/lib.rs | 3 |
16 files changed, 175 insertions, 107 deletions
diff --git a/crates/paths/src/lib.rs b/crates/paths/src/lib.rs index c7ce0c42f..190c50913 100644 --- a/crates/paths/src/lib.rs +++ b/crates/paths/src/lib.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | //! relative paths. | 2 | //! relative paths. |
3 | use std::{ | 3 | use std::{ |
4 | convert::{TryFrom, TryInto}, | 4 | convert::{TryFrom, TryInto}, |
5 | ops, | 5 | io, ops, |
6 | path::{Component, Path, PathBuf}, | 6 | path::{Component, Path, PathBuf}, |
7 | }; | 7 | }; |
8 | 8 | ||
@@ -46,6 +46,9 @@ impl TryFrom<&str> for AbsPathBuf { | |||
46 | } | 46 | } |
47 | 47 | ||
48 | impl AbsPathBuf { | 48 | impl AbsPathBuf { |
49 | pub fn canonicalized(path: &Path) -> io::Result<AbsPathBuf> { | ||
50 | path.canonicalize().map(|it| AbsPathBuf::try_from(it).unwrap()) | ||
51 | } | ||
49 | pub fn as_path(&self) -> &AbsPath { | 52 | pub fn as_path(&self) -> &AbsPath { |
50 | AbsPath::new_unchecked(self.0.as_path()) | 53 | AbsPath::new_unchecked(self.0.as_path()) |
51 | } | 54 | } |
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index b3e5f491a..b8560fdc9 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -119,13 +119,6 @@ impl Default for ModuleOrigin { | |||
119 | } | 119 | } |
120 | 120 | ||
121 | impl ModuleOrigin { | 121 | impl ModuleOrigin { |
122 | pub(crate) fn not_sure_file(file: Option<FileId>, declaration: AstId<ast::Module>) -> Self { | ||
123 | match file { | ||
124 | None => ModuleOrigin::Inline { definition: declaration }, | ||
125 | Some(definition) => ModuleOrigin::File { declaration, definition }, | ||
126 | } | ||
127 | } | ||
128 | |||
129 | fn declaration(&self) -> Option<AstId<ast::Module>> { | 122 | fn declaration(&self) -> Option<AstId<ast::Module>> { |
130 | match self { | 123 | match self { |
131 | ModuleOrigin::File { declaration: module, .. } | 124 | ModuleOrigin::File { declaration: module, .. } |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 976e5e585..77baa4c69 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -825,7 +825,10 @@ impl ModCollector<'_, '_> { | |||
825 | let modules = &mut self.def_collector.def_map.modules; | 825 | let modules = &mut self.def_collector.def_map.modules; |
826 | let res = modules.alloc(ModuleData::default()); | 826 | let res = modules.alloc(ModuleData::default()); |
827 | modules[res].parent = Some(self.module_id); | 827 | modules[res].parent = Some(self.module_id); |
828 | modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration); | 828 | modules[res].origin = match definition { |
829 | None => ModuleOrigin::Inline { definition: declaration }, | ||
830 | Some(definition) => ModuleOrigin::File { declaration, definition }, | ||
831 | }; | ||
829 | for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() { | 832 | for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() { |
830 | modules[res].scope.define_legacy_macro(name, mac) | 833 | modules[res].scope.define_legacy_macro(name, mac) |
831 | } | 834 | } |
diff --git a/crates/ra_hir_ty/src/_match.rs b/crates/ra_hir_ty/src/_match.rs index 02a7a61f1..5495ce284 100644 --- a/crates/ra_hir_ty/src/_match.rs +++ b/crates/ra_hir_ty/src/_match.rs | |||
@@ -312,20 +312,16 @@ impl PatStack { | |||
312 | Self(v) | 312 | Self(v) |
313 | } | 313 | } |
314 | 314 | ||
315 | fn is_empty(&self) -> bool { | ||
316 | self.0.is_empty() | ||
317 | } | ||
318 | |||
319 | fn head(&self) -> PatIdOrWild { | ||
320 | self.0[0] | ||
321 | } | ||
322 | |||
323 | fn get_head(&self) -> Option<PatIdOrWild> { | 315 | fn get_head(&self) -> Option<PatIdOrWild> { |
324 | self.0.first().copied() | 316 | self.0.first().copied() |
325 | } | 317 | } |
326 | 318 | ||
319 | fn tail(&self) -> &[PatIdOrWild] { | ||
320 | self.0.get(1..).unwrap_or(&[]) | ||
321 | } | ||
322 | |||
327 | fn to_tail(&self) -> PatStack { | 323 | fn to_tail(&self) -> PatStack { |
328 | Self::from_slice(&self.0[1..]) | 324 | Self::from_slice(self.tail()) |
329 | } | 325 | } |
330 | 326 | ||
331 | fn replace_head_with<I, T>(&self, pats: I) -> PatStack | 327 | fn replace_head_with<I, T>(&self, pats: I) -> PatStack |
@@ -347,7 +343,7 @@ impl PatStack { | |||
347 | /// | 343 | /// |
348 | /// See the module docs and the associated documentation in rustc for details. | 344 | /// See the module docs and the associated documentation in rustc for details. |
349 | fn specialize_wildcard(&self, cx: &MatchCheckCtx) -> Option<PatStack> { | 345 | fn specialize_wildcard(&self, cx: &MatchCheckCtx) -> Option<PatStack> { |
350 | if matches!(self.head().as_pat(cx), Pat::Wild) { | 346 | if matches!(self.get_head()?.as_pat(cx), Pat::Wild) { |
351 | Some(self.to_tail()) | 347 | Some(self.to_tail()) |
352 | } else { | 348 | } else { |
353 | None | 349 | None |
@@ -362,11 +358,12 @@ impl PatStack { | |||
362 | cx: &MatchCheckCtx, | 358 | cx: &MatchCheckCtx, |
363 | constructor: &Constructor, | 359 | constructor: &Constructor, |
364 | ) -> MatchCheckResult<Option<PatStack>> { | 360 | ) -> MatchCheckResult<Option<PatStack>> { |
365 | if self.is_empty() { | 361 | let head = match self.get_head() { |
366 | return Ok(None); | 362 | Some(head) => head, |
367 | } | 363 | None => return Ok(None), |
364 | }; | ||
368 | 365 | ||
369 | let head_pat = self.head().as_pat(cx); | 366 | let head_pat = head.as_pat(cx); |
370 | let result = match (head_pat, constructor) { | 367 | let result = match (head_pat, constructor) { |
371 | (Pat::Tuple { args: ref pat_ids, ellipsis }, Constructor::Tuple { arity: _ }) => { | 368 | (Pat::Tuple { args: ref pat_ids, ellipsis }, Constructor::Tuple { arity: _ }) => { |
372 | if ellipsis.is_some() { | 369 | if ellipsis.is_some() { |
@@ -394,7 +391,7 @@ impl PatStack { | |||
394 | (Pat::Wild, constructor) => Some(self.expand_wildcard(cx, constructor)?), | 391 | (Pat::Wild, constructor) => Some(self.expand_wildcard(cx, constructor)?), |
395 | (Pat::Path(_), Constructor::Enum(constructor)) => { | 392 | (Pat::Path(_), Constructor::Enum(constructor)) => { |
396 | // unit enum variants become `Pat::Path` | 393 | // unit enum variants become `Pat::Path` |
397 | let pat_id = self.head().as_id().expect("we know this isn't a wild"); | 394 | let pat_id = head.as_id().expect("we know this isn't a wild"); |
398 | if !enum_variant_matches(cx, pat_id, *constructor) { | 395 | if !enum_variant_matches(cx, pat_id, *constructor) { |
399 | None | 396 | None |
400 | } else { | 397 | } else { |
@@ -405,7 +402,7 @@ impl PatStack { | |||
405 | Pat::TupleStruct { args: ref pat_ids, ellipsis, .. }, | 402 | Pat::TupleStruct { args: ref pat_ids, ellipsis, .. }, |
406 | Constructor::Enum(enum_constructor), | 403 | Constructor::Enum(enum_constructor), |
407 | ) => { | 404 | ) => { |
408 | let pat_id = self.head().as_id().expect("we know this isn't a wild"); | 405 | let pat_id = head.as_id().expect("we know this isn't a wild"); |
409 | if !enum_variant_matches(cx, pat_id, *enum_constructor) { | 406 | if !enum_variant_matches(cx, pat_id, *enum_constructor) { |
410 | None | 407 | None |
411 | } else { | 408 | } else { |
@@ -445,7 +442,7 @@ impl PatStack { | |||
445 | } | 442 | } |
446 | } | 443 | } |
447 | (Pat::Record { args: ref arg_patterns, .. }, Constructor::Enum(e)) => { | 444 | (Pat::Record { args: ref arg_patterns, .. }, Constructor::Enum(e)) => { |
448 | let pat_id = self.head().as_id().expect("we know this isn't a wild"); | 445 | let pat_id = head.as_id().expect("we know this isn't a wild"); |
449 | if !enum_variant_matches(cx, pat_id, *e) { | 446 | if !enum_variant_matches(cx, pat_id, *e) { |
450 | None | 447 | None |
451 | } else { | 448 | } else { |
@@ -491,7 +488,7 @@ impl PatStack { | |||
491 | ) -> MatchCheckResult<PatStack> { | 488 | ) -> MatchCheckResult<PatStack> { |
492 | assert_eq!( | 489 | assert_eq!( |
493 | Pat::Wild, | 490 | Pat::Wild, |
494 | self.head().as_pat(cx), | 491 | self.get_head().expect("expand_wildcard called on empty PatStack").as_pat(cx), |
495 | "expand_wildcard must only be called on PatStack with wild at head", | 492 | "expand_wildcard must only be called on PatStack with wild at head", |
496 | ); | 493 | ); |
497 | 494 | ||
@@ -509,7 +506,6 @@ impl PatStack { | |||
509 | } | 506 | } |
510 | } | 507 | } |
511 | 508 | ||
512 | #[derive(Debug)] | ||
513 | /// A collection of PatStack. | 509 | /// A collection of PatStack. |
514 | /// | 510 | /// |
515 | /// This type is modeled from the struct of the same name in `rustc`. | 511 | /// This type is modeled from the struct of the same name in `rustc`. |
@@ -623,13 +619,16 @@ pub(crate) fn is_useful( | |||
623 | _ => (), | 619 | _ => (), |
624 | } | 620 | } |
625 | 621 | ||
626 | if v.is_empty() { | 622 | let head = match v.get_head() { |
627 | let result = if matrix.is_empty() { Usefulness::Useful } else { Usefulness::NotUseful }; | 623 | Some(head) => head, |
624 | None => { | ||
625 | let result = if matrix.is_empty() { Usefulness::Useful } else { Usefulness::NotUseful }; | ||
628 | 626 | ||
629 | return Ok(result); | 627 | return Ok(result); |
630 | } | 628 | } |
629 | }; | ||
631 | 630 | ||
632 | if let Pat::Or(pat_ids) = v.head().as_pat(cx) { | 631 | if let Pat::Or(pat_ids) = head.as_pat(cx) { |
633 | let mut found_unimplemented = false; | 632 | let mut found_unimplemented = false; |
634 | let any_useful = pat_ids.iter().any(|&pat_id| { | 633 | let any_useful = pat_ids.iter().any(|&pat_id| { |
635 | let v = PatStack::from_pattern(pat_id); | 634 | let v = PatStack::from_pattern(pat_id); |
@@ -653,7 +652,7 @@ pub(crate) fn is_useful( | |||
653 | }; | 652 | }; |
654 | } | 653 | } |
655 | 654 | ||
656 | if let Some(constructor) = pat_constructor(cx, v.head())? { | 655 | if let Some(constructor) = pat_constructor(cx, head)? { |
657 | let matrix = matrix.specialize_constructor(&cx, &constructor)?; | 656 | let matrix = matrix.specialize_constructor(&cx, &constructor)?; |
658 | let v = v | 657 | let v = v |
659 | .specialize_constructor(&cx, &constructor)? | 658 | .specialize_constructor(&cx, &constructor)? |
@@ -854,10 +853,10 @@ mod tests { | |||
854 | } | 853 | } |
855 | 854 | ||
856 | pub(super) fn check_no_diagnostic(ra_fixture: &str) { | 855 | pub(super) fn check_no_diagnostic(ra_fixture: &str) { |
857 | let diagnostic_count = | 856 | let (s, diagnostic_count) = |
858 | TestDB::with_single_file(ra_fixture).0.diagnostic::<MissingMatchArms>().1; | 857 | TestDB::with_single_file(ra_fixture).0.diagnostic::<MissingMatchArms>(); |
859 | 858 | ||
860 | assert_eq!(0, diagnostic_count, "expected no diagnostic, found one"); | 859 | assert_eq!(0, diagnostic_count, "expected no diagnostic, found one: {}", s); |
861 | } | 860 | } |
862 | 861 | ||
863 | #[test] | 862 | #[test] |
@@ -2014,6 +2013,28 @@ mod tests { | |||
2014 | ", | 2013 | ", |
2015 | ); | 2014 | ); |
2016 | } | 2015 | } |
2016 | |||
2017 | #[test] | ||
2018 | fn or_pattern_panic_2() { | ||
2019 | // FIXME: This is a false positive, but the code used to cause a panic in the match checker, | ||
2020 | // so this acts as a regression test for that. | ||
2021 | check_diagnostic( | ||
2022 | r" | ||
2023 | pub enum Category { | ||
2024 | Infinity, | ||
2025 | Zero, | ||
2026 | } | ||
2027 | |||
2028 | fn panic(a: Category, b: Category) { | ||
2029 | match (a, b) { | ||
2030 | (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => {} | ||
2031 | |||
2032 | (Category::Infinity | Category::Zero, _) => {} | ||
2033 | } | ||
2034 | } | ||
2035 | ", | ||
2036 | ); | ||
2037 | } | ||
2017 | } | 2038 | } |
2018 | 2039 | ||
2019 | #[cfg(test)] | 2040 | #[cfg(test)] |
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs index c7bb1e69f..0b52b01ab 100644 --- a/crates/ra_ide/src/display/navigation_target.rs +++ b/crates/ra_ide/src/display/navigation_target.rs | |||
@@ -135,8 +135,8 @@ impl NavigationTarget { | |||
135 | db: &RootDatabase, | 135 | db: &RootDatabase, |
136 | node: InFile<&dyn ast::NameOwner>, | 136 | node: InFile<&dyn ast::NameOwner>, |
137 | ) -> NavigationTarget { | 137 | ) -> NavigationTarget { |
138 | //FIXME: use `_` instead of empty string | 138 | let name = |
139 | let name = node.value.name().map(|it| it.text().clone()).unwrap_or_default(); | 139 | node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); |
140 | let focus_range = | 140 | let focus_range = |
141 | node.value.name().map(|it| original_range(db, node.with_value(it.syntax())).range); | 141 | node.value.name().map(|it| original_range(db, node.with_value(it.syntax())).range); |
142 | let frange = original_range(db, node.map(|it| it.syntax())); | 142 | let frange = original_range(db, node.map(|it| it.syntax())); |
@@ -150,6 +150,25 @@ impl NavigationTarget { | |||
150 | ) | 150 | ) |
151 | } | 151 | } |
152 | 152 | ||
153 | /// Allows `NavigationTarget` to be created from a `DocCommentsOwner` and a `NameOwner` | ||
154 | pub(crate) fn from_doc_commented( | ||
155 | db: &RootDatabase, | ||
156 | named: InFile<&dyn ast::NameOwner>, | ||
157 | node: InFile<&dyn ast::DocCommentsOwner>, | ||
158 | ) -> NavigationTarget { | ||
159 | let name = | ||
160 | named.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); | ||
161 | let frange = original_range(db, node.map(|it| it.syntax())); | ||
162 | |||
163 | NavigationTarget::from_syntax( | ||
164 | frange.file_id, | ||
165 | name, | ||
166 | None, | ||
167 | frange.range, | ||
168 | node.value.syntax().kind(), | ||
169 | ) | ||
170 | } | ||
171 | |||
153 | fn from_syntax( | 172 | fn from_syntax( |
154 | file_id: FileId, | 173 | file_id: FileId, |
155 | name: SmolStr, | 174 | name: SmolStr, |
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs index fc57dc33d..8105ef373 100644 --- a/crates/ra_ide/src/runnables.rs +++ b/crates/ra_ide/src/runnables.rs | |||
@@ -171,7 +171,15 @@ fn runnable_fn( | |||
171 | let cfg_exprs = | 171 | let cfg_exprs = |
172 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); | 172 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); |
173 | 173 | ||
174 | let nav = NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &fn_def)); | 174 | let nav = if let RunnableKind::DocTest { .. } = kind { |
175 | NavigationTarget::from_doc_commented( | ||
176 | sema.db, | ||
177 | InFile::new(file_id.into(), &fn_def), | ||
178 | InFile::new(file_id.into(), &fn_def), | ||
179 | ) | ||
180 | } else { | ||
181 | NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &fn_def)) | ||
182 | }; | ||
175 | Some(Runnable { nav, kind, cfg_exprs }) | 183 | Some(Runnable { nav, kind, cfg_exprs }) |
176 | } | 184 | } |
177 | 185 | ||
@@ -419,9 +427,7 @@ mod tests { | |||
419 | full_range: 22..64, | 427 | full_range: 22..64, |
420 | name: "foo", | 428 | name: "foo", |
421 | kind: FN_DEF, | 429 | kind: FN_DEF, |
422 | focus_range: Some( | 430 | focus_range: None, |
423 | 56..59, | ||
424 | ), | ||
425 | container_name: None, | 431 | container_name: None, |
426 | description: None, | 432 | description: None, |
427 | docs: None, | 433 | docs: None, |
@@ -486,9 +492,7 @@ mod tests { | |||
486 | full_range: 51..105, | 492 | full_range: 51..105, |
487 | name: "foo", | 493 | name: "foo", |
488 | kind: FN_DEF, | 494 | kind: FN_DEF, |
489 | focus_range: Some( | 495 | focus_range: None, |
490 | 97..100, | ||
491 | ), | ||
492 | container_name: None, | 496 | container_name: None, |
493 | description: None, | 497 | description: None, |
494 | docs: None, | 498 | docs: None, |
diff --git a/crates/ra_ide/src/snapshots/highlight_doctest.html b/crates/ra_ide/src/snapshots/highlight_doctest.html index f92a0aba5..f61c0daa5 100644 --- a/crates/ra_ide/src/snapshots/highlight_doctest.html +++ b/crates/ra_ide/src/snapshots/highlight_doctest.html | |||
@@ -39,48 +39,48 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
39 | <span class="keyword">impl</span> <span class="struct">Foo</span> { | 39 | <span class="keyword">impl</span> <span class="struct">Foo</span> { |
40 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration">bar</span>: <span class="builtin_type">bool</span> = <span class="bool_literal">true</span>; | 40 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration">bar</span>: <span class="builtin_type">bool</span> = <span class="bool_literal">true</span>; |
41 | 41 | ||
42 | <span class="comment">/// Constructs a new `Foo`.</span> | 42 | <span class="comment documentation">/// Constructs a new `Foo`.</span> |
43 | <span class="comment">///</span> | 43 | <span class="comment documentation">///</span> |
44 | <span class="comment">/// # Examples</span> | 44 | <span class="comment documentation">/// # Examples</span> |
45 | <span class="comment">///</span> | 45 | <span class="comment documentation">///</span> |
46 | <span class="comment">/// ```</span> | 46 | <span class="comment documentation">/// ```</span> |
47 | <span class="comment">/// #</span> <span class="attribute">#![</span><span class="function attribute">allow</span><span class="attribute">(unused_mut)]</span> | 47 | <span class="comment documentation">/// #</span> <span class="attribute">#![</span><span class="function attribute">allow</span><span class="attribute">(unused_mut)]</span> |
48 | <span class="comment">/// </span><span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span>: <span class="struct">Foo</span> = <span class="struct">Foo</span>::<span class="function">new</span>(); | 48 | <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span>: <span class="struct">Foo</span> = <span class="struct">Foo</span>::<span class="function">new</span>(); |
49 | <span class="comment">/// ```</span> | 49 | <span class="comment documentation">/// ```</span> |
50 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration">new</span>() -> <span class="struct">Foo</span> { | 50 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration">new</span>() -> <span class="struct">Foo</span> { |
51 | <span class="struct">Foo</span> { <span class="field">bar</span>: <span class="bool_literal">true</span> } | 51 | <span class="struct">Foo</span> { <span class="field">bar</span>: <span class="bool_literal">true</span> } |
52 | } | 52 | } |
53 | 53 | ||
54 | <span class="comment">/// `bar` method on `Foo`.</span> | 54 | <span class="comment documentation">/// `bar` method on `Foo`.</span> |
55 | <span class="comment">///</span> | 55 | <span class="comment documentation">///</span> |
56 | <span class="comment">/// # Examples</span> | 56 | <span class="comment documentation">/// # Examples</span> |
57 | <span class="comment">///</span> | 57 | <span class="comment documentation">///</span> |
58 | <span class="comment">/// ```</span> | 58 | <span class="comment documentation">/// ```</span> |
59 | <span class="comment">/// </span><span class="keyword">use</span> <span class="module">x</span>::<span class="module">y</span>; | 59 | <span class="comment documentation">/// </span><span class="keyword">use</span> <span class="module">x</span>::<span class="module">y</span>; |
60 | <span class="comment">///</span> | 60 | <span class="comment documentation">///</span> |
61 | <span class="comment">/// </span><span class="keyword">let</span> <span class="variable declaration">foo</span> = <span class="struct">Foo</span>::<span class="function">new</span>(); | 61 | <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="variable declaration">foo</span> = <span class="struct">Foo</span>::<span class="function">new</span>(); |
62 | <span class="comment">///</span> | 62 | <span class="comment documentation">///</span> |
63 | <span class="comment">/// </span><span class="comment">// calls bar on foo</span> | 63 | <span class="comment documentation">/// </span><span class="comment">// calls bar on foo</span> |
64 | <span class="comment">/// </span><span class="macro">assert!</span>(foo.bar()); | 64 | <span class="comment documentation">/// </span><span class="macro">assert!</span>(foo.bar()); |
65 | <span class="comment">///</span> | 65 | <span class="comment documentation">///</span> |
66 | <span class="comment">/// </span><span class="keyword">let</span> <span class="variable declaration">bar</span> = <span class="variable">foo</span>.<span class="field">bar</span> || <span class="struct">Foo</span>::<span class="constant">bar</span>; | 66 | <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="variable declaration">bar</span> = <span class="variable">foo</span>.<span class="field">bar</span> || <span class="struct">Foo</span>::<span class="constant">bar</span>; |
67 | <span class="comment">///</span> | 67 | <span class="comment documentation">///</span> |
68 | <span class="comment">/// </span><span class="comment">/* multi-line | 68 | <span class="comment documentation">/// </span><span class="comment">/* multi-line |
69 | </span><span class="comment">/// </span><span class="comment"> comment */</span> | 69 | </span><span class="comment documentation">/// </span><span class="comment"> comment */</span> |
70 | <span class="comment">///</span> | 70 | <span class="comment documentation">///</span> |
71 | <span class="comment">/// </span><span class="keyword">let</span> <span class="variable declaration">multi_line_string</span> = <span class="string_literal">"Foo | 71 | <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="variable declaration">multi_line_string</span> = <span class="string_literal">"Foo |
72 | </span><span class="comment">/// </span><span class="string_literal"> bar | 72 | </span><span class="comment documentation">/// </span><span class="string_literal"> bar |
73 | </span><span class="comment">/// </span><span class="string_literal"> "</span>; | 73 | </span><span class="comment documentation">/// </span><span class="string_literal"> "</span>; |
74 | <span class="comment">///</span> | 74 | <span class="comment documentation">///</span> |
75 | <span class="comment">/// ```</span> | 75 | <span class="comment documentation">/// ```</span> |
76 | <span class="comment">///</span> | 76 | <span class="comment documentation">///</span> |
77 | <span class="comment">/// ```rust,no_run</span> | 77 | <span class="comment documentation">/// ```rust,no_run</span> |
78 | <span class="comment">/// </span><span class="keyword">let</span> <span class="variable declaration">foobar</span> = <span class="struct">Foo</span>::<span class="function">new</span>().<span class="function">bar</span>(); | 78 | <span class="comment documentation">/// </span><span class="keyword">let</span> <span class="variable declaration">foobar</span> = <span class="struct">Foo</span>::<span class="function">new</span>().<span class="function">bar</span>(); |
79 | <span class="comment">/// ```</span> | 79 | <span class="comment documentation">/// ```</span> |
80 | <span class="comment">///</span> | 80 | <span class="comment documentation">///</span> |
81 | <span class="comment">/// ```sh</span> | 81 | <span class="comment documentation">/// ```sh</span> |
82 | <span class="comment">/// echo 1</span> | 82 | <span class="comment documentation">/// echo 1</span> |
83 | <span class="comment">/// ```</span> | 83 | <span class="comment documentation">/// ```</span> |
84 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">foo</span>(&<span class="self_keyword">self</span>) -> <span class="builtin_type">bool</span> { | 84 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">foo</span>(&<span class="self_keyword">self</span>) -> <span class="builtin_type">bool</span> { |
85 | <span class="bool_literal">true</span> | 85 | <span class="bool_literal">true</span> |
86 | } | 86 | } |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 854b6cc6d..f8f790e59 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -489,7 +489,14 @@ fn highlight_element( | |||
489 | } | 489 | } |
490 | 490 | ||
491 | // Simple token-based highlighting | 491 | // Simple token-based highlighting |
492 | COMMENT => HighlightTag::Comment.into(), | 492 | COMMENT => { |
493 | let comment = element.into_token().and_then(ast::Comment::cast)?; | ||
494 | let h = HighlightTag::Comment; | ||
495 | match comment.kind().doc { | ||
496 | Some(_) => h | HighlightModifier::Documentation, | ||
497 | None => h.into(), | ||
498 | } | ||
499 | } | ||
493 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => HighlightTag::StringLiteral.into(), | 500 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => HighlightTag::StringLiteral.into(), |
494 | ATTR => HighlightTag::Attribute.into(), | 501 | ATTR => HighlightTag::Attribute.into(), |
495 | INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(), | 502 | INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(), |
diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs index 929a5cc5c..415f24a6d 100644 --- a/crates/ra_ide/src/syntax_highlighting/injection.rs +++ b/crates/ra_ide/src/syntax_highlighting/injection.rs | |||
@@ -7,7 +7,10 @@ use hir::Semantics; | |||
7 | use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; | 7 | use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; |
8 | use stdx::SepBy; | 8 | use stdx::SepBy; |
9 | 9 | ||
10 | use crate::{call_info::ActiveParameter, Analysis, HighlightTag, HighlightedRange, RootDatabase}; | 10 | use crate::{ |
11 | call_info::ActiveParameter, Analysis, HighlightModifier, HighlightTag, HighlightedRange, | ||
12 | RootDatabase, | ||
13 | }; | ||
11 | 14 | ||
12 | use super::HighlightedRangeStack; | 15 | use super::HighlightedRangeStack; |
13 | 16 | ||
@@ -118,7 +121,7 @@ pub(super) fn extract_doc_comments( | |||
118 | range.start(), | 121 | range.start(), |
119 | range.start() + TextSize::try_from(pos).unwrap(), | 122 | range.start() + TextSize::try_from(pos).unwrap(), |
120 | ), | 123 | ), |
121 | highlight: HighlightTag::Comment.into(), | 124 | highlight: HighlightTag::Comment | HighlightModifier::Documentation, |
122 | binding_hash: None, | 125 | binding_hash: None, |
123 | }); | 126 | }); |
124 | line_start += range.len() - TextSize::try_from(pos).unwrap(); | 127 | line_start += range.len() - TextSize::try_from(pos).unwrap(); |
@@ -164,6 +167,7 @@ pub(super) fn highlight_doc_comment( | |||
164 | h.range.start() + start_offset, | 167 | h.range.start() + start_offset, |
165 | h.range.end() + end_offset.unwrap_or(start_offset), | 168 | h.range.end() + end_offset.unwrap_or(start_offset), |
166 | ); | 169 | ); |
170 | |||
167 | stack.add(h); | 171 | stack.add(h); |
168 | } | 172 | } |
169 | } | 173 | } |
diff --git a/crates/ra_ide/src/syntax_highlighting/tags.rs b/crates/ra_ide/src/syntax_highlighting/tags.rs index 400d22fb6..93bbb4b4d 100644 --- a/crates/ra_ide/src/syntax_highlighting/tags.rs +++ b/crates/ra_ide/src/syntax_highlighting/tags.rs | |||
@@ -56,6 +56,7 @@ pub enum HighlightModifier { | |||
56 | /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is | 56 | /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is |
57 | /// not. | 57 | /// not. |
58 | Definition, | 58 | Definition, |
59 | Documentation, | ||
59 | Mutable, | 60 | Mutable, |
60 | Unsafe, | 61 | Unsafe, |
61 | } | 62 | } |
@@ -108,6 +109,7 @@ impl HighlightModifier { | |||
108 | HighlightModifier::Attribute, | 109 | HighlightModifier::Attribute, |
109 | HighlightModifier::ControlFlow, | 110 | HighlightModifier::ControlFlow, |
110 | HighlightModifier::Definition, | 111 | HighlightModifier::Definition, |
112 | HighlightModifier::Documentation, | ||
111 | HighlightModifier::Mutable, | 113 | HighlightModifier::Mutable, |
112 | HighlightModifier::Unsafe, | 114 | HighlightModifier::Unsafe, |
113 | ]; | 115 | ]; |
@@ -117,6 +119,7 @@ impl HighlightModifier { | |||
117 | HighlightModifier::Attribute => "attribute", | 119 | HighlightModifier::Attribute => "attribute", |
118 | HighlightModifier::ControlFlow => "control", | 120 | HighlightModifier::ControlFlow => "control", |
119 | HighlightModifier::Definition => "declaration", | 121 | HighlightModifier::Definition => "declaration", |
122 | HighlightModifier::Documentation => "documentation", | ||
120 | HighlightModifier::Mutable => "mutable", | 123 | HighlightModifier::Mutable => "mutable", |
121 | HighlightModifier::Unsafe => "unsafe", | 124 | HighlightModifier::Unsafe => "unsafe", |
122 | } | 125 | } |
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index ca95d776a..1527c9947 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -18,7 +18,7 @@ use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsTask, Watch}; | |||
18 | use stdx::format_to; | 18 | use stdx::format_to; |
19 | 19 | ||
20 | use crate::{ | 20 | use crate::{ |
21 | config::Config, | 21 | config::{Config, FilesWatcher}, |
22 | diagnostics::{CheckFixes, DiagnosticCollection}, | 22 | diagnostics::{CheckFixes, DiagnosticCollection}, |
23 | main_loop::pending_requests::{CompletedRequest, LatestRequests}, | 23 | main_loop::pending_requests::{CompletedRequest, LatestRequests}, |
24 | to_proto::url_from_abs_path, | 24 | to_proto::url_from_abs_path, |
@@ -76,7 +76,6 @@ impl GlobalState { | |||
76 | workspaces: Vec<ProjectWorkspace>, | 76 | workspaces: Vec<ProjectWorkspace>, |
77 | lru_capacity: Option<usize>, | 77 | lru_capacity: Option<usize>, |
78 | exclude_globs: &[Glob], | 78 | exclude_globs: &[Glob], |
79 | watch: Watch, | ||
80 | config: Config, | 79 | config: Config, |
81 | ) -> GlobalState { | 80 | ) -> GlobalState { |
82 | let mut change = AnalysisChange::new(); | 81 | let mut change = AnalysisChange::new(); |
@@ -111,6 +110,7 @@ impl GlobalState { | |||
111 | 110 | ||
112 | let (task_sender, task_receiver) = unbounded(); | 111 | let (task_sender, task_receiver) = unbounded(); |
113 | let task_sender = Box::new(move |t| task_sender.send(t).unwrap()); | 112 | let task_sender = Box::new(move |t| task_sender.send(t).unwrap()); |
113 | let watch = Watch(matches!(config.files.watcher, FilesWatcher::Notify)); | ||
114 | let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch); | 114 | let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch); |
115 | 115 | ||
116 | let mut extern_source_roots = FxHashMap::default(); | 116 | let mut extern_source_roots = FxHashMap::default(); |
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 08b0a5a16..f0aaaa21e 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -27,7 +27,7 @@ use ra_flycheck::{CheckTask, Status}; | |||
27 | use ra_ide::{Canceled, FileId, LineIndex}; | 27 | use ra_ide::{Canceled, FileId, LineIndex}; |
28 | use ra_prof::profile; | 28 | use ra_prof::profile; |
29 | use ra_project_model::{PackageRoot, ProjectWorkspace}; | 29 | use ra_project_model::{PackageRoot, ProjectWorkspace}; |
30 | use ra_vfs::{VfsTask, Watch}; | 30 | use ra_vfs::VfsTask; |
31 | use rustc_hash::FxHashSet; | 31 | use rustc_hash::FxHashSet; |
32 | use serde::{de::DeserializeOwned, Serialize}; | 32 | use serde::{de::DeserializeOwned, Serialize}; |
33 | use threadpool::ThreadPool; | 33 | use threadpool::ThreadPool; |
@@ -160,13 +160,7 @@ pub fn main_loop(config: Config, connection: Connection) -> Result<()> { | |||
160 | connection.sender.send(request.into()).unwrap(); | 160 | connection.sender.send(request.into()).unwrap(); |
161 | } | 161 | } |
162 | 162 | ||
163 | GlobalState::new( | 163 | GlobalState::new(workspaces, config.lru_capacity, &globs, config) |
164 | workspaces, | ||
165 | config.lru_capacity, | ||
166 | &globs, | ||
167 | Watch(matches!(config.files.watcher, FilesWatcher::Notify)), | ||
168 | config, | ||
169 | ) | ||
170 | }; | 164 | }; |
171 | 165 | ||
172 | loop_state.roots_total = global_state.vfs.read().n_roots(); | 166 | loop_state.roots_total = global_state.vfs.read().n_roots(); |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 055c97455..ec153097e 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -331,6 +331,7 @@ fn semantic_token_type_and_modifiers( | |||
331 | let modifier = match modifier { | 331 | let modifier = match modifier { |
332 | HighlightModifier::Attribute => semantic_tokens::ATTRIBUTE_MODIFIER, | 332 | HighlightModifier::Attribute => semantic_tokens::ATTRIBUTE_MODIFIER, |
333 | HighlightModifier::Definition => lsp_types::SemanticTokenModifier::DECLARATION, | 333 | HighlightModifier::Definition => lsp_types::SemanticTokenModifier::DECLARATION, |
334 | HighlightModifier::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION, | ||
334 | HighlightModifier::ControlFlow => semantic_tokens::CONTROL_FLOW, | 335 | HighlightModifier::ControlFlow => semantic_tokens::CONTROL_FLOW, |
335 | HighlightModifier::Mutable => semantic_tokens::MUTABLE, | 336 | HighlightModifier::Mutable => semantic_tokens::MUTABLE, |
336 | HighlightModifier::Unsafe => semantic_tokens::UNSAFE, | 337 | HighlightModifier::Unsafe => semantic_tokens::UNSAFE, |
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index c0356344c..f2ff0e435 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs | |||
@@ -1,5 +1,4 @@ | |||
1 | //! Missing batteries for standard libraries. | 1 | //! Missing batteries for standard libraries. |
2 | |||
3 | use std::{cell::Cell, fmt, time::Instant}; | 2 | use std::{cell::Cell, fmt, time::Instant}; |
4 | 3 | ||
5 | #[inline(always)] | 4 | #[inline(always)] |
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs index 7dc721f7e..724606a3d 100644 --- a/crates/vfs/src/file_set.rs +++ b/crates/vfs/src/file_set.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | //! | 2 | //! |
3 | //! Files which do not belong to any explicitly configured `FileSet` belong to | 3 | //! Files which do not belong to any explicitly configured `FileSet` belong to |
4 | //! the default `FileSet`. | 4 | //! the default `FileSet`. |
5 | use std::{cmp, fmt, iter}; | 5 | use std::{fmt, iter}; |
6 | 6 | ||
7 | use paths::AbsPathBuf; | 7 | use paths::AbsPathBuf; |
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
@@ -44,6 +44,12 @@ pub struct FileSetConfig { | |||
44 | roots: Vec<(AbsPathBuf, usize)>, | 44 | roots: Vec<(AbsPathBuf, usize)>, |
45 | } | 45 | } |
46 | 46 | ||
47 | impl Default for FileSetConfig { | ||
48 | fn default() -> Self { | ||
49 | FileSetConfig::builder().build() | ||
50 | } | ||
51 | } | ||
52 | |||
47 | impl FileSetConfig { | 53 | impl FileSetConfig { |
48 | pub fn builder() -> FileSetConfigBuilder { | 54 | pub fn builder() -> FileSetConfigBuilder { |
49 | FileSetConfigBuilder::default() | 55 | FileSetConfigBuilder::default() |
@@ -60,14 +66,19 @@ impl FileSetConfig { | |||
60 | self.n_file_sets | 66 | self.n_file_sets |
61 | } | 67 | } |
62 | fn classify(&self, path: &VfsPath) -> usize { | 68 | fn classify(&self, path: &VfsPath) -> usize { |
63 | for (root, idx) in self.roots.iter() { | 69 | let path = match path.as_path() { |
64 | if let Some(path) = path.as_path() { | 70 | Some(it) => it, |
65 | if path.starts_with(root) { | 71 | None => return self.len() - 1, |
66 | return *idx; | 72 | }; |
67 | } | 73 | let idx = match self.roots.binary_search_by(|(p, _)| p.as_path().cmp(path)) { |
68 | } | 74 | Ok(it) => it, |
75 | Err(it) => it.saturating_sub(1), | ||
76 | }; | ||
77 | if path.starts_with(&self.roots[idx].0) { | ||
78 | self.roots[idx].1 | ||
79 | } else { | ||
80 | self.len() - 1 | ||
69 | } | 81 | } |
70 | self.len() - 1 | ||
71 | } | 82 | } |
72 | } | 83 | } |
73 | 84 | ||
@@ -82,6 +93,9 @@ impl Default for FileSetConfigBuilder { | |||
82 | } | 93 | } |
83 | 94 | ||
84 | impl FileSetConfigBuilder { | 95 | impl FileSetConfigBuilder { |
96 | pub fn len(&self) -> usize { | ||
97 | self.roots.len() | ||
98 | } | ||
85 | pub fn add_file_set(&mut self, roots: Vec<AbsPathBuf>) { | 99 | pub fn add_file_set(&mut self, roots: Vec<AbsPathBuf>) { |
86 | self.roots.push(roots) | 100 | self.roots.push(roots) |
87 | } | 101 | } |
@@ -93,7 +107,7 @@ impl FileSetConfigBuilder { | |||
93 | .enumerate() | 107 | .enumerate() |
94 | .flat_map(|(i, paths)| paths.into_iter().zip(iter::repeat(i))) | 108 | .flat_map(|(i, paths)| paths.into_iter().zip(iter::repeat(i))) |
95 | .collect(); | 109 | .collect(); |
96 | roots.sort_by_key(|(path, _)| cmp::Reverse(path.to_string_lossy().len())); | 110 | roots.sort(); |
97 | FileSetConfig { n_file_sets, roots } | 111 | FileSetConfig { n_file_sets, roots } |
98 | } | 112 | } |
99 | } | 113 | } |
diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs index 75ce61cf9..055219b0c 100644 --- a/crates/vfs/src/lib.rs +++ b/crates/vfs/src/lib.rs | |||
@@ -79,6 +79,9 @@ pub enum ChangeKind { | |||
79 | } | 79 | } |
80 | 80 | ||
81 | impl Vfs { | 81 | impl Vfs { |
82 | pub fn len(&self) -> usize { | ||
83 | self.data.len() | ||
84 | } | ||
82 | pub fn file_id(&self, path: &VfsPath) -> Option<FileId> { | 85 | pub fn file_id(&self, path: &VfsPath) -> Option<FileId> { |
83 | self.interner.get(path).filter(|&it| self.get(it).is_some()) | 86 | self.interner.get(path).filter(|&it| self.get(it).is_some()) |
84 | } | 87 | } |