diff options
-rw-r--r-- | crates/base_db/src/fixture.rs | 3 | ||||
-rw-r--r-- | crates/base_db/src/input.rs | 13 | ||||
-rw-r--r-- | crates/cfg/src/lib.rs | 20 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 135 | ||||
-rw-r--r-- | crates/ide/src/lib.rs | 9 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/attribute.rs | 15 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/attribute/cfg.rs | 112 | ||||
-rw-r--r-- | crates/proc_macro_test/build.rs | 14 | ||||
-rw-r--r-- | crates/project_model/src/workspace.rs | 11 | ||||
-rw-r--r-- | crates/rust-analyzer/src/bin/main.rs | 9 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 87 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 24 | ||||
-rw-r--r-- | crates/syntax/src/ptr.rs | 2 | ||||
-rw-r--r-- | docs/dev/README.md | 3 | ||||
-rw-r--r-- | editors/code/package-lock.json | 62 | ||||
-rw-r--r-- | editors/code/package.json | 2 |
17 files changed, 389 insertions, 136 deletions
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index 6ce377710..7d5d12e63 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs | |||
@@ -128,6 +128,7 @@ impl ChangeFixture { | |||
128 | file_id, | 128 | file_id, |
129 | meta.edition, | 129 | meta.edition, |
130 | Some(crate_name.clone().into()), | 130 | Some(crate_name.clone().into()), |
131 | meta.cfg.clone(), | ||
131 | meta.cfg, | 132 | meta.cfg, |
132 | meta.env, | 133 | meta.env, |
133 | Default::default(), | 134 | Default::default(), |
@@ -157,6 +158,7 @@ impl ChangeFixture { | |||
157 | crate_root, | 158 | crate_root, |
158 | Edition::Edition2018, | 159 | Edition::Edition2018, |
159 | Some(CrateName::new("test").unwrap().into()), | 160 | Some(CrateName::new("test").unwrap().into()), |
161 | default_cfg.clone(), | ||
160 | default_cfg, | 162 | default_cfg, |
161 | Env::default(), | 163 | Env::default(), |
162 | Default::default(), | 164 | Default::default(), |
@@ -186,6 +188,7 @@ impl ChangeFixture { | |||
186 | Edition::Edition2021, | 188 | Edition::Edition2021, |
187 | Some(CrateDisplayName::from_canonical_name("core".to_string())), | 189 | Some(CrateDisplayName::from_canonical_name("core".to_string())), |
188 | CfgOptions::default(), | 190 | CfgOptions::default(), |
191 | CfgOptions::default(), | ||
189 | Env::default(), | 192 | Env::default(), |
190 | Vec::new(), | 193 | Vec::new(), |
191 | ); | 194 | ); |
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs index 23cb0c839..0c51a59a0 100644 --- a/crates/base_db/src/input.rs +++ b/crates/base_db/src/input.rs | |||
@@ -189,6 +189,7 @@ pub struct CrateData { | |||
189 | /// `Dependency` matters), this name should only be used for UI. | 189 | /// `Dependency` matters), this name should only be used for UI. |
190 | pub display_name: Option<CrateDisplayName>, | 190 | pub display_name: Option<CrateDisplayName>, |
191 | pub cfg_options: CfgOptions, | 191 | pub cfg_options: CfgOptions, |
192 | pub potential_cfg_options: CfgOptions, | ||
192 | pub env: Env, | 193 | pub env: Env, |
193 | pub dependencies: Vec<Dependency>, | 194 | pub dependencies: Vec<Dependency>, |
194 | pub proc_macro: Vec<ProcMacro>, | 195 | pub proc_macro: Vec<ProcMacro>, |
@@ -219,6 +220,7 @@ impl CrateGraph { | |||
219 | edition: Edition, | 220 | edition: Edition, |
220 | display_name: Option<CrateDisplayName>, | 221 | display_name: Option<CrateDisplayName>, |
221 | cfg_options: CfgOptions, | 222 | cfg_options: CfgOptions, |
223 | potential_cfg_options: CfgOptions, | ||
222 | env: Env, | 224 | env: Env, |
223 | proc_macro: Vec<ProcMacro>, | 225 | proc_macro: Vec<ProcMacro>, |
224 | ) -> CrateId { | 226 | ) -> CrateId { |
@@ -227,6 +229,7 @@ impl CrateGraph { | |||
227 | edition, | 229 | edition, |
228 | display_name, | 230 | display_name, |
229 | cfg_options, | 231 | cfg_options, |
232 | potential_cfg_options, | ||
230 | env, | 233 | env, |
231 | proc_macro, | 234 | proc_macro, |
232 | dependencies: Vec::new(), | 235 | dependencies: Vec::new(), |
@@ -504,6 +507,7 @@ mod tests { | |||
504 | Edition2018, | 507 | Edition2018, |
505 | None, | 508 | None, |
506 | CfgOptions::default(), | 509 | CfgOptions::default(), |
510 | CfgOptions::default(), | ||
507 | Env::default(), | 511 | Env::default(), |
508 | Default::default(), | 512 | Default::default(), |
509 | ); | 513 | ); |
@@ -512,6 +516,7 @@ mod tests { | |||
512 | Edition2018, | 516 | Edition2018, |
513 | None, | 517 | None, |
514 | CfgOptions::default(), | 518 | CfgOptions::default(), |
519 | CfgOptions::default(), | ||
515 | Env::default(), | 520 | Env::default(), |
516 | Default::default(), | 521 | Default::default(), |
517 | ); | 522 | ); |
@@ -520,6 +525,7 @@ mod tests { | |||
520 | Edition2018, | 525 | Edition2018, |
521 | None, | 526 | None, |
522 | CfgOptions::default(), | 527 | CfgOptions::default(), |
528 | CfgOptions::default(), | ||
523 | Env::default(), | 529 | Env::default(), |
524 | Default::default(), | 530 | Default::default(), |
525 | ); | 531 | ); |
@@ -536,6 +542,7 @@ mod tests { | |||
536 | Edition2018, | 542 | Edition2018, |
537 | None, | 543 | None, |
538 | CfgOptions::default(), | 544 | CfgOptions::default(), |
545 | CfgOptions::default(), | ||
539 | Env::default(), | 546 | Env::default(), |
540 | Default::default(), | 547 | Default::default(), |
541 | ); | 548 | ); |
@@ -544,6 +551,7 @@ mod tests { | |||
544 | Edition2018, | 551 | Edition2018, |
545 | None, | 552 | None, |
546 | CfgOptions::default(), | 553 | CfgOptions::default(), |
554 | CfgOptions::default(), | ||
547 | Env::default(), | 555 | Env::default(), |
548 | Default::default(), | 556 | Default::default(), |
549 | ); | 557 | ); |
@@ -559,6 +567,7 @@ mod tests { | |||
559 | Edition2018, | 567 | Edition2018, |
560 | None, | 568 | None, |
561 | CfgOptions::default(), | 569 | CfgOptions::default(), |
570 | CfgOptions::default(), | ||
562 | Env::default(), | 571 | Env::default(), |
563 | Default::default(), | 572 | Default::default(), |
564 | ); | 573 | ); |
@@ -567,6 +576,7 @@ mod tests { | |||
567 | Edition2018, | 576 | Edition2018, |
568 | None, | 577 | None, |
569 | CfgOptions::default(), | 578 | CfgOptions::default(), |
579 | CfgOptions::default(), | ||
570 | Env::default(), | 580 | Env::default(), |
571 | Default::default(), | 581 | Default::default(), |
572 | ); | 582 | ); |
@@ -575,6 +585,7 @@ mod tests { | |||
575 | Edition2018, | 585 | Edition2018, |
576 | None, | 586 | None, |
577 | CfgOptions::default(), | 587 | CfgOptions::default(), |
588 | CfgOptions::default(), | ||
578 | Env::default(), | 589 | Env::default(), |
579 | Default::default(), | 590 | Default::default(), |
580 | ); | 591 | ); |
@@ -590,6 +601,7 @@ mod tests { | |||
590 | Edition2018, | 601 | Edition2018, |
591 | None, | 602 | None, |
592 | CfgOptions::default(), | 603 | CfgOptions::default(), |
604 | CfgOptions::default(), | ||
593 | Env::default(), | 605 | Env::default(), |
594 | Default::default(), | 606 | Default::default(), |
595 | ); | 607 | ); |
@@ -598,6 +610,7 @@ mod tests { | |||
598 | Edition2018, | 610 | Edition2018, |
599 | None, | 611 | None, |
600 | CfgOptions::default(), | 612 | CfgOptions::default(), |
613 | CfgOptions::default(), | ||
601 | Env::default(), | 614 | Env::default(), |
602 | Default::default(), | 615 | Default::default(), |
603 | ); | 616 | ); |
diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index 916d39a0b..9a4baa636 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs | |||
@@ -50,6 +50,26 @@ impl CfgOptions { | |||
50 | self.enabled.remove(&atom); | 50 | self.enabled.remove(&atom); |
51 | } | 51 | } |
52 | } | 52 | } |
53 | |||
54 | pub fn get_cfg_keys(&self) -> Vec<&SmolStr> { | ||
55 | self.enabled | ||
56 | .iter() | ||
57 | .map(|x| match x { | ||
58 | CfgAtom::Flag(key) => key, | ||
59 | CfgAtom::KeyValue { key, .. } => key, | ||
60 | }) | ||
61 | .collect() | ||
62 | } | ||
63 | |||
64 | pub fn get_cfg_values(&self, cfg_key: &str) -> Vec<&SmolStr> { | ||
65 | self.enabled | ||
66 | .iter() | ||
67 | .filter_map(|x| match x { | ||
68 | CfgAtom::KeyValue { key, value } if cfg_key == key => Some(value), | ||
69 | _ => None, | ||
70 | }) | ||
71 | .collect() | ||
72 | } | ||
53 | } | 73 | } |
54 | 74 | ||
55 | #[derive(Clone, Debug, PartialEq, Eq)] | 75 | #[derive(Clone, Debug, PartialEq, Eq)] |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 88490fea9..30cc34403 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -233,6 +233,10 @@ impl Crate { | |||
233 | pub fn cfg(&self, db: &dyn HirDatabase) -> CfgOptions { | 233 | pub fn cfg(&self, db: &dyn HirDatabase) -> CfgOptions { |
234 | db.crate_graph()[self.id].cfg_options.clone() | 234 | db.crate_graph()[self.id].cfg_options.clone() |
235 | } | 235 | } |
236 | |||
237 | pub fn potential_cfg(&self, db: &dyn HirDatabase) -> CfgOptions { | ||
238 | db.crate_graph()[self.id].potential_cfg_options.clone() | ||
239 | } | ||
236 | } | 240 | } |
237 | 241 | ||
238 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 242 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 0c1da8774..c6d6bb74a 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use either::Either; | 1 | use either::Either; |
2 | use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay}; | 2 | use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics}; |
3 | use ide_db::{ | 3 | use ide_db::{ |
4 | base_db::SourceDatabase, | 4 | base_db::SourceDatabase, |
5 | defs::{Definition, NameClass, NameRefClass}, | 5 | defs::{Definition, NameClass, NameRefClass}, |
@@ -30,39 +30,20 @@ use crate::{ | |||
30 | 30 | ||
31 | #[derive(Clone, Debug, PartialEq, Eq)] | 31 | #[derive(Clone, Debug, PartialEq, Eq)] |
32 | pub struct HoverConfig { | 32 | pub struct HoverConfig { |
33 | pub implementations: bool, | ||
34 | pub references: bool, | ||
35 | pub run: bool, | ||
36 | pub debug: bool, | ||
37 | pub goto_type_def: bool, | ||
38 | pub links_in_hover: bool, | 33 | pub links_in_hover: bool, |
39 | pub markdown: bool, | 34 | pub documentation: Option<HoverDocFormat>, |
40 | pub documentation: bool, | ||
41 | } | 35 | } |
42 | 36 | ||
43 | impl HoverConfig { | 37 | impl HoverConfig { |
44 | pub const NO_ACTIONS: Self = Self { | 38 | fn markdown(&self) -> bool { |
45 | implementations: false, | 39 | matches!(self.documentation, Some(HoverDocFormat::Markdown)) |
46 | references: false, | ||
47 | run: false, | ||
48 | debug: false, | ||
49 | goto_type_def: false, | ||
50 | links_in_hover: true, | ||
51 | markdown: true, | ||
52 | documentation: true, | ||
53 | }; | ||
54 | |||
55 | pub fn any_actions(&self) -> bool { | ||
56 | self.implementations || self.references || self.runnable() || self.goto_type_def | ||
57 | } | ||
58 | |||
59 | pub fn no_actions(&self) -> bool { | ||
60 | !self.any_actions() | ||
61 | } | 40 | } |
41 | } | ||
62 | 42 | ||
63 | pub fn runnable(&self) -> bool { | 43 | #[derive(Clone, Debug, PartialEq, Eq)] |
64 | self.run || self.debug | 44 | pub enum HoverDocFormat { |
65 | } | 45 | Markdown, |
46 | PlainText, | ||
66 | } | 47 | } |
67 | 48 | ||
68 | #[derive(Debug, Clone)] | 49 | #[derive(Debug, Clone)] |
@@ -95,9 +76,7 @@ pub struct HoverResult { | |||
95 | pub(crate) fn hover( | 76 | pub(crate) fn hover( |
96 | db: &RootDatabase, | 77 | db: &RootDatabase, |
97 | position: FilePosition, | 78 | position: FilePosition, |
98 | links_in_hover: bool, | 79 | config: &HoverConfig, |
99 | documentation: bool, | ||
100 | markdown: bool, | ||
101 | ) -> Option<RangeInfo<HoverResult>> { | 80 | ) -> Option<RangeInfo<HoverResult>> { |
102 | let sema = hir::Semantics::new(db); | 81 | let sema = hir::Semantics::new(db); |
103 | let file = sema.parse(position.file_id).syntax().clone(); | 82 | let file = sema.parse(position.file_id).syntax().clone(); |
@@ -156,10 +135,8 @@ pub(crate) fn hover( | |||
156 | } | 135 | } |
157 | _ => None, | 136 | _ => None, |
158 | }; | 137 | }; |
159 | if let Some(markup) = | 138 | if let Some(markup) = hover_for_definition(db, definition, famous_defs.as_ref(), config) { |
160 | hover_for_definition(db, definition, famous_defs.as_ref(), documentation) | 139 | res.markup = process_markup(sema.db, definition, &markup, config); |
161 | { | ||
162 | res.markup = process_markup(sema.db, definition, &markup, links_in_hover, markdown); | ||
163 | if let Some(action) = show_implementations_action(db, definition) { | 140 | if let Some(action) = show_implementations_action(db, definition) { |
164 | res.actions.push(action); | 141 | res.actions.push(action); |
165 | } | 142 | } |
@@ -181,8 +158,7 @@ pub(crate) fn hover( | |||
181 | } | 158 | } |
182 | } | 159 | } |
183 | 160 | ||
184 | if let res @ Some(_) = hover_for_keyword(&sema, links_in_hover, markdown, documentation, &token) | 161 | if let res @ Some(_) = hover_for_keyword(&sema, config, &token) { |
185 | { | ||
186 | return res; | 162 | return res; |
187 | } | 163 | } |
188 | 164 | ||
@@ -201,7 +177,7 @@ pub(crate) fn hover( | |||
201 | } | 177 | } |
202 | }; | 178 | }; |
203 | 179 | ||
204 | res.markup = if markdown { | 180 | res.markup = if config.markdown() { |
205 | Markup::fenced_block(&ty.display(db)) | 181 | Markup::fenced_block(&ty.display(db)) |
206 | } else { | 182 | } else { |
207 | ty.display(db).to_string().into() | 183 | ty.display(db).to_string().into() |
@@ -375,13 +351,12 @@ fn process_markup( | |||
375 | db: &RootDatabase, | 351 | db: &RootDatabase, |
376 | def: Definition, | 352 | def: Definition, |
377 | markup: &Markup, | 353 | markup: &Markup, |
378 | links_in_hover: bool, | 354 | config: &HoverConfig, |
379 | markdown: bool, | ||
380 | ) -> Markup { | 355 | ) -> Markup { |
381 | let markup = markup.as_str(); | 356 | let markup = markup.as_str(); |
382 | let markup = if !markdown { | 357 | let markup = if !config.markdown() { |
383 | remove_markdown(markup) | 358 | remove_markdown(markup) |
384 | } else if links_in_hover { | 359 | } else if config.links_in_hover { |
385 | rewrite_links(db, markup, &def) | 360 | rewrite_links(db, markup, &def) |
386 | } else { | 361 | } else { |
387 | remove_links(markup) | 362 | remove_links(markup) |
@@ -428,7 +403,7 @@ fn hover_for_definition( | |||
428 | db: &RootDatabase, | 403 | db: &RootDatabase, |
429 | def: Definition, | 404 | def: Definition, |
430 | famous_defs: Option<&FamousDefs>, | 405 | famous_defs: Option<&FamousDefs>, |
431 | documentation: bool, | 406 | config: &HoverConfig, |
432 | ) -> Option<Markup> { | 407 | ) -> Option<Markup> { |
433 | let mod_path = definition_mod_path(db, &def); | 408 | let mod_path = definition_mod_path(db, &def); |
434 | let (label, docs) = match def { | 409 | let (label, docs) = match def { |
@@ -466,7 +441,11 @@ fn hover_for_definition( | |||
466 | Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db))), | 441 | Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db))), |
467 | }; | 442 | }; |
468 | 443 | ||
469 | return hover_markup(docs.filter(|_| documentation).map(Into::into), label, mod_path); | 444 | return hover_markup( |
445 | docs.filter(|_| config.documentation.is_some()).map(Into::into), | ||
446 | label, | ||
447 | mod_path, | ||
448 | ); | ||
470 | 449 | ||
471 | fn label_and_docs<D>(db: &RootDatabase, def: D) -> (String, Option<hir::Documentation>) | 450 | fn label_and_docs<D>(db: &RootDatabase, def: D) -> (String, Option<hir::Documentation>) |
472 | where | 451 | where |
@@ -502,13 +481,11 @@ fn hover_for_local(it: hir::Local, db: &RootDatabase) -> Option<Markup> { | |||
502 | } | 481 | } |
503 | 482 | ||
504 | fn hover_for_keyword( | 483 | fn hover_for_keyword( |
505 | sema: &hir::Semantics<RootDatabase>, | 484 | sema: &Semantics<RootDatabase>, |
506 | links_in_hover: bool, | 485 | config: &HoverConfig, |
507 | markdown: bool, | ||
508 | documentation: bool, | ||
509 | token: &SyntaxToken, | 486 | token: &SyntaxToken, |
510 | ) -> Option<RangeInfo<HoverResult>> { | 487 | ) -> Option<RangeInfo<HoverResult>> { |
511 | if !token.kind().is_keyword() || !documentation { | 488 | if !token.kind().is_keyword() || !config.documentation.is_some() { |
512 | return None; | 489 | return None; |
513 | } | 490 | } |
514 | let famous_defs = FamousDefs(sema, sema.scope(&token.parent()?).krate()); | 491 | let famous_defs = FamousDefs(sema, sema.scope(&token.parent()?).krate()); |
@@ -520,8 +497,7 @@ fn hover_for_keyword( | |||
520 | sema.db, | 497 | sema.db, |
521 | Definition::ModuleDef(doc_owner.into()), | 498 | Definition::ModuleDef(doc_owner.into()), |
522 | &hover_markup(Some(docs.into()), token.text().into(), None)?, | 499 | &hover_markup(Some(docs.into()), token.text().into(), None)?, |
523 | links_in_hover, | 500 | config, |
524 | markdown, | ||
525 | ); | 501 | ); |
526 | Some(RangeInfo::new(token.text_range(), HoverResult { markup, actions: Default::default() })) | 502 | Some(RangeInfo::new(token.text_range(), HoverResult { markup, actions: Default::default() })) |
527 | } | 503 | } |
@@ -561,16 +537,34 @@ mod tests { | |||
561 | use expect_test::{expect, Expect}; | 537 | use expect_test::{expect, Expect}; |
562 | use ide_db::base_db::FileLoader; | 538 | use ide_db::base_db::FileLoader; |
563 | 539 | ||
564 | use crate::fixture; | 540 | use crate::{fixture, hover::HoverDocFormat, HoverConfig}; |
565 | 541 | ||
566 | fn check_hover_no_result(ra_fixture: &str) { | 542 | fn check_hover_no_result(ra_fixture: &str) { |
567 | let (analysis, position) = fixture::position(ra_fixture); | 543 | let (analysis, position) = fixture::position(ra_fixture); |
568 | assert!(analysis.hover(position, true, true, true).unwrap().is_none()); | 544 | assert!(analysis |
545 | .hover( | ||
546 | position, | ||
547 | &HoverConfig { | ||
548 | links_in_hover: true, | ||
549 | documentation: Some(HoverDocFormat::Markdown) | ||
550 | } | ||
551 | ) | ||
552 | .unwrap() | ||
553 | .is_none()); | ||
569 | } | 554 | } |
570 | 555 | ||
571 | fn check(ra_fixture: &str, expect: Expect) { | 556 | fn check(ra_fixture: &str, expect: Expect) { |
572 | let (analysis, position) = fixture::position(ra_fixture); | 557 | let (analysis, position) = fixture::position(ra_fixture); |
573 | let hover = analysis.hover(position, true, true, true).unwrap().unwrap(); | 558 | let hover = analysis |
559 | .hover( | ||
560 | position, | ||
561 | &HoverConfig { | ||
562 | links_in_hover: true, | ||
563 | documentation: Some(HoverDocFormat::Markdown), | ||
564 | }, | ||
565 | ) | ||
566 | .unwrap() | ||
567 | .unwrap(); | ||
574 | 568 | ||
575 | let content = analysis.db.file_text(position.file_id); | 569 | let content = analysis.db.file_text(position.file_id); |
576 | let hovered_element = &content[hover.range]; | 570 | let hovered_element = &content[hover.range]; |
@@ -581,7 +575,16 @@ mod tests { | |||
581 | 575 | ||
582 | fn check_hover_no_links(ra_fixture: &str, expect: Expect) { | 576 | fn check_hover_no_links(ra_fixture: &str, expect: Expect) { |
583 | let (analysis, position) = fixture::position(ra_fixture); | 577 | let (analysis, position) = fixture::position(ra_fixture); |
584 | let hover = analysis.hover(position, false, true, true).unwrap().unwrap(); | 578 | let hover = analysis |
579 | .hover( | ||
580 | position, | ||
581 | &HoverConfig { | ||
582 | links_in_hover: false, | ||
583 | documentation: Some(HoverDocFormat::Markdown), | ||
584 | }, | ||
585 | ) | ||
586 | .unwrap() | ||
587 | .unwrap(); | ||
585 | 588 | ||
586 | let content = analysis.db.file_text(position.file_id); | 589 | let content = analysis.db.file_text(position.file_id); |
587 | let hovered_element = &content[hover.range]; | 590 | let hovered_element = &content[hover.range]; |
@@ -592,7 +595,16 @@ mod tests { | |||
592 | 595 | ||
593 | fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) { | 596 | fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) { |
594 | let (analysis, position) = fixture::position(ra_fixture); | 597 | let (analysis, position) = fixture::position(ra_fixture); |
595 | let hover = analysis.hover(position, true, true, false).unwrap().unwrap(); | 598 | let hover = analysis |
599 | .hover( | ||
600 | position, | ||
601 | &HoverConfig { | ||
602 | links_in_hover: true, | ||
603 | documentation: Some(HoverDocFormat::PlainText), | ||
604 | }, | ||
605 | ) | ||
606 | .unwrap() | ||
607 | .unwrap(); | ||
596 | 608 | ||
597 | let content = analysis.db.file_text(position.file_id); | 609 | let content = analysis.db.file_text(position.file_id); |
598 | let hovered_element = &content[hover.range]; | 610 | let hovered_element = &content[hover.range]; |
@@ -603,7 +615,16 @@ mod tests { | |||
603 | 615 | ||
604 | fn check_actions(ra_fixture: &str, expect: Expect) { | 616 | fn check_actions(ra_fixture: &str, expect: Expect) { |
605 | let (analysis, position) = fixture::position(ra_fixture); | 617 | let (analysis, position) = fixture::position(ra_fixture); |
606 | let hover = analysis.hover(position, true, true, true).unwrap().unwrap(); | 618 | let hover = analysis |
619 | .hover( | ||
620 | position, | ||
621 | &HoverConfig { | ||
622 | links_in_hover: true, | ||
623 | documentation: Some(HoverDocFormat::Markdown), | ||
624 | }, | ||
625 | ) | ||
626 | .unwrap() | ||
627 | .unwrap(); | ||
607 | expect.assert_debug_eq(&hover.info.actions) | 628 | expect.assert_debug_eq(&hover.info.actions) |
608 | } | 629 | } |
609 | 630 | ||
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 3798f32cc..b978e36af 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -75,7 +75,7 @@ pub use crate::{ | |||
75 | expand_macro::ExpandedMacro, | 75 | expand_macro::ExpandedMacro, |
76 | file_structure::{StructureNode, StructureNodeKind}, | 76 | file_structure::{StructureNode, StructureNodeKind}, |
77 | folding_ranges::{Fold, FoldKind}, | 77 | folding_ranges::{Fold, FoldKind}, |
78 | hover::{HoverAction, HoverConfig, HoverGotoTypeData, HoverResult}, | 78 | hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult}, |
79 | inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, | 79 | inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, |
80 | markup::Markup, | 80 | markup::Markup, |
81 | move_item::Direction, | 81 | move_item::Direction, |
@@ -217,6 +217,7 @@ impl Analysis { | |||
217 | file_id, | 217 | file_id, |
218 | Edition::Edition2018, | 218 | Edition::Edition2018, |
219 | None, | 219 | None, |
220 | cfg_options.clone(), | ||
220 | cfg_options, | 221 | cfg_options, |
221 | Env::default(), | 222 | Env::default(), |
222 | Default::default(), | 223 | Default::default(), |
@@ -407,11 +408,9 @@ impl Analysis { | |||
407 | pub fn hover( | 408 | pub fn hover( |
408 | &self, | 409 | &self, |
409 | position: FilePosition, | 410 | position: FilePosition, |
410 | links_in_hover: bool, | 411 | config: &HoverConfig, |
411 | documentation: bool, | ||
412 | markdown: bool, | ||
413 | ) -> Cancellable<Option<RangeInfo<HoverResult>>> { | 412 | ) -> Cancellable<Option<RangeInfo<HoverResult>>> { |
414 | self.with_db(|db| hover::hover(db, position, links_in_hover, documentation, markdown)) | 413 | self.with_db(|db| hover::hover(db, position, config)) |
415 | } | 414 | } |
416 | 415 | ||
417 | /// Return URL(s) for the documentation of the symbol under the cursor. | 416 | /// Return URL(s) for the documentation of the symbol under the cursor. |
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index 78fc30e16..cc4f4b2af 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs | |||
@@ -15,6 +15,7 @@ use crate::{ | |||
15 | Completions, | 15 | Completions, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | mod cfg; | ||
18 | mod derive; | 19 | mod derive; |
19 | mod lint; | 20 | mod lint; |
20 | mod repr; | 21 | mod repr; |
@@ -30,6 +31,9 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) | |||
30 | lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS); | 31 | lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS); |
31 | lint::complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); | 32 | lint::complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); |
32 | } | 33 | } |
34 | "cfg" => { | ||
35 | cfg::complete_cfg(acc, ctx); | ||
36 | } | ||
33 | _ => (), | 37 | _ => (), |
34 | }, | 38 | }, |
35 | (None, Some(_)) => (), | 39 | (None, Some(_)) => (), |
@@ -852,4 +856,15 @@ mod tests { | |||
852 | "#]], | 856 | "#]], |
853 | ); | 857 | ); |
854 | } | 858 | } |
859 | |||
860 | #[test] | ||
861 | fn test_cfg() { | ||
862 | check( | ||
863 | r#"#[cfg(target_endian = $0"#, | ||
864 | expect![[r#" | ||
865 | at little | ||
866 | at big | ||
867 | "#]], | ||
868 | ); | ||
869 | } | ||
855 | } | 870 | } |
diff --git a/crates/ide_completion/src/completions/attribute/cfg.rs b/crates/ide_completion/src/completions/attribute/cfg.rs new file mode 100644 index 000000000..847e6529a --- /dev/null +++ b/crates/ide_completion/src/completions/attribute/cfg.rs | |||
@@ -0,0 +1,112 @@ | |||
1 | //! Completion for cfg | ||
2 | |||
3 | use std::iter; | ||
4 | |||
5 | use syntax::SyntaxKind; | ||
6 | |||
7 | use crate::{ | ||
8 | completions::Completions, context::CompletionContext, item::CompletionKind, CompletionItem, | ||
9 | CompletionItemKind, | ||
10 | }; | ||
11 | |||
12 | pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) { | ||
13 | let add_completion = |item: &&str| { | ||
14 | let mut completion = | ||
15 | CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), *item); | ||
16 | completion.insert_text(format!(r#""{}""#, item)); | ||
17 | completion.kind(CompletionItemKind::Attribute); | ||
18 | acc.add(completion.build()); | ||
19 | }; | ||
20 | |||
21 | let previous = iter::successors(ctx.original_token.prev_token(), |t| { | ||
22 | (matches!(t.kind(), SyntaxKind::EQ) || t.kind().is_trivia()) | ||
23 | .then(|| t.prev_token()) | ||
24 | .flatten() | ||
25 | }) | ||
26 | .find(|t| matches!(t.kind(), SyntaxKind::IDENT)); | ||
27 | |||
28 | match previous.as_ref().map(|p| p.text()) { | ||
29 | Some("target_arch") => KNOWN_ARCH.iter().for_each(add_completion), | ||
30 | Some("target_env") => KNOWN_ENV.iter().for_each(add_completion), | ||
31 | Some("target_os") => KNOWN_OS.iter().for_each(add_completion), | ||
32 | Some("target_vendor") => KNOWN_VENDOR.iter().for_each(add_completion), | ||
33 | Some("target_endian") => ["little", "big"].iter().for_each(add_completion), | ||
34 | Some(name) => { | ||
35 | ctx.krate.map(|krate| { | ||
36 | krate.potential_cfg(ctx.db).get_cfg_values(&name).iter().for_each(|s| { | ||
37 | let mut item = CompletionItem::new( | ||
38 | CompletionKind::Attribute, | ||
39 | ctx.source_range(), | ||
40 | s.as_str(), | ||
41 | ); | ||
42 | item.insert_text(format!(r#""{}""#, s)); | ||
43 | |||
44 | acc.add(item.build()); | ||
45 | }) | ||
46 | }); | ||
47 | } | ||
48 | None => { | ||
49 | ctx.krate.map(|krate| { | ||
50 | krate.potential_cfg(ctx.db).get_cfg_keys().iter().for_each(|s| { | ||
51 | let item = CompletionItem::new( | ||
52 | CompletionKind::Attribute, | ||
53 | ctx.source_range(), | ||
54 | s.as_str(), | ||
55 | ); | ||
56 | acc.add(item.build()); | ||
57 | }) | ||
58 | }); | ||
59 | } | ||
60 | }; | ||
61 | } | ||
62 | |||
63 | const KNOWN_ARCH: [&'static str; 19] = [ | ||
64 | "aarch64", | ||
65 | "arm", | ||
66 | "avr", | ||
67 | "hexagon", | ||
68 | "mips", | ||
69 | "mips64", | ||
70 | "msp430", | ||
71 | "nvptx64", | ||
72 | "powerpc", | ||
73 | "powerpc64", | ||
74 | "riscv32", | ||
75 | "riscv64", | ||
76 | "s390x", | ||
77 | "sparc", | ||
78 | "sparc64", | ||
79 | "wasm32", | ||
80 | "wasm64", | ||
81 | "x86", | ||
82 | "x86_64", | ||
83 | ]; | ||
84 | |||
85 | const KNOWN_ENV: [&'static str; 7] = | ||
86 | ["eabihf", "gnu", "gnueabihf", "msvc", "relibc", "sgx", "uclibc"]; | ||
87 | |||
88 | const KNOWN_OS: [&'static str; 20] = [ | ||
89 | "cuda", | ||
90 | "dragonfly", | ||
91 | "emscripten", | ||
92 | "freebsd", | ||
93 | "fuchsia", | ||
94 | "haiku", | ||
95 | "hermit", | ||
96 | "illumos", | ||
97 | "l4re", | ||
98 | "linux", | ||
99 | "netbsd", | ||
100 | "none", | ||
101 | "openbsd", | ||
102 | "psp", | ||
103 | "redox", | ||
104 | "solaris", | ||
105 | "uefi", | ||
106 | "unknown", | ||
107 | "vxworks", | ||
108 | "windows", | ||
109 | ]; | ||
110 | |||
111 | const KNOWN_VENDOR: [&'static str; 8] = | ||
112 | ["apple", "fortanix", "nvidia", "pc", "sony", "unknown", "wrs", "uwp"]; | ||
diff --git a/crates/proc_macro_test/build.rs b/crates/proc_macro_test/build.rs index 4653a93dd..1e7aa026f 100644 --- a/crates/proc_macro_test/build.rs +++ b/crates/proc_macro_test/build.rs | |||
@@ -17,9 +17,16 @@ fn main() { | |||
17 | 17 | ||
18 | let name = "proc_macro_test_impl"; | 18 | let name = "proc_macro_test_impl"; |
19 | let version = "0.0.0"; | 19 | let version = "0.0.0"; |
20 | let target_dir = out_dir.join("target"); | ||
20 | let output = Command::new(toolchain::cargo()) | 21 | let output = Command::new(toolchain::cargo()) |
21 | .current_dir("imp") | 22 | .current_dir("imp") |
22 | .args(&["build", "-p", "proc_macro_test_impl", "--message-format", "json"]) | 23 | .args(&["build", "-p", "proc_macro_test_impl", "--message-format", "json"]) |
24 | // Explicit override the target directory to avoid using the same one which the parent | ||
25 | // cargo is using, or we'll deadlock. | ||
26 | // This can happen when `CARGO_TARGET_DIR` is set or global config forces all cargo | ||
27 | // instance to use the same target directory. | ||
28 | .arg("--target-dir") | ||
29 | .arg(&target_dir) | ||
23 | .output() | 30 | .output() |
24 | .unwrap(); | 31 | .unwrap(); |
25 | assert!(output.status.success()); | 32 | assert!(output.status.success()); |
@@ -39,10 +46,9 @@ fn main() { | |||
39 | } | 46 | } |
40 | } | 47 | } |
41 | 48 | ||
42 | let src_path = artifact_path.expect("no dylib for proc_macro_test_impl found"); | 49 | // This file is under `target_dir` and is already under `OUT_DIR`. |
43 | let dest_path = out_dir.join(src_path.file_name().unwrap()); | 50 | let artifact_path = artifact_path.expect("no dylib for proc_macro_test_impl found"); |
44 | fs::copy(src_path, &dest_path).unwrap(); | ||
45 | 51 | ||
46 | let info_path = out_dir.join("proc_macro_test_location.txt"); | 52 | let info_path = out_dir.join("proc_macro_test_location.txt"); |
47 | fs::write(info_path, dest_path.to_str().unwrap()).unwrap(); | 53 | fs::write(info_path, artifact_path.to_str().unwrap()).unwrap(); |
48 | } | 54 | } |
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index d8217f714..e67ba2bd9 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs | |||
@@ -384,6 +384,7 @@ fn project_json_to_crate_graph( | |||
384 | file_id, | 384 | file_id, |
385 | krate.edition, | 385 | krate.edition, |
386 | krate.display_name.clone(), | 386 | krate.display_name.clone(), |
387 | cfg_options.clone(), | ||
387 | cfg_options, | 388 | cfg_options, |
388 | env, | 389 | env, |
389 | proc_macro.unwrap_or_default(), | 390 | proc_macro.unwrap_or_default(), |
@@ -580,6 +581,7 @@ fn detached_files_to_crate_graph( | |||
580 | Edition::Edition2018, | 581 | Edition::Edition2018, |
581 | display_name, | 582 | display_name, |
582 | cfg_options.clone(), | 583 | cfg_options.clone(), |
584 | cfg_options.clone(), | ||
583 | Env::default(), | 585 | Env::default(), |
584 | Vec::new(), | 586 | Vec::new(), |
585 | ); | 587 | ); |
@@ -719,11 +721,19 @@ fn add_target_crate_root( | |||
719 | .unwrap_or_default(); | 721 | .unwrap_or_default(); |
720 | 722 | ||
721 | let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string()); | 723 | let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string()); |
724 | let mut potential_cfg_options = cfg_options.clone(); | ||
725 | potential_cfg_options.extend( | ||
726 | pkg.features | ||
727 | .iter() | ||
728 | .map(|feat| CfgFlag::KeyValue { key: "feature".into(), value: feat.0.into() }), | ||
729 | ); | ||
730 | |||
722 | let crate_id = crate_graph.add_crate_root( | 731 | let crate_id = crate_graph.add_crate_root( |
723 | file_id, | 732 | file_id, |
724 | edition, | 733 | edition, |
725 | Some(display_name), | 734 | Some(display_name), |
726 | cfg_options, | 735 | cfg_options, |
736 | potential_cfg_options, | ||
727 | env, | 737 | env, |
728 | proc_macro, | 738 | proc_macro, |
729 | ); | 739 | ); |
@@ -753,6 +763,7 @@ fn sysroot_to_crate_graph( | |||
753 | Edition::Edition2018, | 763 | Edition::Edition2018, |
754 | Some(display_name), | 764 | Some(display_name), |
755 | cfg_options.clone(), | 765 | cfg_options.clone(), |
766 | cfg_options.clone(), | ||
756 | env, | 767 | env, |
757 | proc_macro, | 768 | proc_macro, |
758 | ); | 769 | ); |
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index afc96505f..97246cae6 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs | |||
@@ -60,7 +60,14 @@ fn try_main() -> Result<()> { | |||
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | setup_logging(flags.log_file.as_deref(), flags.no_log_buffering)?; | 63 | let mut log_file = flags.log_file.as_deref(); |
64 | |||
65 | let env_log_file = env::var("RA_LOG_FILE").ok(); | ||
66 | if let Some(env_log_file) = env_log_file.as_deref() { | ||
67 | log_file = Some(Path::new(env_log_file)); | ||
68 | } | ||
69 | |||
70 | setup_logging(log_file, flags.no_log_buffering)?; | ||
64 | let verbosity = flags.verbosity(); | 71 | let verbosity = flags.verbosity(); |
65 | 72 | ||
66 | match flags.subcommand { | 73 | match flags.subcommand { |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 3aeca8839..b9aa6f0aa 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -10,7 +10,10 @@ | |||
10 | use std::{ffi::OsString, iter, path::PathBuf}; | 10 | use std::{ffi::OsString, iter, path::PathBuf}; |
11 | 11 | ||
12 | use flycheck::FlycheckConfig; | 12 | use flycheck::FlycheckConfig; |
13 | use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig}; | 13 | use ide::{ |
14 | AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, HoverDocFormat, | ||
15 | InlayHintsConfig, | ||
16 | }; | ||
14 | use ide_db::helpers::{ | 17 | use ide_db::helpers::{ |
15 | insert_use::{ImportGranularity, InsertUseConfig, PrefixKind}, | 18 | insert_use::{ImportGranularity, InsertUseConfig, PrefixKind}, |
16 | SnippetCap, | 19 | SnippetCap, |
@@ -32,6 +35,9 @@ use crate::{ | |||
32 | // | 35 | // |
33 | // However, editor specific config, which the server doesn't know about, should | 36 | // However, editor specific config, which the server doesn't know about, should |
34 | // be specified directly in `package.json`. | 37 | // be specified directly in `package.json`. |
38 | // | ||
39 | // To deprecate an option by replacing it with another name use `new_name | `old_name` so that we keep | ||
40 | // parsing the old name. | ||
35 | config_data! { | 41 | config_data! { |
36 | struct ConfigData { | 42 | struct ConfigData { |
37 | /// How imports should be grouped into use statements. | 43 | /// How imports should be grouped into use statements. |
@@ -309,6 +315,37 @@ impl LensConfig { | |||
309 | } | 315 | } |
310 | } | 316 | } |
311 | 317 | ||
318 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
319 | pub struct HoverActionsConfig { | ||
320 | pub implementations: bool, | ||
321 | pub references: bool, | ||
322 | pub run: bool, | ||
323 | pub debug: bool, | ||
324 | pub goto_type_def: bool, | ||
325 | } | ||
326 | |||
327 | impl HoverActionsConfig { | ||
328 | pub const NO_ACTIONS: Self = Self { | ||
329 | implementations: false, | ||
330 | references: false, | ||
331 | run: false, | ||
332 | debug: false, | ||
333 | goto_type_def: false, | ||
334 | }; | ||
335 | |||
336 | pub fn any(&self) -> bool { | ||
337 | self.implementations || self.references || self.runnable() || self.goto_type_def | ||
338 | } | ||
339 | |||
340 | pub fn none(&self) -> bool { | ||
341 | !self.any() | ||
342 | } | ||
343 | |||
344 | pub fn runnable(&self) -> bool { | ||
345 | self.run || self.debug | ||
346 | } | ||
347 | } | ||
348 | |||
312 | #[derive(Debug, Clone)] | 349 | #[derive(Debug, Clone)] |
313 | pub struct FilesConfig { | 350 | pub struct FilesConfig { |
314 | pub watcher: FilesWatcher, | 351 | pub watcher: FilesWatcher, |
@@ -527,7 +564,7 @@ impl Config { | |||
527 | pub fn code_action_group(&self) -> bool { | 564 | pub fn code_action_group(&self) -> bool { |
528 | self.experimental("codeActionGroup") | 565 | self.experimental("codeActionGroup") |
529 | } | 566 | } |
530 | pub fn hover_actions(&self) -> bool { | 567 | pub fn experimental_hover_actions(&self) -> bool { |
531 | self.experimental("hoverActions") | 568 | self.experimental("hoverActions") |
532 | } | 569 | } |
533 | pub fn server_status_notification(&self) -> bool { | 570 | pub fn server_status_notification(&self) -> bool { |
@@ -727,31 +764,41 @@ impl Config { | |||
727 | refs: self.data.lens_enable && self.data.lens_references, | 764 | refs: self.data.lens_enable && self.data.lens_references, |
728 | } | 765 | } |
729 | } | 766 | } |
730 | pub fn highlighting_strings(&self) -> bool { | 767 | pub fn hover_actions(&self) -> HoverActionsConfig { |
731 | self.data.highlighting_strings | 768 | HoverActionsConfig { |
732 | } | ||
733 | pub fn hover(&self) -> HoverConfig { | ||
734 | HoverConfig { | ||
735 | implementations: self.data.hoverActions_enable | 769 | implementations: self.data.hoverActions_enable |
736 | && self.data.hoverActions_implementations, | 770 | && self.data.hoverActions_implementations, |
737 | references: self.data.hoverActions_enable && self.data.hoverActions_references, | 771 | references: self.data.hoverActions_enable && self.data.hoverActions_references, |
738 | run: self.data.hoverActions_enable && self.data.hoverActions_run, | 772 | run: self.data.hoverActions_enable && self.data.hoverActions_run, |
739 | debug: self.data.hoverActions_enable && self.data.hoverActions_debug, | 773 | debug: self.data.hoverActions_enable && self.data.hoverActions_debug, |
740 | goto_type_def: self.data.hoverActions_enable && self.data.hoverActions_gotoTypeDef, | 774 | goto_type_def: self.data.hoverActions_enable && self.data.hoverActions_gotoTypeDef, |
775 | } | ||
776 | } | ||
777 | pub fn highlighting_strings(&self) -> bool { | ||
778 | self.data.highlighting_strings | ||
779 | } | ||
780 | pub fn hover(&self) -> HoverConfig { | ||
781 | HoverConfig { | ||
741 | links_in_hover: self.data.hover_linksInHover, | 782 | links_in_hover: self.data.hover_linksInHover, |
742 | markdown: try_or!( | 783 | documentation: self.data.hover_documentation.then(|| { |
743 | self.caps | 784 | let is_markdown = try_or!( |
744 | .text_document | 785 | self.caps |
745 | .as_ref()? | 786 | .text_document |
746 | .hover | 787 | .as_ref()? |
747 | .as_ref()? | 788 | .hover |
748 | .content_format | 789 | .as_ref()? |
749 | .as_ref()? | 790 | .content_format |
750 | .as_slice(), | 791 | .as_ref()? |
751 | &[] | 792 | .as_slice(), |
752 | ) | 793 | &[] |
753 | .contains(&MarkupKind::Markdown), | 794 | ) |
754 | documentation: self.data.hover_documentation, | 795 | .contains(&MarkupKind::Markdown); |
796 | if is_markdown { | ||
797 | HoverDocFormat::Markdown | ||
798 | } else { | ||
799 | HoverDocFormat::PlainText | ||
800 | } | ||
801 | }), | ||
755 | } | 802 | } |
756 | } | 803 | } |
757 | 804 | ||
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index eff1e6c93..dcead5f5c 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -861,13 +861,7 @@ pub(crate) fn handle_hover( | |||
861 | ) -> Result<Option<lsp_ext::Hover>> { | 861 | ) -> Result<Option<lsp_ext::Hover>> { |
862 | let _p = profile::span("handle_hover"); | 862 | let _p = profile::span("handle_hover"); |
863 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; | 863 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
864 | let hover_config = snap.config.hover(); | 864 | let info = match snap.analysis.hover(position, &snap.config.hover())? { |
865 | let info = match snap.analysis.hover( | ||
866 | position, | ||
867 | hover_config.links_in_hover, | ||
868 | hover_config.documentation, | ||
869 | hover_config.markdown, | ||
870 | )? { | ||
871 | None => return Ok(None), | 865 | None => return Ok(None), |
872 | Some(info) => info, | 866 | Some(info) => info, |
873 | }; | 867 | }; |
@@ -1487,7 +1481,7 @@ fn show_impl_command_link( | |||
1487 | snap: &GlobalStateSnapshot, | 1481 | snap: &GlobalStateSnapshot, |
1488 | position: &FilePosition, | 1482 | position: &FilePosition, |
1489 | ) -> Option<lsp_ext::CommandLinkGroup> { | 1483 | ) -> Option<lsp_ext::CommandLinkGroup> { |
1490 | if snap.config.hover().implementations { | 1484 | if snap.config.hover_actions().implementations { |
1491 | if let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None) { | 1485 | if let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None) { |
1492 | let uri = to_proto::url(snap, position.file_id); | 1486 | let uri = to_proto::url(snap, position.file_id); |
1493 | let line_index = snap.file_line_index(position.file_id).ok()?; | 1487 | let line_index = snap.file_line_index(position.file_id).ok()?; |
@@ -1513,7 +1507,7 @@ fn show_ref_command_link( | |||
1513 | snap: &GlobalStateSnapshot, | 1507 | snap: &GlobalStateSnapshot, |
1514 | position: &FilePosition, | 1508 | position: &FilePosition, |
1515 | ) -> Option<lsp_ext::CommandLinkGroup> { | 1509 | ) -> Option<lsp_ext::CommandLinkGroup> { |
1516 | if snap.config.hover().references { | 1510 | if snap.config.hover_actions().references { |
1517 | if let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None) { | 1511 | if let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None) { |
1518 | let uri = to_proto::url(snap, position.file_id); | 1512 | let uri = to_proto::url(snap, position.file_id); |
1519 | let line_index = snap.file_line_index(position.file_id).ok()?; | 1513 | let line_index = snap.file_line_index(position.file_id).ok()?; |
@@ -1544,8 +1538,8 @@ fn runnable_action_links( | |||
1544 | runnable: Runnable, | 1538 | runnable: Runnable, |
1545 | ) -> Option<lsp_ext::CommandLinkGroup> { | 1539 | ) -> Option<lsp_ext::CommandLinkGroup> { |
1546 | let cargo_spec = CargoTargetSpec::for_file(snap, runnable.nav.file_id).ok()?; | 1540 | let cargo_spec = CargoTargetSpec::for_file(snap, runnable.nav.file_id).ok()?; |
1547 | let hover_config = snap.config.hover(); | 1541 | let hover_actions_config = snap.config.hover_actions(); |
1548 | if !hover_config.runnable() || should_skip_target(&runnable, cargo_spec.as_ref()) { | 1542 | if !hover_actions_config.runnable() || should_skip_target(&runnable, cargo_spec.as_ref()) { |
1549 | return None; | 1543 | return None; |
1550 | } | 1544 | } |
1551 | 1545 | ||
@@ -1553,12 +1547,12 @@ fn runnable_action_links( | |||
1553 | to_proto::runnable(snap, runnable).ok().map(|r| { | 1547 | to_proto::runnable(snap, runnable).ok().map(|r| { |
1554 | let mut group = lsp_ext::CommandLinkGroup::default(); | 1548 | let mut group = lsp_ext::CommandLinkGroup::default(); |
1555 | 1549 | ||
1556 | if hover_config.run { | 1550 | if hover_actions_config.run { |
1557 | let run_command = to_proto::command::run_single(&r, action.run_title); | 1551 | let run_command = to_proto::command::run_single(&r, action.run_title); |
1558 | group.commands.push(to_command_link(run_command, r.label.clone())); | 1552 | group.commands.push(to_command_link(run_command, r.label.clone())); |
1559 | } | 1553 | } |
1560 | 1554 | ||
1561 | if hover_config.debug { | 1555 | if hover_actions_config.debug { |
1562 | let dbg_command = to_proto::command::debug_single(&r); | 1556 | let dbg_command = to_proto::command::debug_single(&r); |
1563 | group.commands.push(to_command_link(dbg_command, r.label)); | 1557 | group.commands.push(to_command_link(dbg_command, r.label)); |
1564 | } | 1558 | } |
@@ -1571,7 +1565,7 @@ fn goto_type_action_links( | |||
1571 | snap: &GlobalStateSnapshot, | 1565 | snap: &GlobalStateSnapshot, |
1572 | nav_targets: &[HoverGotoTypeData], | 1566 | nav_targets: &[HoverGotoTypeData], |
1573 | ) -> Option<lsp_ext::CommandLinkGroup> { | 1567 | ) -> Option<lsp_ext::CommandLinkGroup> { |
1574 | if !snap.config.hover().goto_type_def || nav_targets.is_empty() { | 1568 | if !snap.config.hover_actions().goto_type_def || nav_targets.is_empty() { |
1575 | return None; | 1569 | return None; |
1576 | } | 1570 | } |
1577 | 1571 | ||
@@ -1591,7 +1585,7 @@ fn prepare_hover_actions( | |||
1591 | snap: &GlobalStateSnapshot, | 1585 | snap: &GlobalStateSnapshot, |
1592 | actions: &[HoverAction], | 1586 | actions: &[HoverAction], |
1593 | ) -> Vec<lsp_ext::CommandLinkGroup> { | 1587 | ) -> Vec<lsp_ext::CommandLinkGroup> { |
1594 | if snap.config.hover().no_actions() || !snap.config.hover_actions() { | 1588 | if snap.config.hover_actions().none() || !snap.config.experimental_hover_actions() { |
1595 | return Vec::new(); | 1589 | return Vec::new(); |
1596 | } | 1590 | } |
1597 | 1591 | ||
diff --git a/crates/syntax/src/ptr.rs b/crates/syntax/src/ptr.rs index c077a04cb..282470bae 100644 --- a/crates/syntax/src/ptr.rs +++ b/crates/syntax/src/ptr.rs | |||
@@ -44,7 +44,7 @@ impl SyntaxNodePtr { | |||
44 | pub fn to_node(&self, root: &SyntaxNode) -> SyntaxNode { | 44 | pub fn to_node(&self, root: &SyntaxNode) -> SyntaxNode { |
45 | assert!(root.parent().is_none()); | 45 | assert!(root.parent().is_none()); |
46 | successors(Some(root.clone()), |node| { | 46 | successors(Some(root.clone()), |node| { |
47 | node.children().find(|it| it.text_range().contains_range(self.range)) | 47 | node.child_or_token_at_range(self.range).and_then(|it| it.into_node()) |
48 | }) | 48 | }) |
49 | .find(|it| it.text_range() == self.range && it.kind() == self.kind) | 49 | .find(|it| it.text_range() == self.range && it.kind() == self.kind) |
50 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) | 50 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) |
diff --git a/docs/dev/README.md b/docs/dev/README.md index e81f1e74c..a394b8501 100644 --- a/docs/dev/README.md +++ b/docs/dev/README.md | |||
@@ -131,7 +131,8 @@ Logging is done by both rust-analyzer and VS Code, so it might be tricky to figu | |||
131 | 131 | ||
132 | Inside rust-analyzer, we use the standard `log` crate for logging, and `env_logger` for logging frontend. | 132 | Inside rust-analyzer, we use the standard `log` crate for logging, and `env_logger` for logging frontend. |
133 | By default, log goes to stderr, but the stderr itself is processed by VS Code. | 133 | By default, log goes to stderr, but the stderr itself is processed by VS Code. |
134 | `--log-file <PATH>` CLI argument allows logging to file. | 134 | `--log-file <PATH>` CLI argument allows logging to file. |
135 | Setting the `RA_LOG_FILE=<PATH>` environment variable will also log to file, it will also override `--log-file`. | ||
135 | 136 | ||
136 | To see stderr in the running VS Code instance, go to the "Output" tab of the panel and select `rust-analyzer`. | 137 | To see stderr in the running VS Code instance, go to the "Output" tab of the panel and select `rust-analyzer`. |
137 | This shows `eprintln!` as well. | 138 | This shows `eprintln!` as well. |
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json index d22c80754..95c9571e9 100644 --- a/editors/code/package-lock.json +++ b/editors/code/package-lock.json | |||
@@ -11,7 +11,7 @@ | |||
11 | "dependencies": { | 11 | "dependencies": { |
12 | "https-proxy-agent": "^5.0.0", | 12 | "https-proxy-agent": "^5.0.0", |
13 | "node-fetch": "^2.6.1", | 13 | "node-fetch": "^2.6.1", |
14 | "vscode-languageclient": "^7.1.0-next.4" | 14 | "vscode-languageclient": "^7.1.0-next.5" |
15 | }, | 15 | }, |
16 | "devDependencies": { | 16 | "devDependencies": { |
17 | "@rollup/plugin-commonjs": "^17.0.0", | 17 | "@rollup/plugin-commonjs": "^17.0.0", |
@@ -3388,39 +3388,39 @@ | |||
3388 | } | 3388 | } |
3389 | }, | 3389 | }, |
3390 | "node_modules/vscode-jsonrpc": { | 3390 | "node_modules/vscode-jsonrpc": { |
3391 | "version": "6.1.0-next.2", | 3391 | "version": "7.0.0-next.1", |
3392 | "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.1.0-next.2.tgz", | 3392 | "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-7.0.0-next.1.tgz", |
3393 | "integrity": "sha512-nkiNDGI+Ytp7uj1lxHXddXCoEunhcry1D+KmVHBfUUgWT9jMF8ZJyH5KQObdF+OGAh7bXZxD/SV4uGwSCeHHWA==", | 3393 | "integrity": "sha512-dEmliPZGbSyIcEeKRGzosCy7y7zsc8FXg1l5BBOGgMUbemlo3vUnsa2GFqpILJwJvlbvkRcF2QASNwIlKe9J7g==", |
3394 | "engines": { | 3394 | "engines": { |
3395 | "node": ">=8.0.0 || >=10.0.0" | 3395 | "node": ">=8.0.0 || >=10.0.0" |
3396 | } | 3396 | } |
3397 | }, | 3397 | }, |
3398 | "node_modules/vscode-languageclient": { | 3398 | "node_modules/vscode-languageclient": { |
3399 | "version": "7.1.0-next.4", | 3399 | "version": "7.1.0-next.5", |
3400 | "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.1.0-next.4.tgz", | 3400 | "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.1.0-next.5.tgz", |
3401 | "integrity": "sha512-Gal+DvbI1KIwO1z90MvSnghMCVBCGlwdpOVIS0Hhmep7rjHUOwuC5Df7YlVkpzfPm+RCRyZQnUSJ19VNrnxxhA==", | 3401 | "integrity": "sha512-TpzpAhpdCNJHaLzptFRs54xsU6xTmaiVPCse0W0rRB5jJBPjOBKilrFPMMm/sJA0y8Yxa9sOvZaNu6WPg3dYAw==", |
3402 | "dependencies": { | 3402 | "dependencies": { |
3403 | "minimatch": "^3.0.4", | 3403 | "minimatch": "^3.0.4", |
3404 | "semver": "^7.3.4", | 3404 | "semver": "^7.3.4", |
3405 | "vscode-languageserver-protocol": "3.17.0-next.5" | 3405 | "vscode-languageserver-protocol": "3.17.0-next.6" |
3406 | }, | 3406 | }, |
3407 | "engines": { | 3407 | "engines": { |
3408 | "vscode": "^1.53.0" | 3408 | "vscode": "^1.53.0" |
3409 | } | 3409 | } |
3410 | }, | 3410 | }, |
3411 | "node_modules/vscode-languageserver-protocol": { | 3411 | "node_modules/vscode-languageserver-protocol": { |
3412 | "version": "3.17.0-next.5", | 3412 | "version": "3.17.0-next.6", |
3413 | "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.5.tgz", | 3413 | "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.6.tgz", |
3414 | "integrity": "sha512-LFZ6WMB3iPezQAU9OnGoERzcIVKhcs0OLfD/NHcqSj3g1wgxuLUL5kSlZbbjFySQCmhzm6b0yb3hjTSeBtq1+w==", | 3414 | "integrity": "sha512-f1kGsoOpISB5jSqQNeMDl2446enxVahyux2e5vZap6pu/TC+2UlvPT4DCR0gPph95KOQZweL9zq1SzLoPdqhuA==", |
3415 | "dependencies": { | 3415 | "dependencies": { |
3416 | "vscode-jsonrpc": "6.1.0-next.2", | 3416 | "vscode-jsonrpc": "7.0.0-next.1", |
3417 | "vscode-languageserver-types": "3.17.0-next.1" | 3417 | "vscode-languageserver-types": "3.17.0-next.2" |
3418 | } | 3418 | } |
3419 | }, | 3419 | }, |
3420 | "node_modules/vscode-languageserver-types": { | 3420 | "node_modules/vscode-languageserver-types": { |
3421 | "version": "3.17.0-next.1", | 3421 | "version": "3.17.0-next.2", |
3422 | "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.1.tgz", | 3422 | "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.2.tgz", |
3423 | "integrity": "sha512-VGzh06oynbYa6JbTKUbxOEZN7CYEtWhN7DK5wfzUpeCJl8X8xZX39g2PVfpqXrIEduu7dcJgK007KgnX9tHNKA==" | 3423 | "integrity": "sha512-L5S2kNLCgYJMVWgsZjBaorMM/6+itAfvOyl6Kv1bgFzDNaUKm9HsnUlehjpWPdV5DqnfJhJ5E03Z+/3Mw8ii+Q==" |
3424 | }, | 3424 | }, |
3425 | "node_modules/vscode-test": { | 3425 | "node_modules/vscode-test": { |
3426 | "version": "1.5.2", | 3426 | "version": "1.5.2", |
@@ -6167,33 +6167,33 @@ | |||
6167 | } | 6167 | } |
6168 | }, | 6168 | }, |
6169 | "vscode-jsonrpc": { | 6169 | "vscode-jsonrpc": { |
6170 | "version": "6.1.0-next.2", | 6170 | "version": "7.0.0-next.1", |
6171 | "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.1.0-next.2.tgz", | 6171 | "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-7.0.0-next.1.tgz", |
6172 | "integrity": "sha512-nkiNDGI+Ytp7uj1lxHXddXCoEunhcry1D+KmVHBfUUgWT9jMF8ZJyH5KQObdF+OGAh7bXZxD/SV4uGwSCeHHWA==" | 6172 | "integrity": "sha512-dEmliPZGbSyIcEeKRGzosCy7y7zsc8FXg1l5BBOGgMUbemlo3vUnsa2GFqpILJwJvlbvkRcF2QASNwIlKe9J7g==" |
6173 | }, | 6173 | }, |
6174 | "vscode-languageclient": { | 6174 | "vscode-languageclient": { |
6175 | "version": "7.1.0-next.4", | 6175 | "version": "7.1.0-next.5", |
6176 | "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.1.0-next.4.tgz", | 6176 | "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.1.0-next.5.tgz", |
6177 | "integrity": "sha512-Gal+DvbI1KIwO1z90MvSnghMCVBCGlwdpOVIS0Hhmep7rjHUOwuC5Df7YlVkpzfPm+RCRyZQnUSJ19VNrnxxhA==", | 6177 | "integrity": "sha512-TpzpAhpdCNJHaLzptFRs54xsU6xTmaiVPCse0W0rRB5jJBPjOBKilrFPMMm/sJA0y8Yxa9sOvZaNu6WPg3dYAw==", |
6178 | "requires": { | 6178 | "requires": { |
6179 | "minimatch": "^3.0.4", | 6179 | "minimatch": "^3.0.4", |
6180 | "semver": "^7.3.4", | 6180 | "semver": "^7.3.4", |
6181 | "vscode-languageserver-protocol": "3.17.0-next.5" | 6181 | "vscode-languageserver-protocol": "3.17.0-next.6" |
6182 | } | 6182 | } |
6183 | }, | 6183 | }, |
6184 | "vscode-languageserver-protocol": { | 6184 | "vscode-languageserver-protocol": { |
6185 | "version": "3.17.0-next.5", | 6185 | "version": "3.17.0-next.6", |
6186 | "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.5.tgz", | 6186 | "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.6.tgz", |
6187 | "integrity": "sha512-LFZ6WMB3iPezQAU9OnGoERzcIVKhcs0OLfD/NHcqSj3g1wgxuLUL5kSlZbbjFySQCmhzm6b0yb3hjTSeBtq1+w==", | 6187 | "integrity": "sha512-f1kGsoOpISB5jSqQNeMDl2446enxVahyux2e5vZap6pu/TC+2UlvPT4DCR0gPph95KOQZweL9zq1SzLoPdqhuA==", |
6188 | "requires": { | 6188 | "requires": { |
6189 | "vscode-jsonrpc": "6.1.0-next.2", | 6189 | "vscode-jsonrpc": "7.0.0-next.1", |
6190 | "vscode-languageserver-types": "3.17.0-next.1" | 6190 | "vscode-languageserver-types": "3.17.0-next.2" |
6191 | } | 6191 | } |
6192 | }, | 6192 | }, |
6193 | "vscode-languageserver-types": { | 6193 | "vscode-languageserver-types": { |
6194 | "version": "3.17.0-next.1", | 6194 | "version": "3.17.0-next.2", |
6195 | "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.1.tgz", | 6195 | "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.2.tgz", |
6196 | "integrity": "sha512-VGzh06oynbYa6JbTKUbxOEZN7CYEtWhN7DK5wfzUpeCJl8X8xZX39g2PVfpqXrIEduu7dcJgK007KgnX9tHNKA==" | 6196 | "integrity": "sha512-L5S2kNLCgYJMVWgsZjBaorMM/6+itAfvOyl6Kv1bgFzDNaUKm9HsnUlehjpWPdV5DqnfJhJ5E03Z+/3Mw8ii+Q==" |
6197 | }, | 6197 | }, |
6198 | "vscode-test": { | 6198 | "vscode-test": { |
6199 | "version": "1.5.2", | 6199 | "version": "1.5.2", |
diff --git a/editors/code/package.json b/editors/code/package.json index 666016ae4..0b9b4e42f 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -37,7 +37,7 @@ | |||
37 | "dependencies": { | 37 | "dependencies": { |
38 | "https-proxy-agent": "^5.0.0", | 38 | "https-proxy-agent": "^5.0.0", |
39 | "node-fetch": "^2.6.1", | 39 | "node-fetch": "^2.6.1", |
40 | "vscode-languageclient": "^7.1.0-next.4" | 40 | "vscode-languageclient": "^7.1.0-next.5" |
41 | }, | 41 | }, |
42 | "devDependencies": { | 42 | "devDependencies": { |
43 | "@rollup/plugin-commonjs": "^17.0.0", | 43 | "@rollup/plugin-commonjs": "^17.0.0", |