diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/find_path.rs | 45 |
3 files changed, 45 insertions, 31 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 443b057ab..c69e0efea 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -60,13 +60,10 @@ pub(super) fn lower( | |||
60 | params: Option<ast::ParamList>, | 60 | params: Option<ast::ParamList>, |
61 | body: Option<ast::Expr>, | 61 | body: Option<ast::Expr>, |
62 | ) -> (Body, BodySourceMap) { | 62 | ) -> (Body, BodySourceMap) { |
63 | let ctx = LowerCtx::new(db, expander.current_file_id.clone()); | ||
64 | |||
65 | ExprCollector { | 63 | ExprCollector { |
66 | db, | 64 | db, |
67 | def, | 65 | def, |
68 | expander, | 66 | expander, |
69 | ctx, | ||
70 | source_map: BodySourceMap::default(), | 67 | source_map: BodySourceMap::default(), |
71 | body: Body { | 68 | body: Body { |
72 | exprs: Arena::default(), | 69 | exprs: Arena::default(), |
@@ -83,7 +80,6 @@ struct ExprCollector<'a> { | |||
83 | db: &'a dyn DefDatabase, | 80 | db: &'a dyn DefDatabase, |
84 | def: DefWithBodyId, | 81 | def: DefWithBodyId, |
85 | expander: Expander, | 82 | expander: Expander, |
86 | ctx: LowerCtx, | ||
87 | body: Body, | 83 | body: Body, |
88 | source_map: BodySourceMap, | 84 | source_map: BodySourceMap, |
89 | } | 85 | } |
@@ -122,6 +118,10 @@ impl ExprCollector<'_> { | |||
122 | (self.body, self.source_map) | 118 | (self.body, self.source_map) |
123 | } | 119 | } |
124 | 120 | ||
121 | fn ctx(&self) -> LowerCtx { | ||
122 | LowerCtx::new(self.db, self.expander.current_file_id) | ||
123 | } | ||
124 | |||
125 | 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 { |
126 | let src = self.expander.to_source(ptr); | 126 | let src = self.expander.to_source(ptr); |
127 | let id = self.make_expr(expr, Ok(src.clone())); | 127 | let id = self.make_expr(expr, Ok(src.clone())); |
@@ -268,7 +268,7 @@ impl ExprCollector<'_> { | |||
268 | }; | 268 | }; |
269 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 269 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
270 | let generic_args = | 270 | let generic_args = |
271 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it)); | 271 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); |
272 | self.alloc_expr( | 272 | self.alloc_expr( |
273 | Expr::MethodCall { receiver, method_name, args, generic_args }, | 273 | Expr::MethodCall { receiver, method_name, args, generic_args }, |
274 | syntax_ptr, | 274 | syntax_ptr, |
@@ -373,7 +373,7 @@ impl ExprCollector<'_> { | |||
373 | } | 373 | } |
374 | ast::Expr::CastExpr(e) => { | 374 | ast::Expr::CastExpr(e) => { |
375 | let expr = self.collect_expr_opt(e.expr()); | 375 | let expr = self.collect_expr_opt(e.expr()); |
376 | let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref()); | 376 | let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.type_ref()); |
377 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) | 377 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) |
378 | } | 378 | } |
379 | ast::Expr::RefExpr(e) => { | 379 | ast::Expr::RefExpr(e) => { |
@@ -396,7 +396,7 @@ impl ExprCollector<'_> { | |||
396 | for param in pl.params() { | 396 | for param in pl.params() { |
397 | let pat = self.collect_pat_opt(param.pat()); | 397 | let pat = self.collect_pat_opt(param.pat()); |
398 | let type_ref = | 398 | let type_ref = |
399 | param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); | 399 | param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); |
400 | args.push(pat); | 400 | args.push(pat); |
401 | arg_types.push(type_ref); | 401 | arg_types.push(type_ref); |
402 | } | 402 | } |
@@ -404,7 +404,7 @@ impl ExprCollector<'_> { | |||
404 | let ret_type = e | 404 | let ret_type = e |
405 | .ret_type() | 405 | .ret_type() |
406 | .and_then(|r| r.type_ref()) | 406 | .and_then(|r| r.type_ref()) |
407 | .map(|it| TypeRef::from_ast(&self.ctx, it)); | 407 | .map(|it| TypeRef::from_ast(&self.ctx(), it)); |
408 | let body = self.collect_expr_opt(e.body()); | 408 | let body = self.collect_expr_opt(e.body()); |
409 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) | 409 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) |
410 | } | 410 | } |
@@ -507,7 +507,8 @@ impl ExprCollector<'_> { | |||
507 | .map(|s| match s { | 507 | .map(|s| match s { |
508 | ast::Stmt::LetStmt(stmt) => { | 508 | ast::Stmt::LetStmt(stmt) => { |
509 | let pat = self.collect_pat_opt(stmt.pat()); | 509 | let pat = self.collect_pat_opt(stmt.pat()); |
510 | let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); | 510 | let type_ref = |
511 | stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); | ||
511 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 512 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
512 | Statement::Let { pat, type_ref, initializer } | 513 | Statement::Let { pat, type_ref, initializer } |
513 | } | 514 | } |
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index e665ab45d..2f71511ba 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Defines database & queries for name resolution. | 1 | //! Defines database & queries for name resolution. |
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use hir_expand::{db::AstDatabase, HirFileId}; | 4 | use hir_expand::{db::AstDatabase, name::Name, HirFileId}; |
5 | use ra_db::{salsa, CrateId, SourceDatabase, Upcast}; | 5 | use ra_db::{salsa, CrateId, SourceDatabase, Upcast}; |
6 | use ra_prof::profile; | 6 | use ra_prof::profile; |
7 | use ra_syntax::SmolStr; | 7 | use ra_syntax::SmolStr; |
@@ -12,9 +12,12 @@ use crate::{ | |||
12 | body::{scope::ExprScopes, Body, BodySourceMap}, | 12 | body::{scope::ExprScopes, Body, BodySourceMap}, |
13 | data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData}, | 13 | data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData}, |
14 | docs::Documentation, | 14 | docs::Documentation, |
15 | find_path, | ||
15 | generics::GenericParams, | 16 | generics::GenericParams, |
17 | item_scope::ItemInNs, | ||
16 | lang_item::{LangItemTarget, LangItems}, | 18 | lang_item::{LangItemTarget, LangItems}, |
17 | nameres::{raw::RawItems, CrateDefMap}, | 19 | nameres::{raw::RawItems, CrateDefMap}, |
20 | visibility::Visibility, | ||
18 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, | 21 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, |
19 | GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, | 22 | GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, |
20 | TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, | 23 | TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, |
@@ -108,6 +111,13 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> { | |||
108 | // Remove this query completely, in favor of `Attrs::docs` method | 111 | // Remove this query completely, in favor of `Attrs::docs` method |
109 | #[salsa::invoke(Documentation::documentation_query)] | 112 | #[salsa::invoke(Documentation::documentation_query)] |
110 | fn documentation(&self, def: AttrDefId) -> Option<Documentation>; | 113 | fn documentation(&self, def: AttrDefId) -> Option<Documentation>; |
114 | |||
115 | #[salsa::invoke(find_path::importable_locations_of_query)] | ||
116 | fn importable_locations_of( | ||
117 | &self, | ||
118 | item: ItemInNs, | ||
119 | krate: CrateId, | ||
120 | ) -> Arc<[(ModuleId, Name, Visibility)]>; | ||
111 | } | 121 | } |
112 | 122 | ||
113 | fn crate_def_map_wait(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> { | 123 | fn crate_def_map_wait(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> { |
diff --git a/crates/ra_hir_def/src/find_path.rs b/crates/ra_hir_def/src/find_path.rs index 70dcb03e6..2eb12ec8f 100644 --- a/crates/ra_hir_def/src/find_path.rs +++ b/crates/ra_hir_def/src/find_path.rs | |||
@@ -1,5 +1,11 @@ | |||
1 | //! An algorithm to find a path to refer to a certain item. | 1 | //! An algorithm to find a path to refer to a certain item. |
2 | 2 | ||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::name::{known, AsName, Name}; | ||
6 | use ra_prof::profile; | ||
7 | use test_utils::tested_by; | ||
8 | |||
3 | use crate::{ | 9 | use crate::{ |
4 | db::DefDatabase, | 10 | db::DefDatabase, |
5 | item_scope::ItemInNs, | 11 | item_scope::ItemInNs, |
@@ -7,25 +13,28 @@ use crate::{ | |||
7 | visibility::Visibility, | 13 | visibility::Visibility, |
8 | CrateId, ModuleDefId, ModuleId, | 14 | CrateId, ModuleDefId, ModuleId, |
9 | }; | 15 | }; |
10 | use hir_expand::name::{known, AsName, Name}; | 16 | |
11 | use test_utils::tested_by; | 17 | // FIXME: handle local items |
18 | |||
19 | /// Find a path that can be used to refer to a certain item. This can depend on | ||
20 | /// *from where* you're referring to the item, hence the `from` parameter. | ||
21 | pub fn find_path(db: &dyn DefDatabase, item: ItemInNs, from: ModuleId) -> Option<ModPath> { | ||
22 | let _p = profile("find_path"); | ||
23 | find_path_inner(db, item, from, MAX_PATH_LEN) | ||
24 | } | ||
12 | 25 | ||
13 | const MAX_PATH_LEN: usize = 15; | 26 | const MAX_PATH_LEN: usize = 15; |
14 | 27 | ||
15 | impl ModPath { | 28 | impl ModPath { |
16 | fn starts_with_std(&self) -> bool { | 29 | fn starts_with_std(&self) -> bool { |
17 | self.segments.first().filter(|&first_segment| first_segment == &known::std).is_some() | 30 | self.segments.first() == Some(&known::std) |
18 | } | 31 | } |
19 | 32 | ||
20 | // When std library is present, paths starting with `std::` | 33 | // When std library is present, paths starting with `std::` |
21 | // should be preferred over paths starting with `core::` and `alloc::` | 34 | // should be preferred over paths starting with `core::` and `alloc::` |
22 | fn can_start_with_std(&self) -> bool { | 35 | fn can_start_with_std(&self) -> bool { |
23 | self.segments | 36 | let first_segment = self.segments.first(); |
24 | .first() | 37 | first_segment == Some(&known::alloc) || first_segment == Some(&known::core) |
25 | .filter(|&first_segment| { | ||
26 | first_segment == &known::alloc || first_segment == &known::core | ||
27 | }) | ||
28 | .is_some() | ||
29 | } | 38 | } |
30 | 39 | ||
31 | fn len(&self) -> usize { | 40 | fn len(&self) -> usize { |
@@ -40,14 +49,6 @@ impl ModPath { | |||
40 | } | 49 | } |
41 | } | 50 | } |
42 | 51 | ||
43 | // FIXME: handle local items | ||
44 | |||
45 | /// Find a path that can be used to refer to a certain item. This can depend on | ||
46 | /// *from where* you're referring to the item, hence the `from` parameter. | ||
47 | pub fn find_path(db: &dyn DefDatabase, item: ItemInNs, from: ModuleId) -> Option<ModPath> { | ||
48 | find_path_inner(db, item, from, MAX_PATH_LEN) | ||
49 | } | ||
50 | |||
51 | fn find_path_inner( | 52 | fn find_path_inner( |
52 | db: &dyn DefDatabase, | 53 | db: &dyn DefDatabase, |
53 | item: ItemInNs, | 54 | item: ItemInNs, |
@@ -198,7 +199,7 @@ fn find_importable_locations( | |||
198 | .chain(crate_graph[from.krate].dependencies.iter().map(|dep| dep.crate_id)) | 199 | .chain(crate_graph[from.krate].dependencies.iter().map(|dep| dep.crate_id)) |
199 | { | 200 | { |
200 | result.extend( | 201 | result.extend( |
201 | importable_locations_in_crate(db, item, krate) | 202 | db.importable_locations_of(item, krate) |
202 | .iter() | 203 | .iter() |
203 | .filter(|(_, _, vis)| vis.is_visible_from(db, from)) | 204 | .filter(|(_, _, vis)| vis.is_visible_from(db, from)) |
204 | .map(|(m, n, _)| (*m, n.clone())), | 205 | .map(|(m, n, _)| (*m, n.clone())), |
@@ -213,11 +214,12 @@ fn find_importable_locations( | |||
213 | /// | 214 | /// |
214 | /// Note that the crate doesn't need to be the one in which the item is defined; | 215 | /// Note that the crate doesn't need to be the one in which the item is defined; |
215 | /// it might be re-exported in other crates. | 216 | /// it might be re-exported in other crates. |
216 | fn importable_locations_in_crate( | 217 | pub(crate) fn importable_locations_of_query( |
217 | db: &dyn DefDatabase, | 218 | db: &dyn DefDatabase, |
218 | item: ItemInNs, | 219 | item: ItemInNs, |
219 | krate: CrateId, | 220 | krate: CrateId, |
220 | ) -> Vec<(ModuleId, Name, Visibility)> { | 221 | ) -> Arc<[(ModuleId, Name, Visibility)]> { |
222 | let _p = profile("importable_locations_of_query"); | ||
221 | let def_map = db.crate_def_map(krate); | 223 | let def_map = db.crate_def_map(krate); |
222 | let mut result = Vec::new(); | 224 | let mut result = Vec::new(); |
223 | for (local_id, data) in def_map.modules.iter() { | 225 | for (local_id, data) in def_map.modules.iter() { |
@@ -243,7 +245,8 @@ fn importable_locations_in_crate( | |||
243 | result.push((ModuleId { krate, local_id }, name.clone(), vis)); | 245 | result.push((ModuleId { krate, local_id }, name.clone(), vis)); |
244 | } | 246 | } |
245 | } | 247 | } |
246 | result | 248 | |
249 | Arc::from(result) | ||
247 | } | 250 | } |
248 | 251 | ||
249 | #[cfg(test)] | 252 | #[cfg(test)] |