Skip to content

Commit 595b06a

Browse files
committed
Create modules via SourceBinder
1 parent 9a6c26e commit 595b06a

File tree

10 files changed

+65
-112
lines changed

10 files changed

+65
-112
lines changed

crates/ra_hir/src/from_source.rs

Lines changed: 0 additions & 38 deletions
This file was deleted.

crates/ra_hir/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ mod from_id;
3636
mod code_model;
3737

3838
mod has_source;
39-
mod from_source;
4039

4140
pub use crate::{
4241
code_model::{

crates/ra_hir/src/source_binder.rs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use ra_syntax::{
1919
};
2020
use rustc_hash::FxHashMap;
2121

22-
use crate::{db::HirDatabase, Local, Module, ModuleSource, SourceAnalyzer, TypeParam};
22+
use crate::{db::HirDatabase, Local, Module, SourceAnalyzer, TypeParam};
23+
use ra_db::FileId;
2324

2425
pub struct SourceBinder<'a, DB> {
2526
pub db: &'a DB,
@@ -60,6 +61,16 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
6061
T::to_def(self, src)
6162
}
6263

64+
pub fn to_module_def(&mut self, file: FileId) -> Option<Module> {
65+
let _p = profile("SourceBinder::to_module_def");
66+
let (krate, local_id) = self.db.relevant_crates(file).iter().find_map(|&crate_id| {
67+
let crate_def_map = self.db.crate_def_map(crate_id);
68+
let local_id = crate_def_map.modules_for_file(file).next()?;
69+
Some((crate_id, local_id))
70+
})?;
71+
Some(Module { id: ModuleId { krate, local_id } })
72+
}
73+
6374
fn to_id<T: ToId>(&mut self, src: InFile<T>) -> Option<T::ID> {
6475
T::to_id(self, src)
6576
}
@@ -107,8 +118,7 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
107118
return Some(res);
108119
}
109120

110-
let module_source = ModuleSource::from_child_node(self.db, src);
111-
let c = crate::Module::from_definition(self.db, src.with_value(module_source))?;
121+
let c = self.to_module_def(src.file_id.original_file(self.db))?;
112122
Some(c.id.into())
113123
}
114124

@@ -248,14 +258,12 @@ impl ToId for ast::MacroCall {
248258
) -> Option<Self::ID> {
249259
let kind = MacroDefKind::Declarative;
250260

251-
let module_src = ModuleSource::from_child_node(sb.db, src.as_ref().map(|it| it.syntax()));
252-
let module = crate::Module::from_definition(sb.db, InFile::new(src.file_id, module_src))?;
253-
let krate = Some(module.krate().id);
261+
let krate = sb.to_module_def(src.file_id.original_file(sb.db))?.id.krate;
254262

255263
let ast_id =
256264
Some(AstId::new(src.file_id, sb.db.ast_id_map(src.file_id).ast_id(&src.value)));
257265

258-
Some(MacroDefId { krate, ast_id, kind })
266+
Some(MacroDefId { krate: Some(krate), ast_id, kind })
259267
}
260268
}
261269

@@ -319,21 +327,22 @@ impl ToDef for ast::Module {
319327
) -> Option<Module> {
320328
{
321329
let _p = profile("ast::Module::to_def");
322-
let parent_declaration =
323-
src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
330+
let parent_declaration = src
331+
.as_ref()
332+
.map(|it| it.syntax())
333+
.cloned()
334+
.ancestors_with_macros(sb.db)
335+
.skip(1)
336+
.find_map(|it| {
337+
let m = ast::Module::cast(it.value.clone())?;
338+
Some(it.with_value(m))
339+
});
324340

325341
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-
}
342+
Some(parent_declaration) => sb.to_def(parent_declaration),
330343
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)
344+
let file_id = src.file_id.original_file(sb.db);
345+
sb.to_module_def(file_id)
337346
}
338347
}?;
339348

