aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs65
-rw-r--r--crates/ra_hir/src/code_model/src.rs4
-rw-r--r--crates/ra_hir_def/src/lib.rs62
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs18
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::{
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,7 +168,7 @@ 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: 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
36use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; 36use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source};
37use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; 37use ra_arena::{impl_arena_id, map::ArenaMap, RawId};
38use ra_db::{salsa, CrateId, FileId}; 38use ra_db::{salsa, CrateId};
39use ra_syntax::{ast, AstNode, SyntaxNode}; 39use ra_syntax::{ast, AstNode};
40 40
41use crate::{builtin_type::BuiltinType, db::InternDatabase}; 41use crate::{builtin_type::BuiltinType, db::InternDatabase};
42 42
43pub enum ModuleSource {
44 SourceFile(ast::SourceFile),
45 Module(ast::Module),
46}
47
48impl 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)]
102pub struct LocalImportId(RawId); 44pub struct LocalImportId(RawId);
103impl_arena_id!(LocalImportId); 45impl_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::{
12use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 12use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
13use ra_syntax::{ 13use ra_syntax::{
14 ast::{self, AttrsOwner, NameOwner}, 14 ast::{self, AttrsOwner, NameOwner},
15 AstNode, AstPtr, SourceFile, 15 AstNode, AstPtr,
16}; 16};
17use test_utils::tested_by; 17use 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
46type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; 46type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
47type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>;
48
49fn 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
53impl ImportSourceMap { 48impl 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