diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 31 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 132 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 41 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 166 |
5 files changed, 307 insertions, 82 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 443b057ab..c69e0efea 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -60,13 +60,10 @@ pub(super) fn lower( | |||
60 | params: Option<ast::ParamList>, | 60 | params: Option<ast::ParamList>, |
61 | body: Option<ast::Expr>, | 61 | body: Option<ast::Expr>, |
62 | ) -> (Body, BodySourceMap) { | 62 | ) -> (Body, BodySourceMap) { |
63 | let ctx = LowerCtx::new(db, expander.current_file_id.clone()); | ||
64 | |||
65 | ExprCollector { | 63 | ExprCollector { |
66 | db, | 64 | db, |
67 | def, | 65 | def, |
68 | expander, | 66 | expander, |
69 | ctx, | ||
70 | source_map: BodySourceMap::default(), | 67 | source_map: BodySourceMap::default(), |
71 | body: Body { | 68 | body: Body { |
72 | exprs: Arena::default(), | 69 | exprs: Arena::default(), |
@@ -83,7 +80,6 @@ struct ExprCollector<'a> { | |||
83 | db: &'a dyn DefDatabase, | 80 | db: &'a dyn DefDatabase, |
84 | def: DefWithBodyId, | 81 | def: DefWithBodyId, |
85 | expander: Expander, | 82 | expander: Expander, |
86 | ctx: LowerCtx, | ||
87 | body: Body, | 83 | body: Body, |
88 | source_map: BodySourceMap, | 84 | source_map: BodySourceMap, |
89 | } | 85 | } |
@@ -122,6 +118,10 @@ impl ExprCollector<'_> { | |||
122 | (self.body, self.source_map) | 118 | (self.body, self.source_map) |
123 | } | 119 | } |
124 | 120 | ||
121 | fn ctx(&self) -> LowerCtx { | ||
122 | LowerCtx::new(self.db, self.expander.current_file_id) | ||
123 | } | ||
124 | |||
125 | fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { | 125 | fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { |
126 | let src = self.expander.to_source(ptr); | 126 | let src = self.expander.to_source(ptr); |
127 | let id = self.make_expr(expr, Ok(src.clone())); | 127 | let id = self.make_expr(expr, Ok(src.clone())); |
@@ -268,7 +268,7 @@ impl ExprCollector<'_> { | |||
268 | }; | 268 | }; |
269 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 269 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
270 | let generic_args = | 270 | let generic_args = |
271 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it)); | 271 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); |
272 | self.alloc_expr( | 272 | self.alloc_expr( |
273 | Expr::MethodCall { receiver, method_name, args, generic_args }, | 273 | Expr::MethodCall { receiver, method_name, args, generic_args }, |
274 | syntax_ptr, | 274 | syntax_ptr, |
@@ -373,7 +373,7 @@ impl ExprCollector<'_> { | |||
373 | } | 373 | } |
374 | ast::Expr::CastExpr(e) => { | 374 | ast::Expr::CastExpr(e) => { |
375 | let expr = self.collect_expr_opt(e.expr()); | 375 | let expr = self.collect_expr_opt(e.expr()); |
376 | let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref()); | 376 | let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.type_ref()); |
377 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) | 377 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) |
378 | } | 378 | } |
379 | ast::Expr::RefExpr(e) => { | 379 | ast::Expr::RefExpr(e) => { |
@@ -396,7 +396,7 @@ impl ExprCollector<'_> { | |||
396 | for param in pl.params() { | 396 | for param in pl.params() { |
397 | let pat = self.collect_pat_opt(param.pat()); | 397 | let pat = self.collect_pat_opt(param.pat()); |
398 | let type_ref = | 398 | let type_ref = |
399 | param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); | 399 | param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); |
400 | args.push(pat); | 400 | args.push(pat); |
401 | arg_types.push(type_ref); | 401 | arg_types.push(type_ref); |
402 | } | 402 | } |
@@ -404,7 +404,7 @@ impl ExprCollector<'_> { | |||
404 | let ret_type = e | 404 | let ret_type = e |
405 | .ret_type() | 405 | .ret_type() |
406 | .and_then(|r| r.type_ref()) | 406 | .and_then(|r| r.type_ref()) |
407 | .map(|it| TypeRef::from_ast(&self.ctx, it)); | 407 | .map(|it| TypeRef::from_ast(&self.ctx(), it)); |
408 | let body = self.collect_expr_opt(e.body()); | 408 | let body = self.collect_expr_opt(e.body()); |
409 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) | 409 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) |
410 | } | 410 | } |
@@ -507,7 +507,8 @@ impl ExprCollector<'_> { | |||
507 | .map(|s| match s { | 507 | .map(|s| match s { |
508 | ast::Stmt::LetStmt(stmt) => { | 508 | ast::Stmt::LetStmt(stmt) => { |
509 | let pat = self.collect_pat_opt(stmt.pat()); | 509 | let pat = self.collect_pat_opt(stmt.pat()); |
510 | let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); | 510 | let type_ref = |
511 | stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); | ||
511 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 512 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
512 | Statement::Let { pat, type_ref, initializer } | 513 | Statement::Let { pat, type_ref, initializer } |
513 | } | 514 | } |
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index 115ad8328..c2168222e 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs | |||
@@ -564,6 +564,37 @@ fn main() { | |||
564 | } | 564 | } |
565 | 565 | ||
566 | #[test] | 566 | #[test] |
567 | fn issue_4465_dollar_crate_at_type() { | ||
568 | assert_snapshot!( | ||
569 | infer(r#" | ||
570 | pub struct Foo {} | ||
571 | pub fn anything<T>() -> T { | ||
572 | loop {} | ||
573 | } | ||
574 | macro_rules! foo { | ||
575 | () => {{ | ||
576 | let r: $crate::Foo = anything(); | ||
577 | r | ||
578 | }}; | ||
579 | } | ||
580 | fn main() { | ||
581 | let _a = foo!(); | ||
582 | } | ||
583 | "#), @r###" | ||
584 | 45..60 '{ loop {} }': T | ||
585 | 51..58 'loop {}': ! | ||
586 | 56..58 '{}': () | ||
587 | !0..31 '{letr:...g();r}': Foo | ||
588 | !4..5 'r': Foo | ||
589 | !18..26 'anything': fn anything<Foo>() -> Foo | ||
590 | !18..28 'anything()': Foo | ||
591 | !29..30 'r': Foo | ||
592 | 164..188 '{ ...!(); }': () | ||
593 | 174..176 '_a': Foo | ||
594 | "###); | ||
595 | } | ||
596 | |||
597 | #[test] | ||
567 | fn issue_4053_diesel_where_clauses() { | 598 | fn issue_4053_diesel_where_clauses() { |
568 | assert_snapshot!( | 599 | assert_snapshot!( |
569 | infer(r#" | 600 | infer(r#" |
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 9d32cbc7a..c49aacf98 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1617,6 +1617,138 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) { | |||
1617 | } | 1617 | } |
1618 | 1618 | ||
1619 | #[test] | 1619 | #[test] |
1620 | fn fn_ptr_and_item() { | ||
1621 | assert_snapshot!( | ||
1622 | infer(r#" | ||
1623 | #[lang="fn_once"] | ||
1624 | trait FnOnce<Args> { | ||
1625 | type Output; | ||
1626 | |||
1627 | fn call_once(self, args: Args) -> Self::Output; | ||
1628 | } | ||
1629 | |||
1630 | trait Foo<T> { | ||
1631 | fn foo(&self) -> T; | ||
1632 | } | ||
1633 | |||
1634 | struct Bar<T>(T); | ||
1635 | |||
1636 | impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { | ||
1637 | fn foo(&self) -> (A1, R) {} | ||
1638 | } | ||
1639 | |||
1640 | enum Opt<T> { None, Some(T) } | ||
1641 | impl<T> Opt<T> { | ||
1642 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} | ||
1643 | } | ||
1644 | |||
1645 | fn test() { | ||
1646 | let bar: Bar<fn(u8) -> u32>; | ||
1647 | bar.foo(); | ||
1648 | |||
1649 | let opt: Opt<u8>; | ||
1650 | let f: fn(u8) -> u32; | ||
1651 | opt.map(f); | ||
1652 | } | ||
1653 | "#), | ||
1654 | @r###" | ||
1655 | 75..79 'self': Self | ||
1656 | 81..85 'args': Args | ||
1657 | 140..144 'self': &Self | ||
1658 | 244..248 'self': &Bar<F> | ||
1659 | 261..263 '{}': () | ||
1660 | 347..351 'self': Opt<T> | ||
1661 | 353..354 'f': F | ||
1662 | 369..371 '{}': () | ||
1663 | 385..501 '{ ...(f); }': () | ||
1664 | 395..398 'bar': Bar<fn(u8) -> u32> | ||
1665 | 424..427 'bar': Bar<fn(u8) -> u32> | ||
1666 | 424..433 'bar.foo()': {unknown} | ||
1667 | 444..447 'opt': Opt<u8> | ||
1668 | 466..467 'f': fn(u8) -> u32 | ||
1669 | 488..491 'opt': Opt<u8> | ||
1670 | 488..498 'opt.map(f)': Opt<FnOnce::Output<fn(u8) -> u32, (u8,)>> | ||
1671 | 496..497 'f': fn(u8) -> u32 | ||
1672 | "### | ||
1673 | ); | ||
1674 | } | ||
1675 | |||
1676 | #[test] | ||
1677 | fn fn_trait_deref_with_ty_default() { | ||
1678 | assert_snapshot!( | ||
1679 | infer(r#" | ||
1680 | #[lang = "deref"] | ||
1681 | trait Deref { | ||
1682 | type Target; | ||
1683 | |||
1684 | fn deref(&self) -> &Self::Target; | ||
1685 | } | ||
1686 | |||
1687 | #[lang="fn_once"] | ||
1688 | trait FnOnce<Args> { | ||
1689 | type Output; | ||
1690 | |||
1691 | fn call_once(self, args: Args) -> Self::Output; | ||
1692 | } | ||
1693 | |||
1694 | struct Foo; | ||
1695 | |||
1696 | impl Foo { | ||
1697 | fn foo(&self) -> usize {} | ||
1698 | } | ||
1699 | |||
1700 | struct Lazy<T, F = fn() -> T>(F); | ||
1701 | |||
1702 | impl<T, F> Lazy<T, F> { | ||
1703 | pub fn new(f: F) -> Lazy<T, F> {} | ||
1704 | } | ||
1705 | |||
1706 | impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { | ||
1707 | type Target = T; | ||
1708 | } | ||
1709 | |||
1710 | fn test() { | ||
1711 | let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); | ||
1712 | let r1 = lazy1.foo(); | ||
1713 | |||
1714 | fn make_foo_fn() -> Foo {} | ||
1715 | let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; | ||
1716 | let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); | ||
1717 | let r2 = lazy2.foo(); | ||
1718 | } | ||
1719 | "#), | ||
1720 | @r###" | ||
1721 | 65..69 'self': &Self | ||
1722 | 166..170 'self': Self | ||
1723 | 172..176 'args': Args | ||
1724 | 240..244 'self': &Foo | ||
1725 | 255..257 '{}': () | ||
1726 | 335..336 'f': F | ||
1727 | 355..357 '{}': () | ||
1728 | 444..690 '{ ...o(); }': () | ||
1729 | 454..459 'lazy1': Lazy<Foo, fn() -> T> | ||
1730 | 476..485 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T> | ||
1731 | 476..493 'Lazy::...| Foo)': Lazy<Foo, fn() -> T> | ||
1732 | 486..492 '|| Foo': || -> T | ||
1733 | 489..492 'Foo': Foo | ||
1734 | 503..505 'r1': {unknown} | ||
1735 | 508..513 'lazy1': Lazy<Foo, fn() -> T> | ||
1736 | 508..519 'lazy1.foo()': {unknown} | ||
1737 | 561..576 'make_foo_fn_ptr': fn() -> Foo | ||
1738 | 592..603 'make_foo_fn': fn make_foo_fn() -> Foo | ||
1739 | 613..618 'lazy2': Lazy<Foo, fn() -> T> | ||
1740 | 635..644 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T> | ||
1741 | 635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> T> | ||
1742 | 645..660 'make_foo_fn_ptr': fn() -> Foo | ||
1743 | 671..673 'r2': {unknown} | ||
1744 | 676..681 'lazy2': Lazy<Foo, fn() -> T> | ||
1745 | 676..687 'lazy2.foo()': {unknown} | ||
1746 | 550..552 '{}': () | ||
1747 | "### | ||
1748 | ); | ||
1749 | } | ||
1750 | |||
1751 | #[test] | ||
1620 | fn closure_1() { | 1752 | fn closure_1() { |
1621 | assert_snapshot!( | 1753 | assert_snapshot!( |
1622 | infer(r#" | 1754 | infer(r#" |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 53aee833d..b5dc6f0fa 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -33,6 +33,36 @@ pub struct Config { | |||
33 | pub inlay_hints: InlayHintsConfig, | 33 | pub inlay_hints: InlayHintsConfig, |
34 | pub completion: CompletionConfig, | 34 | pub completion: CompletionConfig, |
35 | pub call_info_full: bool, | 35 | pub call_info_full: bool, |
36 | pub lens: LensConfig, | ||
37 | } | ||
38 | |||
39 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
40 | pub struct LensConfig { | ||
41 | pub run: bool, | ||
42 | pub debug: bool, | ||
43 | pub impementations: bool, | ||
44 | } | ||
45 | |||
46 | impl Default for LensConfig { | ||
47 | fn default() -> Self { | ||
48 | Self { run: true, debug: true, impementations: true } | ||
49 | } | ||
50 | } | ||
51 | |||
52 | impl LensConfig { | ||
53 | pub const NO_LENS: LensConfig = Self { run: false, debug: false, impementations: false }; | ||
54 | |||
55 | pub fn any(&self) -> bool { | ||
56 | self.impementations || self.runnable() | ||
57 | } | ||
58 | |||
59 | pub fn none(&self) -> bool { | ||
60 | !self.any() | ||
61 | } | ||
62 | |||
63 | pub fn runnable(&self) -> bool { | ||
64 | self.run || self.debug | ||
65 | } | ||
36 | } | 66 | } |
37 | 67 | ||
38 | #[derive(Debug, Clone)] | 68 | #[derive(Debug, Clone)] |
@@ -107,6 +137,7 @@ impl Default for Config { | |||
107 | ..CompletionConfig::default() | 137 | ..CompletionConfig::default() |
108 | }, | 138 | }, |
109 | call_info_full: true, | 139 | call_info_full: true, |
140 | lens: LensConfig::default(), | ||
110 | } | 141 | } |
111 | } | 142 | } |
112 | } | 143 | } |
@@ -196,6 +227,16 @@ impl Config { | |||
196 | set(value, "/completion/addCallArgumentSnippets", &mut self.completion.add_call_argument_snippets); | 227 | set(value, "/completion/addCallArgumentSnippets", &mut self.completion.add_call_argument_snippets); |
197 | set(value, "/callInfo/full", &mut self.call_info_full); | 228 | set(value, "/callInfo/full", &mut self.call_info_full); |
198 | 229 | ||
230 | let mut lens_enabled = true; | ||
231 | set(value, "/lens/enable", &mut lens_enabled); | ||
232 | if lens_enabled { | ||
233 | set(value, "/lens/run", &mut self.lens.run); | ||
234 | set(value, "/lens/debug", &mut self.lens.debug); | ||
235 | set(value, "/lens/implementations", &mut self.lens.impementations); | ||
236 | } else { | ||
237 | self.lens = LensConfig::NO_LENS; | ||
238 | } | ||
239 | |||
199 | log::info!("Config::update() = {:#?}", self); | 240 | log::info!("Config::update() = {:#?}", self); |
200 | 241 | ||
201 | fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option<T> { | 242 | fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option<T> { |
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 6b14830b6..e67556752 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs | |||
@@ -812,88 +812,108 @@ pub fn handle_code_lens( | |||
812 | params: lsp_types::CodeLensParams, | 812 | params: lsp_types::CodeLensParams, |
813 | ) -> Result<Option<Vec<CodeLens>>> { | 813 | ) -> Result<Option<Vec<CodeLens>>> { |
814 | let _p = profile("handle_code_lens"); | 814 | let _p = profile("handle_code_lens"); |
815 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | ||
816 | let line_index = world.analysis().file_line_index(file_id)?; | ||
817 | |||
818 | let mut lenses: Vec<CodeLens> = Default::default(); | 815 | let mut lenses: Vec<CodeLens> = Default::default(); |
819 | 816 | ||
817 | if world.config.lens.none() { | ||
818 | // early return before any db query! | ||
819 | return Ok(Some(lenses)); | ||
820 | } | ||
821 | |||
822 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | ||
823 | let line_index = world.analysis().file_line_index(file_id)?; | ||
820 | let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; | 824 | let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; |
821 | // Gather runnables | 825 | |
822 | for runnable in world.analysis().runnables(file_id)? { | 826 | if world.config.lens.runnable() { |
823 | let title = match &runnable.kind { | 827 | // Gather runnables |
824 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => "▶\u{fe0e} Run Test", | 828 | for runnable in world.analysis().runnables(file_id)? { |
825 | RunnableKind::DocTest { .. } => "▶\u{fe0e} Run Doctest", | 829 | let (run_title, debugee) = match &runnable.kind { |
826 | RunnableKind::Bench { .. } => "Run Bench", | 830 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { |
827 | RunnableKind::Bin => { | 831 | ("▶️\u{fe0e}Run Test", true) |
828 | // Do not suggest binary run on other target than binary | ||
829 | match &cargo_spec { | ||
830 | Some(spec) => match spec.target_kind { | ||
831 | TargetKind::Bin => "Run", | ||
832 | _ => continue, | ||
833 | }, | ||
834 | None => continue, | ||
835 | } | 832 | } |
833 | RunnableKind::DocTest { .. } => { | ||
834 | // cargo does not support -no-run for doctests | ||
835 | ("▶️\u{fe0e}Run Doctest", false) | ||
836 | } | ||
837 | RunnableKind::Bench { .. } => { | ||
838 | // Nothing wrong with bench debugging | ||
839 | ("Run Bench", true) | ||
840 | } | ||
841 | RunnableKind::Bin => { | ||
842 | // Do not suggest binary run on other target than binary | ||
843 | match &cargo_spec { | ||
844 | Some(spec) => match spec.target_kind { | ||
845 | TargetKind::Bin => ("Run", true), | ||
846 | _ => continue, | ||
847 | }, | ||
848 | None => continue, | ||
849 | } | ||
850 | } | ||
851 | }; | ||
852 | |||
853 | let mut r = to_lsp_runnable(&world, file_id, runnable)?; | ||
854 | if world.config.lens.run { | ||
855 | let lens = CodeLens { | ||
856 | range: r.range, | ||
857 | command: Some(Command { | ||
858 | title: run_title.to_string(), | ||
859 | command: "rust-analyzer.runSingle".into(), | ||
860 | arguments: Some(vec![to_value(&r).unwrap()]), | ||
861 | }), | ||
862 | data: None, | ||
863 | }; | ||
864 | lenses.push(lens); | ||
836 | } | 865 | } |
837 | } | ||
838 | .to_string(); | ||
839 | let mut r = to_lsp_runnable(&world, file_id, runnable)?; | ||
840 | let lens = CodeLens { | ||
841 | range: r.range, | ||
842 | command: Some(Command { | ||
843 | title, | ||
844 | command: "rust-analyzer.runSingle".into(), | ||
845 | arguments: Some(vec![to_value(&r).unwrap()]), | ||
846 | }), | ||
847 | data: None, | ||
848 | }; | ||
849 | lenses.push(lens); | ||
850 | 866 | ||
851 | if r.args[0] == "run" { | 867 | if debugee && world.config.lens.debug { |
852 | r.args[0] = "build".into(); | 868 | if r.args[0] == "run" { |
853 | } else { | 869 | r.args[0] = "build".into(); |
854 | r.args.push("--no-run".into()); | 870 | } else { |
871 | r.args.push("--no-run".into()); | ||
872 | } | ||
873 | let debug_lens = CodeLens { | ||
874 | range: r.range, | ||
875 | command: Some(Command { | ||
876 | title: "Debug".into(), | ||
877 | command: "rust-analyzer.debugSingle".into(), | ||
878 | arguments: Some(vec![to_value(r).unwrap()]), | ||
879 | }), | ||
880 | data: None, | ||
881 | }; | ||
882 | lenses.push(debug_lens); | ||
883 | } | ||
855 | } | 884 | } |
856 | let debug_lens = CodeLens { | ||
857 | range: r.range, | ||
858 | command: Some(Command { | ||
859 | title: "Debug".into(), | ||
860 | command: "rust-analyzer.debugSingle".into(), | ||
861 | arguments: Some(vec![to_value(r).unwrap()]), | ||
862 | }), | ||
863 | data: None, | ||
864 | }; | ||
865 | lenses.push(debug_lens); | ||
866 | } | 885 | } |
867 | 886 | ||
868 | // Handle impls | 887 | if world.config.lens.impementations { |
869 | lenses.extend( | 888 | // Handle impls |
870 | world | 889 | lenses.extend( |
871 | .analysis() | 890 | world |
872 | .file_structure(file_id)? | 891 | .analysis() |
873 | .into_iter() | 892 | .file_structure(file_id)? |
874 | .filter(|it| match it.kind { | 893 | .into_iter() |
875 | SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, | 894 | .filter(|it| match it.kind { |
876 | _ => false, | 895 | SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, |
877 | }) | 896 | _ => false, |
878 | .map(|it| { | 897 | }) |
879 | let range = to_proto::range(&line_index, it.node_range); | 898 | .map(|it| { |
880 | let pos = range.start; | 899 | let range = to_proto::range(&line_index, it.node_range); |
881 | let lens_params = lsp_types::request::GotoImplementationParams { | 900 | let pos = range.start; |
882 | text_document_position_params: lsp_types::TextDocumentPositionParams::new( | 901 | let lens_params = lsp_types::request::GotoImplementationParams { |
883 | params.text_document.clone(), | 902 | text_document_position_params: lsp_types::TextDocumentPositionParams::new( |
884 | pos, | 903 | params.text_document.clone(), |
885 | ), | 904 | pos, |
886 | work_done_progress_params: Default::default(), | 905 | ), |
887 | partial_result_params: Default::default(), | 906 | work_done_progress_params: Default::default(), |
888 | }; | 907 | partial_result_params: Default::default(), |
889 | CodeLens { | 908 | }; |
890 | range, | 909 | CodeLens { |
891 | command: None, | 910 | range, |
892 | data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()), | 911 | command: None, |
893 | } | 912 | data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()), |
894 | }), | 913 | } |
895 | ); | 914 | }), |
896 | 915 | ); | |
916 | } | ||
897 | Ok(Some(lenses)) | 917 | Ok(Some(lenses)) |
898 | } | 918 | } |
899 | 919 | ||