aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model.rs77
-rw-r--r--crates/ra_hir/src/code_model/src.rs4
2 files changed, 71 insertions, 10 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 50c9a79fc..fd7776fb7 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -9,18 +9,19 @@ use hir_def::{
9 body::scope::ExprScopes, 9 body::scope::ExprScopes,
10 builtin_type::BuiltinType, 10 builtin_type::BuiltinType,
11 docs::Documentation, 11 docs::Documentation,
12 nameres::{per_ns::PerNs, raw::ImportId}, 12 per_ns::PerNs,
13 resolver::{HasResolver, TypeNs}, 13 resolver::{HasResolver, TypeNs},
14 type_ref::TypeRef, 14 type_ref::TypeRef,
15 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, 15 ContainerId, HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId,
16 ModuleId, UnionId, 16 LocalStructFieldId, Lookup, ModuleId, UnionId,
17}; 17};
18use hir_expand::{ 18use hir_expand::{
19 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
20 name::{self, AsName}, 20 name::{self, AsName},
21 AstId,
21}; 22};
22use ra_db::{CrateId, Edition}; 23use ra_db::{CrateId, Edition, FileId, FilePosition};
23use ra_syntax::ast; 24use ra_syntax::{ast, AstNode, SyntaxNode};
24 25
25use crate::{ 26use crate::{
26 db::{DefDatabase, HirDatabase}, 27 db::{DefDatabase, HirDatabase},
@@ -78,6 +79,64 @@ impl Crate {
78 } 79 }
79} 80}
80 81
82pub enum ModuleSource {
83 SourceFile(ast::SourceFile),
84 Module(ast::Module),
85}
86
87impl ModuleSource {
88 pub fn new(
89 db: &impl DefDatabase,
90 file_id: Option<FileId>,
91 decl_id: Option<AstId<ast::Module>>,
92 ) -> ModuleSource {
93 match (file_id, decl_id) {
94 (Some(file_id), _) => {
95 let source_file = db.parse(file_id).tree();
96 ModuleSource::SourceFile(source_file)
97 }
98 (None, Some(item_id)) => {
99 let module = item_id.to_node(db);
100 assert!(module.item_list().is_some(), "expected inline module");
101 ModuleSource::Module(module)
102 }
103 (None, None) => panic!(),
104 }
105 }
106
107 // FIXME: this methods do not belong here
108 pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource {
109 let parse = db.parse(position.file_id);
110 match &ra_syntax::algo::find_node_at_offset::<ast::Module>(
111 parse.tree().syntax(),
112 position.offset,
113 ) {
114 Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
115 _ => {
116 let source_file = parse.tree();
117 ModuleSource::SourceFile(source_file)
118 }
119 }
120 }
121
122 pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource {
123 if let Some(m) =
124 child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
125 {
126 ModuleSource::Module(m)
127 } else {
128 let file_id = child.file_id.original_file(db);
129 let source_file = db.parse(file_id).tree();
130 ModuleSource::SourceFile(source_file)
131 }
132 }
133
134 pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource {
135 let source_file = db.parse(file_id).tree();
136 ModuleSource::SourceFile(source_file)
137 }
138}
139
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
82pub struct Module { 141pub struct Module {
83 pub(crate) id: ModuleId, 142 pub(crate) id: ModuleId,
@@ -109,10 +168,10 @@ impl_froms!(
109 BuiltinType 168 BuiltinType
110); 169);
111 170
112pub use hir_def::{attr::Attrs, ModuleSource}; 171pub use hir_def::attr::Attrs;
113 172
114impl Module { 173impl Module {
115 pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module { 174 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
116 Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } 175 Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } }
117 } 176 }
118 177
@@ -222,14 +281,14 @@ impl Module {
222 def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() 281 def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect()
223 } 282 }
224 283
225 fn with_module_id(self, module_id: CrateModuleId) -> Module { 284 fn with_module_id(self, module_id: LocalModuleId) -> Module {
226 Module::new(self.krate(), module_id) 285 Module::new(self.krate(), module_id)
227 } 286 }
228} 287}
229 288
230pub struct Import { 289pub struct Import {
231 pub(crate) parent: Module, 290 pub(crate) parent: Module,
232 pub(crate) id: ImportId, 291 pub(crate) id: LocalImportId,
233} 292}
234 293
235#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 294#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index 402f821bf..b7bafe23d 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -117,7 +117,9 @@ impl HasSource for Import {
117 fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> { 117 fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> {
118 let src = self.parent.definition_source(db); 118 let src = self.parent.definition_source(db);
119 let (_, source_map) = db.raw_items_with_source_map(src.file_id); 119 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
120 src.with_value(source_map.get(&src.value, self.id)) 120 let root = db.parse_or_expand(src.file_id).unwrap();
121 let ptr = source_map.get(self.id);
122 src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root)))
121 } 123 }
122} 124}
123 125