diff options
author | Aleksey Kladov <[email protected]> | 2020-02-18 17:35:10 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-02-26 11:55:50 +0000 |
commit | c3a4c4429de83450654795534e64e878a774a088 (patch) | |
tree | 12d89798f61b276f8bd640db07276a7d4e92b1c2 /crates/ra_ide/src/impls.rs | |
parent | 04deae3dba7c9b7054f7a1d64e4b93a05aecc132 (diff) |
Refactor primary IDE API
This introduces the new type -- Semantics.
Semantics maps SyntaxNodes to various semantic info, such as type,
name resolution or macro expansions.
To do so, Semantics maintains a HashMap which maps every node it saw
to the file from which the node originated. This is enough to get all
the necessary hir bits just from syntax.
Diffstat (limited to 'crates/ra_ide/src/impls.rs')
-rw-r--r-- | crates/ra_ide/src/impls.rs | 49 |
1 files changed, 18 insertions, 31 deletions
diff --git a/crates/ra_ide/src/impls.rs b/crates/ra_ide/src/impls.rs index 64a2dadc8..bf82b2a16 100644 --- a/crates/ra_ide/src/impls.rs +++ b/crates/ra_ide/src/impls.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{Crate, ImplBlock, SourceBinder}; | 3 | use hir::{Crate, ImplBlock, Semantics}; |
4 | use ra_db::SourceDatabase; | ||
5 | use ra_ide_db::RootDatabase; | 4 | use ra_ide_db::RootDatabase; |
6 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | 5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; |
7 | 6 | ||
@@ -11,21 +10,21 @@ pub(crate) fn goto_implementation( | |||
11 | db: &RootDatabase, | 10 | db: &RootDatabase, |
12 | position: FilePosition, | 11 | position: FilePosition, |
13 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { | 12 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { |
14 | let parse = db.parse(position.file_id); | 13 | let sema = Semantics::new(db); |
15 | let syntax = parse.tree().syntax().clone(); | 14 | let source_file = sema.parse(position.file_id); |
16 | let mut sb = SourceBinder::new(db); | 15 | let syntax = source_file.syntax().clone(); |
17 | 16 | ||
18 | let krate = sb.to_module_def(position.file_id)?.krate(); | 17 | let krate = sema.to_module_def(position.file_id)?.krate(); |
19 | 18 | ||
20 | if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) { | 19 | if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) { |
21 | return Some(RangeInfo::new( | 20 | return Some(RangeInfo::new( |
22 | nominal_def.syntax().text_range(), | 21 | nominal_def.syntax().text_range(), |
23 | impls_for_def(&mut sb, position, &nominal_def, krate)?, | 22 | impls_for_def(&sema, &nominal_def, krate)?, |
24 | )); | 23 | )); |
25 | } else if let Some(trait_def) = find_node_at_offset::<ast::TraitDef>(&syntax, position.offset) { | 24 | } else if let Some(trait_def) = find_node_at_offset::<ast::TraitDef>(&syntax, position.offset) { |
26 | return Some(RangeInfo::new( | 25 | return Some(RangeInfo::new( |
27 | trait_def.syntax().text_range(), | 26 | trait_def.syntax().text_range(), |
28 | impls_for_trait(&mut sb, position, &trait_def, krate)?, | 27 | impls_for_trait(&sema, &trait_def, krate)?, |
29 | )); | 28 | )); |
30 | } | 29 | } |
31 | 30 | ||
@@ -33,49 +32,37 @@ pub(crate) fn goto_implementation( | |||
33 | } | 32 | } |
34 | 33 | ||
35 | fn impls_for_def( | 34 | fn impls_for_def( |
36 | sb: &mut SourceBinder<RootDatabase>, | 35 | sema: &Semantics<RootDatabase>, |
37 | position: FilePosition, | ||
38 | node: &ast::NominalDef, | 36 | node: &ast::NominalDef, |
39 | krate: Crate, | 37 | krate: Crate, |
40 | ) -> Option<Vec<NavigationTarget>> { | 38 | ) -> Option<Vec<NavigationTarget>> { |
41 | let ty = match node { | 39 | let ty = match node { |
42 | ast::NominalDef::StructDef(def) => { | 40 | ast::NominalDef::StructDef(def) => sema.to_def(def)?.ty(sema.db), |
43 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; | 41 | ast::NominalDef::EnumDef(def) => sema.to_def(def)?.ty(sema.db), |
44 | sb.to_def(src)?.ty(sb.db) | 42 | ast::NominalDef::UnionDef(def) => sema.to_def(def)?.ty(sema.db), |
45 | } | ||
46 | ast::NominalDef::EnumDef(def) => { | ||
47 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; | ||
48 | sb.to_def(src)?.ty(sb.db) | ||
49 | } | ||
50 | ast::NominalDef::UnionDef(def) => { | ||
51 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; | ||
52 | sb.to_def(src)?.ty(sb.db) | ||
53 | } | ||
54 | }; | 43 | }; |
55 | 44 | ||
56 | let impls = ImplBlock::all_in_crate(sb.db, krate); | 45 | let impls = ImplBlock::all_in_crate(sema.db, krate); |
57 | 46 | ||
58 | Some( | 47 | Some( |
59 | impls | 48 | impls |
60 | .into_iter() | 49 | .into_iter() |
61 | .filter(|impl_block| ty.is_equal_for_find_impls(&impl_block.target_ty(sb.db))) | 50 | .filter(|impl_block| ty.is_equal_for_find_impls(&impl_block.target_ty(sema.db))) |
62 | .map(|imp| imp.to_nav(sb.db)) | 51 | .map(|imp| imp.to_nav(sema.db)) |
63 | .collect(), | 52 | .collect(), |
64 | ) | 53 | ) |
65 | } | 54 | } |
66 | 55 | ||
67 | fn impls_for_trait( | 56 | fn impls_for_trait( |
68 | sb: &mut SourceBinder<RootDatabase>, | 57 | sema: &Semantics<RootDatabase>, |
69 | position: FilePosition, | ||
70 | node: &ast::TraitDef, | 58 | node: &ast::TraitDef, |
71 | krate: Crate, | 59 | krate: Crate, |
72 | ) -> Option<Vec<NavigationTarget>> { | 60 | ) -> Option<Vec<NavigationTarget>> { |
73 | let src = hir::InFile { file_id: position.file_id.into(), value: node.clone() }; | 61 | let tr = sema.to_def(node)?; |
74 | let tr = sb.to_def(src)?; | ||
75 | 62 | ||
76 | let impls = ImplBlock::for_trait(sb.db, krate, tr); | 63 | let impls = ImplBlock::for_trait(sema.db, krate, tr); |
77 | 64 | ||
78 | Some(impls.into_iter().map(|imp| imp.to_nav(sb.db)).collect()) | 65 | Some(impls.into_iter().map(|imp| imp.to_nav(sema.db)).collect()) |
79 | } | 66 | } |
80 | 67 | ||
81 | #[cfg(test)] | 68 | #[cfg(test)] |