diff options
Diffstat (limited to 'crates/ra_ide/src/impls.rs')
-rw-r--r-- | crates/ra_ide/src/impls.rs | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/crates/ra_ide/src/impls.rs b/crates/ra_ide/src/impls.rs index 31195036e..9834025d3 100644 --- a/crates/ra_ide/src/impls.rs +++ b/crates/ra_ide/src/impls.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{FromSource, ImplBlock}; | 3 | use hir::{Crate, ImplBlock, SourceBinder}; |
4 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | 5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; |
6 | 6 | ||
@@ -12,22 +12,19 @@ pub(crate) fn goto_implementation( | |||
12 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { | 12 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { |
13 | let parse = db.parse(position.file_id); | 13 | let parse = db.parse(position.file_id); |
14 | let syntax = parse.tree().syntax().clone(); | 14 | let syntax = parse.tree().syntax().clone(); |
15 | let mut sb = SourceBinder::new(db); | ||
15 | 16 | ||
16 | let src = hir::ModuleSource::from_position(db, position); | 17 | let krate = sb.to_module_def(position.file_id)?.krate(); |
17 | let module = hir::Module::from_definition( | ||
18 | db, | ||
19 | hir::InFile { file_id: position.file_id.into(), value: src }, | ||
20 | )?; | ||
21 | 18 | ||
22 | 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) { |
23 | return Some(RangeInfo::new( | 20 | return Some(RangeInfo::new( |
24 | nominal_def.syntax().text_range(), | 21 | nominal_def.syntax().text_range(), |
25 | impls_for_def(db, position, &nominal_def, module)?, | 22 | impls_for_def(&mut sb, position, &nominal_def, krate)?, |
26 | )); | 23 | )); |
27 | } 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) { |
28 | return Some(RangeInfo::new( | 25 | return Some(RangeInfo::new( |
29 | trait_def.syntax().text_range(), | 26 | trait_def.syntax().text_range(), |
30 | impls_for_trait(db, position, &trait_def, module)?, | 27 | impls_for_trait(&mut sb, position, &trait_def, krate)?, |
31 | )); | 28 | )); |
32 | } | 29 | } |
33 | 30 | ||
@@ -35,51 +32,49 @@ pub(crate) fn goto_implementation( | |||
35 | } | 32 | } |
36 | 33 | ||
37 | fn impls_for_def( | 34 | fn impls_for_def( |
38 | db: &RootDatabase, | 35 | sb: &mut SourceBinder<RootDatabase>, |
39 | position: FilePosition, | 36 | position: FilePosition, |
40 | node: &ast::NominalDef, | 37 | node: &ast::NominalDef, |
41 | module: hir::Module, | 38 | krate: Crate, |
42 | ) -> Option<Vec<NavigationTarget>> { | 39 | ) -> Option<Vec<NavigationTarget>> { |
43 | let ty = match node { | 40 | let ty = match node { |
44 | ast::NominalDef::StructDef(def) => { | 41 | ast::NominalDef::StructDef(def) => { |
45 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; | 42 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; |
46 | hir::Struct::from_source(db, src)?.ty(db) | 43 | sb.to_def(src)?.ty(sb.db) |
47 | } | 44 | } |
48 | ast::NominalDef::EnumDef(def) => { | 45 | ast::NominalDef::EnumDef(def) => { |
49 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; | 46 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; |
50 | hir::Enum::from_source(db, src)?.ty(db) | 47 | sb.to_def(src)?.ty(sb.db) |
51 | } | 48 | } |
52 | ast::NominalDef::UnionDef(def) => { | 49 | ast::NominalDef::UnionDef(def) => { |
53 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; | 50 | let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() }; |
54 | hir::Union::from_source(db, src)?.ty(db) | 51 | sb.to_def(src)?.ty(sb.db) |
55 | } | 52 | } |
56 | }; | 53 | }; |
57 | 54 | ||
58 | let krate = module.krate(); | 55 | let impls = ImplBlock::all_in_crate(sb.db, krate); |
59 | let impls = ImplBlock::all_in_crate(db, krate); | ||
60 | 56 | ||
61 | Some( | 57 | Some( |
62 | impls | 58 | impls |
63 | .into_iter() | 59 | .into_iter() |
64 | .filter(|impl_block| ty.is_equal_for_find_impls(&impl_block.target_ty(db))) | 60 | .filter(|impl_block| ty.is_equal_for_find_impls(&impl_block.target_ty(sb.db))) |
65 | .map(|imp| imp.to_nav(db)) | 61 | .map(|imp| imp.to_nav(sb.db)) |
66 | .collect(), | 62 | .collect(), |
67 | ) | 63 | ) |
68 | } | 64 | } |
69 | 65 | ||
70 | fn impls_for_trait( | 66 | fn impls_for_trait( |
71 | db: &RootDatabase, | 67 | sb: &mut SourceBinder<RootDatabase>, |
72 | position: FilePosition, | 68 | position: FilePosition, |
73 | node: &ast::TraitDef, | 69 | node: &ast::TraitDef, |
74 | module: hir::Module, | 70 | krate: Crate, |
75 | ) -> Option<Vec<NavigationTarget>> { | 71 | ) -> Option<Vec<NavigationTarget>> { |
76 | let src = hir::InFile { file_id: position.file_id.into(), value: node.clone() }; | 72 | let src = hir::InFile { file_id: position.file_id.into(), value: node.clone() }; |
77 | let tr = hir::Trait::from_source(db, src)?; | 73 | let tr = sb.to_def(src)?; |
78 | 74 | ||
79 | let krate = module.krate(); | 75 | let impls = ImplBlock::for_trait(sb.db, krate, tr); |
80 | let impls = ImplBlock::for_trait(db, krate, tr); | ||
81 | 76 | ||
82 | Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect()) | 77 | Some(impls.into_iter().map(|imp| imp.to_nav(sb.db)).collect()) |
83 | } | 78 | } |
84 | 79 | ||
85 | #[cfg(test)] | 80 | #[cfg(test)] |
@@ -210,7 +205,7 @@ mod tests { | |||
210 | " | 205 | " |
211 | //- /lib.rs | 206 | //- /lib.rs |
212 | #[derive(Copy)] | 207 | #[derive(Copy)] |
213 | struct Foo<|>; | 208 | struct Foo<|>; |
214 | ", | 209 | ", |
215 | &["impl IMPL_BLOCK FileId(1) [0; 15)"], | 210 | &["impl IMPL_BLOCK FileId(1) [0; 15)"], |
216 | ); | 211 | ); |