diff options
author | Aleksey Kladov <[email protected]> | 2020-01-16 15:53:11 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-01-16 15:53:11 +0000 |
commit | 9a6c26e34806a05260170029ace4b64adf484a23 (patch) | |
tree | 2fc837f43e859e569b8b156c1d090d1c5fec63c1 | |
parent | 16cfc8d50c9b5b4deb1065b9394e7663df7e9500 (diff) |
Move module to SourceBinder
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 44 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 38 | ||||
-rw-r--r-- | crates/ra_ide/src/references/classify.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/references/rename.rs | 2 |
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 | ||
4 | use hir_def::{nameres::ModuleSource, ModuleId}; | 4 | use hir_def::{nameres::ModuleSource, ModuleId}; |
5 | use hir_expand::name::AsName; | ||
6 | use ra_db::FileId; | 5 | use ra_db::FileId; |
7 | use ra_prof::profile; | 6 | use ra_prof::profile; |
8 | use ra_syntax::ast::{self, AstNode, NameOwner}; | ||
9 | 7 | ||
10 | use crate::{db::DefDatabase, InFile, Module}; | 8 | use crate::{ |
9 | db::{DefDatabase, HirDatabase}, | ||
10 | InFile, Module, | ||
11 | }; | ||
11 | 12 | ||
12 | impl Module { | 13 | impl 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 | }; |
14 | use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind}; | 14 | use hir_expand::{name::AsName, AstId, InFile, MacroDefId, MacroDefKind}; |
15 | use ra_prof::profile; | 15 | use ra_prof::profile; |
16 | use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit}; | 16 | use ra_syntax::{ |
17 | ast::{self, NameOwner}, | ||
18 | match_ast, AstNode, SyntaxNode, TextUnit, | ||
19 | }; | ||
17 | use rustc_hash::FxHashMap; | 20 | use rustc_hash::FxHashMap; |
18 | 21 | ||
19 | use crate::{db::HirDatabase, Local, ModuleSource, SourceAnalyzer, TypeParam}; | 22 | use crate::{db::HirDatabase, Local, Module, ModuleSource, SourceAnalyzer, TypeParam}; |
20 | 23 | ||
21 | pub struct SourceBinder<'a, DB> { | 24 | pub 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 | |||
313 | impl 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 | ||
69 | pub(crate) fn reference_definition( | 70 | pub(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 | ||
104 | pub(crate) fn name_definition( | 104 | fn 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 { |