diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/assists/src/handlers/generate_function.rs | 132 | ||||
-rw-r--r-- | crates/assists/src/tests/generated.rs | 4 | ||||
-rw-r--r-- | crates/base_db/src/input.rs | 28 | ||||
-rw-r--r-- | crates/hir/src/code_model.rs | 6 | ||||
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 5 | ||||
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 81 | ||||
-rw-r--r-- | crates/ide/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/ide/src/prime_caches.rs | 43 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 118 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlight_strings.html | 2 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlighting.html | 6 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 42 | ||||
-rw-r--r-- | crates/rust-analyzer/src/thread_pool.rs | 11 | ||||
-rw-r--r-- | crates/syntax/src/ast/make.rs | 12 |
15 files changed, 383 insertions, 119 deletions
diff --git a/crates/assists/src/handlers/generate_function.rs b/crates/assists/src/handlers/generate_function.rs index b38d64058..d23f4293b 100644 --- a/crates/assists/src/handlers/generate_function.rs +++ b/crates/assists/src/handlers/generate_function.rs | |||
@@ -36,8 +36,8 @@ use crate::{ | |||
36 | // bar("", baz()); | 36 | // bar("", baz()); |
37 | // } | 37 | // } |
38 | // | 38 | // |
39 | // fn bar(arg: &str, baz: Baz) { | 39 | // fn bar(arg: &str, baz: Baz) ${0:-> ()} { |
40 | // ${0:todo!()} | 40 | // todo!() |
41 | // } | 41 | // } |
42 | // | 42 | // |
43 | // ``` | 43 | // ``` |
@@ -80,9 +80,9 @@ pub(crate) fn generate_function(acc: &mut Assists, ctx: &AssistContext) -> Optio | |||
80 | 80 | ||
81 | struct FunctionTemplate { | 81 | struct FunctionTemplate { |
82 | insert_offset: TextSize, | 82 | insert_offset: TextSize, |
83 | placeholder_expr: ast::MacroCall, | ||
84 | leading_ws: String, | 83 | leading_ws: String, |
85 | fn_def: ast::Fn, | 84 | fn_def: ast::Fn, |
85 | ret_type: ast::RetType, | ||
86 | trailing_ws: String, | 86 | trailing_ws: String, |
87 | file: FileId, | 87 | file: FileId, |
88 | } | 88 | } |
@@ -90,11 +90,9 @@ struct FunctionTemplate { | |||
90 | impl FunctionTemplate { | 90 | impl FunctionTemplate { |
91 | fn to_string(&self, cap: Option<SnippetCap>) -> String { | 91 | fn to_string(&self, cap: Option<SnippetCap>) -> String { |
92 | let f = match cap { | 92 | let f = match cap { |
93 | Some(cap) => render_snippet( | 93 | Some(cap) => { |
94 | cap, | 94 | render_snippet(cap, self.fn_def.syntax(), Cursor::Replace(self.ret_type.syntax())) |
95 | self.fn_def.syntax(), | 95 | } |
96 | Cursor::Replace(self.placeholder_expr.syntax()), | ||
97 | ), | ||
98 | None => self.fn_def.to_string(), | 96 | None => self.fn_def.to_string(), |
99 | }; | 97 | }; |
100 | format!("{}{}{}", self.leading_ws, f, self.trailing_ws) | 98 | format!("{}{}{}", self.leading_ws, f, self.trailing_ws) |
@@ -141,8 +139,14 @@ impl FunctionBuilder { | |||
141 | let placeholder_expr = make::expr_todo(); | 139 | let placeholder_expr = make::expr_todo(); |
142 | let fn_body = make::block_expr(vec![], Some(placeholder_expr)); | 140 | let fn_body = make::block_expr(vec![], Some(placeholder_expr)); |
143 | let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None }; | 141 | let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None }; |
144 | let mut fn_def = | 142 | let mut fn_def = make::fn_( |
145 | make::fn_(visibility, self.fn_name, self.type_params, self.params, fn_body); | 143 | visibility, |
144 | self.fn_name, | ||
145 | self.type_params, | ||
146 | self.params, | ||
147 | fn_body, | ||
148 | Some(make::ret_type(make::ty("()"))), | ||
149 | ); | ||
146 | let leading_ws; | 150 | let leading_ws; |
147 | let trailing_ws; | 151 | let trailing_ws; |
148 | 152 | ||
@@ -163,12 +167,10 @@ impl FunctionBuilder { | |||
163 | } | 167 | } |
164 | }; | 168 | }; |
165 | 169 | ||
166 | let placeholder_expr = | ||
167 | fn_def.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | ||
168 | FunctionTemplate { | 170 | FunctionTemplate { |
169 | insert_offset, | 171 | insert_offset, |
170 | placeholder_expr, | ||
171 | leading_ws, | 172 | leading_ws, |
173 | ret_type: fn_def.ret_type().unwrap(), | ||
172 | fn_def, | 174 | fn_def, |
173 | trailing_ws, | 175 | trailing_ws, |
174 | file: self.file, | 176 | file: self.file, |
@@ -349,8 +351,8 @@ fn foo() { | |||
349 | bar(); | 351 | bar(); |
350 | } | 352 | } |
351 | 353 | ||
352 | fn bar() { | 354 | fn bar() ${0:-> ()} { |
353 | ${0:todo!()} | 355 | todo!() |
354 | } | 356 | } |
355 | ", | 357 | ", |
356 | ) | 358 | ) |
@@ -376,8 +378,8 @@ impl Foo { | |||
376 | } | 378 | } |
377 | } | 379 | } |
378 | 380 | ||
379 | fn bar() { | 381 | fn bar() ${0:-> ()} { |
380 | ${0:todo!()} | 382 | todo!() |
381 | } | 383 | } |
382 | ", | 384 | ", |
383 | ) | 385 | ) |
@@ -400,8 +402,8 @@ fn foo1() { | |||
400 | bar(); | 402 | bar(); |
401 | } | 403 | } |
402 | 404 | ||
403 | fn bar() { | 405 | fn bar() ${0:-> ()} { |
404 | ${0:todo!()} | 406 | todo!() |
405 | } | 407 | } |
406 | 408 | ||
407 | fn foo2() {} | 409 | fn foo2() {} |
@@ -426,8 +428,8 @@ mod baz { | |||
426 | bar(); | 428 | bar(); |
427 | } | 429 | } |
428 | 430 | ||
429 | fn bar() { | 431 | fn bar() ${0:-> ()} { |
430 | ${0:todo!()} | 432 | todo!() |
431 | } | 433 | } |
432 | } | 434 | } |
433 | ", | 435 | ", |
@@ -452,8 +454,8 @@ fn foo() { | |||
452 | bar(baz()); | 454 | bar(baz()); |
453 | } | 455 | } |
454 | 456 | ||
455 | fn bar(baz: Baz) { | 457 | fn bar(baz: Baz) ${0:-> ()} { |
456 | ${0:todo!()} | 458 | todo!() |
457 | } | 459 | } |
458 | ", | 460 | ", |
459 | ); | 461 | ); |
@@ -485,8 +487,8 @@ impl Baz { | |||
485 | } | 487 | } |
486 | } | 488 | } |
487 | 489 | ||
488 | fn bar(baz: Baz) { | 490 | fn bar(baz: Baz) ${0:-> ()} { |
489 | ${0:todo!()} | 491 | todo!() |
490 | } | 492 | } |
491 | ", | 493 | ", |
492 | ) | 494 | ) |
@@ -506,8 +508,8 @@ fn foo() { | |||
506 | bar("bar") | 508 | bar("bar") |
507 | } | 509 | } |
508 | 510 | ||
509 | fn bar(arg: &str) { | 511 | fn bar(arg: &str) ${0:-> ()} { |
510 | ${0:todo!()} | 512 | todo!() |
511 | } | 513 | } |
512 | "#, | 514 | "#, |
513 | ) | 515 | ) |
@@ -527,8 +529,8 @@ fn foo() { | |||
527 | bar('x') | 529 | bar('x') |
528 | } | 530 | } |
529 | 531 | ||
530 | fn bar(arg: char) { | 532 | fn bar(arg: char) ${0:-> ()} { |
531 | ${0:todo!()} | 533 | todo!() |
532 | } | 534 | } |
533 | "#, | 535 | "#, |
534 | ) | 536 | ) |
@@ -548,8 +550,8 @@ fn foo() { | |||
548 | bar(42) | 550 | bar(42) |
549 | } | 551 | } |
550 | 552 | ||
551 | fn bar(arg: i32) { | 553 | fn bar(arg: i32) ${0:-> ()} { |
552 | ${0:todo!()} | 554 | todo!() |
553 | } | 555 | } |
554 | ", | 556 | ", |
555 | ) | 557 | ) |
@@ -569,8 +571,8 @@ fn foo() { | |||
569 | bar(42 as u8) | 571 | bar(42 as u8) |
570 | } | 572 | } |
571 | 573 | ||
572 | fn bar(arg: u8) { | 574 | fn bar(arg: u8) ${0:-> ()} { |
573 | ${0:todo!()} | 575 | todo!() |
574 | } | 576 | } |
575 | ", | 577 | ", |
576 | ) | 578 | ) |
@@ -594,8 +596,8 @@ fn foo() { | |||
594 | bar(x as u8) | 596 | bar(x as u8) |
595 | } | 597 | } |
596 | 598 | ||
597 | fn bar(x: u8) { | 599 | fn bar(x: u8) ${0:-> ()} { |
598 | ${0:todo!()} | 600 | todo!() |
599 | } | 601 | } |
600 | ", | 602 | ", |
601 | ) | 603 | ) |
@@ -617,8 +619,8 @@ fn foo() { | |||
617 | bar(worble) | 619 | bar(worble) |
618 | } | 620 | } |
619 | 621 | ||
620 | fn bar(worble: ()) { | 622 | fn bar(worble: ()) ${0:-> ()} { |
621 | ${0:todo!()} | 623 | todo!() |
622 | } | 624 | } |
623 | ", | 625 | ", |
624 | ) | 626 | ) |
@@ -646,8 +648,8 @@ fn baz() { | |||
646 | bar(foo()) | 648 | bar(foo()) |
647 | } | 649 | } |
648 | 650 | ||
649 | fn bar(foo: impl Foo) { | 651 | fn bar(foo: impl Foo) ${0:-> ()} { |
650 | ${0:todo!()} | 652 | todo!() |
651 | } | 653 | } |
652 | ", | 654 | ", |
653 | ) | 655 | ) |
@@ -673,8 +675,8 @@ fn foo() { | |||
673 | bar(&baz()) | 675 | bar(&baz()) |
674 | } | 676 | } |
675 | 677 | ||
676 | fn bar(baz: &Baz) { | 678 | fn bar(baz: &Baz) ${0:-> ()} { |
677 | ${0:todo!()} | 679 | todo!() |
678 | } | 680 | } |
679 | ", | 681 | ", |
680 | ) | 682 | ) |
@@ -702,8 +704,8 @@ fn foo() { | |||
702 | bar(Baz::baz()) | 704 | bar(Baz::baz()) |
703 | } | 705 | } |
704 | 706 | ||
705 | fn bar(baz: Baz::Bof) { | 707 | fn bar(baz: Baz::Bof) ${0:-> ()} { |
706 | ${0:todo!()} | 708 | todo!() |
707 | } | 709 | } |
708 | ", | 710 | ", |
709 | ) | 711 | ) |
@@ -725,8 +727,8 @@ fn foo<T>(t: T) { | |||
725 | bar(t) | 727 | bar(t) |
726 | } | 728 | } |
727 | 729 | ||
728 | fn bar<T>(t: T) { | 730 | fn bar<T>(t: T) ${0:-> ()} { |
729 | ${0:todo!()} | 731 | todo!() |
730 | } | 732 | } |
731 | ", | 733 | ", |
732 | ) | 734 | ) |
@@ -756,8 +758,8 @@ fn foo() { | |||
756 | bar(Baz::new); | 758 | bar(Baz::new); |
757 | } | 759 | } |
758 | 760 | ||
759 | fn bar(arg: fn() -> Baz) { | 761 | fn bar(arg: fn() -> Baz) ${0:-> ()} { |
760 | ${0:todo!()} | 762 | todo!() |
761 | } | 763 | } |
762 | ", | 764 | ", |
763 | ) | 765 | ) |
@@ -781,8 +783,8 @@ fn foo() { | |||
781 | bar(closure) | 783 | bar(closure) |
782 | } | 784 | } |
783 | 785 | ||
784 | fn bar(closure: impl Fn(i64) -> i64) { | 786 | fn bar(closure: impl Fn(i64) -> i64) ${0:-> ()} { |
785 | ${0:todo!()} | 787 | todo!() |
786 | } | 788 | } |
787 | ", | 789 | ", |
788 | ) | 790 | ) |
@@ -802,8 +804,8 @@ fn foo() { | |||
802 | bar(baz) | 804 | bar(baz) |
803 | } | 805 | } |
804 | 806 | ||
805 | fn bar(baz: ()) { | 807 | fn bar(baz: ()) ${0:-> ()} { |
806 | ${0:todo!()} | 808 | todo!() |
807 | } | 809 | } |
808 | ", | 810 | ", |
809 | ) | 811 | ) |
@@ -827,8 +829,8 @@ fn foo() { | |||
827 | bar(baz(), baz()) | 829 | bar(baz(), baz()) |
828 | } | 830 | } |
829 | 831 | ||
830 | fn bar(baz_1: Baz, baz_2: Baz) { | 832 | fn bar(baz_1: Baz, baz_2: Baz) ${0:-> ()} { |
831 | ${0:todo!()} | 833 | todo!() |
832 | } | 834 | } |
833 | ", | 835 | ", |
834 | ) | 836 | ) |
@@ -852,8 +854,8 @@ fn foo() { | |||
852 | bar(baz(), baz(), "foo", "bar") | 854 | bar(baz(), baz(), "foo", "bar") |
853 | } | 855 | } |
854 | 856 | ||
855 | fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) { | 857 | fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) ${0:-> ()} { |
856 | ${0:todo!()} | 858 | todo!() |
857 | } | 859 | } |
858 | "#, | 860 | "#, |
859 | ) | 861 | ) |
@@ -872,8 +874,8 @@ fn foo() { | |||
872 | ", | 874 | ", |
873 | r" | 875 | r" |
874 | mod bar { | 876 | mod bar { |
875 | pub(crate) fn my_fn() { | 877 | pub(crate) fn my_fn() ${0:-> ()} { |
876 | ${0:todo!()} | 878 | todo!() |
877 | } | 879 | } |
878 | } | 880 | } |
879 | 881 | ||
@@ -911,8 +913,8 @@ fn bar() { | |||
911 | baz(foo) | 913 | baz(foo) |
912 | } | 914 | } |
913 | 915 | ||
914 | fn baz(foo: foo::Foo) { | 916 | fn baz(foo: foo::Foo) ${0:-> ()} { |
915 | ${0:todo!()} | 917 | todo!() |
916 | } | 918 | } |
917 | ", | 919 | ", |
918 | ) | 920 | ) |
@@ -935,8 +937,8 @@ fn foo() { | |||
935 | mod bar { | 937 | mod bar { |
936 | fn something_else() {} | 938 | fn something_else() {} |
937 | 939 | ||
938 | pub(crate) fn my_fn() { | 940 | pub(crate) fn my_fn() ${0:-> ()} { |
939 | ${0:todo!()} | 941 | todo!() |
940 | } | 942 | } |
941 | } | 943 | } |
942 | 944 | ||
@@ -963,8 +965,8 @@ fn foo() { | |||
963 | r" | 965 | r" |
964 | mod bar { | 966 | mod bar { |
965 | mod baz { | 967 | mod baz { |
966 | pub(crate) fn my_fn() { | 968 | pub(crate) fn my_fn() ${0:-> ()} { |
967 | ${0:todo!()} | 969 | todo!() |
968 | } | 970 | } |
969 | } | 971 | } |
970 | } | 972 | } |
@@ -992,8 +994,8 @@ fn main() { | |||
992 | r" | 994 | r" |
993 | 995 | ||
994 | 996 | ||
995 | pub(crate) fn bar() { | 997 | pub(crate) fn bar() ${0:-> ()} { |
996 | ${0:todo!()} | 998 | todo!() |
997 | }", | 999 | }", |
998 | ) | 1000 | ) |
999 | } | 1001 | } |
diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs index 7f6e98a54..41f536574 100644 --- a/crates/assists/src/tests/generated.rs +++ b/crates/assists/src/tests/generated.rs | |||
@@ -454,8 +454,8 @@ fn foo() { | |||
454 | bar("", baz()); | 454 | bar("", baz()); |
455 | } | 455 | } |
456 | 456 | ||
457 | fn bar(arg: &str, baz: Baz) { | 457 | fn bar(arg: &str, baz: Baz) ${0:-> ()} { |
458 | ${0:todo!()} | 458 | todo!() |
459 | } | 459 | } |
460 | 460 | ||
461 | "#####, | 461 | "#####, |
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs index c330314d4..215ac4b41 100644 --- a/crates/base_db/src/input.rs +++ b/crates/base_db/src/input.rs | |||
@@ -221,6 +221,34 @@ impl CrateGraph { | |||
221 | deps.into_iter() | 221 | deps.into_iter() |
222 | } | 222 | } |
223 | 223 | ||
224 | /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate | ||
225 | /// come before the crate itself). | ||
226 | pub fn crates_in_topological_order(&self) -> Vec<CrateId> { | ||
227 | let mut res = Vec::new(); | ||
228 | let mut visited = FxHashSet::default(); | ||
229 | |||
230 | for krate in self.arena.keys().copied() { | ||
231 | go(self, &mut visited, &mut res, krate); | ||
232 | } | ||
233 | |||
234 | return res; | ||
235 | |||
236 | fn go( | ||
237 | graph: &CrateGraph, | ||
238 | visited: &mut FxHashSet<CrateId>, | ||
239 | res: &mut Vec<CrateId>, | ||
240 | source: CrateId, | ||
241 | ) { | ||
242 | if !visited.insert(source) { | ||
243 | return; | ||
244 | } | ||
245 | for dep in graph[source].dependencies.iter() { | ||
246 | go(graph, visited, res, dep.crate_id) | ||
247 | } | ||
248 | res.push(source) | ||
249 | } | ||
250 | } | ||
251 | |||
224 | // FIXME: this only finds one crate with the given root; we could have multiple | 252 | // FIXME: this only finds one crate with the given root; we could have multiple |
225 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | 253 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { |
226 | let (&crate_id, _) = | 254 | let (&crate_id, _) = |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index fb85041fd..b65be4fe1 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -1411,7 +1411,7 @@ impl Type { | |||
1411 | r#trait: Trait, | 1411 | r#trait: Trait, |
1412 | args: &[Type], | 1412 | args: &[Type], |
1413 | alias: TypeAlias, | 1413 | alias: TypeAlias, |
1414 | ) -> Option<Ty> { | 1414 | ) -> Option<Type> { |
1415 | let subst = Substs::build_for_def(db, r#trait.id) | 1415 | let subst = Substs::build_for_def(db, r#trait.id) |
1416 | .push(self.ty.value.clone()) | 1416 | .push(self.ty.value.clone()) |
1417 | .fill(args.iter().map(|t| t.ty.value.clone())) | 1417 | .fill(args.iter().map(|t| t.ty.value.clone())) |
@@ -1432,6 +1432,10 @@ impl Type { | |||
1432 | Solution::Unique(SolutionVariables(subst)) => subst.value.first().cloned(), | 1432 | Solution::Unique(SolutionVariables(subst)) => subst.value.first().cloned(), |
1433 | Solution::Ambig(_) => None, | 1433 | Solution::Ambig(_) => None, |
1434 | } | 1434 | } |
1435 | .map(|ty| Type { | ||
1436 | krate: self.krate, | ||
1437 | ty: InEnvironment { value: ty, environment: Arc::clone(&self.ty.environment) }, | ||
1438 | }) | ||
1435 | } | 1439 | } |
1436 | 1440 | ||
1437 | pub fn is_copy(&self, db: &dyn HirDatabase) -> bool { | 1441 | pub fn is_copy(&self, db: &dyn HirDatabase) -> bool { |
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 2d91bb21f..01e72690a 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -107,7 +107,10 @@ impl ExprCollector<'_> { | |||
107 | let param_pat = self.alloc_pat( | 107 | let param_pat = self.alloc_pat( |
108 | Pat::Bind { | 108 | Pat::Bind { |
109 | name: name![self], | 109 | name: name![self], |
110 | mode: BindingAnnotation::Unannotated, | 110 | mode: BindingAnnotation::new( |
111 | self_param.mut_token().is_some() && self_param.amp_token().is_none(), | ||
112 | false, | ||
113 | ), | ||
111 | subpat: None, | 114 | subpat: None, |
112 | }, | 115 | }, |
113 | Either::Right(ptr), | 116 | Either::Right(ptr), |
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 7d716577e..e2079bbcf 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -220,8 +220,8 @@ fn hint_iterator( | |||
220 | } | 220 | } |
221 | let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; | 221 | let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; |
222 | let iter_mod = FamousDefs(sema, krate).core_iter()?; | 222 | let iter_mod = FamousDefs(sema, krate).core_iter()?; |
223 | // assert this type comes from `core::iter` | 223 | // assert this struct comes from `core::iter` |
224 | iter_mod.visibility_of(db, &iter_trait.into()).filter(|&vis| vis == hir::Visibility::Public)?; | 224 | iter_mod.visibility_of(db, &strukt.into()).filter(|&vis| vis == hir::Visibility::Public)?; |
225 | if ty.impls_trait(db, iter_trait, &[]) { | 225 | if ty.impls_trait(db, iter_trait, &[]) { |
226 | let assoc_type_item = iter_trait.items(db).into_iter().find_map(|item| match item { | 226 | let assoc_type_item = iter_trait.items(db).into_iter().find_map(|item| match item { |
227 | hir::AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias), | 227 | hir::AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias), |
@@ -231,12 +231,17 @@ fn hint_iterator( | |||
231 | const LABEL_START: &str = "impl Iterator<Item = "; | 231 | const LABEL_START: &str = "impl Iterator<Item = "; |
232 | const LABEL_END: &str = ">"; | 232 | const LABEL_END: &str = ">"; |
233 | 233 | ||
234 | let ty_display = ty.display_truncated( | 234 | let ty_display = hint_iterator(sema, config, &ty) |
235 | db, | 235 | .map(|assoc_type_impl| assoc_type_impl.to_string()) |
236 | config | 236 | .unwrap_or_else(|| { |
237 | .max_length | 237 | ty.display_truncated( |
238 | .map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len())), | 238 | db, |
239 | ); | 239 | config |
240 | .max_length | ||
241 | .map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len())), | ||
242 | ) | ||
243 | .to_string() | ||
244 | }); | ||
240 | return Some(format!("{}{}{}", LABEL_START, ty_display, LABEL_END).into()); | 245 | return Some(format!("{}{}{}", LABEL_START, ty_display, LABEL_END).into()); |
241 | } | 246 | } |
242 | } | 247 | } |
@@ -1002,18 +1007,6 @@ fn main() { | |||
1002 | 1007 | ||
1003 | println!("Unit expr"); | 1008 | println!("Unit expr"); |
1004 | } | 1009 | } |
1005 | |||
1006 | //- /alloc.rs crate:alloc deps:core | ||
1007 | mod collections { | ||
1008 | struct Vec<T> {} | ||
1009 | impl<T> Vec<T> { | ||
1010 | fn new() -> Self { Vec {} } | ||
1011 | fn push(&mut self, t: T) { } | ||
1012 | } | ||
1013 | impl<T> IntoIterator for Vec<T> { | ||
1014 | type Item=T; | ||
1015 | } | ||
1016 | } | ||
1017 | "#, | 1010 | "#, |
1018 | ); | 1011 | ); |
1019 | } | 1012 | } |
@@ -1043,17 +1036,6 @@ fn main() { | |||
1043 | //^ &str | 1036 | //^ &str |
1044 | } | 1037 | } |
1045 | } | 1038 | } |
1046 | //- /alloc.rs crate:alloc deps:core | ||
1047 | mod collections { | ||
1048 | struct Vec<T> {} | ||
1049 | impl<T> Vec<T> { | ||
1050 | fn new() -> Self { Vec {} } | ||
1051 | fn push(&mut self, t: T) { } | ||
1052 | } | ||
1053 | impl<T> IntoIterator for Vec<T> { | ||
1054 | type Item=T; | ||
1055 | } | ||
1056 | } | ||
1057 | "#, | 1039 | "#, |
1058 | ); | 1040 | ); |
1059 | } | 1041 | } |
@@ -1183,4 +1165,41 @@ fn main() { | |||
1183 | "#]], | 1165 | "#]], |
1184 | ); | 1166 | ); |
1185 | } | 1167 | } |
1168 | |||
1169 | #[test] | ||
1170 | fn shorten_iterators_in_associated_params() { | ||
1171 | check_with_config( | ||
1172 | InlayHintsConfig { | ||
1173 | parameter_hints: false, | ||
1174 | type_hints: true, | ||
1175 | chaining_hints: false, | ||
1176 | max_length: None, | ||
1177 | }, | ||
1178 | r#" | ||
1179 | use core::iter; | ||
1180 | |||
1181 | pub struct SomeIter<T> {} | ||
1182 | |||
1183 | impl<T> SomeIter<T> { | ||
1184 | pub fn new() -> Self { SomeIter {} } | ||
1185 | pub fn push(&mut self, t: T) {} | ||
1186 | } | ||
1187 | |||
1188 | impl<T> Iterator for SomeIter<T> { | ||
1189 | type Item = T; | ||
1190 | fn next(&mut self) -> Option<Self::Item> { | ||
1191 | None | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | fn main() { | ||
1196 | let mut some_iter = SomeIter::new(); | ||
1197 | //^^^^^^^^^^^^^ SomeIter<Take<Repeat<i32>>> | ||
1198 | some_iter.push(iter::repeat(2).take(2)); | ||
1199 | let iter_of_iters = some_iter.take(2); | ||
1200 | //^^^^^^^^^^^^^ impl Iterator<Item = impl Iterator<Item = i32>> | ||
1201 | } | ||
1202 | "#, | ||
1203 | ); | ||
1204 | } | ||
1186 | } | 1205 | } |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 686cee3a1..aaf9b3b4b 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -77,6 +77,7 @@ pub use crate::{ | |||
77 | hover::{HoverAction, HoverConfig, HoverGotoTypeData, HoverResult}, | 77 | hover::{HoverAction, HoverConfig, HoverGotoTypeData, HoverResult}, |
78 | inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, | 78 | inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, |
79 | markup::Markup, | 79 | markup::Markup, |
80 | prime_caches::PrimeCachesProgress, | ||
80 | references::{ | 81 | references::{ |
81 | Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, RenameError, | 82 | Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, RenameError, |
82 | }, | 83 | }, |
@@ -223,8 +224,11 @@ impl Analysis { | |||
223 | self.with_db(|db| status::status(&*db, file_id)) | 224 | self.with_db(|db| status::status(&*db, file_id)) |
224 | } | 225 | } |
225 | 226 | ||
226 | pub fn prime_caches(&self, files: Vec<FileId>) -> Cancelable<()> { | 227 | pub fn prime_caches<F>(&self, cb: F) -> Cancelable<()> |
227 | self.with_db(|db| prime_caches::prime_caches(db, files)) | 228 | where |
229 | F: Fn(PrimeCachesProgress) + Sync + std::panic::UnwindSafe, | ||
230 | { | ||
231 | self.with_db(move |db| prime_caches::prime_caches(db, &cb)) | ||
228 | } | 232 | } |
229 | 233 | ||
230 | /// Gets the text of the source file. | 234 | /// Gets the text of the source file. |
diff --git a/crates/ide/src/prime_caches.rs b/crates/ide/src/prime_caches.rs index c5ab5a1d8..9687c2734 100644 --- a/crates/ide/src/prime_caches.rs +++ b/crates/ide/src/prime_caches.rs | |||
@@ -3,10 +3,45 @@ | |||
3 | //! request takes longer to compute. This modules implemented prepopulating of | 3 | //! request takes longer to compute. This modules implemented prepopulating of |
4 | //! various caches, it's not really advanced at the moment. | 4 | //! various caches, it's not really advanced at the moment. |
5 | 5 | ||
6 | use crate::{FileId, RootDatabase}; | 6 | use base_db::SourceDatabase; |
7 | use hir::db::DefDatabase; | ||
7 | 8 | ||
8 | pub(crate) fn prime_caches(db: &RootDatabase, files: Vec<FileId>) { | 9 | use crate::RootDatabase; |
9 | for file in files { | 10 | |
10 | let _ = crate::syntax_highlighting::highlight(db, file, None, false); | 11 | #[derive(Debug)] |
12 | pub enum PrimeCachesProgress { | ||
13 | Started, | ||
14 | /// We started indexing a crate. | ||
15 | StartedOnCrate { | ||
16 | on_crate: String, | ||
17 | n_done: usize, | ||
18 | n_total: usize, | ||
19 | }, | ||
20 | /// We finished indexing all crates. | ||
21 | Finished, | ||
22 | } | ||
23 | |||
24 | pub(crate) fn prime_caches(db: &RootDatabase, cb: &(dyn Fn(PrimeCachesProgress) + Sync)) { | ||
25 | let _p = profile::span("prime_caches"); | ||
26 | let graph = db.crate_graph(); | ||
27 | let topo = &graph.crates_in_topological_order(); | ||
28 | |||
29 | cb(PrimeCachesProgress::Started); | ||
30 | |||
31 | // FIXME: This would be easy to parallelize, since it's in the ideal ordering for that. | ||
32 | // Unfortunately rayon prevents panics from propagation out of a `scope`, which breaks | ||
33 | // cancellation, so we cannot use rayon. | ||
34 | for (i, krate) in topo.iter().enumerate() { | ||
35 | let crate_name = | ||
36 | graph[*krate].declaration_name.as_ref().map(ToString::to_string).unwrap_or_default(); | ||
37 | |||
38 | cb(PrimeCachesProgress::StartedOnCrate { | ||
39 | on_crate: crate_name, | ||
40 | n_done: i, | ||
41 | n_total: topo.len(), | ||
42 | }); | ||
43 | db.crate_def_map(*krate); | ||
11 | } | 44 | } |
45 | |||
46 | cb(PrimeCachesProgress::Finished); | ||
12 | } | 47 | } |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index d9fc25d88..6aafd6fd5 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -68,7 +68,7 @@ pub(crate) fn highlight( | |||
68 | // When we leave a node, the we use it to flatten the highlighted ranges. | 68 | // When we leave a node, the we use it to flatten the highlighted ranges. |
69 | let mut stack = HighlightedRangeStack::new(); | 69 | let mut stack = HighlightedRangeStack::new(); |
70 | 70 | ||
71 | let mut current_macro_call: Option<ast::MacroCall> = None; | 71 | let mut current_macro_call: Option<(ast::MacroCall, Option<MacroMatcherParseState>)> = None; |
72 | let mut format_string: Option<SyntaxElement> = None; | 72 | let mut format_string: Option<SyntaxElement> = None; |
73 | 73 | ||
74 | // Walk all nodes, keeping track of whether we are inside a macro or not. | 74 | // Walk all nodes, keeping track of whether we are inside a macro or not. |
@@ -92,7 +92,6 @@ pub(crate) fn highlight( | |||
92 | // Track "inside macro" state | 92 | // Track "inside macro" state |
93 | match event.clone().map(|it| it.into_node().and_then(ast::MacroCall::cast)) { | 93 | match event.clone().map(|it| it.into_node().and_then(ast::MacroCall::cast)) { |
94 | WalkEvent::Enter(Some(mc)) => { | 94 | WalkEvent::Enter(Some(mc)) => { |
95 | current_macro_call = Some(mc.clone()); | ||
96 | if let Some(range) = macro_call_range(&mc) { | 95 | if let Some(range) = macro_call_range(&mc) { |
97 | stack.add(HighlightedRange { | 96 | stack.add(HighlightedRange { |
98 | range, | 97 | range, |
@@ -100,7 +99,9 @@ pub(crate) fn highlight( | |||
100 | binding_hash: None, | 99 | binding_hash: None, |
101 | }); | 100 | }); |
102 | } | 101 | } |
102 | let mut is_macro_rules = None; | ||
103 | if let Some(name) = mc.is_macro_rules() { | 103 | if let Some(name) = mc.is_macro_rules() { |
104 | is_macro_rules = Some(MacroMatcherParseState::new()); | ||
104 | if let Some((highlight, binding_hash)) = highlight_element( | 105 | if let Some((highlight, binding_hash)) = highlight_element( |
105 | &sema, | 106 | &sema, |
106 | &mut bindings_shadow_count, | 107 | &mut bindings_shadow_count, |
@@ -114,10 +115,11 @@ pub(crate) fn highlight( | |||
114 | }); | 115 | }); |
115 | } | 116 | } |
116 | } | 117 | } |
118 | current_macro_call = Some((mc.clone(), is_macro_rules)); | ||
117 | continue; | 119 | continue; |
118 | } | 120 | } |
119 | WalkEvent::Leave(Some(mc)) => { | 121 | WalkEvent::Leave(Some(mc)) => { |
120 | assert!(current_macro_call == Some(mc)); | 122 | assert!(current_macro_call.map(|it| it.0) == Some(mc)); |
121 | current_macro_call = None; | 123 | current_macro_call = None; |
122 | format_string = None; | 124 | format_string = None; |
123 | } | 125 | } |
@@ -146,6 +148,20 @@ pub(crate) fn highlight( | |||
146 | WalkEvent::Leave(_) => continue, | 148 | WalkEvent::Leave(_) => continue, |
147 | }; | 149 | }; |
148 | 150 | ||
151 | // check if in matcher part of a macro_rules rule | ||
152 | if let Some((_, Some(ref mut state))) = current_macro_call { | ||
153 | if let Some(tok) = element.as_token() { | ||
154 | if matches!( | ||
155 | update_macro_rules_state(tok, state), | ||
156 | RuleState::Matcher | RuleState::Expander | ||
157 | ) { | ||
158 | if skip_metavariables(element.clone()) { | ||
159 | continue; | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
149 | let range = element.text_range(); | 165 | let range = element.text_range(); |
150 | 166 | ||
151 | let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT { | 167 | let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT { |
@@ -918,3 +934,99 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
918 | _ => default.into(), | 934 | _ => default.into(), |
919 | } | 935 | } |
920 | } | 936 | } |
937 | |||
938 | struct MacroMatcherParseState { | ||
939 | /// Opening and corresponding closing bracket of the matcher or expander of the current rule | ||
940 | paren_ty: Option<(SyntaxKind, SyntaxKind)>, | ||
941 | paren_level: usize, | ||
942 | rule_state: RuleState, | ||
943 | /// Whether we are inside the outer `{` `}` macro block that holds the rules | ||
944 | in_invoc_body: bool, | ||
945 | } | ||
946 | |||
947 | impl MacroMatcherParseState { | ||
948 | fn new() -> Self { | ||
949 | MacroMatcherParseState { | ||
950 | paren_ty: None, | ||
951 | paren_level: 0, | ||
952 | in_invoc_body: false, | ||
953 | rule_state: RuleState::None, | ||
954 | } | ||
955 | } | ||
956 | } | ||
957 | |||
958 | #[derive(Copy, Clone, PartialEq)] | ||
959 | enum RuleState { | ||
960 | Matcher, | ||
961 | Expander, | ||
962 | Between, | ||
963 | None, | ||
964 | } | ||
965 | |||
966 | impl RuleState { | ||
967 | fn transition(&mut self) { | ||
968 | *self = match self { | ||
969 | RuleState::Matcher => RuleState::Between, | ||
970 | RuleState::Expander => RuleState::None, | ||
971 | RuleState::Between => RuleState::Expander, | ||
972 | RuleState::None => RuleState::Matcher, | ||
973 | }; | ||
974 | } | ||
975 | } | ||
976 | |||
977 | fn update_macro_rules_state(tok: &SyntaxToken, state: &mut MacroMatcherParseState) -> RuleState { | ||
978 | if !state.in_invoc_body { | ||
979 | if tok.kind() == T!['{'] { | ||
980 | state.in_invoc_body = true; | ||
981 | } | ||
982 | return state.rule_state; | ||
983 | } | ||
984 | |||
985 | match state.paren_ty { | ||
986 | Some((open, close)) => { | ||
987 | if tok.kind() == open { | ||
988 | state.paren_level += 1; | ||
989 | } else if tok.kind() == close { | ||
990 | state.paren_level -= 1; | ||
991 | if state.paren_level == 0 { | ||
992 | let res = state.rule_state; | ||
993 | state.rule_state.transition(); | ||
994 | state.paren_ty = None; | ||
995 | return res; | ||
996 | } | ||
997 | } | ||
998 | } | ||
999 | None => { | ||
1000 | match tok.kind() { | ||
1001 | T!['('] => { | ||
1002 | state.paren_ty = Some((T!['('], T![')'])); | ||
1003 | } | ||
1004 | T!['{'] => { | ||
1005 | state.paren_ty = Some((T!['{'], T!['}'])); | ||
1006 | } | ||
1007 | T!['['] => { | ||
1008 | state.paren_ty = Some((T!['['], T![']'])); | ||
1009 | } | ||
1010 | _ => (), | ||
1011 | } | ||
1012 | if state.paren_ty.is_some() { | ||
1013 | state.paren_level = 1; | ||
1014 | state.rule_state.transition(); | ||
1015 | } | ||
1016 | } | ||
1017 | } | ||
1018 | state.rule_state | ||
1019 | } | ||
1020 | |||
1021 | fn skip_metavariables(element: SyntaxElement) -> bool { | ||
1022 | let tok = match element.as_token() { | ||
1023 | Some(tok) => tok, | ||
1024 | None => return false, | ||
1025 | }; | ||
1026 | let is_fragment = || tok.prev_token().map(|tok| tok.kind()) == Some(T![$]); | ||
1027 | match tok.kind() { | ||
1028 | IDENT if is_fragment() => true, | ||
1029 | kind if kind.is_keyword() && is_fragment() => true, | ||
1030 | _ => false, | ||
1031 | } | ||
1032 | } | ||
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index 1b681b2c6..43f1b32fd 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html | |||
@@ -37,7 +37,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
37 | </style> | 37 | </style> |
38 | <pre><code><span class="macro">macro_rules!</span> <span class="macro declaration">println</span> <span class="punctuation">{</span> | 38 | <pre><code><span class="macro">macro_rules!</span> <span class="macro declaration">println</span> <span class="punctuation">{</span> |
39 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<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> | 39 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<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> |
40 | <span class="punctuation">$</span><span class="keyword">crate</span><span class="punctuation">:</span><span class="punctuation">:</span>io<span class="punctuation">:</span><span class="punctuation">:</span>_print<span class="punctuation">(</span><span class="punctuation">$</span><span class="keyword">crate</span><span class="punctuation">:</span><span class="punctuation">:</span>format_args_nl<span class="punctuation">!</span><span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> | 40 | <span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>io<span class="punctuation">:</span><span class="punctuation">:</span>_print<span class="punctuation">(</span><span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>format_args_nl<span class="punctuation">!</span><span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> |
41 | <span class="punctuation">}</span><span class="punctuation">)</span> | 41 | <span class="punctuation">}</span><span class="punctuation">)</span> |
42 | <span class="punctuation">}</span> | 42 | <span class="punctuation">}</span> |
43 | #[rustc_builtin_macro] | 43 | #[rustc_builtin_macro] |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 1d8a3c404..0bb0928e4 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -62,7 +62,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
62 | 62 | ||
63 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 63 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> |
64 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> | 64 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> |
65 | <span class="value_param">f</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="self_keyword consuming">self</span><span class="punctuation">)</span> | 65 | <span class="value_param">f</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span> |
66 | <span class="punctuation">}</span> | 66 | <span class="punctuation">}</span> |
67 | 67 | ||
68 | <span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 68 | <span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
@@ -115,6 +115,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
115 | <span class="punctuation">}</span> | 115 | <span class="punctuation">}</span> |
116 | <span class="punctuation">}</span> | 116 | <span class="punctuation">}</span> |
117 | 117 | ||
118 | <span class="macro">macro_rules!</span> <span class="macro declaration">keyword_frag</span> <span class="punctuation">{</span> | ||
119 | <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">:</span>ty<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">)</span> | ||
120 | <span class="punctuation">}</span> | ||
121 | |||
118 | <span class="comment">// comment</span> | 122 | <span class="comment">// comment</span> |
119 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 123 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
120 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello, {}!"</span><span class="punctuation">,</span> <span class="numeric_literal">92</span><span class="punctuation">)</span><span class="punctuation">;</span> | 124 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello, {}!"</span><span class="punctuation">,</span> <span class="numeric_literal">92</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 694c4b7fa..126363b8b 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -89,6 +89,10 @@ macro_rules! noop { | |||
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | macro_rules! keyword_frag { | ||
93 | ($type:ty) => ($type) | ||
94 | } | ||
95 | |||
92 | // comment | 96 | // comment |
93 | fn main() { | 97 | fn main() { |
94 | println!("Hello, {}!", 92); | 98 | println!("Hello, {}!", 92); |
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 06b38d99c..fb18f9014 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -7,6 +7,7 @@ use std::{ | |||
7 | 7 | ||
8 | use base_db::VfsPath; | 8 | use base_db::VfsPath; |
9 | use crossbeam_channel::{select, Receiver}; | 9 | use crossbeam_channel::{select, Receiver}; |
10 | use ide::PrimeCachesProgress; | ||
10 | use ide::{Canceled, FileId}; | 11 | use ide::{Canceled, FileId}; |
11 | use lsp_server::{Connection, Notification, Request, Response}; | 12 | use lsp_server::{Connection, Notification, Request, Response}; |
12 | use lsp_types::notification::Notification as _; | 13 | use lsp_types::notification::Notification as _; |
@@ -61,7 +62,7 @@ pub(crate) enum Task { | |||
61 | Response(Response), | 62 | Response(Response), |
62 | Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>), | 63 | Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>), |
63 | Workspaces(Vec<anyhow::Result<ProjectWorkspace>>), | 64 | Workspaces(Vec<anyhow::Result<ProjectWorkspace>>), |
64 | Unit, | 65 | PrimeCaches(PrimeCachesProgress), |
65 | } | 66 | } |
66 | 67 | ||
67 | impl fmt::Debug for Event { | 68 | impl fmt::Debug for Event { |
@@ -197,7 +198,28 @@ impl GlobalState { | |||
197 | } | 198 | } |
198 | } | 199 | } |
199 | Task::Workspaces(workspaces) => self.switch_workspaces(workspaces), | 200 | Task::Workspaces(workspaces) => self.switch_workspaces(workspaces), |
200 | Task::Unit => (), | 201 | Task::PrimeCaches(progress) => { |
202 | let (state, message, fraction); | ||
203 | match progress { | ||
204 | PrimeCachesProgress::Started => { | ||
205 | state = Progress::Begin; | ||
206 | message = None; | ||
207 | fraction = 0.0; | ||
208 | } | ||
209 | PrimeCachesProgress::StartedOnCrate { on_crate, n_done, n_total } => { | ||
210 | state = Progress::Report; | ||
211 | message = Some(format!("{}/{} ({})", n_done, n_total, on_crate)); | ||
212 | fraction = Progress::fraction(n_done, n_total); | ||
213 | } | ||
214 | PrimeCachesProgress::Finished => { | ||
215 | state = Progress::End; | ||
216 | message = None; | ||
217 | fraction = 1.0; | ||
218 | } | ||
219 | }; | ||
220 | |||
221 | self.report_progress("indexing", state, message, Some(fraction)); | ||
222 | } | ||
201 | }, | 223 | }, |
202 | Event::Vfs(mut task) => { | 224 | Event::Vfs(mut task) => { |
203 | let _p = profile::span("GlobalState::handle_event/vfs"); | 225 | let _p = profile::span("GlobalState::handle_event/vfs"); |
@@ -573,12 +595,18 @@ impl GlobalState { | |||
573 | Task::Diagnostics(diagnostics) | 595 | Task::Diagnostics(diagnostics) |
574 | }) | 596 | }) |
575 | } | 597 | } |
576 | self.task_pool.handle.spawn({ | 598 | self.task_pool.handle.spawn_with_sender({ |
577 | let subs = subscriptions; | ||
578 | let snap = self.snapshot(); | 599 | let snap = self.snapshot(); |
579 | move || { | 600 | move |sender| { |
580 | snap.analysis.prime_caches(subs).unwrap_or_else(|_: Canceled| ()); | 601 | snap.analysis |
581 | Task::Unit | 602 | .prime_caches(|progress| { |
603 | sender.send(Task::PrimeCaches(progress)).unwrap(); | ||
604 | }) | ||
605 | .unwrap_or_else(|_: Canceled| { | ||
606 | // Pretend that we're done, so that the progress bar is removed. Otherwise | ||
607 | // the editor may complain about it already existing. | ||
608 | sender.send(Task::PrimeCaches(PrimeCachesProgress::Finished)).unwrap() | ||
609 | }); | ||
582 | } | 610 | } |
583 | }); | 611 | }); |
584 | } | 612 | } |
diff --git a/crates/rust-analyzer/src/thread_pool.rs b/crates/rust-analyzer/src/thread_pool.rs index 4fa502925..833893739 100644 --- a/crates/rust-analyzer/src/thread_pool.rs +++ b/crates/rust-analyzer/src/thread_pool.rs | |||
@@ -23,6 +23,17 @@ impl<T> TaskPool<T> { | |||
23 | }) | 23 | }) |
24 | } | 24 | } |
25 | 25 | ||
26 | pub(crate) fn spawn_with_sender<F>(&mut self, task: F) | ||
27 | where | ||
28 | F: FnOnce(Sender<T>) + Send + 'static, | ||
29 | T: Send + 'static, | ||
30 | { | ||
31 | self.inner.execute({ | ||
32 | let sender = self.sender.clone(); | ||
33 | move || task(sender) | ||
34 | }) | ||
35 | } | ||
36 | |||
26 | pub(crate) fn len(&self) -> usize { | 37 | pub(crate) fn len(&self) -> usize { |
27 | self.inner.queued_count() | 38 | self.inner.queued_count() |
28 | } | 39 | } |
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 3a184094c..74dbdfaf7 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -320,6 +320,10 @@ pub fn param(name: String, ty: String) -> ast::Param { | |||
320 | ast_from_text(&format!("fn f({}: {}) {{ }}", name, ty)) | 320 | ast_from_text(&format!("fn f({}: {}) {{ }}", name, ty)) |
321 | } | 321 | } |
322 | 322 | ||
323 | pub fn ret_type(ty: ast::Type) -> ast::RetType { | ||
324 | ast_from_text(&format!("fn f() -> {} {{ }}", ty)) | ||
325 | } | ||
326 | |||
323 | pub fn param_list(pats: impl IntoIterator<Item = ast::Param>) -> ast::ParamList { | 327 | pub fn param_list(pats: impl IntoIterator<Item = ast::Param>) -> ast::ParamList { |
324 | let args = pats.into_iter().join(", "); | 328 | let args = pats.into_iter().join(", "); |
325 | ast_from_text(&format!("fn f({}) {{ }}", args)) | 329 | ast_from_text(&format!("fn f({}) {{ }}", args)) |
@@ -350,14 +354,20 @@ pub fn fn_( | |||
350 | type_params: Option<ast::GenericParamList>, | 354 | type_params: Option<ast::GenericParamList>, |
351 | params: ast::ParamList, | 355 | params: ast::ParamList, |
352 | body: ast::BlockExpr, | 356 | body: ast::BlockExpr, |
357 | ret_type: Option<ast::RetType>, | ||
353 | ) -> ast::Fn { | 358 | ) -> ast::Fn { |
354 | let type_params = | 359 | let type_params = |
355 | if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() }; | 360 | if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() }; |
361 | let ret_type = if let Some(ret_type) = ret_type { format!("{} ", ret_type) } else { "".into() }; | ||
356 | let visibility = match visibility { | 362 | let visibility = match visibility { |
357 | None => String::new(), | 363 | None => String::new(), |
358 | Some(it) => format!("{} ", it), | 364 | Some(it) => format!("{} ", it), |
359 | }; | 365 | }; |
360 | ast_from_text(&format!("{}fn {}{}{} {}", visibility, fn_name, type_params, params, body)) | 366 | |
367 | ast_from_text(&format!( | ||
368 | "{}fn {}{}{} {}{}", | ||
369 | visibility, fn_name, type_params, params, ret_type, body | ||
370 | )) | ||
361 | } | 371 | } |
362 | 372 | ||
363 | fn ast_from_text<N: AstNode>(text: &str) -> N { | 373 | fn ast_from_text<N: AstNode>(text: &str) -> N { |