diff options
Diffstat (limited to 'crates/ra_hir_def/src/data.rs')
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 164 |
1 files changed, 42 insertions, 122 deletions
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 697fde3d2..921253c42 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs | |||
@@ -2,23 +2,16 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_expand::{ | 5 | use hir_expand::{name::Name, InFile}; |
6 | hygiene::Hygiene, | ||
7 | name::{name, AsName, Name}, | ||
8 | InFile, | ||
9 | }; | ||
10 | use ra_prof::profile; | 6 | use ra_prof::profile; |
11 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, TypeBoundsOwner, VisibilityOwner}; | 7 | use ra_syntax::ast; |
12 | 8 | ||
13 | use crate::{ | 9 | use crate::{ |
14 | attr::Attrs, | 10 | attr::Attrs, |
15 | body::Expander, | 11 | body::Expander, |
16 | body::LowerCtx, | ||
17 | db::DefDatabase, | 12 | db::DefDatabase, |
18 | item_tree::{AssocItem, ItemTreeId, ModItem}, | 13 | item_tree::{AssocItem, ItemTreeId, ModItem}, |
19 | path::{path, AssociatedTypeBinding, GenericArgs, Path}, | 14 | type_ref::{TypeBound, TypeRef}, |
20 | src::HasSource, | ||
21 | type_ref::{Mutability, TypeBound, TypeRef}, | ||
22 | visibility::RawVisibility, | 15 | visibility::RawVisibility, |
23 | AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, | 16 | AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, |
24 | Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, | 17 | Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, |
@@ -40,82 +33,27 @@ pub struct FunctionData { | |||
40 | impl FunctionData { | 33 | impl FunctionData { |
41 | pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> { | 34 | pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> { |
42 | let loc = func.lookup(db); | 35 | let loc = func.lookup(db); |
43 | let src = loc.source(db); | 36 | let item_tree = db.item_tree(loc.id.file_id); |
44 | let ctx = LowerCtx::new(db, src.file_id); | 37 | let func = &item_tree[loc.id.value]; |
45 | let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); | 38 | |
46 | let mut params = Vec::new(); | 39 | Arc::new(FunctionData { |
47 | let mut has_self_param = false; | 40 | name: func.name.clone(), |
48 | if let Some(param_list) = src.value.param_list() { | 41 | params: func.params.clone(), |
49 | if let Some(self_param) = param_list.self_param() { | 42 | ret_type: func.ret_type.clone(), |
50 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { | 43 | attrs: func.attrs.clone(), |
51 | TypeRef::from_ast(&ctx, type_ref) | 44 | has_self_param: func.has_self_param, |
52 | } else { | 45 | is_unsafe: func.is_unsafe, |
53 | let self_type = TypeRef::Path(name![Self].into()); | 46 | visibility: func.visibility.clone(), |
54 | match self_param.kind() { | 47 | }) |
55 | ast::SelfParamKind::Owned => self_type, | ||
56 | ast::SelfParamKind::Ref => { | ||
57 | TypeRef::Reference(Box::new(self_type), Mutability::Shared) | ||
58 | } | ||
59 | ast::SelfParamKind::MutRef => { | ||
60 | TypeRef::Reference(Box::new(self_type), Mutability::Mut) | ||
61 | } | ||
62 | } | ||
63 | }; | ||
64 | params.push(self_type); | ||
65 | has_self_param = true; | ||
66 | } | ||
67 | for param in param_list.params() { | ||
68 | let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type()); | ||
69 | params.push(type_ref); | ||
70 | } | ||
71 | } | ||
72 | let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id)); | ||
73 | |||
74 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { | ||
75 | TypeRef::from_ast(&ctx, type_ref) | ||
76 | } else { | ||
77 | TypeRef::unit() | ||
78 | }; | ||
79 | |||
80 | let ret_type = if src.value.async_token().is_some() { | ||
81 | let future_impl = desugar_future_path(ret_type); | ||
82 | let ty_bound = TypeBound::Path(future_impl); | ||
83 | TypeRef::ImplTrait(vec![ty_bound]) | ||
84 | } else { | ||
85 | ret_type | ||
86 | }; | ||
87 | |||
88 | let is_unsafe = src.value.unsafe_token().is_some(); | ||
89 | |||
90 | let vis_default = RawVisibility::default_for_container(loc.container); | ||
91 | let visibility = | ||
92 | RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility())); | ||
93 | |||
94 | let sig = | ||
95 | FunctionData { name, params, ret_type, has_self_param, is_unsafe, visibility, attrs }; | ||
96 | Arc::new(sig) | ||
97 | } | 48 | } |
98 | } | 49 | } |
99 | 50 | ||
100 | fn desugar_future_path(orig: TypeRef) -> Path { | ||
101 | let path = path![core::future::Future]; | ||
102 | let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments.len() - 1).collect(); | ||
103 | let mut last = GenericArgs::empty(); | ||
104 | last.bindings.push(AssociatedTypeBinding { | ||
105 | name: name![Output], | ||
106 | type_ref: Some(orig), | ||
107 | bounds: Vec::new(), | ||
108 | }); | ||
109 | generic_args.push(Some(Arc::new(last))); | ||
110 | |||
111 | Path::from_known_path(path, generic_args) | ||
112 | } | ||
113 | |||
114 | #[derive(Debug, Clone, PartialEq, Eq)] | 51 | #[derive(Debug, Clone, PartialEq, Eq)] |
115 | pub struct TypeAliasData { | 52 | pub struct TypeAliasData { |
116 | pub name: Name, | 53 | pub name: Name, |
117 | pub type_ref: Option<TypeRef>, | 54 | pub type_ref: Option<TypeRef>, |
118 | pub visibility: RawVisibility, | 55 | pub visibility: RawVisibility, |
56 | /// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl). | ||
119 | pub bounds: Vec<TypeBound>, | 57 | pub bounds: Vec<TypeBound>, |
120 | } | 58 | } |
121 | 59 | ||
@@ -125,22 +63,15 @@ impl TypeAliasData { | |||
125 | typ: TypeAliasId, | 63 | typ: TypeAliasId, |
126 | ) -> Arc<TypeAliasData> { | 64 | ) -> Arc<TypeAliasData> { |
127 | let loc = typ.lookup(db); | 65 | let loc = typ.lookup(db); |
128 | let node = loc.source(db); | 66 | let item_tree = db.item_tree(loc.id.file_id); |
129 | let name = node.value.name().map_or_else(Name::missing, |n| n.as_name()); | 67 | let typ = &item_tree[loc.id.value]; |
130 | let lower_ctx = LowerCtx::new(db, node.file_id); | 68 | |
131 | let type_ref = node.value.type_ref().map(|it| TypeRef::from_ast(&lower_ctx, it)); | 69 | Arc::new(TypeAliasData { |
132 | let vis_default = RawVisibility::default_for_container(loc.container); | 70 | name: typ.name.clone(), |
133 | let visibility = RawVisibility::from_ast_with_default( | 71 | type_ref: typ.type_ref.clone(), |
134 | db, | 72 | visibility: typ.visibility.clone(), |
135 | vis_default, | 73 | bounds: typ.bounds.clone(), |
136 | node.as_ref().map(|n| n.visibility()), | 74 | }) |
137 | ); | ||
138 | let bounds = if let Some(bound_list) = node.value.type_bound_list() { | ||
139 | bound_list.bounds().map(|it| TypeBound::from_ast(&lower_ctx, it)).collect() | ||
140 | } else { | ||
141 | Vec::new() | ||
142 | }; | ||
143 | Arc::new(TypeAliasData { name, type_ref, visibility, bounds }) | ||
144 | } | 75 | } |
145 | } | 76 | } |
146 | 77 | ||
@@ -238,22 +169,14 @@ pub struct ConstData { | |||
238 | impl ConstData { | 169 | impl ConstData { |
239 | pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc<ConstData> { | 170 | pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc<ConstData> { |
240 | let loc = konst.lookup(db); | 171 | let loc = konst.lookup(db); |
241 | let node = loc.source(db); | 172 | let item_tree = db.item_tree(loc.id.file_id); |
242 | let vis_default = RawVisibility::default_for_container(loc.container); | 173 | let konst = &item_tree[loc.id.value]; |
243 | Arc::new(ConstData::new(db, vis_default, node)) | ||
244 | } | ||
245 | 174 | ||
246 | fn new<N: NameOwner + TypeAscriptionOwner + VisibilityOwner>( | 175 | Arc::new(ConstData { |
247 | db: &dyn DefDatabase, | 176 | name: konst.name.clone(), |
248 | vis_default: RawVisibility, | 177 | type_ref: konst.type_ref.clone(), |
249 | node: InFile<N>, | 178 | visibility: konst.visibility.clone(), |
250 | ) -> ConstData { | 179 | }) |
251 | let ctx = LowerCtx::new(db, node.file_id); | ||
252 | let name = node.value.name().map(|n| n.as_name()); | ||
253 | let type_ref = TypeRef::from_ast_opt(&ctx, node.value.ascribed_type()); | ||
254 | let visibility = | ||
255 | RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); | ||
256 | ConstData { name, type_ref, visibility } | ||
257 | } | 180 | } |
258 | } | 181 | } |
259 | 182 | ||
@@ -267,19 +190,16 @@ pub struct StaticData { | |||
267 | 190 | ||
268 | impl StaticData { | 191 | impl StaticData { |
269 | pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> { | 192 | pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> { |
270 | let node = konst.lookup(db).source(db); | 193 | let node = konst.lookup(db); |
271 | let ctx = LowerCtx::new(db, node.file_id); | 194 | let item_tree = db.item_tree(node.id.file_id); |
272 | 195 | let statik = &item_tree[node.id.value]; | |
273 | let name = node.value.name().map(|n| n.as_name()); | 196 | |
274 | let type_ref = TypeRef::from_ast_opt(&ctx, node.value.ascribed_type()); | 197 | Arc::new(StaticData { |
275 | let mutable = node.value.mut_token().is_some(); | 198 | name: Some(statik.name.clone()), |
276 | let visibility = RawVisibility::from_ast_with_default( | 199 | type_ref: statik.type_ref.clone(), |
277 | db, | 200 | visibility: statik.visibility.clone(), |
278 | RawVisibility::private(), | 201 | mutable: statik.mutable, |
279 | node.map(|n| n.visibility()), | 202 | }) |
280 | ); | ||
281 | |||
282 | Arc::new(StaticData { name, type_ref, visibility, mutable }) | ||
283 | } | 203 | } |
284 | } | 204 | } |
285 | 205 | ||