diff options
author | kjeremy <[email protected]> | 2019-04-23 19:11:27 +0100 |
---|---|---|
committer | kjeremy <[email protected]> | 2019-04-23 19:32:47 +0100 |
commit | 7125192c1e46f2350707c4903a1679b2a0178ea6 (patch) | |
tree | 4bcb7609a4477a270f361c7e83abdb093107d040 /crates/ra_ide_api | |
parent | a094d5c621e44ff78dce953c0cae7cfba4b2840e (diff) |
Basic resolution for ADT
Diffstat (limited to 'crates/ra_ide_api')
-rw-r--r-- | crates/ra_ide_api/src/goto_type_definition.rs | 68 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 8 |
2 files changed, 76 insertions, 0 deletions
diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide_api/src/goto_type_definition.rs new file mode 100644 index 000000000..b6a3c1c3a --- /dev/null +++ b/crates/ra_ide_api/src/goto_type_definition.rs | |||
@@ -0,0 +1,68 @@ | |||
1 | use ra_db::SourceDatabase; | ||
2 | use ra_syntax::{ | ||
3 | AstNode, ast, | ||
4 | algo::find_token_at_offset | ||
5 | }; | ||
6 | |||
7 | use crate::{FilePosition, NavigationTarget, db::RootDatabase, RangeInfo}; | ||
8 | |||
9 | pub(crate) fn goto_type_definition( | ||
10 | db: &RootDatabase, | ||
11 | position: FilePosition, | ||
12 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { | ||
13 | let file = db.parse(position.file_id); | ||
14 | |||
15 | let node = find_token_at_offset(file.syntax(), position.offset).find_map(|token| { | ||
16 | token | ||
17 | .parent() | ||
18 | .ancestors() | ||
19 | .find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some()) | ||
20 | })?; | ||
21 | |||
22 | let analyzer = hir::SourceAnalyzer::new(db, position.file_id, node, None); | ||
23 | |||
24 | let ty: hir::Ty = if let Some(ty) = ast::Expr::cast(node).and_then(|e| analyzer.type_of(db, e)) | ||
25 | { | ||
26 | ty | ||
27 | } else if let Some(ty) = ast::Pat::cast(node).and_then(|p| analyzer.type_of_pat(db, p)) { | ||
28 | ty | ||
29 | } else { | ||
30 | return None; | ||
31 | }; | ||
32 | |||
33 | if let Some((adt_def, _)) = ty.as_adt() { | ||
34 | let nav = NavigationTarget::from_adt_def(db, adt_def); | ||
35 | return Some(RangeInfo::new(node.range(), vec![nav])); | ||
36 | }; | ||
37 | |||
38 | None | ||
39 | } | ||
40 | |||
41 | #[cfg(test)] | ||
42 | mod tests { | ||
43 | use crate::mock_analysis::analysis_and_position; | ||
44 | |||
45 | fn check_goto(fixture: &str, expected: &str) { | ||
46 | let (analysis, pos) = analysis_and_position(fixture); | ||
47 | |||
48 | let mut navs = analysis.goto_type_definition(pos).unwrap().unwrap().info; | ||
49 | assert_eq!(navs.len(), 1); | ||
50 | let nav = navs.pop().unwrap(); | ||
51 | nav.assert_match(expected); | ||
52 | } | ||
53 | |||
54 | #[test] | ||
55 | fn goto_type_definition_works_simple() { | ||
56 | check_goto( | ||
57 | " | ||
58 | //- /lib.rs | ||
59 | struct Foo; | ||
60 | fn foo() { | ||
61 | let f: Foo; | ||
62 | f<|> | ||
63 | } | ||
64 | ", | ||
65 | "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", | ||
66 | ); | ||
67 | } | ||
68 | } | ||
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index d25795adc..d4be8bd6c 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -19,6 +19,7 @@ mod status; | |||
19 | mod completion; | 19 | mod completion; |
20 | mod runnables; | 20 | mod runnables; |
21 | mod goto_definition; | 21 | mod goto_definition; |
22 | mod goto_type_definition; | ||
22 | mod extend_selection; | 23 | mod extend_selection; |
23 | mod hover; | 24 | mod hover; |
24 | mod call_info; | 25 | mod call_info; |
@@ -416,6 +417,13 @@ impl Analysis { | |||
416 | self.with_db(|db| impls::goto_implementation(db, position)) | 417 | self.with_db(|db| impls::goto_implementation(db, position)) |
417 | } | 418 | } |
418 | 419 | ||
420 | pub fn goto_type_definition( | ||
421 | &self, | ||
422 | position: FilePosition, | ||
423 | ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> { | ||
424 | self.with_db(|db| goto_type_definition::goto_type_definition(db, position)) | ||
425 | } | ||
426 | |||
419 | /// Finds all usages of the reference at point. | 427 | /// Finds all usages of the reference at point. |
420 | pub fn find_all_refs( | 428 | pub fn find_all_refs( |
421 | &self, | 429 | &self, |