crates/ra_ide/src/completion/completion_context.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,11 @@ impl<'a> CompletionContext<'a> {
5252
original_parse: &'a Parse<ast::SourceFile>,
5353
position: FilePosition,
5454
) -> Option<CompletionContext<'a>> {
55-
let src = hir::ModuleSource::from_position(db, position);
56-
let module = hir::Module::from_definition(
57-
db,
58-
hir::InFile { file_id: position.file_id.into(), value: src },
59-
);
55+
let mut sb = hir::SourceBinder::new(db);
56+
let module = sb.to_module_def(position.file_id);
6057
let token =
6158
original_parse.tree().syntax().token_at_offset(position.offset).left_biased()?;
62-
let analyzer = hir::SourceAnalyzer::new(
63-
db,
59+
let analyzer = sb.analyze(
6460
hir::InFile::new(position.file_id.into(), &token.parent()),
6561
Some(position.offset),
6662
);

crates/ra_ide/src/diagnostics.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub enum Severity {
2323

2424
pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> {
2525
let _p = profile("diagnostics");
26+
let mut sb = hir::SourceBinder::new(db);
2627
let parse = db.parse(file_id);
2728
let mut res = Vec::new();
2829

@@ -108,10 +109,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
108109
fix: Some(fix),
109110
})
110111
});
111-
let source_file = db.parse(file_id).tree();
112-
let src =
113-
hir::InFile { file_id: file_id.into(), value: hir::ModuleSource::SourceFile(source_file) };
114-
if let Some(m) = hir::Module::from_definition(db, src) {
112+
if let Some(m) = sb.to_module_def(file_id) {
115113
m.diagnostics(db, &mut sink);
116114
};
117115
drop(sink);

crates/ra_ide/src/impls.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! FIXME: write short doc here
22
3-
use hir::{ImplBlock, SourceBinder};
3+
use hir::{Crate, ImplBlock, SourceBinder};
44
use ra_db::SourceDatabase;
55
use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
66

@@ -14,21 +14,17 @@ pub(crate) fn goto_implementation(
1414
let syntax = parse.tree().syntax().clone();
1515
let mut sb = SourceBinder::new(db);
1616

17-
let src = hir::ModuleSource::from_position(db, position);
18-
let module = hir::Module::from_definition(
19-
db,
20-
hir::InFile { file_id: position.file_id.into(), value: src },
21-
)?;
17+
let krate = sb.to_module_def(position.file_id)?.krate();
2218

2319
if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) {
2420
return Some(RangeInfo::new(
2521
nominal_def.syntax().text_range(),
26-
impls_for_def(&mut sb, position, &nominal_def, module)?,
22+
impls_for_def(&mut sb, position, &nominal_def, krate)?,
2723
));
2824
} else if let Some(trait_def) = find_node_at_offset::<ast::TraitDef>(&syntax, position.offset) {
2925
return Some(RangeInfo::new(
3026
trait_def.syntax().text_range(),
31-
impls_for_trait(&mut sb, position, &trait_def, module)?,
27+
impls_for_trait(&mut sb, position, &trait_def, krate)?,
3228
));
3329
}
3430

@@ -39,7 +35,7 @@ fn impls_for_def(
3935
sb: &mut SourceBinder<RootDatabase>,
4036
position: FilePosition,
4137
node: &ast::NominalDef,
42-
module: hir::Module,
38+
krate: Crate,
4339
) -> Option<Vec<NavigationTarget>> {
4440
let ty = match node {
4541
ast::NominalDef::StructDef(def) => {
@@ -56,7 +52,6 @@ fn impls_for_def(
5652
}
5753
};
5854

59-
let krate = module.krate();
6055
let impls = ImplBlock::all_in_crate(sb.db, krate);
6156

6257
Some(
@@ -72,12 +67,11 @@ fn impls_for_trait(
7267
sb: &mut SourceBinder<RootDatabase>,
7368
position: FilePosition,
7469
node: &ast::TraitDef,
75-
module: hir::Module,
70+
krate: Crate,
7671
) -> Option<Vec<NavigationTarget>> {
7772
let src = hir::InFile { file_id: position.file_id.into(), value: node.clone() };
7873
let tr = sb.to_def(src)?;
7974

80-
let krate = module.krate();
8175
let impls = ImplBlock::for_trait(sb.db, krate, tr);
8276

8377
Some(impls.into_iter().map(|imp| imp.to_nav(sb.db)).collect())

crates/ra_ide/src/parent_module.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
//! FIXME: write short doc here
22
33
use ra_db::{CrateId, FileId, FilePosition, SourceDatabase};
4+
use ra_syntax::{
5+
algo::find_node_at_offset,
6+
ast::{self, AstNode},
7+
};
48

59
use crate::{db::RootDatabase, NavigationTarget};
610

711
/// This returns `Vec` because a module may be included from several places. We
812
/// don't handle this case yet though, so the Vec has length at most one.
913
pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<NavigationTarget> {
10-
let src = hir::ModuleSource::from_position(db, position);
11-
let module = match hir::Module::from_definition(
12-
db,
13-
hir::InFile { file_id: position.file_id.into(), value: src },
14-
) {
14+
let mut sb = hir::SourceBinder::new(db);
15+
let parse = db.parse(position.file_id);
16+
let module = match find_node_at_offset::<ast::Module>(parse.tree().syntax(), position.offset) {
17+
Some(module) => sb.to_def(hir::InFile::new(position.file_id.into(), module)),
18+
None => sb.to_module_def(position.file_id),
19+
};
20+
let module = match module {
1521
None => return Vec::new(),
1622
Some(it) => it,
1723
};
@@ -21,14 +27,11 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
2127

2228
/// Returns `Vec` for the same reason as `parent_module`
2329
pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
24-
let source_file = db.parse(file_id).tree();
25-
let src = hir::ModuleSource::SourceFile(source_file);
26-
let module =
27-
match hir::Module::from_definition(db, hir::InFile { file_id: file_id.into(), value: src })
28-
{
29-
Some(it) => it,
30-
None => return Vec::new(),
31-
};
30+
let mut sb = hir::SourceBinder::new(db);
31+
let module = match sb.to_module_def(file_id) {
32+
Some(it) => it,
33+
None => return Vec::new(),
34+
};
3235
let krate = module.krate();
3336
vec![krate.into()]
3437
}

crates/ra_ide/src/references/classify.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Functions that are used to classify an element from its definition or reference.
22
3-
use hir::{InFile, Module, ModuleSource, PathResolution, SourceBinder};
3+
use hir::{InFile, PathResolution, SourceBinder};
44
use ra_prof::profile;
55
use ra_syntax::{ast, match_ast, AstNode};
66
use test_utils::tested_by;
@@ -35,16 +35,7 @@ pub(crate) fn classify_name(
3535
Some(from_struct_field(sb.db, field))
3636
},
3737
ast::Module(it) => {
38-
let def = {
39-
if !it.has_semi() {
40-
let ast = hir::ModuleSource::Module(it);
41-
let src = name.with_value(ast);
42-
hir::Module::from_definition(sb.db, src)
43-
} else {
44-
let src = name.with_value(it);
45-
sb.to_def(src)
46-
}
47-
}?;
38+
let def = sb.to_def(name.with_value(it))?;
4839
Some(from_module_def(sb.db, def.into(), None))
4940
},
5041
ast::StructDef(it) => {
@@ -103,8 +94,7 @@ pub(crate) fn classify_name(
10394
let src = name.with_value(it);
10495
let def = sb.to_def(src.clone())?;
10596

106-
let module_src = ModuleSource::from_child_node(sb.db, src.as_ref().map(|it| it.syntax()));
107-
let module = Module::from_definition(sb.db, src.with_value(module_src))?;
97+
let module = sb.to_module_def(src.file_id.original_file(sb.db))?;
10898

10999
Some(NameDefinition {
110100
visibility: None,
@@ -157,10 +147,9 @@ pub(crate) fn classify_name_ref(
157147
}
158148
}
159149

160-
let ast = ModuleSource::from_child_node(sb.db, name_ref.with_value(&parent));
161150
// FIXME: find correct container and visibility for each case
162-
let container = Module::from_definition(sb.db, name_ref.with_value(ast))?;
163151
let visibility = None;
152+
let container = sb.to_module_def(name_ref.file_id.original_file(sb.db))?;
164153

165154
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
166155
tested_by!(goto_def_for_macros);
@@ -178,12 +167,13 @@ pub(crate) fn classify_name_ref(
178167
PathResolution::Def(def) => Some(from_module_def(sb.db, def, Some(container))),
179168
PathResolution::AssocItem(item) => Some(from_assoc_item(sb.db, item)),
180169
PathResolution::Local(local) => {
181-
let container = local.module(sb.db);
182170
let kind = NameKind::Local(local);
171+
let container = local.module(sb.db);
183172
Some(NameDefinition { kind, container, visibility: None })
184173
}
185174
PathResolution::TypeParam(par) => {
186175
let kind = NameKind::TypeParam(par);
176+
let container = par.module(sb.db);
187177
Some(NameDefinition { kind, container, visibility })
188178
}
189179
PathResolution::Macro(def) => {

crates/ra_ide/src/references/name_definition.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub enum NameKind {
2525
#[derive(PartialEq, Eq)]
2626
pub(crate) struct NameDefinition {
2727
pub visibility: Option<ast::Visibility>,
28+
/// FIXME: this doesn't really make sense. For example, builtin types don't
29+
/// really have a module.
2830
pub container: Module,
2931
pub kind: NameKind,
3032
}

crates/ra_ide/src/runnables.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Opti
6666
return None;
6767
}
6868
let range = module.syntax().text_range();
69-
let src = hir::ModuleSource::from_child_node(db, InFile::new(file_id.into(), &module.syntax()));
70-
let module = hir::Module::from_definition(db, InFile::new(file_id.into(), src))?;
69+
let mut sb = hir::SourceBinder::new(db);
70+
let module = sb.to_def(InFile::new(file_id.into(), module))?;
7171

7272
let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::");
7373
Some(Runnable { range, kind: RunnableKind::TestMod { path } })

0 commit comments

Comments
 (0)