diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 65 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 62 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 18 |
4 files changed, 71 insertions, 78 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index cd178bf88..fd7776fb7 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -18,9 +18,10 @@ use hir_def::{ | |||
18 | use hir_expand::{ | 18 | use hir_expand::{ |
19 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
20 | name::{self, AsName}, | 20 | name::{self, AsName}, |
21 | AstId, | ||
21 | }; | 22 | }; |
22 | use ra_db::{CrateId, Edition}; | 23 | use ra_db::{CrateId, Edition, FileId, FilePosition}; |
23 | use ra_syntax::ast; | 24 | use ra_syntax::{ast, AstNode, SyntaxNode}; |
24 | 25 | ||
25 | use crate::{ | 26 | use crate::{ |
26 | db::{DefDatabase, HirDatabase}, | 27 | db::{DefDatabase, HirDatabase}, |
@@ -78,6 +79,64 @@ impl Crate { | |||
78 | } | 79 | } |
79 | } | 80 | } |
80 | 81 | ||
82 | pub enum ModuleSource { | ||
83 | SourceFile(ast::SourceFile), | ||
84 | Module(ast::Module), | ||
85 | } | ||
86 | |||
87 | impl 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)] |
82 | pub struct Module { | 141 | pub struct Module { |
83 | pub(crate) id: ModuleId, | 142 | pub(crate) id: ModuleId, |
@@ -109,7 +168,7 @@ impl_froms!( | |||
109 | BuiltinType | 168 | BuiltinType |
110 | ); | 169 | ); |
111 | 170 | ||
112 | pub use hir_def::{attr::Attrs, ModuleSource}; | 171 | pub use hir_def::attr::Attrs; |
113 | 172 | ||
114 | impl Module { | 173 | impl Module { |
115 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 174 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
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 | ||
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 11ae9cdc0..1d195d65d 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -35,69 +35,11 @@ use std::hash::{Hash, Hasher}; | |||
35 | 35 | ||
36 | use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; | 36 | use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; |
37 | use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; | 37 | use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; |
38 | use ra_db::{salsa, CrateId, FileId}; | 38 | use ra_db::{salsa, CrateId}; |
39 | use ra_syntax::{ast, AstNode, SyntaxNode}; | 39 | use ra_syntax::{ast, AstNode}; |
40 | 40 | ||
41 | use crate::{builtin_type::BuiltinType, db::InternDatabase}; | 41 | use crate::{builtin_type::BuiltinType, db::InternDatabase}; |
42 | 42 | ||
43 | pub enum ModuleSource { | ||
44 | SourceFile(ast::SourceFile), | ||
45 | Module(ast::Module), | ||
46 | } | ||
47 | |||
48 | impl ModuleSource { | ||
49 | pub fn new( | ||
50 | db: &impl db::DefDatabase, | ||
51 | file_id: Option<FileId>, | ||
52 | decl_id: Option<AstId<ast::Module>>, | ||
53 | ) -> ModuleSource { | ||
54 | match (file_id, decl_id) { | ||
55 | (Some(file_id), _) => { | ||
56 | let source_file = db.parse(file_id).tree(); | ||
57 | ModuleSource::SourceFile(source_file) | ||
58 | } | ||
59 | (None, Some(item_id)) => { | ||
60 | let module = item_id.to_node(db); | ||
61 | assert!(module.item_list().is_some(), "expected inline module"); | ||
62 | ModuleSource::Module(module) | ||
63 | } | ||
64 | (None, None) => panic!(), | ||
65 | } | ||
66 | } | ||
67 | |||
68 | // FIXME: this methods do not belong here | ||
69 | pub fn from_position(db: &impl db::DefDatabase, position: ra_db::FilePosition) -> ModuleSource { | ||
70 | let parse = db.parse(position.file_id); | ||
71 | match &ra_syntax::algo::find_node_at_offset::<ast::Module>( | ||
72 | parse.tree().syntax(), | ||
73 | position.offset, | ||
74 | ) { | ||
75 | Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()), | ||
76 | _ => { | ||
77 | let source_file = parse.tree(); | ||
78 | ModuleSource::SourceFile(source_file) | ||
79 | } | ||
80 | } | ||
81 | } | ||
82 | |||
83 | pub fn from_child_node(db: &impl db::DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource { | ||
84 | if let Some(m) = | ||
85 | child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) | ||
86 | { | ||
87 | ModuleSource::Module(m) | ||
88 | } else { | ||
89 | let file_id = child.file_id.original_file(db); | ||
90 | let source_file = db.parse(file_id).tree(); | ||
91 | ModuleSource::SourceFile(source_file) | ||
92 | } | ||
93 | } | ||
94 | |||
95 | pub fn from_file_id(db: &impl db::DefDatabase, file_id: FileId) -> ModuleSource { | ||
96 | let source_file = db.parse(file_id).tree(); | ||
97 | ModuleSource::SourceFile(source_file) | ||
98 | } | ||
99 | } | ||
100 | |||
101 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 43 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
102 | pub struct LocalImportId(RawId); | 44 | pub struct LocalImportId(RawId); |
103 | impl_arena_id!(LocalImportId); | 45 | impl_arena_id!(LocalImportId); |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 8ee6f54cd..552cbe544 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -12,7 +12,7 @@ use hir_expand::{ | |||
12 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | 12 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; |
13 | use ra_syntax::{ | 13 | use ra_syntax::{ |
14 | ast::{self, AttrsOwner, NameOwner}, | 14 | ast::{self, AttrsOwner, NameOwner}, |
15 | AstNode, AstPtr, SourceFile, | 15 | AstNode, AstPtr, |
16 | }; | 16 | }; |
17 | use test_utils::tested_by; | 17 | use test_utils::tested_by; |
18 | 18 | ||
@@ -20,7 +20,7 @@ use crate::{ | |||
20 | attr::{Attr, Attrs}, | 20 | attr::{Attr, Attrs}, |
21 | db::DefDatabase, | 21 | db::DefDatabase, |
22 | path::Path, | 22 | path::Path, |
23 | FileAstId, HirFileId, LocalImportId, ModuleSource, Source, | 23 | FileAstId, HirFileId, LocalImportId, Source, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | /// `RawItems` is a set of top-level items in a file (except for impls). | 26 | /// `RawItems` is a set of top-level items in a file (except for impls). |
@@ -44,24 +44,14 @@ pub struct ImportSourceMap { | |||
44 | } | 44 | } |
45 | 45 | ||
46 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; | 46 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; |
47 | type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>; | ||
48 | |||
49 | fn to_node(ptr: ImportSourcePtr, file: &SourceFile) -> ImportSource { | ||
50 | ptr.map(|ptr| ptr.to_node(file.syntax()), |ptr| ptr.to_node(file.syntax())) | ||
51 | } | ||
52 | 47 | ||
53 | impl ImportSourceMap { | 48 | impl ImportSourceMap { |
54 | fn insert(&mut self, import: LocalImportId, ptr: ImportSourcePtr) { | 49 | fn insert(&mut self, import: LocalImportId, ptr: ImportSourcePtr) { |
55 | self.map.insert(import, ptr) | 50 | self.map.insert(import, ptr) |
56 | } | 51 | } |
57 | 52 | ||
58 | pub fn get(&self, source: &ModuleSource, import: LocalImportId) -> ImportSource { | 53 | pub fn get(&self, import: LocalImportId) -> ImportSourcePtr { |
59 | let file = match source { | 54 | self.map[import].clone() |
60 | ModuleSource::SourceFile(file) => file.clone(), | ||
61 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), | ||
62 | }; | ||
63 | |||
64 | to_node(self.map[import], &file) | ||
65 | } | 55 | } |
66 | } | 56 | } |
67 | 57 | ||