diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 158 |
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 | ||
4 | use either::Either; | 4 | use either::Either; |
5 | use hir_expand::{ | 5 | use 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 | ||
44 | impl LowerCtx { | 43 | impl 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 | }; |
8 | use ra_arena::{Arena, Idx, RawId}; | 9 | use ra_arena::{Arena, Idx, RawId}; |
9 | use ra_syntax::ast; | 10 | use ra_syntax::{ast, match_ast}; |
10 | 11 | ||
11 | use crate::{ | 12 | use 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 | }; |
18 | use ast::{NameOwner, StructKind, TypeAscriptionOwner}; | 20 | use ast::{AstNode, ModuleItemOwner, NameOwner, StructKind, TypeAscriptionOwner}; |
19 | use std::{ | 21 | use 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)] |
25 | pub struct ItemTree { | 27 | pub 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 | ||
43 | impl ItemTree { | 46 | impl 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 | ¯o_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)] | ||
81 | pub struct Import { | 119 | pub 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)] | ||
91 | pub struct Function { | 130 | pub 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)] | ||
102 | pub struct Struct { | 142 | pub 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)] | ||
111 | pub struct Union { | 152 | pub 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)] | ||
119 | pub struct Enum { | 161 | pub 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)] | ||
127 | pub struct Const { | 170 | pub 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)] | ||
134 | pub struct Static { | 178 | pub 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)] | ||
140 | pub struct Trait { | 185 | pub 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)] | ||
148 | pub struct Impl { | 194 | pub 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)] | ||
164 | pub struct Mod { | 211 | pub 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)] | ||
170 | pub struct MacroCall { | 218 | pub 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)] | ||
180 | pub struct Expr; | 229 | pub struct Expr; |
181 | 230 | ||
231 | macro_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)] | ||
182 | pub enum ModItem { | 244 | pub 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 | ||
259 | impl_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)] | ||
197 | pub enum AssocItem { | 275 | pub 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 | ||
282 | impl_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)] | ||
204 | pub struct Variant { | 290 | pub 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 | ||
231 | impl Ctx { | 317 | impl 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 | ||