aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/source_binder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r--crates/ra_hir/src/source_binder.rs80
1 files changed, 52 insertions, 28 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 85bd84469..4c14650c0 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -13,14 +13,16 @@ use ra_syntax::{
13}; 13};
14 14
15use crate::{ 15use crate::{
16 HirDatabase, Module, Function, SourceItemId, 16 HirDatabase, Function, SourceItemId,
17 module::ModuleSource, 17 DefKind, DefLoc, AsName, Module,
18 DefKind, DefLoc, AsName,
19}; 18};
20 19
21/// Locates the module by `FileId`. Picks topmost module in the file. 20/// Locates the module by `FileId`. Picks topmost module in the file.
22pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable<Option<Module>> { 21pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable<Option<Module>> {
23 let module_source = ModuleSource::new_file(file_id.into()); 22 let module_source = SourceItemId {
23 file_id: file_id.into(),
24 item_id: None,
25 };
24 module_from_source(db, module_source) 26 module_from_source(db, module_source)
25} 27}
26 28
@@ -34,7 +36,7 @@ pub fn module_from_declaration(
34 let child_name = decl.name(); 36 let child_name = decl.name();
35 match (parent_module, child_name) { 37 match (parent_module, child_name) {
36 (Some(parent_module), Some(child_name)) => { 38 (Some(parent_module), Some(child_name)) => {
37 if let Some(child) = parent_module.child(&child_name.as_name()) { 39 if let Some(child) = parent_module.child(db, &child_name.as_name())? {
38 return Ok(Some(child)); 40 return Ok(Some(child));
39 } 41 }
40 } 42 }
@@ -49,11 +51,26 @@ pub fn module_from_position(
49 position: FilePosition, 51 position: FilePosition,
50) -> Cancelable<Option<Module>> { 52) -> Cancelable<Option<Module>> {
51 let file = db.source_file(position.file_id); 53 let file = db.source_file(position.file_id);
52 let module_source = match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { 54 match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) {
53 Some(m) if !m.has_semi() => ModuleSource::new_inline(db, position.file_id.into(), m), 55 Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m),
54 _ => ModuleSource::new_file(position.file_id.into()), 56 _ => module_from_file_id(db, position.file_id.into()),
57 }
58}
59
60fn module_from_inline(
61 db: &impl HirDatabase,
62 file_id: FileId,
63 module: ast::Module,
64) -> Cancelable<Option<Module>> {
65 assert!(!module.has_semi());
66 let file_id = file_id.into();
67 let file_items = db.file_items(file_id);
68 let item_id = file_items.id_of(file_id, module.syntax());
69 let source = SourceItemId {
70 file_id,
71 item_id: Some(item_id),
55 }; 72 };
56 module_from_source(db, module_source) 73 module_from_source(db, source)
57} 74}
58 75
59/// Locates the module by child syntax element within the module 76/// Locates the module by child syntax element within the module
@@ -62,29 +79,34 @@ pub fn module_from_child_node(
62 file_id: FileId, 79 file_id: FileId,
63 child: SyntaxNodeRef, 80 child: SyntaxNodeRef,
64) -> Cancelable<Option<Module>> { 81) -> Cancelable<Option<Module>> {
65 let module_source = if let Some(m) = child 82 if let Some(m) = child
66 .ancestors() 83 .ancestors()
67 .filter_map(ast::Module::cast) 84 .filter_map(ast::Module::cast)
68 .find(|it| !it.has_semi()) 85 .find(|it| !it.has_semi())
69 { 86 {
70 ModuleSource::new_inline(db, file_id.into(), m) 87 module_from_inline(db, file_id.into(), m)
71 } else { 88 } else {
72 ModuleSource::new_file(file_id.into()) 89 module_from_file_id(db, file_id.into())
73 }; 90 }
74 module_from_source(db, module_source)
75} 91}
76 92
77fn module_from_source( 93fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Cancelable<Option<Module>> {
78 db: &impl HirDatabase, 94 let source_root_id = db.file_source_root(source.file_id.as_original_file());
79 module_source: ModuleSource,
80) -> Cancelable<Option<Module>> {
81 let source_root_id = db.file_source_root(module_source.file_id().as_original_file());
82 let module_tree = db.module_tree(source_root_id)?; 95 let module_tree = db.module_tree(source_root_id)?;
83 let m = module_tree 96 let module_id = ctry!(module_tree.find_module_by_source(source));
84 .modules_with_sources() 97 Ok(Some(Module::from_module_id(db, source_root_id, module_id)?))
85 .find(|(_id, src)| src == &module_source); 98}
86 let module_id = ctry!(m).0; 99
87 Ok(Some(Module::new(db, source_root_id, module_id)?)) 100pub fn function_from_position(
101 db: &impl HirDatabase,
102 position: FilePosition,
103) -> Cancelable<Option<Function>> {
104 let file = db.source_file(position.file_id);
105 let fn_def = ctry!(find_node_at_offset::<ast::FnDef>(
106 file.syntax(),
107 position.offset
108 ));
109 function_from_source(db, position.file_id, fn_def)
88} 110}
89 111
90pub fn function_from_source( 112pub fn function_from_source(
@@ -102,7 +124,8 @@ pub fn function_from_module(
102 module: &Module, 124 module: &Module,
103 fn_def: ast::FnDef, 125 fn_def: ast::FnDef,
104) -> Function { 126) -> Function {
105 let file_id = module.source().file_id(); 127 let loc = module.def_id.loc(db);
128 let file_id = loc.source_item_id.file_id;
106 let file_items = db.file_items(file_id); 129 let file_items = db.file_items(file_id);
107 let item_id = file_items.id_of(file_id, fn_def.syntax()); 130 let item_id = file_items.id_of(file_id, fn_def.syntax());
108 let source_item_id = SourceItemId { 131 let source_item_id = SourceItemId {
@@ -111,8 +134,8 @@ pub fn function_from_module(
111 }; 134 };
112 let def_loc = DefLoc { 135 let def_loc = DefLoc {
113 kind: DefKind::Function, 136 kind: DefKind::Function,
114 source_root_id: module.source_root_id, 137 source_root_id: loc.source_root_id,
115 module_id: module.module_id, 138 module_id: loc.module_id,
116 source_item_id, 139 source_item_id,
117 }; 140 };
118 Function::new(def_loc.id(db)) 141 Function::new(def_loc.id(db))
@@ -135,7 +158,8 @@ pub fn macro_symbols(
135 Some(it) => it, 158 Some(it) => it,
136 None => return Ok(Vec::new()), 159 None => return Ok(Vec::new()),
137 }; 160 };
138 let items = db.input_module_items(module.source_root_id, module.module_id)?; 161 let loc = module.def_id.loc(db);
162 let items = db.input_module_items(loc.source_root_id, loc.module_id)?;
139 let mut res = Vec::new(); 163 let mut res = Vec::new();
140 164
141 for macro_call_id in items 165 for macro_call_id in items