aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs7
-rw-r--r--crates/ra_hir_def/src/db.rs4
-rw-r--r--crates/ra_hir_def/src/item_tree.rs158
3 files changed, 128 insertions, 41 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 113ec2b78..f159f80af 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -3,7 +3,6 @@
3 3
4use either::Either; 4use either::Either;
5use hir_expand::{ 5use hir_expand::{
6 db::AstDatabase,
7 hygiene::Hygiene, 6 hygiene::Hygiene,
8 name::{name, AsName, Name}, 7 name::{name, AsName, Name},
9 HirFileId, MacroDefId, MacroDefKind, 8 HirFileId, MacroDefId, MacroDefKind,
@@ -42,8 +41,8 @@ pub(crate) struct LowerCtx {
42} 41}
43 42
44impl LowerCtx { 43impl LowerCtx {
45 pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Self { 44 pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self {
46 LowerCtx { hygiene: Hygiene::new(db, file_id) } 45 LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) }
47 } 46 }
48 pub fn with_hygiene(hygiene: &Hygiene) -> Self { 47 pub fn with_hygiene(hygiene: &Hygiene) -> Self {
49 LowerCtx { hygiene: hygiene.clone() } 48 LowerCtx { hygiene: hygiene.clone() }
@@ -120,7 +119,7 @@ impl ExprCollector<'_> {
120 } 119 }
121 120
122 fn ctx(&self) -> LowerCtx { 121 fn ctx(&self) -> LowerCtx {
123 LowerCtx::new(self.db.upcast(), self.expander.current_file_id) 122 LowerCtx::new(self.db, self.expander.current_file_id)
124 } 123 }
125 124
126 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { 125 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 10cc26480..c4c9e10a3 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -14,6 +14,7 @@ use crate::{
14 docs::Documentation, 14 docs::Documentation,
15 generics::GenericParams, 15 generics::GenericParams,
16 import_map::ImportMap, 16 import_map::ImportMap,
17 item_tree::ItemTree,
17 lang_item::{LangItemTarget, LangItems}, 18 lang_item::{LangItemTarget, LangItems},
18 nameres::{raw::RawItems, CrateDefMap}, 19 nameres::{raw::RawItems, CrateDefMap},
19 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
@@ -48,6 +49,9 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
48 #[salsa::invoke(RawItems::raw_items_query)] 49 #[salsa::invoke(RawItems::raw_items_query)]
49 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; 50 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
50 51
52 #[salsa::invoke(ItemTree::item_tree_query)]
53 fn item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
54
51 #[salsa::invoke(crate_def_map_wait)] 55 #[salsa::invoke(crate_def_map_wait)]
52 #[salsa::transparent] 56 #[salsa::transparent]
53 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>; 57 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs
index f4743f0f6..7e81bc178 100644
--- a/crates/ra_hir_def/src/item_tree.rs
+++ b/crates/ra_hir_def/src/item_tree.rs
@@ -4,25 +4,28 @@ use hir_expand::{
4 ast_id_map::{AstIdMap, FileAstId}, 4 ast_id_map::{AstIdMap, FileAstId},
5 hygiene::Hygiene, 5 hygiene::Hygiene,
6 name::{name, AsName, Name}, 6 name::{name, AsName, Name},
7 HirFileId,
7}; 8};
8use ra_arena::{Arena, Idx, RawId}; 9use ra_arena::{Arena, Idx, RawId};
9use ra_syntax::ast; 10use ra_syntax::{ast, match_ast};
10 11
11use crate::{ 12use crate::{
12 attr::Attrs, 13 attr::Attrs,
14 db::DefDatabase,
13 generics::GenericParams, 15 generics::GenericParams,
14 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path}, 16 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path},
15 type_ref::{Mutability, TypeBound, TypeRef}, 17 type_ref::{Mutability, TypeBound, TypeRef},
16 visibility::RawVisibility, 18 visibility::RawVisibility,
17}; 19};
18use ast::{NameOwner, StructKind, TypeAscriptionOwner}; 20use ast::{AstNode, ModuleItemOwner, NameOwner, StructKind, TypeAscriptionOwner};
19use std::{ 21use std::{
20 ops::{Index, Range}, 22 ops::{Index, Range},
21 sync::Arc, 23 sync::Arc,
22}; 24};
23 25
24#[derive(Default)] 26#[derive(Debug, Default, Eq, PartialEq)]
25pub struct ItemTree { 27pub struct ItemTree {
28 top_level: Vec<ModItem>,
26 imports: Arena<Import>, 29 imports: Arena<Import>,
27 functions: Arena<Function>, 30 functions: Arena<Function>,
28 structs: Arena<Struct>, 31 structs: Arena<Struct>,
@@ -41,8 +44,42 @@ pub struct ItemTree {
41} 44}
42 45
43impl ItemTree { 46impl ItemTree {
44 pub fn query(syntax: &ast::SourceFile) -> ItemTree { 47 pub fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
45 todo!() 48 let syntax = if let Some(node) = db.parse_or_expand(file_id) {
49 node
50 } else {
51 return Default::default();
52 };
53
54 let (macro_storage, file_storage);
55 let item_owner = match_ast! {
56 match syntax {
57 ast::MacroItems(items) => {
58 macro_storage = items;
59 &macro_storage as &dyn ModuleItemOwner
60 },
61 ast::SourceFile(file) => {
62 file_storage = file;
63 &file_storage
64 },
65 _ => return Default::default(),
66 }
67 };
68
69 let map = db.ast_id_map(file_id);
70 let ctx = Ctx {
71 tree: ItemTree::default(),
72 hygiene: Hygiene::new(db.upcast(), file_id),
73 source_ast_id_map: map,
74 body_ctx: crate::body::LowerCtx::new(db, file_id),
75 };
76 Arc::new(ctx.lower(item_owner))
77 }
78
79 /// Returns an iterator over all items located at the top level of the `HirFileId` this
80 /// `ItemTree` was created from.
81 pub fn top_level_items(&self) -> impl Iterator<Item = ModItem> + '_ {
82 self.top_level.iter().copied()
46 } 83 }
47} 84}
48 85
@@ -78,6 +115,7 @@ impl_index!(
78 exprs: Expr, 115 exprs: Expr,
79); 116);
80 117
118#[derive(Debug, Eq, PartialEq)]
81pub struct Import { 119pub struct Import {
82 pub path: ModPath, 120 pub path: ModPath,
83 pub alias: Option<ImportAlias>, 121 pub alias: Option<ImportAlias>,
@@ -88,6 +126,7 @@ pub struct Import {
88 pub is_macro_use: bool, 126 pub is_macro_use: bool,
89} 127}
90 128
129#[derive(Debug, Eq, PartialEq)]
91pub struct Function { 130pub struct Function {
92 pub name: Name, 131 pub name: Name,
93 pub attrs: Attrs, 132 pub attrs: Attrs,
@@ -99,6 +138,7 @@ pub struct Function {
99 pub ast: FileAstId<ast::FnDef>, 138 pub ast: FileAstId<ast::FnDef>,
100} 139}
101 140
141#[derive(Debug, Eq, PartialEq)]
102pub struct Struct { 142pub struct Struct {
103 pub name: Name, 143 pub name: Name,
104 pub attrs: Attrs, 144 pub attrs: Attrs,
@@ -108,6 +148,7 @@ pub struct Struct {
108 pub ast: FileAstId<ast::StructDef>, 148 pub ast: FileAstId<ast::StructDef>,
109} 149}
110 150
151#[derive(Debug, Eq, PartialEq)]
111pub struct Union { 152pub struct Union {
112 pub name: Name, 153 pub name: Name,
113 pub attrs: Attrs, 154 pub attrs: Attrs,
@@ -116,6 +157,7 @@ pub struct Union {
116 pub fields: Fields, 157 pub fields: Fields,
117} 158}
118 159
160#[derive(Debug, Eq, PartialEq)]
119pub struct Enum { 161pub struct Enum {
120 pub name: Name, 162 pub name: Name,
121 pub attrs: Attrs, 163 pub attrs: Attrs,
@@ -124,6 +166,7 @@ pub struct Enum {
124 pub variants: Range<Idx<Variant>>, 166 pub variants: Range<Idx<Variant>>,
125} 167}
126 168
169#[derive(Debug, Eq, PartialEq)]
127pub struct Const { 170pub struct Const {
128 /// const _: () = (); 171 /// const _: () = ();
129 pub name: Option<Name>, 172 pub name: Option<Name>,
@@ -131,12 +174,14 @@ pub struct Const {
131 pub type_ref: TypeRef, 174 pub type_ref: TypeRef,
132} 175}
133 176
177#[derive(Debug, Eq, PartialEq)]
134pub struct Static { 178pub struct Static {
135 pub name: Name, 179 pub name: Name,
136 pub visibility: RawVisibility, 180 pub visibility: RawVisibility,
137 pub type_ref: TypeRef, 181 pub type_ref: TypeRef,
138} 182}
139 183
184#[derive(Debug, Eq, PartialEq)]
140pub struct Trait { 185pub struct Trait {
141 pub name: Name, 186 pub name: Name,
142 pub visibility: RawVisibility, 187 pub visibility: RawVisibility,
@@ -145,6 +190,7 @@ pub struct Trait {
145 pub items: Vec<AssocItem>, 190 pub items: Vec<AssocItem>,
146} 191}
147 192
193#[derive(Debug, Eq, PartialEq)]
148pub struct Impl { 194pub struct Impl {
149 pub generic_params: GenericParams, 195 pub generic_params: GenericParams,
150 pub target_trait: Option<TypeRef>, 196 pub target_trait: Option<TypeRef>,
@@ -161,12 +207,14 @@ pub struct TypeAlias {
161 pub type_ref: Option<TypeRef>, 207 pub type_ref: Option<TypeRef>,
162} 208}
163 209
210#[derive(Debug, Eq, PartialEq)]
164pub struct Mod { 211pub struct Mod {
165 pub name: Name, 212 pub name: Name,
166 pub visibility: RawVisibility, 213 pub visibility: RawVisibility,
167 pub items: Vec<ModItem>, 214 pub items: Vec<ModItem>,
168} 215}
169 216
217#[derive(Debug, Eq, PartialEq)]
170pub struct MacroCall { 218pub struct MacroCall {
171 pub name: Option<Name>, 219 pub name: Option<Name>,
172 pub path: ModPath, 220 pub path: ModPath,
@@ -177,8 +225,22 @@ pub struct MacroCall {
177 225
178// NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array 226// NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array
179// lengths, but we don't do much with them yet. 227// lengths, but we don't do much with them yet.
228#[derive(Debug, Eq, PartialEq)]
180pub struct Expr; 229pub struct Expr;
181 230
231macro_rules! impl_froms {
232 ($e:ident { $($v:ident ($t:ty)),* $(,)? }) => {
233 $(
234 impl From<$t> for $e {
235 fn from(it: $t) -> $e {
236 $e::$v(it)
237 }
238 }
239 )*
240 }
241}
242
243#[derive(Debug, Copy, Clone, Eq, PartialEq)]
182pub enum ModItem { 244pub enum ModItem {
183 Import(Idx<Import>), 245 Import(Idx<Import>),
184 Function(Idx<Function>), 246 Function(Idx<Function>),
@@ -194,6 +256,22 @@ pub enum ModItem {
194 MacroCall(Idx<MacroCall>), 256 MacroCall(Idx<MacroCall>),
195} 257}
196 258
259impl_froms!(ModItem {
260 Import(Idx<Import>),
261 Function(Idx<Function>),
262 Struct(Idx<Struct>),
263 Union(Idx<Union>),
264 Enum(Idx<Enum>),
265 Const(Idx<Const>),
266 Static(Idx<Static>),
267 Trait(Idx<Trait>),
268 Impl(Idx<Impl>),
269 TypeAlias(Idx<TypeAlias>),
270 Mod(Idx<Mod>),
271 MacroCall(Idx<MacroCall>),
272});
273
274#[derive(Debug, Eq, PartialEq)]
197pub enum AssocItem { 275pub enum AssocItem {
198 Function(Idx<Function>), 276 Function(Idx<Function>),
199 TypeAlias(Idx<TypeAlias>), 277 TypeAlias(Idx<TypeAlias>),
@@ -201,6 +279,14 @@ pub enum AssocItem {
201 MacroCall(Idx<MacroCall>), 279 MacroCall(Idx<MacroCall>),
202} 280}
203 281
282impl_froms!(AssocItem {
283 Function(Idx<Function>),
284 TypeAlias(Idx<TypeAlias>),
285 Const(Idx<Const>),
286 MacroCall(Idx<MacroCall>),
287});
288
289#[derive(Debug, Eq, PartialEq)]
204pub struct Variant { 290pub struct Variant {
205 pub name: Name, 291 pub name: Name,
206 pub fields: Fields, 292 pub fields: Fields,
@@ -229,55 +315,44 @@ struct Ctx {
229} 315}
230 316
231impl Ctx { 317impl Ctx {
232 fn lower(&mut self, item_owner: &dyn ast::ModuleItemOwner) { 318 fn lower(mut self, item_owner: &dyn ModuleItemOwner) -> ItemTree {
233 for item in item_owner.items() { 319 self.tree.top_level = item_owner.items().flat_map(|item| self.lower_item(&item)).collect();
234 self.lower_item(&item) 320 self.tree
235 }
236 } 321 }
237 322
238 fn lower_item(&mut self, item: &ast::ModuleItem) { 323 fn lower_item(&mut self, item: &ast::ModuleItem) -> Option<ModItem> {
239 match item { 324 match item {
240 ast::ModuleItem::StructDef(ast) => { 325 ast::ModuleItem::StructDef(ast) => {
241 if let Some(data) = self.lower_struct(ast) { 326 self.lower_struct(ast).map(|data| self.tree.structs.alloc(data).into())
242 let idx = self.tree.structs.alloc(data);
243 }
244 } 327 }
245 ast::ModuleItem::UnionDef(ast) => { 328 ast::ModuleItem::UnionDef(ast) => {
246 if let Some(data) = self.lower_union(ast) { 329 self.lower_union(ast).map(|data| self.tree.unions.alloc(data).into())
247 let idx = self.tree.unions.alloc(data);
248 }
249 } 330 }
250 ast::ModuleItem::EnumDef(ast) => { 331 ast::ModuleItem::EnumDef(ast) => {
251 if let Some(data) = self.lower_enum(ast) { 332 self.lower_enum(ast).map(|data| self.tree.enums.alloc(data).into())
252 let idx = self.tree.enums.alloc(data);
253 }
254 } 333 }
255 ast::ModuleItem::FnDef(ast) => { 334 ast::ModuleItem::FnDef(ast) => {
256 if let Some(data) = self.lower_function(ast) { 335 self.lower_function(ast).map(|data| self.tree.functions.alloc(data).into())
257 let idx = self.tree.functions.alloc(data);
258 }
259 } 336 }
260 ast::ModuleItem::TypeAliasDef(ast) => { 337 ast::ModuleItem::TypeAliasDef(ast) => {
261 if let Some(data) = self.lower_type_alias(ast) { 338 self.lower_type_alias(ast).map(|data| self.tree.type_aliases.alloc(data).into())
262 let idx = self.tree.type_aliases.alloc(data);
263 }
264 } 339 }
265 ast::ModuleItem::StaticDef(ast) => { 340 ast::ModuleItem::StaticDef(ast) => {
266 if let Some(data) = self.lower_static(ast) { 341 self.lower_static(ast).map(|data| self.tree.statics.alloc(data).into())
267 let idx = self.tree.statics.alloc(data);
268 }
269 } 342 }
270 ast::ModuleItem::ConstDef(ast) => { 343 ast::ModuleItem::ConstDef(ast) => {
271 let data = self.lower_const(ast); 344 let data = self.lower_const(ast);
272 let idx = self.tree.consts.alloc(data); 345 Some(self.tree.consts.alloc(data).into())
346 }
347 ast::ModuleItem::Module(ast) => {
348 self.lower_module(ast).map(|data| self.tree.mods.alloc(data).into())
273 } 349 }
274 ast::ModuleItem::Module(_) => {} 350 ast::ModuleItem::TraitDef(_) => todo!(),
275 ast::ModuleItem::TraitDef(_) => {} 351 ast::ModuleItem::ImplDef(_) => todo!(),
276 ast::ModuleItem::ImplDef(_) => {} 352 ast::ModuleItem::UseItem(_) => todo!(),
277 ast::ModuleItem::UseItem(_) => {} 353 ast::ModuleItem::ExternCrateItem(_) => todo!(),
278 ast::ModuleItem::ExternCrateItem(_) => {} 354 ast::ModuleItem::MacroCall(_) => todo!(),
279 ast::ModuleItem::MacroCall(_) => {} 355 ast::ModuleItem::ExternBlock(_) => todo!(),
280 ast::ModuleItem::ExternBlock(_) => {}
281 } 356 }
282 } 357 }
283 358
@@ -473,7 +548,16 @@ impl Ctx {
473 Const { name, visibility, type_ref } 548 Const { name, visibility, type_ref }
474 } 549 }
475 550
476 fn lower_generic_params(&mut self, item: &impl ast::TypeParamsOwner) -> GenericParams { 551 fn lower_module(&mut self, module: &ast::Module) -> Option<Mod> {
552 let name = module.name()?.as_name();
553 let visibility = self.lower_visibility(module);
554 let items = module
555 .item_list()
556 .map(move |list| list.items().flat_map(move |item| self.lower_item(&item)).collect());
557 Some(Mod { name, visibility, items: items.unwrap_or_default() })
558 }
559
560 fn lower_generic_params(&mut self, _item: &impl ast::TypeParamsOwner) -> GenericParams {
477 None.unwrap() 561 None.unwrap()
478 } 562 }
479 563