Skip to content

Commit 4c0bd06

Browse files
bors[bot]ice1000
andauthored
Merge #2474
2474: Move `ModuleSource`, create `ModuleOrigin` r=matklad a=ice1000 As title. This comes right after #2473 Co-authored-by: ice1000 <[email protected]>
2 parents ace661b + d15f300 commit 4c0bd06

File tree

10 files changed

+149
-136
lines changed

10 files changed

+149
-136
lines changed

crates/ra_hir/src/code_model.rs

+4-61
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use hir_def::{
1111
builtin_type::BuiltinType,
1212
docs::Documentation,
1313
expr::{BindingAnnotation, Pat, PatId},
14+
nameres::ModuleSource,
1415
per_ns::PerNs,
1516
resolver::HasResolver,
1617
type_ref::{Mutability, TypeRef},
@@ -21,11 +22,11 @@ use hir_def::{
2122
use hir_expand::{
2223
diagnostics::DiagnosticSink,
2324
name::{self, AsName},
24-
AstId, MacroDefId,
25+
MacroDefId,
2526
};
2627
use hir_ty::expr::ExprValidator;
27-
use ra_db::{CrateId, Edition, FileId, FilePosition};
28-
use ra_syntax::{ast, AstNode, SyntaxNode};
28+
use ra_db::{CrateId, Edition};
29+
use ra_syntax::ast;
2930

3031
use crate::{
3132
db::{DefDatabase, HirDatabase},
@@ -79,64 +80,6 @@ impl Crate {
7980
}
8081
}
8182

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: InFile<&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-
14083
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14184
pub struct Module {
14285
pub(crate) id: ModuleId,

crates/ra_hir/src/code_model/src.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
33
use either::Either;
44
use hir_def::{
5+
nameres::ModuleSource,
56
src::{HasChildSource, HasSource as _},
67
AstItemDef, Lookup, VariantId,
78
};
89
use ra_syntax::ast;
910

1011
use crate::{
1112
db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef,
12-
Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
13+
Module, Static, Struct, StructField, Trait, TypeAlias, Union,
1314
};
1415

1516
pub use hir_expand::InFile;
@@ -25,11 +26,7 @@ impl Module {
2526
/// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
2627
pub fn definition_source(self, db: &impl DefDatabase) -> InFile<ModuleSource> {
2728
let def_map = db.crate_def_map(self.id.krate);
28-
let src = def_map[self.id.local_id].definition_source(db);
29-
src.map(|it| match it {
30-
Either::Left(it) => ModuleSource::SourceFile(it),
31-
Either::Right(it) => ModuleSource::Module(it),
32-
})
29+
def_map[self.id.local_id].definition_source(db)
3330
}
3431

3532
/// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.

crates/ra_hir/src/from_source.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! FIXME: write short doc here
22
3-
use hir_def::{AstItemDef, LocationCtx, ModuleId};
3+
use hir_def::{nameres::ModuleSource, AstItemDef, LocationCtx, ModuleId};
44
use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
55
use ra_syntax::{
66
ast::{self, AstNode, NameOwner},
@@ -10,8 +10,8 @@ use ra_syntax::{
1010
use crate::{
1111
db::{AstDatabase, DefDatabase, HirDatabase},
1212
AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock,
13-
InFile, Local, MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait,
14-
TypeAlias, Union, VariantDef,
13+
InFile, Local, MacroDef, Module, ModuleDef, Static, Struct, StructField, Trait, TypeAlias,
14+
Union, VariantDef,
1515
};
1616

1717
pub trait FromSource: Sized {
@@ -235,11 +235,10 @@ impl Module {
235235
let src_parent = InFile { file_id: src.file_id, value: parent_declaration };
236236
Module::from_declaration(db, src_parent)
237237
}
238-
_ => {
239-
let src_parent = InFile {
240-
file_id: src.file_id,
241-
value: ModuleSource::new(db, Some(src.file_id.original_file(db)), None),
242-
};
238+
None => {
239+
let source_file = db.parse(src.file_id.original_file(db)).tree();
240+
let src_parent =
241+
InFile { file_id: src.file_id, value: ModuleSource::SourceFile(source_file) };
243242
Module::from_definition(db, src_parent)
244243
}
245244
}?;

crates/ra_hir/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ pub use crate::{
4343
code_model::{
4444
src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency,
4545
DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam,
46-
HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef,
47-
Static, Struct, StructField, Trait, Type, TypeAlias, Union, VariantDef,
46+
HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, Struct,
47+
StructField, Trait, Type, TypeAlias, Union, VariantDef,
4848
},
4949
from_source::FromSource,
5050
source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
@@ -59,6 +59,7 @@ pub use hir_def::{
5959
body::scope::ExprScopes,
6060
builtin_type::BuiltinType,
6161
docs::Documentation,
62+
nameres::ModuleSource,
6263
path::{Path, PathKind},
6364
type_ref::Mutability,
6465
};

crates/ra_hir/src/source_binder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use hir_def::{
1414
BodySourceMap,
1515
},
1616
expr::{ExprId, PatId},
17+
nameres::ModuleSource,
1718
path::known,
1819
resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
1920
AssocItemId, DefWithBodyId,
@@ -46,7 +47,7 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -
4647
Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
4748
},
4849
ast::SourceFile(it) => {
49-
let src = node.with_value(crate::ModuleSource::SourceFile(it));
50+
let src = node.with_value(ModuleSource::SourceFile(it));
5051
Some(crate::Module::from_definition(db, src)?.id.resolver(db))
5152
},
5253
ast::StructDef(it) => {

crates/ra_hir_def/src/nameres.rs

+109-23
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,17 @@ mod tests;
5757

5858
use std::sync::Arc;
5959

60-
use either::Either;
6160
use hir_expand::{
6261
ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId,
6362
};
6463
use once_cell::sync::Lazy;
6564
use ra_arena::Arena;
66-
use ra_db::{CrateId, Edition, FileId};
65+
use ra_db::{CrateId, Edition, FileId, FilePosition};
6766
use ra_prof::profile;
68-
use ra_syntax::ast;
67+
use ra_syntax::{
68+
ast::{self, AstNode},
69+
SyntaxNode,
70+
};
6971
use rustc_hash::FxHashMap;
7072

7173
use crate::{
@@ -100,19 +102,76 @@ impl std::ops::Index<LocalModuleId> for CrateDefMap {
100102
}
101103
}
102104

105+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
106+
pub enum ModuleOrigin {
107+
CrateRoot {
108+
definition: FileId,
109+
},
110+
/// Note that non-inline modules, by definition, live inside non-macro file.
111+
File {
112+
declaration: AstId<ast::Module>,
113+
definition: FileId,
114+
},
115+
Inline {
116+
definition: AstId<ast::Module>,
117+
},
118+
}
119+
120+
impl Default for ModuleOrigin {
121+
fn default() -> Self {
122+
ModuleOrigin::CrateRoot { definition: FileId(0) }
123+
}
124+
}
125+
126+
impl ModuleOrigin {
127+
pub(crate) fn not_sure_file(file: Option<FileId>, declaration: AstId<ast::Module>) -> Self {
128+
match file {
129+
None => ModuleOrigin::Inline { definition: declaration },
130+
Some(definition) => ModuleOrigin::File { declaration, definition },
131+
}
132+
}
133+
134+
fn declaration(&self) -> Option<AstId<ast::Module>> {
135+
match self {
136+
ModuleOrigin::File { declaration: module, .. }
137+
| ModuleOrigin::Inline { definition: module, .. } => Some(*module),
138+
ModuleOrigin::CrateRoot { .. } => None,
139+
}
140+
}
141+
142+
pub fn file_id(&self) -> Option<FileId> {
143+
match self {
144+
ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
145+
Some(*definition)
146+
}
147+
_ => None,
148+
}
149+
}
150+
151+
/// Returns a node which defines this module.
152+
/// That is, a file or a `mod foo {}` with items.
153+
fn definition_source(&self, db: &impl DefDatabase) -> InFile<ModuleSource> {
154+
match self {
155+
ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
156+
let file_id = *definition;
157+
let sf = db.parse(file_id).tree();
158+
return InFile::new(file_id.into(), ModuleSource::SourceFile(sf));
159+
}
160+
ModuleOrigin::Inline { definition } => {
161+
InFile::new(definition.file_id, ModuleSource::Module(definition.to_node(db)))
162+
}
163+
}
164+
}
165+
}
166+
103167
#[derive(Default, Debug, PartialEq, Eq)]
104168
pub struct ModuleData {
105169
pub parent: Option<LocalModuleId>,
106170
pub children: FxHashMap<Name, LocalModuleId>,
107171
pub scope: ModuleScope,
108172

109-
// FIXME: these can't be both null, we need a three-state enum here.
110-
/// None for root
111-
pub declaration: Option<AstId<ast::Module>>,
112-
/// None for inline modules.
113-
///
114-
/// Note that non-inline modules, by definition, live inside non-macro file.
115-
pub definition: Option<FileId>,
173+
/// Where does this module come from?
174+
pub origin: ModuleOrigin,
116175

117176
pub impls: Vec<ImplId>,
118177
}
@@ -262,7 +321,7 @@ impl CrateDefMap {
262321
pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = LocalModuleId> + '_ {
263322
self.modules
264323
.iter()
265-
.filter(move |(_id, data)| data.definition == Some(file_id))
324+
.filter(move |(_id, data)| data.origin.file_id() == Some(file_id))
266325
.map(|(id, _data)| id)
267326
}
268327

@@ -281,27 +340,54 @@ impl CrateDefMap {
281340

282341
impl ModuleData {
283342
/// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
284-
pub fn definition_source(
285-
&self,
286-
db: &impl DefDatabase,
287-
) -> InFile<Either<ast::SourceFile, ast::Module>> {
288-
if let Some(file_id) = self.definition {
289-
let sf = db.parse(file_id).tree();
290-
return InFile::new(file_id.into(), Either::Left(sf));
291-
}
292-
let decl = self.declaration.unwrap();
293-
InFile::new(decl.file_id, Either::Right(decl.to_node(db)))
343+
pub fn definition_source(&self, db: &impl DefDatabase) -> InFile<ModuleSource> {
344+
self.origin.definition_source(db)
294345
}
295346

296347
/// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
297-
/// `None` for the crate root.
348+
/// `None` for the crate root or block.
298349
pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<InFile<ast::Module>> {
299-
let decl = self.declaration?;
350+
let decl = self.origin.declaration()?;
300351
let value = decl.to_node(db);
301352
Some(InFile { file_id: decl.file_id, value })
302353
}
303354
}
304355

356+
#[derive(Debug, Clone, PartialEq, Eq)]
357+
pub enum ModuleSource {
358+
SourceFile(ast::SourceFile),
359+
Module(ast::Module),
360+
}
361+
362+
impl ModuleSource {
363+
// FIXME: this methods do not belong here
364+
pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource {
365+
let parse = db.parse(position.file_id);
366+
match &ra_syntax::algo::find_node_at_offset::<ast::Module>(
367+
parse.tree().syntax(),
368+
position.offset,
369+
) {
370+
Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
371+
_ => {
372+
let source_file = parse.tree();
373+
ModuleSource::SourceFile(source_file)
374+
}
375+
}
376+
}
377+
378+
pub fn from_child_node(db: &impl DefDatabase, child: InFile<&SyntaxNode>) -> ModuleSource {
379+
if let Some(m) =
380+
child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
381+
{
382+
ModuleSource::Module(m)
383+
} else {
384+
let file_id = child.file_id.original_file(db);
385+
let source_file = db.parse(file_id).tree();
386+
ModuleSource::SourceFile(source_file)
387+
}
388+
}
389+
}
390+
305391
mod diagnostics {
306392
use hir_expand::diagnostics::DiagnosticSink;
307393
use ra_db::RelativePathBuf;

crates/ra_hir_def/src/nameres/collector.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{
1919
db::DefDatabase,
2020
nameres::{
2121
diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
22-
raw, BuiltinShadowMode, CrateDefMap, ModuleData, Resolution, ResolveMode,
22+
raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode,
2323
},
2424
path::{Path, PathKind},
2525
per_ns::PerNs,
@@ -131,7 +131,7 @@ where
131131
let file_id = crate_graph.crate_root(self.def_map.krate);
132132
let raw_items = self.db.raw_items(file_id.into());
133133
let module_id = self.def_map.root;
134-
self.def_map.modules[module_id].definition = Some(file_id);
134+
self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
135135
ModCollector {
136136
def_collector: &mut *self,
137137
module_id,
@@ -669,8 +669,7 @@ where
669669
let modules = &mut self.def_collector.def_map.modules;
670670
let res = modules.alloc(ModuleData::default());
671671
modules[res].parent = Some(self.module_id);
672-
modules[res].declaration = Some(declaration);
673-
modules[res].definition = definition;
672+
modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration);
674673
modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone();
675674
modules[self.module_id].children.insert(name.clone(), res);
676675
let resolution = Resolution {

0 commit comments

Comments
 (0)