aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-01-16 15:53:11 +0000
committerAleksey Kladov <[email protected]>2020-01-16 15:53:11 +0000
commit9a6c26e34806a05260170029ace4b64adf484a23 (patch)
tree2fc837f43e859e569b8b156c1d090d1c5fec63c1
parent16cfc8d50c9b5b4deb1065b9394e7663df7e9500 (diff)
Move module to SourceBinder
-rw-r--r--crates/ra_hir/src/from_source.rs38
-rw-r--r--crates/ra_hir/src/source_binder.rs44
-rw-r--r--crates/ra_ide/src/goto_definition.rs38
-rw-r--r--crates/ra_ide/src/references/classify.rs2
-rw-r--r--crates/ra_ide/src/references/rename.rs2
5 files changed, 69 insertions, 55 deletions
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index c766c3f0b..eb76aecb1 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -2,46 +2,22 @@
2//! file. 2//! file.
3 3
4use hir_def::{nameres::ModuleSource, ModuleId}; 4use hir_def::{nameres::ModuleSource, ModuleId};
5use hir_expand::name::AsName;
6use ra_db::FileId; 5use ra_db::FileId;
7use ra_prof::profile; 6use ra_prof::profile;
8use ra_syntax::ast::{self, AstNode, NameOwner};
9 7
10use crate::{db::DefDatabase, InFile, Module}; 8use crate::{
9 db::{DefDatabase, HirDatabase},
10 InFile, Module,
11};
11 12
12impl Module { 13impl Module {
13 pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> { 14 pub fn from_definition(db: &impl HirDatabase, src: InFile<ModuleSource>) -> Option<Self> {
14 let _p = profile("Module::from_declaration");
15 let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
16
17 let parent_module = match parent_declaration {
18 Some(parent_declaration) => {
19 let src_parent = InFile { file_id: src.file_id, value: parent_declaration };
20 Module::from_declaration(db, src_parent)
21 }
22 None => {
23 let source_file = db.parse(src.file_id.original_file(db)).tree();
24 let src_parent =
25 InFile { file_id: src.file_id, value: ModuleSource::SourceFile(source_file) };
26 Module::from_definition(db, src_parent)
27 }
28 }?;
29
30 let child_name = src.value.name()?.as_name();
31 let def_map = db.crate_def_map(parent_module.id.krate);
32 let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?;
33 Some(parent_module.with_module_id(*child_id))
34 }
35
36 pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> {
37 let _p = profile("Module::from_definition"); 15 let _p = profile("Module::from_definition");
16 let mut sb = crate::SourceBinder::new(db);
38 match src.value { 17 match src.value {
39 ModuleSource::Module(ref module) => { 18 ModuleSource::Module(ref module) => {
40 assert!(!module.has_semi()); 19 assert!(!module.has_semi());
41 return Module::from_declaration( 20 return sb.to_def(InFile { file_id: src.file_id, value: module.clone() });
42 db,
43 InFile { file_id: src.file_id, value: module.clone() },
44 );
45 } 21 }
46 ModuleSource::SourceFile(_) => (), 22 ModuleSource::SourceFile(_) => (),
47 }; 23 };
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 00f48177b..26eedbb2c 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -11,12 +11,15 @@ use hir_def::{
11 ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, 11 ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId,
12 StaticId, StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId, 12 StaticId, StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
13}; 13};
14use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind}; 14use hir_expand::{name::AsName, AstId, InFile, MacroDefId, MacroDefKind};
15use ra_prof::profile; 15use ra_prof::profile;
16use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit}; 16use ra_syntax::{
17 ast::{self, NameOwner},
18 match_ast, AstNode, SyntaxNode, TextUnit,
19};
17use rustc_hash::FxHashMap; 20use rustc_hash::FxHashMap;
18 21
19use crate::{db::HirDatabase, Local, ModuleSource, SourceAnalyzer, TypeParam}; 22use crate::{db::HirDatabase, Local, Module, ModuleSource, SourceAnalyzer, TypeParam};
20 23
21pub struct SourceBinder<'a, DB> { 24pub struct SourceBinder<'a, DB> {
22 pub db: &'a DB, 25 pub db: &'a DB,
@@ -306,3 +309,38 @@ impl ToDef for ast::TypeParam {
306 Some(TypeParam { id }) 309 Some(TypeParam { id })
307 } 310 }
308} 311}
312
313impl ToDef for ast::Module {
314 type Def = Module;
315
316 fn to_def<DB: HirDatabase>(
317 sb: &mut SourceBinder<'_, DB>,
318 src: InFile<ast::Module>,
319 ) -> Option<Module> {
320 {
321 let _p = profile("ast::Module::to_def");
322 let parent_declaration =
323 src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
324
325 let parent_module = match parent_declaration {
326 Some(parent_declaration) => {
327 let src_parent = InFile { file_id: src.file_id, value: parent_declaration };
328 sb.to_def(src_parent)
329 }
330 None => {
331 let source_file = sb.db.parse(src.file_id.original_file(sb.db)).tree();
332 let src_parent = InFile {
333 file_id: src.file_id,
334 value: ModuleSource::SourceFile(source_file),
335 };
336 Module::from_definition(sb.db, src_parent)
337 }
338 }?;
339
340 let child_name = src.value.name()?.as_name();
341 let def_map = sb.db.crate_def_map(parent_module.id.krate);
342 let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?;
343 Some(parent_module.with_module_id(*child_id))
344 }
345 }
346}
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index f2b5af321..5a12a619c 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -24,13 +24,14 @@ pub(crate) fn goto_definition(
24 let original_token = pick_best(file.token_at_offset(position.offset))?; 24 let original_token = pick_best(file.token_at_offset(position.offset))?;
25 let token = descend_into_macros(db, position.file_id, original_token.clone()); 25 let token = descend_into_macros(db, position.file_id, original_token.clone());
26 26
27 let mut sb = SourceBinder::new(db);
27 let nav_targets = match_ast! { 28 let nav_targets = match_ast! {
28 match (token.value.parent()) { 29 match (token.value.parent()) {
29 ast::NameRef(name_ref) => { 30 ast::NameRef(name_ref) => {
30 reference_definition(db, token.with_value(&name_ref)).to_vec() 31 reference_definition(&mut sb, token.with_value(&name_ref)).to_vec()
31 }, 32 },
32 ast::Name(name) => { 33 ast::Name(name) => {
33 name_definition(db, token.with_value(&name))? 34 name_definition(&mut sb, token.with_value(&name))?
34 }, 35 },
35 _ => return None, 36 _ => return None,
36 } 37 }
@@ -67,20 +68,19 @@ impl ReferenceResult {
67} 68}
68 69
69pub(crate) fn reference_definition( 70pub(crate) fn reference_definition(
70 db: &RootDatabase, 71 sb: &mut SourceBinder<RootDatabase>,
71 name_ref: InFile<&ast::NameRef>, 72 name_ref: InFile<&ast::NameRef>,
72) -> ReferenceResult { 73) -> ReferenceResult {
73 use self::ReferenceResult::*; 74 use self::ReferenceResult::*;
74 75
75 let mut sb = SourceBinder::new(db); 76 let name_kind = classify_name_ref(sb, name_ref).map(|d| d.kind);
76 let name_kind = classify_name_ref(&mut sb, name_ref).map(|d| d.kind);
77 match name_kind { 77 match name_kind {
78 Some(Macro(it)) => return Exact(it.to_nav(db)), 78 Some(Macro(it)) => return Exact(it.to_nav(sb.db)),
79 Some(Field(it)) => return Exact(it.to_nav(db)), 79 Some(Field(it)) => return Exact(it.to_nav(sb.db)),
80 Some(TypeParam(it)) => return Exact(it.to_nav(db)), 80 Some(TypeParam(it)) => return Exact(it.to_nav(sb.db)),
81 Some(AssocItem(it)) => return Exact(it.to_nav(db)), 81 Some(AssocItem(it)) => return Exact(it.to_nav(sb.db)),
82 Some(Local(it)) => return Exact(it.to_nav(db)), 82 Some(Local(it)) => return Exact(it.to_nav(sb.db)),
83 Some(Def(def)) => match NavigationTarget::from_def(db, def) { 83 Some(Def(def)) => match NavigationTarget::from_def(sb.db, def) {
84 Some(nav) => return Exact(nav), 84 Some(nav) => return Exact(nav),
85 None => return Approximate(vec![]), 85 None => return Approximate(vec![]),
86 }, 86 },
@@ -88,21 +88,21 @@ pub(crate) fn reference_definition(
88 // FIXME: ideally, this should point to the type in the impl, and 88 // FIXME: ideally, this should point to the type in the impl, and
89 // not at the whole impl. And goto **type** definition should bring 89 // not at the whole impl. And goto **type** definition should bring
90 // us to the actual type 90 // us to the actual type
91 return Exact(imp.to_nav(db)); 91 return Exact(imp.to_nav(sb.db));
92 } 92 }
93 None => {} 93 None => {}
94 }; 94 };
95 95
96 // Fallback index based approach: 96 // Fallback index based approach:
97 let navs = crate::symbol_index::index_resolve(db, name_ref.value) 97 let navs = crate::symbol_index::index_resolve(sb.db, name_ref.value)
98 .into_iter() 98 .into_iter()
99 .map(|s| s.to_nav(db)) 99 .map(|s| s.to_nav(sb.db))
100 .collect(); 100 .collect();
101 Approximate(navs) 101 Approximate(navs)
102} 102}
103 103
104pub(crate) fn name_definition( 104fn name_definition(
105 db: &RootDatabase, 105 sb: &mut SourceBinder<RootDatabase>,
106 name: InFile<&ast::Name>, 106 name: InFile<&ast::Name>,
107) -> Option<Vec<NavigationTarget>> { 107) -> Option<Vec<NavigationTarget>> {
108 let parent = name.value.syntax().parent()?; 108 let parent = name.value.syntax().parent()?;
@@ -110,14 +110,14 @@ pub(crate) fn name_definition(
110 if let Some(module) = ast::Module::cast(parent.clone()) { 110 if let Some(module) = ast::Module::cast(parent.clone()) {
111 if module.has_semi() { 111 if module.has_semi() {
112 let src = name.with_value(module); 112 let src = name.with_value(module);
113 if let Some(child_module) = hir::Module::from_declaration(db, src) { 113 if let Some(child_module) = sb.to_def(src) {
114 let nav = child_module.to_nav(db); 114 let nav = child_module.to_nav(sb.db);
115 return Some(vec![nav]); 115 return Some(vec![nav]);
116 } 116 }
117 } 117 }
118 } 118 }
119 119
120 if let Some(nav) = named_target(db, name.with_value(&parent)) { 120 if let Some(nav) = named_target(sb.db, name.with_value(&parent)) {
121 return Some(vec![nav]); 121 return Some(vec![nav]);
122 } 122 }
123 123
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs
index 82a18a0a5..cb7da1fff 100644
--- a/crates/ra_ide/src/references/classify.rs
+++ b/crates/ra_ide/src/references/classify.rs
@@ -42,7 +42,7 @@ pub(crate) fn classify_name(
42 hir::Module::from_definition(sb.db, src) 42 hir::Module::from_definition(sb.db, src)
43 } else { 43 } else {
44 let src = name.with_value(it); 44 let src = name.with_value(it);
45 hir::Module::from_declaration(sb.db, src) 45 sb.to_def(src)
46 } 46 }
47 }?; 47 }?;
48 Some(from_module_def(sb.db, def.into(), None)) 48 Some(from_module_def(sb.db, def.into(), None))
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs
index e02985dcd..626efb603 100644
--- a/crates/ra_ide/src/references/rename.rs
+++ b/crates/ra_ide/src/references/rename.rs
@@ -63,7 +63,7 @@ fn rename_mod(
63 let mut source_file_edits = Vec::new(); 63 let mut source_file_edits = Vec::new();
64 let mut file_system_edits = Vec::new(); 64 let mut file_system_edits = Vec::new();
65 let module_src = hir::InFile { file_id: position.file_id.into(), value: ast_module.clone() }; 65 let module_src = hir::InFile { file_id: position.file_id.into(), value: ast_module.clone() };
66 if let Some(module) = hir::Module::from_declaration(db, module_src) { 66 if let Some(module) = hir::SourceBinder::new(db).to_def(module_src) {
67 let src = module.definition_source(db); 67 let src = module.definition_source(db);
68 let file_id = src.file_id.original_file(db); 68 let file_id = src.file_id.original_file(db);
69 match src.value { 69 match src.value {