aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/data.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-11-22 14:32:10 +0000
committerAleksey Kladov <[email protected]>2019-11-22 14:32:10 +0000
commitb315f05cf160a11b9012fcde2a9aefc240e39135 (patch)
treeced460568980b0bd71ad95267c89f320ce324ba4 /crates/ra_hir_def/src/data.rs
parent78f3b0627cf4a5d34aaf63c7b5a2e1b744a11b14 (diff)
Move data to a single file
Diffstat (limited to 'crates/ra_hir_def/src/data.rs')
-rw-r--r--crates/ra_hir_def/src/data.rs206
1 files changed, 206 insertions, 0 deletions
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
new file mode 100644
index 000000000..b73e0d0a7
--- /dev/null
+++ b/crates/ra_hir_def/src/data.rs
@@ -0,0 +1,206 @@
1use std::sync::Arc;
2
3use hir_expand::{
4 name::{self, AsName, Name},
5 AstId,
6};
7use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
8
9use crate::{
10 db::DefDatabase2,
11 type_ref::{Mutability, TypeRef},
12 AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionId, FunctionLoc, HasSource, ImplId,
13 Intern, Lookup, TraitId, TypeAliasId, TypeAliasLoc,
14};
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct FunctionData {
18 pub name: Name,
19 pub params: Vec<TypeRef>,
20 pub ret_type: TypeRef,
21 /// True if the first param is `self`. This is relevant to decide whether this
22 /// can be called as a method.
23 pub has_self_param: bool,
24}
25
26impl FunctionData {
27 pub(crate) fn fn_data_query(db: &impl DefDatabase2, func: FunctionId) -> Arc<FunctionData> {
28 let src = func.lookup(db).source(db);
29 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
30 let mut params = Vec::new();
31 let mut has_self_param = false;
32 if let Some(param_list) = src.value.param_list() {
33 if let Some(self_param) = param_list.self_param() {
34 let self_type = if let Some(type_ref) = self_param.ascribed_type() {
35 TypeRef::from_ast(type_ref)
36 } else {
37 let self_type = TypeRef::Path(name::SELF_TYPE.into());
38 match self_param.kind() {
39 ast::SelfParamKind::Owned => self_type,
40 ast::SelfParamKind::Ref => {
41 TypeRef::Reference(Box::new(self_type), Mutability::Shared)
42 }
43 ast::SelfParamKind::MutRef => {
44 TypeRef::Reference(Box::new(self_type), Mutability::Mut)
45 }
46 }
47 };
48 params.push(self_type);
49 has_self_param = true;
50 }
51 for param in param_list.params() {
52 let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
53 params.push(type_ref);
54 }
55 }
56 let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
57 TypeRef::from_ast(type_ref)
58 } else {
59 TypeRef::unit()
60 };
61
62 let sig = FunctionData { name, params, ret_type, has_self_param };
63 Arc::new(sig)
64 }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq)]
68pub struct TypeAliasData {
69 pub name: Name,
70 pub type_ref: Option<TypeRef>,
71}
72
73impl TypeAliasData {
74 pub(crate) fn type_alias_data_query(
75 db: &impl DefDatabase2,
76 typ: TypeAliasId,
77 ) -> Arc<TypeAliasData> {
78 let node = typ.lookup(db).source(db).value;
79 let name = node.name().map_or_else(Name::missing, |n| n.as_name());
80 let type_ref = node.type_ref().map(TypeRef::from_ast);
81 Arc::new(TypeAliasData { name, type_ref })
82 }
83}
84
85#[derive(Debug, Clone, PartialEq, Eq)]
86pub struct TraitData {
87 pub name: Option<Name>,
88 pub items: Vec<AssocItemId>,
89 pub auto: bool,
90}
91
92impl TraitData {
93 pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
94 let src = tr.source(db);
95 let name = src.value.name().map(|n| n.as_name());
96 let auto = src.value.is_auto();
97 let ast_id_map = db.ast_id_map(src.file_id);
98 let items = if let Some(item_list) = src.value.item_list() {
99 item_list
100 .impl_items()
101 .map(|item_node| match item_node {
102 ast::ImplItem::FnDef(it) => FunctionLoc {
103 container: ContainerId::TraitId(tr),
104 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
105 }
106 .intern(db)
107 .into(),
108 ast::ImplItem::ConstDef(it) => ConstLoc {
109 container: ContainerId::TraitId(tr),
110 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
111 }
112 .intern(db)
113 .into(),
114 ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc {
115 container: ContainerId::TraitId(tr),
116 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
117 }
118 .intern(db)
119 .into(),
120 })
121 .collect()
122 } else {
123 Vec::new()
124 };
125 Arc::new(TraitData { name, items, auto })
126 }
127
128 pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
129 self.items.iter().filter_map(|item| match item {
130 AssocItemId::TypeAliasId(t) => Some(*t),
131 _ => None,
132 })
133 }
134}
135
136#[derive(Debug, Clone, PartialEq, Eq)]
137pub struct ImplData {
138 target_trait: Option<TypeRef>,
139 target_type: TypeRef,
140 items: Vec<AssocItemId>,
141 negative: bool,
142}
143
144impl ImplData {
145 pub(crate) fn impl_data_query(db: &impl DefDatabase2, id: ImplId) -> Arc<ImplData> {
146 let src = id.source(db);
147 let items = db.ast_id_map(src.file_id);
148
149 let target_trait = src.value.target_trait().map(TypeRef::from_ast);
150 let target_type = TypeRef::from_ast_opt(src.value.target_type());
151 let negative = src.value.is_negative();
152
153 let items = if let Some(item_list) = src.value.item_list() {
154 item_list
155 .impl_items()
156 .map(|item_node| match item_node {
157 ast::ImplItem::FnDef(it) => {
158 let def = FunctionLoc {
159 container: ContainerId::ImplId(id),
160 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
161 }
162 .intern(db);
163 def.into()
164 }
165 ast::ImplItem::ConstDef(it) => {
166 let def = ConstLoc {
167 container: ContainerId::ImplId(id),
168 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
169 }
170 .intern(db);
171 def.into()
172 }
173 ast::ImplItem::TypeAliasDef(it) => {
174 let def = TypeAliasLoc {
175 container: ContainerId::ImplId(id),
176 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
177 }
178 .intern(db);
179 def.into()
180 }
181 })
182 .collect()
183 } else {
184 Vec::new()
185 };
186
187 let res = ImplData { target_trait, target_type, items, negative };
188 Arc::new(res)
189 }
190
191 pub fn target_trait(&self) -> Option<&TypeRef> {
192 self.target_trait.as_ref()
193 }
194
195 pub fn target_type(&self) -> &TypeRef {
196 &self.target_type
197 }
198
199 pub fn items(&self) -> &[AssocItemId] {
200 &self.items
201 }
202
203 pub fn is_negative(&self) -> bool {
204 self.negative
205 }
206}