Skip to content

Commit 575a3ba

Browse files
authored
Merge pull request #271 from baszalmstra/feat/item_tree
feature: refactored RawItems into ItemTree
2 parents c84daf7 + d25a997 commit 575a3ba

File tree

13 files changed

+832
-269
lines changed

13 files changed

+832
-269
lines changed

crates/mun_hir/src/adt.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ use std::{fmt, sync::Arc};
33
use crate::type_ref::{LocalTypeRefId, TypeRefBuilder, TypeRefMap, TypeRefSourceMap};
44
use crate::{
55
arena::{Arena, Idx},
6-
ids::{AstItemDef, StructId, TypeAliasId},
6+
ids::{StructId, TypeAliasId},
77
AsName, DefDatabase, Name,
88
};
99
use mun_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
1010

1111
pub use mun_syntax::ast::StructMemoryKind;
1212

13+
use crate::ids::Lookup;
14+
1315
/// A single field of a record
1416
/// ```mun
1517
/// struct Foo {
@@ -61,21 +63,18 @@ pub struct StructData {
6163

6264
impl StructData {
6365
pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
64-
let src = id.source(db);
65-
let name = src
66-
.value
67-
.name()
68-
.map(|n| n.as_name())
69-
.unwrap_or_else(Name::missing);
66+
let loc = id.lookup(db);
67+
let item_tree = db.item_tree(loc.id.file_id);
68+
let strukt = &item_tree[loc.id.value];
69+
let src = item_tree.source(db, loc.id);
7070

7171
let memory_kind = src
72-
.value
7372
.memory_type_specifier()
7473
.map(|s| s.kind())
7574
.unwrap_or_default();
7675

7776
let mut type_ref_builder = TypeRefBuilder::default();
78-
let (fields, kind) = match src.value.kind() {
77+
let (fields, kind) = match src.kind() {
7978
ast::StructKind::Record(r) => {
8079
let fields = r
8180
.fields()
@@ -102,7 +101,7 @@ impl StructData {
102101

103102
let (type_ref_map, type_ref_source_map) = type_ref_builder.finish();
104103
Arc::new(StructData {
105-
name,
104+
name: strukt.name.clone(),
106105
fields,
107106
kind,
108107
memory_kind,
@@ -132,18 +131,16 @@ impl TypeAliasData {
132131
db: &dyn DefDatabase,
133132
id: TypeAliasId,
134133
) -> Arc<TypeAliasData> {
135-
let src = id.source(db);
136-
let name = src
137-
.value
138-
.name()
139-
.map(|n| n.as_name())
140-
.unwrap_or_else(Name::missing);
134+
let loc = id.lookup(db);
135+
let item_tree = db.item_tree(loc.id.file_id);
136+
let alias = &item_tree[loc.id.value];
137+
let src = item_tree.source(db, loc.id);
141138
let mut type_ref_builder = TypeRefBuilder::default();
142-
let type_ref_opt = src.value.type_ref();
139+
let type_ref_opt = src.type_ref();
143140
let type_ref_id = type_ref_builder.alloc_from_node_opt(type_ref_opt.as_ref());
144141
let (type_ref_map, type_ref_source_map) = type_ref_builder.finish();
145142
Arc::new(TypeAliasData {
146-
name,
143+
name: alias.name.clone(),
147144
type_ref_id,
148145
type_ref_map,
149146
type_ref_source_map,

crates/mun_hir/src/code_model.rs

Lines changed: 78 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
pub(crate) mod src;
22

3-
use self::src::HasSource;
43
use crate::adt::{LocalStructFieldId, StructData, TypeAliasData};
54
use crate::builtin_type::BuiltinType;
65
use crate::code_model::diagnostics::ModuleDefinitionDiagnostic;
76
use crate::diagnostics::DiagnosticSink;
87
use crate::expr::validator::{ExprValidator, TypeAliasValidator};
98
use crate::expr::{Body, BodySourceMap};
10-
use crate::ids::AstItemDef;
11-
use crate::ids::LocationCtx;
9+
use crate::ids::{FunctionLoc, Intern, Lookup, StructLoc, TypeAliasLoc};
10+
use crate::item_tree::ModItem;
1211
use crate::name_resolution::Namespace;
13-
use crate::raw::{DefKind, RawFileItem};
1412
use crate::resolve::{Resolution, Resolver};
1513
use crate::ty::{lower::LowerBatchResult, InferenceResult};
1614
use crate::type_ref::{LocalTypeRefId, TypeRefBuilder, TypeRefMap, TypeRefSourceMap};
1715
use crate::{
1816
ids::{FunctionId, StructId, TypeAliasId},
19-
AsName, DefDatabase, FileId, HirDatabase, Name, Ty,
17+
DefDatabase, FileId, HirDatabase, InFile, Name, Ty,
2018
};
21-
use mun_syntax::ast::{ExternOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner};
19+
use mun_syntax::ast::{TypeAscriptionOwner, VisibilityOwner};
2220
use rustc_hash::FxHashMap;
2321
use std::sync::Arc;
2422

@@ -75,41 +73,47 @@ pub struct ModuleScope {
7573

7674
impl ModuleData {
7775
pub(crate) fn module_data_query(db: &dyn DefDatabase, file_id: FileId) -> Arc<ModuleData> {
78-
let items = db.raw_items(file_id);
76+
let items = db.item_tree(file_id);
7977
let mut data = ModuleData::default();
80-
let loc_ctx = LocationCtx::new(db, file_id);
8178
let mut definition_by_name = FxHashMap::default();
82-
for item in items.items().iter() {
79+
for item in items.top_level_items() {
80+
let name = match item {
81+
ModItem::Function(item) => items[*item].name.clone(),
82+
ModItem::Struct(item) => items[*item].name.clone(),
83+
ModItem::TypeAlias(item) => items[*item].name.clone(),
84+
};
85+
86+
if let Some(prev_definition) = definition_by_name.get(&name) {
87+
data.diagnostics
88+
.push(diagnostics::ModuleDefinitionDiagnostic::DuplicateName {
89+
name,
90+
definition: *item,
91+
first_definition: *prev_definition,
92+
})
93+
} else {
94+
definition_by_name.insert(name, *item);
95+
}
96+
8397
match item {
84-
RawFileItem::Definition(def) => {
85-
if let Some(prev_definition) = definition_by_name.get(&items[*def].name) {
86-
data.diagnostics.push(
87-
diagnostics::ModuleDefinitionDiagnostic::DuplicateName {
88-
name: items[*def].name.clone(),
89-
definition: *def,
90-
first_definition: *prev_definition,
91-
},
92-
)
93-
} else {
94-
definition_by_name.insert(items[*def].name.clone(), *def);
98+
ModItem::Function(item) => data.definitions.push(ModuleDef::Function(Function {
99+
id: FunctionLoc {
100+
id: InFile::new(file_id, *item),
95101
}
96-
match items[*def].kind {
97-
DefKind::Function(ast_id) => {
98-
data.definitions.push(ModuleDef::Function(Function {
99-
id: FunctionId::from_ast_id(loc_ctx, ast_id),
100-
}))
101-
}
102-
DefKind::Struct(ast_id) => {
103-
data.definitions.push(ModuleDef::Struct(Struct {
104-
id: StructId::from_ast_id(loc_ctx, ast_id),
105-
}))
106-
}
107-
DefKind::TypeAlias(ast_id) => {
108-
data.definitions.push(ModuleDef::TypeAlias(TypeAlias {
109-
id: TypeAliasId::from_ast_id(loc_ctx, ast_id),
110-
}))
111-
}
102+
.intern(db),
103+
})),
104+
ModItem::Struct(item) => data.definitions.push(ModuleDef::Struct(Struct {
105+
id: StructLoc {
106+
id: InFile::new(file_id, *item),
112107
}
108+
.intern(db),
109+
})),
110+
ModItem::TypeAlias(item) => {
111+
data.definitions.push(ModuleDef::TypeAlias(TypeAlias {
112+
id: TypeAliasLoc {
113+
id: InFile::new(file_id, *item),
114+
}
115+
.intern(db),
116+
}))
113117
}
114118
};
115119
}
@@ -230,7 +234,7 @@ pub struct Function {
230234
}
231235

232236
#[derive(Debug, PartialEq, Eq)]
233-
pub struct FnData {
237+
pub struct FunctionData {
234238
name: Name,
235239
params: Vec<LocalTypeRefId>,
236240
visibility: Visibility,
@@ -240,48 +244,44 @@ pub struct FnData {
240244
is_extern: bool,
241245
}
242246

243-
impl FnData {
244-
pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: Function) -> Arc<FnData> {
245-
let src = func.source(db);
247+
impl FunctionData {
248+
pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> {
249+
let loc = func.lookup(db);
250+
let item_tree = db.item_tree(loc.id.file_id);
251+
let func = &item_tree[loc.id.value];
252+
let src = item_tree.source(db, loc.id);
253+
246254
let mut type_ref_builder = TypeRefBuilder::default();
247-
let name = src
248-
.value
249-
.name()
250-
.map(|n| n.as_name())
251-
.unwrap_or_else(Name::missing);
252255

253256
let visibility = src
254-
.value
255257
.visibility()
256258
.map(|_v| Visibility::Public)
257259
.unwrap_or(Visibility::Private);
258260

259261
let mut params = Vec::new();
260-
if let Some(param_list) = src.value.param_list() {
262+
if let Some(param_list) = src.param_list() {
261263
for param in param_list.params() {
262264
let type_ref = type_ref_builder.alloc_from_node_opt(param.ascribed_type().as_ref());
263265
params.push(type_ref);
264266
}
265267
}
266268

267-
let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
269+
let ret_type = if let Some(type_ref) = src.ret_type().and_then(|rt| rt.type_ref()) {
268270
type_ref_builder.alloc_from_node(&type_ref)
269271
} else {
270272
type_ref_builder.unit()
271273
};
272274

273275
let (type_ref_map, type_ref_source_map) = type_ref_builder.finish();
274276

275-
let is_extern = src.value.is_extern();
276-
277-
Arc::new(FnData {
278-
name,
277+
Arc::new(FunctionData {
278+
name: func.name.clone(),
279279
params,
280280
visibility,
281281
ret_type,
282282
type_ref_map,
283283
type_ref_source_map,
284-
is_extern,
284+
is_extern: func.is_extern,
285285
})
286286
}
287287

@@ -313,7 +313,7 @@ impl FnData {
313313
impl Function {
314314
pub fn module(self, db: &dyn DefDatabase) -> Module {
315315
Module {
316-
file_id: self.id.file_id(db),
316+
file_id: self.id.lookup(db).id.file_id,
317317
}
318318
}
319319

@@ -325,8 +325,8 @@ impl Function {
325325
self.data(db).visibility()
326326
}
327327

328-
pub fn data(self, db: &dyn HirDatabase) -> Arc<FnData> {
329-
db.fn_data(self)
328+
pub fn data(self, db: &dyn HirDatabase) -> Arc<FunctionData> {
329+
db.fn_data(self.id)
330330
}
331331

332332
pub fn body(self, db: &dyn HirDatabase) -> Arc<Body> {
@@ -343,7 +343,7 @@ impl Function {
343343
}
344344

345345
pub fn is_extern(self, db: &dyn HirDatabase) -> bool {
346-
db.fn_data(self).is_extern
346+
db.fn_data(self.id).is_extern
347347
}
348348

349349
pub(crate) fn body_source_map(self, db: &dyn HirDatabase) -> Arc<BodySourceMap> {
@@ -396,7 +396,7 @@ impl StructField {
396396
impl Struct {
397397
pub fn module(self, db: &dyn DefDatabase) -> Module {
398398
Module {
399-
file_id: self.id.file_id(db),
399+
file_id: self.id.lookup(db).id.file_id,
400400
}
401401
}
402402

@@ -458,7 +458,7 @@ pub struct TypeAlias {
458458
impl TypeAlias {
459459
pub fn module(self, db: &dyn DefDatabase) -> Module {
460460
Module {
461-
file_id: self.id.file_id(db),
461+
file_id: self.id.lookup(db).id.file_id,
462462
}
463463
}
464464

@@ -501,29 +501,31 @@ impl TypeAlias {
501501
mod diagnostics {
502502
use super::Module;
503503
use crate::diagnostics::{DiagnosticSink, DuplicateDefinition};
504-
use crate::raw::{DefKind, LocalDefId};
504+
use crate::item_tree::{ItemTreeId, ModItem};
505505
use crate::{DefDatabase, Name};
506506
use mun_syntax::{AstNode, SyntaxNodePtr};
507507

508508
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
509509
pub(super) enum ModuleDefinitionDiagnostic {
510510
DuplicateName {
511511
name: Name,
512-
definition: LocalDefId,
513-
first_definition: LocalDefId,
512+
definition: ModItem,
513+
first_definition: ModItem,
514514
},
515515
}
516516

517-
fn syntax_ptr_from_def(db: &dyn DefDatabase, owner: Module, kind: DefKind) -> SyntaxNodePtr {
518-
match kind {
519-
DefKind::Function(id) => {
520-
SyntaxNodePtr::new(id.with_file_id(owner.file_id).to_node(db).syntax())
517+
fn syntax_ptr_from_def(db: &dyn DefDatabase, owner: Module, item: ModItem) -> SyntaxNodePtr {
518+
let file_id = owner.file_id;
519+
let item_tree = db.item_tree(file_id);
520+
match item {
521+
ModItem::Function(id) => {
522+
SyntaxNodePtr::new(item_tree.source(db, ItemTreeId::new(file_id, id)).syntax())
521523
}
522-
DefKind::Struct(id) => {
523-
SyntaxNodePtr::new(id.with_file_id(owner.file_id).to_node(db).syntax())
524+
ModItem::Struct(id) => {
525+
SyntaxNodePtr::new(item_tree.source(db, ItemTreeId::new(file_id, id)).syntax())
524526
}
525-
DefKind::TypeAlias(id) => {
526-
SyntaxNodePtr::new(id.with_file_id(owner.file_id).to_node(db).syntax())
527+
ModItem::TypeAlias(id) => {
528+
SyntaxNodePtr::new(item_tree.source(db, ItemTreeId::new(file_id, id)).syntax())
527529
}
528530
}
529531
}
@@ -540,19 +542,12 @@ mod diagnostics {
540542
name,
541543
definition,
542544
first_definition,
543-
} => {
544-
let raw_items = db.raw_items(owner.file_id);
545-
sink.push(DuplicateDefinition {
546-
file: owner.file_id,
547-
name: name.to_string(),
548-
definition: syntax_ptr_from_def(db, owner, raw_items[*definition].kind),
549-
first_definition: syntax_ptr_from_def(
550-
db,
551-
owner,
552-
raw_items[*first_definition].kind,
553-
),
554-
})
555-
}
545+
} => sink.push(DuplicateDefinition {
546+
file: owner.file_id,
547+
name: name.to_string(),
548+
definition: syntax_ptr_from_def(db, owner, *definition),
549+
first_definition: syntax_ptr_from_def(db, owner, *first_definition),
550+
}),
556551
}
557552
}
558553
}

0 commit comments

Comments
 (0)