aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/impls.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/impls.rs')
-rw-r--r--crates/ra_ide/src/impls.rs43
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
3use hir::{FromSource, ImplBlock}; 3use hir::{Crate, ImplBlock, SourceBinder};
4use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
5use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; 5use 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
37fn impls_for_def( 34fn 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
70fn impls_for_trait( 66fn 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 );