diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 119 | ||||
-rw-r--r-- | crates/ra_hir_def/src/expr.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path.rs | 2 |
6 files changed, 98 insertions, 50 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index d9ce6bcff..445d215b7 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -24,7 +24,7 @@ use crate::{ | |||
24 | DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, | 24 | DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | struct Expander { | 27 | pub(crate) struct Expander { |
28 | crate_def_map: Arc<CrateDefMap>, | 28 | crate_def_map: Arc<CrateDefMap>, |
29 | current_file_id: HirFileId, | 29 | current_file_id: HirFileId, |
30 | hygiene: Hygiene, | 30 | hygiene: Hygiene, |
@@ -33,18 +33,22 @@ struct Expander { | |||
33 | } | 33 | } |
34 | 34 | ||
35 | impl Expander { | 35 | impl Expander { |
36 | fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { | 36 | pub(crate) fn new( |
37 | db: &impl DefDatabase, | ||
38 | current_file_id: HirFileId, | ||
39 | module: ModuleId, | ||
40 | ) -> Expander { | ||
37 | let crate_def_map = db.crate_def_map(module.krate); | 41 | let crate_def_map = db.crate_def_map(module.krate); |
38 | let hygiene = Hygiene::new(db, current_file_id); | 42 | let hygiene = Hygiene::new(db, current_file_id); |
39 | let ast_id_map = db.ast_id_map(current_file_id); | 43 | let ast_id_map = db.ast_id_map(current_file_id); |
40 | Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } | 44 | Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } |
41 | } | 45 | } |
42 | 46 | ||
43 | fn enter_expand( | 47 | pub(crate) fn enter_expand<T: ast::AstNode, DB: DefDatabase>( |
44 | &mut self, | 48 | &mut self, |
45 | db: &impl DefDatabase, | 49 | db: &DB, |
46 | macro_call: ast::MacroCall, | 50 | macro_call: ast::MacroCall, |
47 | ) -> Option<(Mark, ast::Expr)> { | 51 | ) -> Option<(Mark, T)> { |
48 | let ast_id = AstId::new( | 52 | let ast_id = AstId::new( |
49 | self.current_file_id, | 53 | self.current_file_id, |
50 | db.ast_id_map(self.current_file_id).ast_id(¯o_call), | 54 | db.ast_id_map(self.current_file_id).ast_id(¯o_call), |
@@ -55,7 +59,7 @@ impl Expander { | |||
55 | let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); | 59 | let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); |
56 | let file_id = call_id.as_file(); | 60 | let file_id = call_id.as_file(); |
57 | if let Some(node) = db.parse_or_expand(file_id) { | 61 | if let Some(node) = db.parse_or_expand(file_id) { |
58 | if let Some(expr) = ast::Expr::cast(node) { | 62 | if let Some(expr) = T::cast(node) { |
59 | log::debug!("macro expansion {:#?}", expr.syntax()); | 63 | log::debug!("macro expansion {:#?}", expr.syntax()); |
60 | 64 | ||
61 | let mark = Mark { | 65 | let mark = Mark { |
@@ -78,14 +82,14 @@ impl Expander { | |||
78 | None | 82 | None |
79 | } | 83 | } |
80 | 84 | ||
81 | fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) { | 85 | pub(crate) fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) { |
82 | self.hygiene = Hygiene::new(db, mark.file_id); | 86 | self.hygiene = Hygiene::new(db, mark.file_id); |
83 | self.current_file_id = mark.file_id; | 87 | self.current_file_id = mark.file_id; |
84 | self.ast_id_map = mem::take(&mut mark.ast_id_map); | 88 | self.ast_id_map = mem::take(&mut mark.ast_id_map); |
85 | mark.bomb.defuse(); | 89 | mark.bomb.defuse(); |
86 | } | 90 | } |
87 | 91 | ||
88 | fn to_source<T>(&self, value: T) -> InFile<T> { | 92 | pub(crate) fn to_source<T>(&self, value: T) -> InFile<T> { |
89 | InFile { file_id: self.current_file_id, value } | 93 | InFile { file_id: self.current_file_id, value } |
90 | } | 94 | } |
91 | 95 | ||
@@ -110,7 +114,7 @@ impl Expander { | |||
110 | } | 114 | } |
111 | } | 115 | } |
112 | 116 | ||
113 | struct Mark { | 117 | pub(crate) struct Mark { |
114 | file_id: HirFileId, | 118 | file_id: HirFileId, |
115 | ast_id_map: Arc<AstIdMap>, | 119 | ast_id_map: Arc<AstIdMap>, |
116 | bomb: DropBomb, | 120 | bomb: DropBomb, |
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 853e17bae..be5d17d85 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -372,8 +372,9 @@ where | |||
372 | arg_types.push(type_ref); | 372 | arg_types.push(type_ref); |
373 | } | 373 | } |
374 | } | 374 | } |
375 | let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); | ||
375 | let body = self.collect_expr_opt(e.body()); | 376 | let body = self.collect_expr_opt(e.body()); |
376 | self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) | 377 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) |
377 | } | 378 | } |
378 | ast::Expr::BinExpr(e) => { | 379 | ast::Expr::BinExpr(e) => { |
379 | let lhs = self.collect_expr_opt(e.lhs()); | 380 | let lhs = self.collect_expr_opt(e.lhs()); |
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 14e86936b..b0a3f1784 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs | |||
@@ -4,16 +4,16 @@ use std::sync::Arc; | |||
4 | 4 | ||
5 | use hir_expand::{ | 5 | use hir_expand::{ |
6 | name::{name, AsName, Name}, | 6 | name::{name, AsName, Name}, |
7 | AstId, | 7 | AstId, InFile, |
8 | }; | 8 | }; |
9 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | 9 | use ra_syntax::ast::{self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner}; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | db::DefDatabase, | 12 | db::DefDatabase, |
13 | src::HasSource, | 13 | src::HasSource, |
14 | type_ref::{Mutability, TypeRef}, | 14 | type_ref::{Mutability, TypeRef}, |
15 | AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, ImplId, Intern, | 15 | AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule, |
16 | Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, | 16 | ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | #[derive(Debug, Clone, PartialEq, Eq)] | 19 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -167,46 +167,24 @@ pub struct ImplData { | |||
167 | 167 | ||
168 | impl ImplData { | 168 | impl ImplData { |
169 | pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> { | 169 | pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> { |
170 | let src = id.lookup(db).source(db); | 170 | let impl_loc = id.lookup(db); |
171 | let items = db.ast_id_map(src.file_id); | 171 | let src = impl_loc.source(db); |
172 | 172 | ||
173 | let target_trait = src.value.target_trait().map(TypeRef::from_ast); | 173 | let target_trait = src.value.target_trait().map(TypeRef::from_ast); |
174 | let target_type = TypeRef::from_ast_opt(src.value.target_type()); | 174 | let target_type = TypeRef::from_ast_opt(src.value.target_type()); |
175 | let is_negative = src.value.is_negative(); | 175 | let is_negative = src.value.is_negative(); |
176 | let module_id = impl_loc.container.module(db); | ||
176 | 177 | ||
177 | let items = if let Some(item_list) = src.value.item_list() { | 178 | let mut items = Vec::new(); |
178 | item_list | 179 | if let Some(item_list) = src.value.item_list() { |
179 | .impl_items() | 180 | items.extend(collect_impl_items(db, item_list.impl_items(), src.file_id, id)); |
180 | .map(|item_node| match item_node { | 181 | items.extend(collect_impl_items_in_macros( |
181 | ast::ImplItem::FnDef(it) => { | 182 | db, |
182 | let def = FunctionLoc { | 183 | module_id, |
183 | container: AssocContainerId::ImplId(id), | 184 | &src.with_value(item_list), |
184 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | 185 | id, |
185 | } | 186 | )); |
186 | .intern(db); | 187 | } |
187 | def.into() | ||
188 | } | ||
189 | ast::ImplItem::ConstDef(it) => { | ||
190 | let def = ConstLoc { | ||
191 | container: AssocContainerId::ImplId(id), | ||
192 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | ||
193 | } | ||
194 | .intern(db); | ||
195 | def.into() | ||
196 | } | ||
197 | ast::ImplItem::TypeAliasDef(it) => { | ||
198 | let def = TypeAliasLoc { | ||
199 | container: AssocContainerId::ImplId(id), | ||
200 | ast_id: AstId::new(src.file_id, items.ast_id(&it)), | ||
201 | } | ||
202 | .intern(db); | ||
203 | def.into() | ||
204 | } | ||
205 | }) | ||
206 | .collect() | ||
207 | } else { | ||
208 | Vec::new() | ||
209 | }; | ||
210 | 188 | ||
211 | let res = ImplData { target_trait, target_type, items, is_negative }; | 189 | let res = ImplData { target_trait, target_type, items, is_negative }; |
212 | Arc::new(res) | 190 | Arc::new(res) |
@@ -237,3 +215,66 @@ impl ConstData { | |||
237 | ConstData { name, type_ref } | 215 | ConstData { name, type_ref } |
238 | } | 216 | } |
239 | } | 217 | } |
218 | |||
219 | fn collect_impl_items_in_macros( | ||
220 | db: &impl DefDatabase, | ||
221 | module_id: ModuleId, | ||
222 | impl_block: &InFile<ast::ItemList>, | ||
223 | id: ImplId, | ||
224 | ) -> Vec<AssocItemId> { | ||
225 | let mut expander = Expander::new(db, impl_block.file_id, module_id); | ||
226 | let mut res = Vec::new(); | ||
227 | |||
228 | for m in impl_block.value.syntax().children().filter_map(ast::MacroCall::cast) { | ||
229 | if let Some((mark, items)) = expander.enter_expand(db, m) { | ||
230 | let items: InFile<ast::MacroItems> = expander.to_source(items); | ||
231 | expander.exit(db, mark); | ||
232 | res.extend(collect_impl_items( | ||
233 | db, | ||
234 | items.value.items().filter_map(|it| ImplItem::cast(it.syntax().clone())), | ||
235 | items.file_id, | ||
236 | id, | ||
237 | )); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | res | ||
242 | } | ||
243 | |||
244 | fn collect_impl_items( | ||
245 | db: &impl DefDatabase, | ||
246 | impl_items: impl Iterator<Item = ImplItem>, | ||
247 | file_id: crate::HirFileId, | ||
248 | id: ImplId, | ||
249 | ) -> Vec<AssocItemId> { | ||
250 | let items = db.ast_id_map(file_id); | ||
251 | |||
252 | impl_items | ||
253 | .map(|item_node| match item_node { | ||
254 | ast::ImplItem::FnDef(it) => { | ||
255 | let def = FunctionLoc { | ||
256 | container: AssocContainerId::ImplId(id), | ||
257 | ast_id: AstId::new(file_id, items.ast_id(&it)), | ||
258 | } | ||
259 | .intern(db); | ||
260 | def.into() | ||
261 | } | ||
262 | ast::ImplItem::ConstDef(it) => { | ||
263 | let def = ConstLoc { | ||
264 | container: AssocContainerId::ImplId(id), | ||
265 | ast_id: AstId::new(file_id, items.ast_id(&it)), | ||
266 | } | ||
267 | .intern(db); | ||
268 | def.into() | ||
269 | } | ||
270 | ast::ImplItem::TypeAliasDef(it) => { | ||
271 | let def = TypeAliasLoc { | ||
272 | container: AssocContainerId::ImplId(id), | ||
273 | ast_id: AstId::new(file_id, items.ast_id(&it)), | ||
274 | } | ||
275 | .intern(db); | ||
276 | def.into() | ||
277 | } | ||
278 | }) | ||
279 | .collect() | ||
280 | } | ||
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index 6fad80a8d..a75ef9970 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs | |||
@@ -143,6 +143,7 @@ pub enum Expr { | |||
143 | Lambda { | 143 | Lambda { |
144 | args: Vec<PatId>, | 144 | args: Vec<PatId>, |
145 | arg_types: Vec<Option<TypeRef>>, | 145 | arg_types: Vec<Option<TypeRef>>, |
146 | ret_type: Option<TypeRef>, | ||
146 | body: ExprId, | 147 | body: ExprId, |
147 | }, | 148 | }, |
148 | Tuple { | 149 | Tuple { |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index bf8d6d1d4..acd4f4af1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -48,6 +48,7 @@ use ra_arena::{impl_arena_id, RawId}; | |||
48 | use ra_db::{impl_intern_key, salsa, CrateId}; | 48 | use ra_db::{impl_intern_key, salsa, CrateId}; |
49 | use ra_syntax::{ast, AstNode}; | 49 | use ra_syntax::{ast, AstNode}; |
50 | 50 | ||
51 | use crate::body::Expander; | ||
51 | use crate::builtin_type::BuiltinType; | 52 | use crate::builtin_type::BuiltinType; |
52 | 53 | ||
53 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 54 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 00325cd99..8e1294201 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs | |||
@@ -135,7 +135,7 @@ impl Path { | |||
135 | } | 135 | } |
136 | 136 | ||
137 | pub fn type_anchor(&self) -> Option<&TypeRef> { | 137 | pub fn type_anchor(&self) -> Option<&TypeRef> { |
138 | self.type_anchor.as_ref().map(|it| &**it) | 138 | self.type_anchor.as_deref() |
139 | } | 139 | } |
140 | 140 | ||
141 | pub fn segments(&self) -> PathSegments<'_> { | 141 | pub fn segments(&self) -> PathSegments<'_> { |