diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 409 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 128 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/debug.rs | 94 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 362 | ||||
-rw-r--r-- | crates/ra_hir/src/has_source.rs | 127 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 26 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 213 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 4 |
11 files changed, 498 insertions, 885 deletions
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index e79361e7c..7dc31ad3c 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml | |||
@@ -10,9 +10,11 @@ doctest = false | |||
10 | [dependencies] | 10 | [dependencies] |
11 | log = "0.4.5" | 11 | log = "0.4.5" |
12 | rustc-hash = "1.0" | 12 | rustc-hash = "1.0" |
13 | either = "1.5" | ||
13 | 14 | ||
14 | ra_syntax = { path = "../ra_syntax" } | 15 | ra_syntax = { path = "../ra_syntax" } |
15 | ra_db = { path = "../ra_db" } | 16 | ra_db = { path = "../ra_db" } |
17 | ra_prof = { path = "../ra_prof" } | ||
16 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } | 18 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } |
17 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | 19 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } |
18 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } | 20 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 38d66c2a7..bcfc0d03e 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -1,36 +1,35 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | |||
3 | pub(crate) mod src; | ||
4 | |||
5 | use std::sync::Arc; | 2 | use std::sync::Arc; |
6 | 3 | ||
4 | use either::Either; | ||
7 | use hir_def::{ | 5 | use hir_def::{ |
8 | adt::VariantData, | 6 | adt::VariantData, |
9 | body::{Body, BodySourceMap}, | ||
10 | builtin_type::BuiltinType, | 7 | builtin_type::BuiltinType, |
11 | docs::Documentation, | 8 | docs::Documentation, |
12 | expr::{BindingAnnotation, Pat, PatId}, | 9 | expr::{BindingAnnotation, Pat, PatId}, |
10 | nameres::ModuleSource, | ||
13 | per_ns::PerNs, | 11 | per_ns::PerNs, |
14 | resolver::HasResolver, | 12 | resolver::HasResolver, |
15 | type_ref::{Mutability, TypeRef}, | 13 | type_ref::{Mutability, TypeRef}, |
16 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, | 14 | AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, |
17 | HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, | 15 | LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, |
18 | Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, | 16 | TypeParamId, UnionId, |
19 | }; | 17 | }; |
20 | use hir_expand::{ | 18 | use hir_expand::{ |
21 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
22 | name::{self, AsName}, | 20 | name::{name, AsName}, |
23 | AstId, MacroDefId, | 21 | MacroDefId, |
22 | }; | ||
23 | use hir_ty::{ | ||
24 | autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment, | ||
25 | TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, | ||
24 | }; | 26 | }; |
25 | use hir_ty::expr::ExprValidator; | 27 | use ra_db::{CrateId, Edition, FileId}; |
26 | use ra_db::{CrateId, Edition, FileId, FilePosition}; | 28 | use ra_syntax::ast; |
27 | use ra_syntax::{ast, AstNode, SyntaxNode}; | ||
28 | 29 | ||
29 | use crate::{ | 30 | use crate::{ |
30 | db::{DefDatabase, HirDatabase}, | 31 | db::{DefDatabase, HirDatabase}, |
31 | ty::display::HirFormatter, | 32 | CallableDef, HirDisplay, InFile, Name, |
32 | ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk}, | ||
33 | CallableDef, Either, HirDisplay, Name, Source, | ||
34 | }; | 33 | }; |
35 | 34 | ||
36 | /// hir::Crate describes a single crate. It's the main interface with which | 35 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -38,7 +37,7 @@ use crate::{ | |||
38 | /// root module. | 37 | /// root module. |
39 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 38 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
40 | pub struct Crate { | 39 | pub struct Crate { |
41 | pub(crate) crate_id: CrateId, | 40 | pub(crate) id: CrateId, |
42 | } | 41 | } |
43 | 42 | ||
44 | #[derive(Debug)] | 43 | #[derive(Debug)] |
@@ -48,91 +47,43 @@ pub struct CrateDependency { | |||
48 | } | 47 | } |
49 | 48 | ||
50 | impl Crate { | 49 | impl Crate { |
51 | pub fn crate_id(self) -> CrateId { | ||
52 | self.crate_id | ||
53 | } | ||
54 | |||
55 | pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> { | 50 | pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> { |
56 | db.crate_graph() | 51 | db.crate_graph() |
57 | .dependencies(self.crate_id) | 52 | .dependencies(self.id) |
58 | .map(|dep| { | 53 | .map(|dep| { |
59 | let krate = Crate { crate_id: dep.crate_id() }; | 54 | let krate = Crate { id: dep.crate_id() }; |
60 | let name = dep.as_name(); | 55 | let name = dep.as_name(); |
61 | CrateDependency { krate, name } | 56 | CrateDependency { krate, name } |
62 | }) | 57 | }) |
63 | .collect() | 58 | .collect() |
64 | } | 59 | } |
65 | 60 | ||
66 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { | 61 | // FIXME: add `transitive_reverse_dependencies`. |
67 | let module_id = db.crate_def_map(self.crate_id).root; | 62 | pub fn reverse_dependencies(self, db: &impl DefDatabase) -> Vec<Crate> { |
68 | Some(Module::new(self, module_id)) | ||
69 | } | ||
70 | |||
71 | pub fn edition(self, db: &impl DefDatabase) -> Edition { | ||
72 | let crate_graph = db.crate_graph(); | 63 | let crate_graph = db.crate_graph(); |
73 | crate_graph.edition(self.crate_id) | 64 | crate_graph |
74 | } | 65 | .iter() |
75 | 66 | .filter(|&krate| crate_graph.dependencies(krate).any(|it| it.crate_id == self.id)) | |
76 | pub fn all(db: &impl DefDatabase) -> Vec<Crate> { | 67 | .map(|id| Crate { id }) |
77 | db.crate_graph().iter().map(|crate_id| Crate { crate_id }).collect() | 68 | .collect() |
78 | } | 69 | } |
79 | } | ||
80 | |||
81 | pub enum ModuleSource { | ||
82 | SourceFile(ast::SourceFile), | ||
83 | Module(ast::Module), | ||
84 | } | ||
85 | 70 | ||
86 | impl ModuleSource { | 71 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { |
87 | pub fn new( | 72 | let module_id = db.crate_def_map(self.id).root; |
88 | db: &impl DefDatabase, | 73 | Some(Module::new(self, module_id)) |
89 | file_id: Option<FileId>, | ||
90 | decl_id: Option<AstId<ast::Module>>, | ||
91 | ) -> ModuleSource { | ||
92 | match (file_id, decl_id) { | ||
93 | (Some(file_id), _) => { | ||
94 | let source_file = db.parse(file_id).tree(); | ||
95 | ModuleSource::SourceFile(source_file) | ||
96 | } | ||
97 | (None, Some(item_id)) => { | ||
98 | let module = item_id.to_node(db); | ||
99 | assert!(module.item_list().is_some(), "expected inline module"); | ||
100 | ModuleSource::Module(module) | ||
101 | } | ||
102 | (None, None) => panic!(), | ||
103 | } | ||
104 | } | 74 | } |
105 | 75 | ||
106 | // FIXME: this methods do not belong here | 76 | pub fn root_file(self, db: &impl DefDatabase) -> FileId { |
107 | pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource { | 77 | db.crate_graph().crate_root(self.id) |
108 | let parse = db.parse(position.file_id); | ||
109 | match &ra_syntax::algo::find_node_at_offset::<ast::Module>( | ||
110 | parse.tree().syntax(), | ||
111 | position.offset, | ||
112 | ) { | ||
113 | Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()), | ||
114 | _ => { | ||
115 | let source_file = parse.tree(); | ||
116 | ModuleSource::SourceFile(source_file) | ||
117 | } | ||
118 | } | ||
119 | } | 78 | } |
120 | 79 | ||
121 | pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource { | 80 | pub fn edition(self, db: &impl DefDatabase) -> Edition { |
122 | if let Some(m) = | 81 | let crate_graph = db.crate_graph(); |
123 | child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) | 82 | crate_graph.edition(self.id) |
124 | { | ||
125 | ModuleSource::Module(m) | ||
126 | } else { | ||
127 | let file_id = child.file_id.original_file(db); | ||
128 | let source_file = db.parse(file_id).tree(); | ||
129 | ModuleSource::SourceFile(source_file) | ||
130 | } | ||
131 | } | 83 | } |
132 | 84 | ||
133 | pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource { | 85 | pub fn all(db: &impl DefDatabase) -> Vec<Crate> { |
134 | let source_file = db.parse(file_id).tree(); | 86 | db.crate_graph().iter().map(|id| Crate { id }).collect() |
135 | ModuleSource::SourceFile(source_file) | ||
136 | } | 87 | } |
137 | } | 88 | } |
138 | 89 | ||
@@ -171,7 +122,7 @@ pub use hir_def::attr::Attrs; | |||
171 | 122 | ||
172 | impl Module { | 123 | impl Module { |
173 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 124 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
174 | Module { id: ModuleId { krate: krate.crate_id, local_id: crate_module_id } } | 125 | Module { id: ModuleId { krate: krate.id, local_id: crate_module_id } } |
175 | } | 126 | } |
176 | 127 | ||
177 | /// Name of this module. | 128 | /// Name of this module. |
@@ -189,7 +140,7 @@ impl Module { | |||
189 | 140 | ||
190 | /// Returns the crate this module is part of. | 141 | /// Returns the crate this module is part of. |
191 | pub fn krate(self) -> Crate { | 142 | pub fn krate(self) -> Crate { |
192 | Crate { crate_id: self.id.krate } | 143 | Crate { id: self.id.krate } |
193 | } | 144 | } |
194 | 145 | ||
195 | /// Topmost parent of this module. Every module has a `crate_root`, but some | 146 | /// Topmost parent of this module. Every module has a `crate_root`, but some |
@@ -200,13 +151,6 @@ impl Module { | |||
200 | self.with_module_id(def_map.root) | 151 | self.with_module_id(def_map.root) |
201 | } | 152 | } |
202 | 153 | ||
203 | /// Finds a child module with the specified name. | ||
204 | pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> { | ||
205 | let def_map = db.crate_def_map(self.id.krate); | ||
206 | let child_id = def_map[self.id.local_id].children.get(name)?; | ||
207 | Some(self.with_module_id(*child_id)) | ||
208 | } | ||
209 | |||
210 | /// Iterates over all child modules. | 154 | /// Iterates over all child modules. |
211 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { | 155 | pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { |
212 | let def_map = db.crate_def_map(self.id.krate); | 156 | let def_map = db.crate_def_map(self.id.krate); |
@@ -236,13 +180,11 @@ impl Module { | |||
236 | } | 180 | } |
237 | 181 | ||
238 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 182 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
239 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { | 183 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> { |
240 | db.crate_def_map(self.id.krate)[self.id.local_id] | 184 | db.crate_def_map(self.id.krate)[self.id.local_id] |
241 | .scope | 185 | .scope |
242 | .entries() | 186 | .entries() |
243 | .map(|(name, res)| { | 187 | .map(|(name, def)| (name.clone(), def.into())) |
244 | (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id })) | ||
245 | }) | ||
246 | .collect() | 188 | .collect() |
247 | } | 189 | } |
248 | 190 | ||
@@ -277,19 +219,14 @@ impl Module { | |||
277 | 219 | ||
278 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { | 220 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { |
279 | let def_map = db.crate_def_map(self.id.krate); | 221 | let def_map = db.crate_def_map(self.id.krate); |
280 | def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() | 222 | def_map[self.id.local_id].scope.impls().map(ImplBlock::from).collect() |
281 | } | 223 | } |
282 | 224 | ||
283 | fn with_module_id(self, module_id: LocalModuleId) -> Module { | 225 | pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { |
284 | Module::new(self.krate(), module_id) | 226 | Module::new(self.krate(), module_id) |
285 | } | 227 | } |
286 | } | 228 | } |
287 | 229 | ||
288 | pub struct Import { | ||
289 | pub(crate) parent: Module, | ||
290 | pub(crate) id: LocalImportId, | ||
291 | } | ||
292 | |||
293 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 230 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
294 | pub struct StructField { | 231 | pub struct StructField { |
295 | pub(crate) parent: VariantDef, | 232 | pub(crate) parent: VariantDef, |
@@ -307,8 +244,10 @@ impl StructField { | |||
307 | self.parent.variant_data(db).fields()[self.id].name.clone() | 244 | self.parent.variant_data(db).fields()[self.id].name.clone() |
308 | } | 245 | } |
309 | 246 | ||
310 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { | 247 | pub fn ty(&self, db: &impl HirDatabase) -> Type { |
311 | db.field_types(self.parent.into())[self.id].clone() | 248 | let var_id = self.parent.into(); |
249 | let ty = db.field_types(var_id)[self.id].clone(); | ||
250 | Type::new(db, self.parent.module(db).id.krate.into(), var_id, ty) | ||
312 | } | 251 | } |
313 | 252 | ||
314 | pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { | 253 | pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { |
@@ -323,7 +262,7 @@ pub struct Struct { | |||
323 | 262 | ||
324 | impl Struct { | 263 | impl Struct { |
325 | pub fn module(self, db: &impl DefDatabase) -> Module { | 264 | pub fn module(self, db: &impl DefDatabase) -> Module { |
326 | Module { id: self.id.module(db) } | 265 | Module { id: self.id.lookup(db).container.module(db) } |
327 | } | 266 | } |
328 | 267 | ||
329 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 268 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -343,21 +282,8 @@ impl Struct { | |||
343 | .collect() | 282 | .collect() |
344 | } | 283 | } |
345 | 284 | ||
346 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
347 | db.struct_data(self.id.into()) | ||
348 | .variant_data | ||
349 | .fields() | ||
350 | .iter() | ||
351 | .find(|(_id, data)| data.name == *name) | ||
352 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
353 | } | ||
354 | |||
355 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 285 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
356 | Type::from_def(db, self.id.module(db).krate, self.id) | 286 | Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id) |
357 | } | ||
358 | |||
359 | pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { | ||
360 | db.value_ty(self.id.into()) | ||
361 | } | 287 | } |
362 | 288 | ||
363 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 289 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
@@ -376,11 +302,11 @@ impl Union { | |||
376 | } | 302 | } |
377 | 303 | ||
378 | pub fn module(self, db: &impl DefDatabase) -> Module { | 304 | pub fn module(self, db: &impl DefDatabase) -> Module { |
379 | Module { id: self.id.module(db) } | 305 | Module { id: self.id.lookup(db).container.module(db) } |
380 | } | 306 | } |
381 | 307 | ||
382 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 308 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
383 | Type::from_def(db, self.id.module(db).krate, self.id) | 309 | Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id) |
384 | } | 310 | } |
385 | 311 | ||
386 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | 312 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { |
@@ -392,15 +318,6 @@ impl Union { | |||
392 | .collect() | 318 | .collect() |
393 | } | 319 | } |
394 | 320 | ||
395 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
396 | db.union_data(self.id) | ||
397 | .variant_data | ||
398 | .fields() | ||
399 | .iter() | ||
400 | .find(|(_id, data)| data.name == *name) | ||
401 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
402 | } | ||
403 | |||
404 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 321 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
405 | db.union_data(self.id).variant_data.clone() | 322 | db.union_data(self.id).variant_data.clone() |
406 | } | 323 | } |
@@ -413,7 +330,7 @@ pub struct Enum { | |||
413 | 330 | ||
414 | impl Enum { | 331 | impl Enum { |
415 | pub fn module(self, db: &impl DefDatabase) -> Module { | 332 | pub fn module(self, db: &impl DefDatabase) -> Module { |
416 | Module { id: self.id.module(db) } | 333 | Module { id: self.id.lookup(db).container.module(db) } |
417 | } | 334 | } |
418 | 335 | ||
419 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 336 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -432,13 +349,8 @@ impl Enum { | |||
432 | .collect() | 349 | .collect() |
433 | } | 350 | } |
434 | 351 | ||
435 | pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> { | ||
436 | let id = db.enum_data(self.id).variant(name)?; | ||
437 | Some(EnumVariant { parent: self, id }) | ||
438 | } | ||
439 | |||
440 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 352 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
441 | Type::from_def(db, self.id.module(db).krate, self.id) | 353 | Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id) |
442 | } | 354 | } |
443 | } | 355 | } |
444 | 356 | ||
@@ -468,14 +380,6 @@ impl EnumVariant { | |||
468 | .collect() | 380 | .collect() |
469 | } | 381 | } |
470 | 382 | ||
471 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
472 | self.variant_data(db) | ||
473 | .fields() | ||
474 | .iter() | ||
475 | .find(|(_id, data)| data.name == *name) | ||
476 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
477 | } | ||
478 | |||
479 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 383 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
480 | db.enum_data(self.parent.id).variants[self.id].variant_data.clone() | 384 | db.enum_data(self.parent.id).variants[self.id].variant_data.clone() |
481 | } | 385 | } |
@@ -593,48 +497,8 @@ impl Function { | |||
593 | db.function_data(self.id).params.clone() | 497 | db.function_data(self.id).params.clone() |
594 | } | 498 | } |
595 | 499 | ||
596 | pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
597 | db.body_with_source_map(self.id.into()).1 | ||
598 | } | ||
599 | |||
600 | pub fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
601 | db.body(self.id.into()) | ||
602 | } | ||
603 | |||
604 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | ||
605 | db.value_ty(self.id.into()) | ||
606 | } | ||
607 | |||
608 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
609 | db.infer(self.id.into()) | ||
610 | } | ||
611 | |||
612 | /// The containing impl block, if this is a method. | ||
613 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | ||
614 | match self.container(db) { | ||
615 | Some(Container::ImplBlock(it)) => Some(it), | ||
616 | _ => None, | ||
617 | } | ||
618 | } | ||
619 | |||
620 | /// The containing trait, if this is a trait method definition. | ||
621 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | ||
622 | match self.container(db) { | ||
623 | Some(Container::Trait(it)) => Some(it), | ||
624 | _ => None, | ||
625 | } | ||
626 | } | ||
627 | |||
628 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | ||
629 | match self.id.lookup(db).container { | ||
630 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), | ||
631 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), | ||
632 | ContainerId::ModuleId(_) => None, | ||
633 | } | ||
634 | } | ||
635 | |||
636 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 500 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
637 | let infer = self.infer(db); | 501 | let infer = db.infer(self.id.into()); |
638 | infer.add_diagnostics(db, self.id, sink); | 502 | infer.add_diagnostics(db, self.id, sink); |
639 | let mut validator = ExprValidator::new(self.id, infer, sink); | 503 | let mut validator = ExprValidator::new(self.id, infer, sink); |
640 | validator.validate_body(db); | 504 | validator.validate_body(db); |
@@ -658,34 +522,6 @@ impl Const { | |||
658 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { | 522 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { |
659 | db.const_data(self.id).name.clone() | 523 | db.const_data(self.id).name.clone() |
660 | } | 524 | } |
661 | |||
662 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
663 | db.infer(self.id.into()) | ||
664 | } | ||
665 | |||
666 | /// The containing impl block, if this is a type alias. | ||
667 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | ||
668 | match self.container(db) { | ||
669 | Some(Container::ImplBlock(it)) => Some(it), | ||
670 | _ => None, | ||
671 | } | ||
672 | } | ||
673 | |||
674 | /// The containing trait, if this is a trait type alias definition. | ||
675 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | ||
676 | match self.container(db) { | ||
677 | Some(Container::Trait(it)) => Some(it), | ||
678 | _ => None, | ||
679 | } | ||
680 | } | ||
681 | |||
682 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | ||
683 | match self.id.lookup(db).container { | ||
684 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), | ||
685 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), | ||
686 | ContainerId::ModuleId(_) => None, | ||
687 | } | ||
688 | } | ||
689 | } | 525 | } |
690 | 526 | ||
691 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 527 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -701,10 +537,6 @@ impl Static { | |||
701 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 537 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
702 | Some(self.module(db).krate()) | 538 | Some(self.module(db).krate()) |
703 | } | 539 | } |
704 | |||
705 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
706 | db.infer(self.id.into()) | ||
707 | } | ||
708 | } | 540 | } |
709 | 541 | ||
710 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 542 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -714,7 +546,7 @@ pub struct Trait { | |||
714 | 546 | ||
715 | impl Trait { | 547 | impl Trait { |
716 | pub fn module(self, db: &impl DefDatabase) -> Module { | 548 | pub fn module(self, db: &impl DefDatabase) -> Module { |
717 | Module { id: self.id.module(db) } | 549 | Module { id: self.id.lookup(db).container.module(db) } |
718 | } | 550 | } |
719 | 551 | ||
720 | pub fn name(self, db: &impl DefDatabase) -> Name { | 552 | pub fn name(self, db: &impl DefDatabase) -> Name { |
@@ -749,30 +581,6 @@ impl TypeAlias { | |||
749 | Some(self.module(db).krate()) | 581 | Some(self.module(db).krate()) |
750 | } | 582 | } |
751 | 583 | ||
752 | /// The containing impl block, if this is a type alias. | ||
753 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | ||
754 | match self.container(db) { | ||
755 | Some(Container::ImplBlock(it)) => Some(it), | ||
756 | _ => None, | ||
757 | } | ||
758 | } | ||
759 | |||
760 | /// The containing trait, if this is a trait type alias definition. | ||
761 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | ||
762 | match self.container(db) { | ||
763 | Some(Container::Trait(it)) => Some(it), | ||
764 | _ => None, | ||
765 | } | ||
766 | } | ||
767 | |||
768 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | ||
769 | match self.id.lookup(db).container { | ||
770 | ContainerId::TraitId(it) => Some(Container::Trait(it.into())), | ||
771 | ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), | ||
772 | ContainerId::ModuleId(_) => None, | ||
773 | } | ||
774 | } | ||
775 | |||
776 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { | 584 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { |
777 | db.type_alias_data(self.id).type_ref.clone() | 585 | db.type_alias_data(self.id).type_ref.clone() |
778 | } | 586 | } |
@@ -791,14 +599,6 @@ pub struct MacroDef { | |||
791 | pub(crate) id: MacroDefId, | 599 | pub(crate) id: MacroDefId, |
792 | } | 600 | } |
793 | 601 | ||
794 | impl MacroDef {} | ||
795 | |||
796 | pub enum Container { | ||
797 | Trait(Trait), | ||
798 | ImplBlock(ImplBlock), | ||
799 | } | ||
800 | impl_froms!(Container: Trait, ImplBlock); | ||
801 | |||
802 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 602 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
803 | pub enum AssocItem { | 603 | pub enum AssocItem { |
804 | Function(Function), | 604 | Function(Function), |
@@ -819,15 +619,6 @@ impl AssocItem { | |||
819 | AssocItem::TypeAlias(t) => t.module(db), | 619 | AssocItem::TypeAlias(t) => t.module(db), |
820 | } | 620 | } |
821 | } | 621 | } |
822 | |||
823 | pub fn container(self, db: &impl DefDatabase) -> Container { | ||
824 | match self { | ||
825 | AssocItem::Function(f) => f.container(db), | ||
826 | AssocItem::Const(c) => c.container(db), | ||
827 | AssocItem::TypeAlias(t) => t.container(db), | ||
828 | } | ||
829 | .expect("AssocItem without container") | ||
830 | } | ||
831 | } | 622 | } |
832 | 623 | ||
833 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 624 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
@@ -869,7 +660,7 @@ impl Local { | |||
869 | } | 660 | } |
870 | 661 | ||
871 | pub fn is_self(self, db: &impl HirDatabase) -> bool { | 662 | pub fn is_self(self, db: &impl HirDatabase) -> bool { |
872 | self.name(db) == Some(name::SELF_PARAM) | 663 | self.name(db) == Some(name![self]) |
873 | } | 664 | } |
874 | 665 | ||
875 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { | 666 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { |
@@ -901,18 +692,30 @@ impl Local { | |||
901 | Type { krate, ty: InEnvironment { value: ty, environment } } | 692 | Type { krate, ty: InEnvironment { value: ty, environment } } |
902 | } | 693 | } |
903 | 694 | ||
904 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | 695 | pub fn source(self, db: &impl HirDatabase) -> InFile<Either<ast::BindPat, ast::SelfParam>> { |
905 | let (_body, source_map) = db.body_with_source_map(self.parent.into()); | 696 | let (_body, source_map) = db.body_with_source_map(self.parent.into()); |
906 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... | 697 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... |
907 | let root = src.file_syntax(db); | 698 | let root = src.file_syntax(db); |
908 | src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) | 699 | src.map(|ast| { |
700 | ast.map_left(|it| it.cast().unwrap().to_node(&root)).map_right(|it| it.to_node(&root)) | ||
701 | }) | ||
909 | } | 702 | } |
910 | } | 703 | } |
911 | 704 | ||
912 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 705 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
913 | pub struct GenericParam { | 706 | pub struct TypeParam { |
914 | pub(crate) parent: GenericDefId, | 707 | pub(crate) id: TypeParamId, |
915 | pub(crate) idx: u32, | 708 | } |
709 | |||
710 | impl TypeParam { | ||
711 | pub fn name(self, db: &impl HirDatabase) -> Name { | ||
712 | let params = db.generic_params(self.id.parent); | ||
713 | params.types[self.id.local_id].name.clone() | ||
714 | } | ||
715 | |||
716 | pub fn module(self, db: &impl HirDatabase) -> Module { | ||
717 | self.id.parent.module(db).into() | ||
718 | } | ||
916 | } | 719 | } |
917 | 720 | ||
918 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 721 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -922,11 +725,11 @@ pub struct ImplBlock { | |||
922 | 725 | ||
923 | impl ImplBlock { | 726 | impl ImplBlock { |
924 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { | 727 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { |
925 | let impls = db.impls_in_crate(krate.crate_id); | 728 | let impls = db.impls_in_crate(krate.id); |
926 | impls.all_impls().map(Self::from).collect() | 729 | impls.all_impls().map(Self::from).collect() |
927 | } | 730 | } |
928 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { | 731 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { |
929 | let impls = db.impls_in_crate(krate.crate_id); | 732 | let impls = db.impls_in_crate(krate.id); |
930 | impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() | 733 | impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() |
931 | } | 734 | } |
932 | 735 | ||
@@ -943,7 +746,10 @@ impl ImplBlock { | |||
943 | let resolver = self.id.resolver(db); | 746 | let resolver = self.id.resolver(db); |
944 | let environment = TraitEnvironment::lower(db, &resolver); | 747 | let environment = TraitEnvironment::lower(db, &resolver); |
945 | let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); | 748 | let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); |
946 | Type { krate: self.id.module(db).krate, ty: InEnvironment { value: ty, environment } } | 749 | Type { |
750 | krate: self.id.lookup(db).container.module(db).krate, | ||
751 | ty: InEnvironment { value: ty, environment }, | ||
752 | } | ||
947 | } | 753 | } |
948 | 754 | ||
949 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | 755 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { |
@@ -955,11 +761,11 @@ impl ImplBlock { | |||
955 | } | 761 | } |
956 | 762 | ||
957 | pub fn module(&self, db: &impl DefDatabase) -> Module { | 763 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
958 | self.id.module(db).into() | 764 | self.id.lookup(db).container.module(db).into() |
959 | } | 765 | } |
960 | 766 | ||
961 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | 767 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { |
962 | Crate { crate_id: self.module(db).id.krate } | 768 | Crate { id: self.module(db).id.krate } |
963 | } | 769 | } |
964 | } | 770 | } |
965 | 771 | ||
@@ -970,15 +776,19 @@ pub struct Type { | |||
970 | } | 776 | } |
971 | 777 | ||
972 | impl Type { | 778 | impl Type { |
779 | fn new(db: &impl HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { | ||
780 | let resolver = lexical_env.resolver(db); | ||
781 | let environment = TraitEnvironment::lower(db, &resolver); | ||
782 | Type { krate, ty: InEnvironment { value: ty, environment } } | ||
783 | } | ||
784 | |||
973 | fn from_def( | 785 | fn from_def( |
974 | db: &impl HirDatabase, | 786 | db: &impl HirDatabase, |
975 | krate: CrateId, | 787 | krate: CrateId, |
976 | def: impl HasResolver + Into<TyDefId>, | 788 | def: impl HasResolver + Into<TyDefId>, |
977 | ) -> Type { | 789 | ) -> Type { |
978 | let resolver = def.resolver(db); | ||
979 | let environment = TraitEnvironment::lower(db, &resolver); | ||
980 | let ty = db.ty(def.into()); | 790 | let ty = db.ty(def.into()); |
981 | Type { krate, ty: InEnvironment { value: ty, environment } } | 791 | Type::new(db, krate, def, ty) |
982 | } | 792 | } |
983 | 793 | ||
984 | pub fn is_bool(&self) -> bool { | 794 | pub fn is_bool(&self) -> bool { |
@@ -1028,7 +838,7 @@ impl Type { | |||
1028 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { | 838 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { |
1029 | if let Ty::Apply(a_ty) = &self.ty.value { | 839 | if let Ty::Apply(a_ty) = &self.ty.value { |
1030 | match a_ty.ctor { | 840 | match a_ty.ctor { |
1031 | ty::TypeCtor::Adt(AdtId::StructId(s)) => { | 841 | TypeCtor::Adt(AdtId::StructId(s)) => { |
1032 | let var_def = s.into(); | 842 | let var_def = s.into(); |
1033 | return db | 843 | return db |
1034 | .field_types(var_def) | 844 | .field_types(var_def) |
@@ -1050,7 +860,7 @@ impl Type { | |||
1050 | let mut res = Vec::new(); | 860 | let mut res = Vec::new(); |
1051 | if let Ty::Apply(a_ty) = &self.ty.value { | 861 | if let Ty::Apply(a_ty) = &self.ty.value { |
1052 | match a_ty.ctor { | 862 | match a_ty.ctor { |
1053 | ty::TypeCtor::Tuple { .. } => { | 863 | TypeCtor::Tuple { .. } => { |
1054 | for ty in a_ty.parameters.iter() { | 864 | for ty in a_ty.parameters.iter() { |
1055 | let ty = ty.clone().subst(&a_ty.parameters); | 865 | let ty = ty.clone().subst(&a_ty.parameters); |
1056 | res.push(self.derived(ty)); | 866 | res.push(self.derived(ty)); |
@@ -1069,11 +879,16 @@ impl Type { | |||
1069 | ) -> Vec<(StructField, Type)> { | 879 | ) -> Vec<(StructField, Type)> { |
1070 | // FIXME: check that ty and def match | 880 | // FIXME: check that ty and def match |
1071 | match &self.ty.value { | 881 | match &self.ty.value { |
1072 | Ty::Apply(a_ty) => def | 882 | Ty::Apply(a_ty) => { |
1073 | .fields(db) | 883 | let field_types = db.field_types(def.into()); |
1074 | .into_iter() | 884 | def.fields(db) |
1075 | .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters)))) | 885 | .into_iter() |
1076 | .collect(), | 886 | .map(|it| { |
887 | let ty = field_types[it.id].clone().subst(&a_ty.parameters); | ||
888 | (it, self.derived(ty)) | ||
889 | }) | ||
890 | .collect() | ||
891 | } | ||
1077 | _ => Vec::new(), | 892 | _ => Vec::new(), |
1078 | } | 893 | } |
1079 | } | 894 | } |
@@ -1081,10 +896,10 @@ impl Type { | |||
1081 | pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { | 896 | pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { |
1082 | // There should be no inference vars in types passed here | 897 | // There should be no inference vars in types passed here |
1083 | // FIXME check that? | 898 | // FIXME check that? |
1084 | let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 }; | 899 | let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; |
1085 | let environment = self.ty.environment.clone(); | 900 | let environment = self.ty.environment.clone(); |
1086 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; | 901 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; |
1087 | ty::autoderef(db, Some(self.krate), ty) | 902 | autoderef(db, Some(self.krate), ty) |
1088 | .map(|canonical| canonical.value) | 903 | .map(|canonical| canonical.value) |
1089 | .map(move |ty| self.derived(ty)) | 904 | .map(move |ty| self.derived(ty)) |
1090 | } | 905 | } |
@@ -1097,7 +912,7 @@ impl Type { | |||
1097 | krate: Crate, | 912 | krate: Crate, |
1098 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 913 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
1099 | ) -> Option<T> { | 914 | ) -> Option<T> { |
1100 | for krate in self.ty.value.def_crates(db, krate.crate_id)? { | 915 | for krate in self.ty.value.def_crates(db, krate.id)? { |
1101 | let impls = db.impls_in_crate(krate); | 916 | let impls = db.impls_in_crate(krate); |
1102 | 917 | ||
1103 | for impl_block in impls.lookup_impl_blocks(&self.ty.value) { | 918 | for impl_block in impls.lookup_impl_blocks(&self.ty.value) { |
@@ -1111,11 +926,6 @@ impl Type { | |||
1111 | None | 926 | None |
1112 | } | 927 | } |
1113 | 928 | ||
1114 | // FIXME: remove | ||
1115 | pub fn into_ty(self) -> Ty { | ||
1116 | self.ty.value | ||
1117 | } | ||
1118 | |||
1119 | pub fn as_adt(&self) -> Option<Adt> { | 929 | pub fn as_adt(&self) -> Option<Adt> { |
1120 | let (adt, _subst) = self.ty.value.as_adt()?; | 930 | let (adt, _subst) = self.ty.value.as_adt()?; |
1121 | Some(adt.into()) | 931 | Some(adt.into()) |
@@ -1124,15 +934,14 @@ impl Type { | |||
1124 | // FIXME: provide required accessors such that it becomes implementable from outside. | 934 | // FIXME: provide required accessors such that it becomes implementable from outside. |
1125 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | 935 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { |
1126 | match (&self.ty.value, &other.ty.value) { | 936 | match (&self.ty.value, &other.ty.value) { |
1127 | (Ty::Apply(a_original_ty), Ty::Apply(ty::ApplicationTy { ctor, parameters })) => { | 937 | (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor |
1128 | match ctor { | 938 | { |
1129 | TypeCtor::Ref(..) => match parameters.as_single() { | 939 | TypeCtor::Ref(..) => match parameters.as_single() { |
1130 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, | 940 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, |
1131 | _ => false, | 941 | _ => false, |
1132 | }, | 942 | }, |
1133 | _ => a_original_ty.ctor == *ctor, | 943 | _ => a_original_ty.ctor == *ctor, |
1134 | } | 944 | }, |
1135 | } | ||
1136 | _ => false, | 945 | _ => false, |
1137 | } | 946 | } |
1138 | } | 947 | } |
@@ -1155,7 +964,7 @@ impl HirDisplay for Type { | |||
1155 | pub enum ScopeDef { | 964 | pub enum ScopeDef { |
1156 | ModuleDef(ModuleDef), | 965 | ModuleDef(ModuleDef), |
1157 | MacroDef(MacroDef), | 966 | MacroDef(MacroDef), |
1158 | GenericParam(GenericParam), | 967 | GenericParam(TypeParam), |
1159 | ImplSelfType(ImplBlock), | 968 | ImplSelfType(ImplBlock), |
1160 | AdtSelfType(Adt), | 969 | AdtSelfType(Adt), |
1161 | Local(Local), | 970 | Local(Local), |
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs deleted file mode 100644 index bf3ee0834..000000000 --- a/crates/ra_hir/src/code_model/src.rs +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId}; | ||
4 | use hir_expand::either::Either; | ||
5 | use ra_syntax::ast; | ||
6 | |||
7 | use crate::{ | ||
8 | db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef, | ||
9 | Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, | ||
10 | }; | ||
11 | |||
12 | pub use hir_expand::Source; | ||
13 | |||
14 | pub trait HasSource { | ||
15 | type Ast; | ||
16 | fn source(self, db: &impl DefDatabase) -> Source<Self::Ast>; | ||
17 | } | ||
18 | |||
19 | /// NB: Module is !HasSource, because it has two source nodes at the same time: | ||
20 | /// definition and declaration. | ||
21 | impl Module { | ||
22 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | ||
23 | pub fn definition_source(self, db: &impl DefDatabase) -> Source<ModuleSource> { | ||
24 | let def_map = db.crate_def_map(self.id.krate); | ||
25 | let src = def_map[self.id.local_id].definition_source(db); | ||
26 | src.map(|it| match it { | ||
27 | Either::A(it) => ModuleSource::SourceFile(it), | ||
28 | Either::B(it) => ModuleSource::Module(it), | ||
29 | }) | ||
30 | } | ||
31 | |||
32 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | ||
33 | /// `None` for the crate root. | ||
34 | pub fn declaration_source(self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { | ||
35 | let def_map = db.crate_def_map(self.id.krate); | ||
36 | def_map[self.id.local_id].declaration_source(db) | ||
37 | } | ||
38 | } | ||
39 | |||
40 | impl HasSource for StructField { | ||
41 | type Ast = FieldSource; | ||
42 | fn source(self, db: &impl DefDatabase) -> Source<FieldSource> { | ||
43 | let var = VariantId::from(self.parent); | ||
44 | let src = var.child_source(db); | ||
45 | src.map(|it| match it[self.id].clone() { | ||
46 | Either::A(it) => FieldSource::Pos(it), | ||
47 | Either::B(it) => FieldSource::Named(it), | ||
48 | }) | ||
49 | } | ||
50 | } | ||
51 | impl HasSource for Struct { | ||
52 | type Ast = ast::StructDef; | ||
53 | fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { | ||
54 | self.id.source(db) | ||
55 | } | ||
56 | } | ||
57 | impl HasSource for Union { | ||
58 | type Ast = ast::UnionDef; | ||
59 | fn source(self, db: &impl DefDatabase) -> Source<ast::UnionDef> { | ||
60 | self.id.source(db) | ||
61 | } | ||
62 | } | ||
63 | impl HasSource for Enum { | ||
64 | type Ast = ast::EnumDef; | ||
65 | fn source(self, db: &impl DefDatabase) -> Source<ast::EnumDef> { | ||
66 | self.id.source(db) | ||
67 | } | ||
68 | } | ||
69 | impl HasSource for EnumVariant { | ||
70 | type Ast = ast::EnumVariant; | ||
71 | fn source(self, db: &impl DefDatabase) -> Source<ast::EnumVariant> { | ||
72 | self.parent.id.child_source(db).map(|map| map[self.id].clone()) | ||
73 | } | ||
74 | } | ||
75 | impl HasSource for Function { | ||
76 | type Ast = ast::FnDef; | ||
77 | fn source(self, db: &impl DefDatabase) -> Source<ast::FnDef> { | ||
78 | self.id.lookup(db).source(db) | ||
79 | } | ||
80 | } | ||
81 | impl HasSource for Const { | ||
82 | type Ast = ast::ConstDef; | ||
83 | fn source(self, db: &impl DefDatabase) -> Source<ast::ConstDef> { | ||
84 | self.id.lookup(db).source(db) | ||
85 | } | ||
86 | } | ||
87 | impl HasSource for Static { | ||
88 | type Ast = ast::StaticDef; | ||
89 | fn source(self, db: &impl DefDatabase) -> Source<ast::StaticDef> { | ||
90 | self.id.lookup(db).source(db) | ||
91 | } | ||
92 | } | ||
93 | impl HasSource for Trait { | ||
94 | type Ast = ast::TraitDef; | ||
95 | fn source(self, db: &impl DefDatabase) -> Source<ast::TraitDef> { | ||
96 | self.id.source(db) | ||
97 | } | ||
98 | } | ||
99 | impl HasSource for TypeAlias { | ||
100 | type Ast = ast::TypeAliasDef; | ||
101 | fn source(self, db: &impl DefDatabase) -> Source<ast::TypeAliasDef> { | ||
102 | self.id.lookup(db).source(db) | ||
103 | } | ||
104 | } | ||
105 | impl HasSource for MacroDef { | ||
106 | type Ast = ast::MacroCall; | ||
107 | fn source(self, db: &impl DefDatabase) -> Source<ast::MacroCall> { | ||
108 | Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } | ||
109 | } | ||
110 | } | ||
111 | impl HasSource for ImplBlock { | ||
112 | type Ast = ast::ImplBlock; | ||
113 | fn source(self, db: &impl DefDatabase) -> Source<ast::ImplBlock> { | ||
114 | self.id.source(db) | ||
115 | } | ||
116 | } | ||
117 | impl HasSource for Import { | ||
118 | type Ast = Either<ast::UseTree, ast::ExternCrateItem>; | ||
119 | |||
120 | /// Returns the syntax of the last path segment corresponding to this import | ||
121 | fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> { | ||
122 | let src = self.parent.definition_source(db); | ||
123 | let (_, source_map) = db.raw_items_with_source_map(src.file_id); | ||
124 | let root = db.parse_or_expand(src.file_id).unwrap(); | ||
125 | let ptr = source_map.get(self.id); | ||
126 | src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root))) | ||
127 | } | ||
128 | } | ||
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index bfae3660b..f5ffd64fa 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -4,8 +4,8 @@ pub use hir_def::db::{ | |||
4 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, | 4 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, |
5 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, | 5 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, |
6 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, | 6 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, |
7 | LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery, | 7 | LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, StaticDataQuery, StructDataQuery, |
8 | StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, | 8 | TraitDataQuery, TypeAliasDataQuery, |
9 | }; | 9 | }; |
10 | pub use hir_expand::db::{ | 10 | pub use hir_expand::db::{ |
11 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 11 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs deleted file mode 100644 index 7a2810f71..000000000 --- a/crates/ra_hir/src/debug.rs +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | //! XXX: This does not work at the moment. | ||
2 | //! | ||
3 | //! printf debugging infrastructure for rust-analyzer. | ||
4 | //! | ||
5 | //! When you print a hir type, like a module, using `eprintln!("{:?}", module)`, | ||
6 | //! you usually get back a numeric ID, which doesn't tell you much: | ||
7 | //! `Module(92)`. | ||
8 | //! | ||
9 | //! This module adds convenience `debug` methods to various types, which resolve | ||
10 | //! the id to a human-readable location info: | ||
11 | //! | ||
12 | //! ```not_rust | ||
13 | //! eprintln!("{:?}", module.debug(db)); | ||
14 | //! => | ||
15 | //! Module { name: collections, path: "liballoc/collections/mod.rs" } | ||
16 | //! ``` | ||
17 | //! | ||
18 | //! Note that to get this info, we might need to execute queries! So | ||
19 | //! | ||
20 | //! * don't use the `debug` methods for logging | ||
21 | //! * when debugging, be aware that interference is possible. | ||
22 | |||
23 | use std::fmt; | ||
24 | |||
25 | use hir_expand::HirFileId; | ||
26 | use ra_db::{CrateId, FileId}; | ||
27 | |||
28 | use crate::{db::HirDatabase, Crate, Module, Name}; | ||
29 | |||
30 | impl Crate { | ||
31 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { | ||
32 | debug_fn(move |fmt| db.debug_crate(self, fmt)) | ||
33 | } | ||
34 | } | ||
35 | |||
36 | impl Module { | ||
37 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { | ||
38 | debug_fn(move |fmt| db.debug_module(self, fmt)) | ||
39 | } | ||
40 | } | ||
41 | |||
42 | pub trait HirDebugHelper: HirDatabase { | ||
43 | fn crate_name(&self, _krate: CrateId) -> Option<String> { | ||
44 | None | ||
45 | } | ||
46 | fn file_path(&self, _file_id: FileId) -> Option<String> { | ||
47 | None | ||
48 | } | ||
49 | } | ||
50 | |||
51 | pub trait HirDebugDatabase { | ||
52 | fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; | ||
53 | fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; | ||
54 | fn debug_hir_file_id(&self, file_id: HirFileId, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; | ||
55 | } | ||
56 | |||
57 | impl<DB: HirDebugHelper> HirDebugDatabase for DB { | ||
58 | fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
59 | let mut builder = fmt.debug_tuple("Crate"); | ||
60 | match self.crate_name(krate.crate_id) { | ||
61 | Some(name) => builder.field(&name), | ||
62 | None => builder.field(&krate.crate_id), | ||
63 | } | ||
64 | .finish() | ||
65 | } | ||
66 | |||
67 | fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
68 | let file_id = module.definition_source(self).file_id.original_file(self); | ||
69 | let path = self.file_path(file_id).unwrap_or_else(|| "N/A".to_string()); | ||
70 | fmt.debug_struct("Module") | ||
71 | .field("name", &module.name(self).unwrap_or_else(Name::missing)) | ||
72 | .field("path", &path) | ||
73 | .finish() | ||
74 | } | ||
75 | |||
76 | fn debug_hir_file_id(&self, file_id: HirFileId, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
77 | let original = file_id.original_file(self); | ||
78 | let path = self.file_path(original).unwrap_or_else(|| "N/A".to_string()); | ||
79 | let is_macro = file_id != original.into(); | ||
80 | fmt.debug_struct("HirFileId").field("path", &path).field("macro", &is_macro).finish() | ||
81 | } | ||
82 | } | ||
83 | |||
84 | fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug { | ||
85 | struct DebugFn<F>(F); | ||
86 | |||
87 | impl<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result> fmt::Debug for DebugFn<F> { | ||
88 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
89 | (&self.0)(fmt) | ||
90 | } | ||
91 | } | ||
92 | |||
93 | DebugFn(f) | ||
94 | } | ||
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index e96a18d12..75a1a7772 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -9,16 +9,10 @@ use hir_def::{ | |||
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | Adt, AssocItem, AttrDef, Crate, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField, | 12 | Adt, AssocItem, AttrDef, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField, |
13 | VariantDef, | 13 | VariantDef, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | impl From<ra_db::CrateId> for Crate { | ||
17 | fn from(crate_id: ra_db::CrateId) -> Self { | ||
18 | Crate { crate_id } | ||
19 | } | ||
20 | } | ||
21 | |||
22 | macro_rules! from_id { | 16 | macro_rules! from_id { |
23 | ($(($id:path, $ty:path)),*) => {$( | 17 | ($(($id:path, $ty:path)),*) => {$( |
24 | impl From<$id> for $ty { | 18 | impl From<$id> for $ty { |
@@ -26,10 +20,16 @@ macro_rules! from_id { | |||
26 | $ty { id } | 20 | $ty { id } |
27 | } | 21 | } |
28 | } | 22 | } |
23 | impl From<$ty> for $id { | ||
24 | fn from(ty: $ty) -> $id { | ||
25 | ty.id | ||
26 | } | ||
27 | } | ||
29 | )*} | 28 | )*} |
30 | } | 29 | } |
31 | 30 | ||
32 | from_id![ | 31 | from_id![ |
32 | (ra_db::CrateId, crate::Crate), | ||
33 | (hir_def::ModuleId, crate::Module), | 33 | (hir_def::ModuleId, crate::Module), |
34 | (hir_def::StructId, crate::Struct), | 34 | (hir_def::StructId, crate::Struct), |
35 | (hir_def::UnionId, crate::Union), | 35 | (hir_def::UnionId, crate::Union), |
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 9f7c22b21..6314be8d4 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -1,219 +1,140 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! Finds a corresponding hir data structure for a syntax node in a specific |
2 | //! file. | ||
2 | 3 | ||
3 | use hir_def::{AstItemDef, LocationCtx, ModuleId}; | 4 | use hir_def::{ |
5 | child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource, | ||
6 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, | ||
7 | StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, | ||
8 | }; | ||
4 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | 9 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; |
10 | use ra_db::FileId; | ||
11 | use ra_prof::profile; | ||
5 | use ra_syntax::{ | 12 | use ra_syntax::{ |
6 | ast::{self, AstNode, NameOwner}, | 13 | ast::{self, AstNode, NameOwner}, |
7 | match_ast, AstPtr, SyntaxNode, | 14 | match_ast, SyntaxNode, |
8 | }; | 15 | }; |
9 | 16 | ||
10 | use crate::{ | 17 | use crate::{ |
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 18 | db::{DefDatabase, HirDatabase}, |
12 | AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock, | 19 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local, |
13 | Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, StructField, Trait, | 20 | MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, |
14 | TypeAlias, Union, VariantDef, | ||
15 | }; | 21 | }; |
16 | 22 | ||
17 | pub trait FromSource: Sized { | 23 | pub trait FromSource: Sized { |
18 | type Ast; | 24 | type Ast; |
19 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>; | 25 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self>; |
20 | } | 26 | } |
21 | 27 | ||
22 | impl FromSource for Struct { | 28 | pub trait FromSourceByContainer: Sized { |
23 | type Ast = ast::StructDef; | 29 | type Ast: AstNode + 'static; |
24 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 30 | type Id: Copy + 'static; |
25 | let id = from_source(db, src)?; | 31 | const KEY: Key<Self::Ast, Self::Id>; |
26 | Some(Struct { id }) | ||
27 | } | ||
28 | } | ||
29 | impl FromSource for Union { | ||
30 | type Ast = ast::UnionDef; | ||
31 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | ||
32 | let id = from_source(db, src)?; | ||
33 | Some(Union { id }) | ||
34 | } | ||
35 | } | ||
36 | impl FromSource for Enum { | ||
37 | type Ast = ast::EnumDef; | ||
38 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | ||
39 | let id = from_source(db, src)?; | ||
40 | Some(Enum { id }) | ||
41 | } | ||
42 | } | ||
43 | impl FromSource for Trait { | ||
44 | type Ast = ast::TraitDef; | ||
45 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | ||
46 | let id = from_source(db, src)?; | ||
47 | Some(Trait { id }) | ||
48 | } | ||
49 | } | ||
50 | impl FromSource for Function { | ||
51 | type Ast = ast::FnDef; | ||
52 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | ||
53 | let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { | ||
54 | Container::Trait(it) => it.items(db), | ||
55 | Container::ImplBlock(it) => it.items(db), | ||
56 | Container::Module(m) => { | ||
57 | return m | ||
58 | .declarations(db) | ||
59 | .into_iter() | ||
60 | .filter_map(|it| match it { | ||
61 | ModuleDef::Function(it) => Some(it), | ||
62 | _ => None, | ||
63 | }) | ||
64 | .find(|it| same_source(&it.source(db), &src)) | ||
65 | } | ||
66 | }; | ||
67 | items | ||
68 | .into_iter() | ||
69 | .filter_map(|it| match it { | ||
70 | AssocItem::Function(it) => Some(it), | ||
71 | _ => None, | ||
72 | }) | ||
73 | .find(|it| same_source(&it.source(db), &src)) | ||
74 | } | ||
75 | } | 32 | } |
76 | 33 | ||
77 | impl FromSource for Const { | 34 | impl<T: FromSourceByContainer> FromSource for T |
78 | type Ast = ast::ConstDef; | 35 | where |
79 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 36 | T: From<<T as FromSourceByContainer>::Id>, |
80 | let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { | 37 | { |
81 | Container::Trait(it) => it.items(db), | 38 | type Ast = <T as FromSourceByContainer>::Ast; |
82 | Container::ImplBlock(it) => it.items(db), | 39 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { |
83 | Container::Module(m) => { | 40 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY] |
84 | return m | 41 | .get(&src) |
85 | .declarations(db) | 42 | .copied() |
86 | .into_iter() | 43 | .map(Self::from) |
87 | .filter_map(|it| match it { | ||
88 | ModuleDef::Const(it) => Some(it), | ||
89 | _ => None, | ||
90 | }) | ||
91 | .find(|it| same_source(&it.source(db), &src)) | ||
92 | } | ||
93 | }; | ||
94 | items | ||
95 | .into_iter() | ||
96 | .filter_map(|it| match it { | ||
97 | AssocItem::Const(it) => Some(it), | ||
98 | _ => None, | ||
99 | }) | ||
100 | .find(|it| same_source(&it.source(db), &src)) | ||
101 | } | ||
102 | } | ||
103 | impl FromSource for Static { | ||
104 | type Ast = ast::StaticDef; | ||
105 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | ||
106 | let module = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { | ||
107 | Container::Module(it) => it, | ||
108 | Container::Trait(_) | Container::ImplBlock(_) => return None, | ||
109 | }; | ||
110 | module | ||
111 | .declarations(db) | ||
112 | .into_iter() | ||
113 | .filter_map(|it| match it { | ||
114 | ModuleDef::Static(it) => Some(it), | ||
115 | _ => None, | ||
116 | }) | ||
117 | .find(|it| same_source(&it.source(db), &src)) | ||
118 | } | 44 | } |
119 | } | 45 | } |
120 | 46 | ||
121 | impl FromSource for TypeAlias { | 47 | macro_rules! from_source_by_container_impls { |
122 | type Ast = ast::TypeAliasDef; | 48 | ($(($hir:ident, $id:ident, $ast:path, $key:path)),* ,) => {$( |
123 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 49 | impl FromSourceByContainer for $hir { |
124 | let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { | 50 | type Ast = $ast; |
125 | Container::Trait(it) => it.items(db), | 51 | type Id = $id; |
126 | Container::ImplBlock(it) => it.items(db), | 52 | const KEY: Key<Self::Ast, Self::Id> = $key; |
127 | Container::Module(m) => { | 53 | } |
128 | return m | 54 | )*} |
129 | .declarations(db) | ||
130 | .into_iter() | ||
131 | .filter_map(|it| match it { | ||
132 | ModuleDef::TypeAlias(it) => Some(it), | ||
133 | _ => None, | ||
134 | }) | ||
135 | .find(|it| same_source(&it.source(db), &src)) | ||
136 | } | ||
137 | }; | ||
138 | items | ||
139 | .into_iter() | ||
140 | .filter_map(|it| match it { | ||
141 | AssocItem::TypeAlias(it) => Some(it), | ||
142 | _ => None, | ||
143 | }) | ||
144 | .find(|it| same_source(&it.source(db), &src)) | ||
145 | } | ||
146 | } | 55 | } |
147 | 56 | ||
57 | from_source_by_container_impls![ | ||
58 | (Struct, StructId, ast::StructDef, keys::STRUCT), | ||
59 | (Union, UnionId, ast::UnionDef, keys::UNION), | ||
60 | (Enum, EnumId, ast::EnumDef, keys::ENUM), | ||
61 | (Trait, TraitId, ast::TraitDef, keys::TRAIT), | ||
62 | (Function, FunctionId, ast::FnDef, keys::FUNCTION), | ||
63 | (Static, StaticId, ast::StaticDef, keys::STATIC), | ||
64 | (Const, ConstId, ast::ConstDef, keys::CONST), | ||
65 | (TypeAlias, TypeAliasId, ast::TypeAliasDef, keys::TYPE_ALIAS), | ||
66 | (ImplBlock, ImplId, ast::ImplBlock, keys::IMPL), | ||
67 | ]; | ||
68 | |||
148 | impl FromSource for MacroDef { | 69 | impl FromSource for MacroDef { |
149 | type Ast = ast::MacroCall; | 70 | type Ast = ast::MacroCall; |
150 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 71 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { |
151 | let kind = MacroDefKind::Declarative; | 72 | let kind = MacroDefKind::Declarative; |
152 | 73 | ||
153 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); | 74 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); |
154 | let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; | 75 | let module = Module::from_definition(db, InFile::new(src.file_id, module_src))?; |
155 | let krate = module.krate().crate_id(); | 76 | let krate = Some(module.krate().id); |
156 | 77 | ||
157 | let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value)); | 78 | let ast_id = Some(AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value))); |
158 | 79 | ||
159 | let id: MacroDefId = MacroDefId { krate, ast_id, kind }; | 80 | let id: MacroDefId = MacroDefId { krate, ast_id, kind }; |
160 | Some(MacroDef { id }) | 81 | Some(MacroDef { id }) |
161 | } | 82 | } |
162 | } | 83 | } |
163 | 84 | ||
164 | impl FromSource for ImplBlock { | ||
165 | type Ast = ast::ImplBlock; | ||
166 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | ||
167 | let id = from_source(db, src)?; | ||
168 | Some(ImplBlock { id }) | ||
169 | } | ||
170 | } | ||
171 | |||
172 | impl FromSource for EnumVariant { | 85 | impl FromSource for EnumVariant { |
173 | type Ast = ast::EnumVariant; | 86 | type Ast = ast::EnumVariant; |
174 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 87 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { |
175 | let parent_enum = src.value.parent_enum(); | 88 | let parent_enum = src.value.parent_enum(); |
176 | let src_enum = Source { file_id: src.file_id, value: parent_enum }; | 89 | let src_enum = InFile { file_id: src.file_id, value: parent_enum }; |
177 | let variants = Enum::from_source(db, src_enum)?.variants(db); | 90 | let parent_enum = Enum::from_source(db, src_enum)?; |
178 | variants.into_iter().find(|v| same_source(&v.source(db), &src)) | 91 | parent_enum.id.child_by_source(db)[keys::ENUM_VARIANT] |
92 | .get(&src) | ||
93 | .copied() | ||
94 | .map(EnumVariant::from) | ||
179 | } | 95 | } |
180 | } | 96 | } |
181 | 97 | ||
182 | impl FromSource for StructField { | 98 | impl FromSource for StructField { |
183 | type Ast = FieldSource; | 99 | type Ast = FieldSource; |
184 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 100 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { |
185 | let variant_def: VariantDef = match src.value { | 101 | let src = src.as_ref(); |
186 | FieldSource::Named(ref field) => { | 102 | |
103 | // FIXME this is buggy | ||
104 | let variant_id: VariantId = match src.value { | ||
105 | FieldSource::Named(field) => { | ||
187 | let value = field.syntax().ancestors().find_map(ast::StructDef::cast)?; | 106 | let value = field.syntax().ancestors().find_map(ast::StructDef::cast)?; |
188 | let src = Source { file_id: src.file_id, value }; | 107 | let src = InFile { file_id: src.file_id, value }; |
189 | let def = Struct::from_source(db, src)?; | 108 | let def = Struct::from_source(db, src)?; |
190 | VariantDef::from(def) | 109 | def.id.into() |
191 | } | 110 | } |
192 | FieldSource::Pos(ref field) => { | 111 | FieldSource::Pos(field) => { |
193 | let value = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; | 112 | let value = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; |
194 | let src = Source { file_id: src.file_id, value }; | 113 | let src = InFile { file_id: src.file_id, value }; |
195 | let def = EnumVariant::from_source(db, src)?; | 114 | let def = EnumVariant::from_source(db, src)?; |
196 | VariantDef::from(def) | 115 | EnumVariantId::from(def).into() |
197 | } | 116 | } |
198 | }; | 117 | }; |
199 | variant_def | 118 | |
200 | .variant_data(db) | 119 | let dyn_map = variant_id.child_by_source(db); |
201 | .fields() | 120 | match src.value { |
202 | .iter() | 121 | FieldSource::Pos(it) => dyn_map[keys::TUPLE_FIELD].get(&src.with_value(it.clone())), |
203 | .map(|(id, _)| StructField { parent: variant_def, id }) | 122 | FieldSource::Named(it) => dyn_map[keys::RECORD_FIELD].get(&src.with_value(it.clone())), |
204 | .find(|f| f.source(db) == src) | 123 | } |
124 | .copied() | ||
125 | .map(StructField::from) | ||
205 | } | 126 | } |
206 | } | 127 | } |
207 | 128 | ||
208 | impl Local { | 129 | impl Local { |
209 | pub fn from_source(db: &impl HirDatabase, src: Source<ast::BindPat>) -> Option<Self> { | 130 | pub fn from_source(db: &impl HirDatabase, src: InFile<ast::BindPat>) -> Option<Self> { |
210 | let file_id = src.file_id; | 131 | let file_id = src.file_id; |
211 | let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| { | 132 | let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| { |
212 | let res = match_ast! { | 133 | let res = match_ast! { |
213 | match it { | 134 | match it { |
214 | ast::ConstDef(value) => { Const::from_source(db, Source { value, file_id})?.into() }, | 135 | ast::ConstDef(value) => { Const::from_source(db, InFile { value, file_id})?.into() }, |
215 | ast::StaticDef(value) => { Static::from_source(db, Source { value, file_id})?.into() }, | 136 | ast::StaticDef(value) => { Static::from_source(db, InFile { value, file_id})?.into() }, |
216 | ast::FnDef(value) => { Function::from_source(db, Source { value, file_id})?.into() }, | 137 | ast::FnDef(value) => { Function::from_source(db, InFile { value, file_id})?.into() }, |
217 | _ => return None, | 138 | _ => return None, |
218 | } | 139 | } |
219 | }; | 140 | }; |
@@ -226,84 +147,111 @@ impl Local { | |||
226 | } | 147 | } |
227 | } | 148 | } |
228 | 149 | ||
150 | impl TypeParam { | ||
151 | pub fn from_source(db: &impl HirDatabase, src: InFile<ast::TypeParam>) -> Option<Self> { | ||
152 | let file_id = src.file_id; | ||
153 | let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| { | ||
154 | let res = match_ast! { | ||
155 | match it { | ||
156 | ast::FnDef(value) => { Function::from_source(db, InFile { value, file_id})?.id.into() }, | ||
157 | ast::StructDef(value) => { Struct::from_source(db, InFile { value, file_id})?.id.into() }, | ||
158 | ast::EnumDef(value) => { Enum::from_source(db, InFile { value, file_id})?.id.into() }, | ||
159 | ast::TraitDef(value) => { Trait::from_source(db, InFile { value, file_id})?.id.into() }, | ||
160 | ast::TypeAliasDef(value) => { TypeAlias::from_source(db, InFile { value, file_id})?.id.into() }, | ||
161 | ast::ImplBlock(value) => { ImplBlock::from_source(db, InFile { value, file_id})?.id.into() }, | ||
162 | _ => return None, | ||
163 | } | ||
164 | }; | ||
165 | Some(res) | ||
166 | })?; | ||
167 | let &id = parent.child_by_source(db)[keys::TYPE_PARAM].get(&src)?; | ||
168 | Some(TypeParam { id }) | ||
169 | } | ||
170 | } | ||
171 | |||
229 | impl Module { | 172 | impl Module { |
230 | pub fn from_declaration(db: &impl DefDatabase, src: Source<ast::Module>) -> Option<Self> { | 173 | pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> { |
174 | let _p = profile("Module::from_declaration"); | ||
231 | let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); | 175 | let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); |
232 | 176 | ||
233 | let parent_module = match parent_declaration { | 177 | let parent_module = match parent_declaration { |
234 | Some(parent_declaration) => { | 178 | Some(parent_declaration) => { |
235 | let src_parent = Source { file_id: src.file_id, value: parent_declaration }; | 179 | let src_parent = InFile { file_id: src.file_id, value: parent_declaration }; |
236 | Module::from_declaration(db, src_parent) | 180 | Module::from_declaration(db, src_parent) |
237 | } | 181 | } |
238 | _ => { | 182 | None => { |
239 | let src_parent = Source { | 183 | let source_file = db.parse(src.file_id.original_file(db)).tree(); |
240 | file_id: src.file_id, | 184 | let src_parent = |
241 | value: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), | 185 | InFile { file_id: src.file_id, value: ModuleSource::SourceFile(source_file) }; |
242 | }; | ||
243 | Module::from_definition(db, src_parent) | 186 | Module::from_definition(db, src_parent) |
244 | } | 187 | } |
245 | }?; | 188 | }?; |
246 | 189 | ||
247 | let child_name = src.value.name()?; | 190 | let child_name = src.value.name()?.as_name(); |
248 | parent_module.child(db, &child_name.as_name()) | 191 | let def_map = db.crate_def_map(parent_module.id.krate); |
192 | let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?; | ||
193 | Some(parent_module.with_module_id(*child_id)) | ||
249 | } | 194 | } |
250 | 195 | ||
251 | pub fn from_definition(db: &impl DefDatabase, src: Source<ModuleSource>) -> Option<Self> { | 196 | pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> { |
197 | let _p = profile("Module::from_definition"); | ||
252 | match src.value { | 198 | match src.value { |
253 | ModuleSource::Module(ref module) => { | 199 | ModuleSource::Module(ref module) => { |
254 | assert!(!module.has_semi()); | 200 | assert!(!module.has_semi()); |
255 | return Module::from_declaration( | 201 | return Module::from_declaration( |
256 | db, | 202 | db, |
257 | Source { file_id: src.file_id, value: module.clone() }, | 203 | InFile { file_id: src.file_id, value: module.clone() }, |
258 | ); | 204 | ); |
259 | } | 205 | } |
260 | ModuleSource::SourceFile(_) => (), | 206 | ModuleSource::SourceFile(_) => (), |
261 | }; | 207 | }; |
262 | 208 | ||
263 | let original_file = src.file_id.original_file(db); | 209 | let original_file = src.file_id.original_file(db); |
210 | Module::from_file(db, original_file) | ||
211 | } | ||
264 | 212 | ||
265 | let (krate, local_id) = db.relevant_crates(original_file).iter().find_map(|&crate_id| { | 213 | fn from_file(db: &impl DefDatabase, file: FileId) -> Option<Self> { |
214 | let _p = profile("Module::from_file"); | ||
215 | let (krate, local_id) = db.relevant_crates(file).iter().find_map(|&crate_id| { | ||
266 | let crate_def_map = db.crate_def_map(crate_id); | 216 | let crate_def_map = db.crate_def_map(crate_id); |
267 | let local_id = crate_def_map.modules_for_file(original_file).next()?; | 217 | let local_id = crate_def_map.modules_for_file(file).next()?; |
268 | Some((crate_id, local_id)) | 218 | Some((crate_id, local_id)) |
269 | })?; | 219 | })?; |
270 | Some(Module { id: ModuleId { krate, local_id } }) | 220 | Some(Module { id: ModuleId { krate, local_id } }) |
271 | } | 221 | } |
272 | } | 222 | } |
273 | 223 | ||
274 | fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: Source<N>) -> Option<DEF> | 224 | fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { |
275 | where | 225 | let _p = profile("analyze_container"); |
276 | N: AstNode, | 226 | return child_by_source(db, src).unwrap_or_default(); |
277 | DEF: AstItemDef<N>, | ||
278 | { | ||
279 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); | ||
280 | let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; | ||
281 | let ctx = LocationCtx::new(db, module.id, src.file_id); | ||
282 | let items = db.ast_id_map(src.file_id); | ||
283 | let item_id = items.ast_id(&src.value); | ||
284 | Some(DEF::from_ast_id(ctx, item_id)) | ||
285 | } | ||
286 | |||
287 | enum Container { | ||
288 | Trait(Trait), | ||
289 | ImplBlock(ImplBlock), | ||
290 | Module(Module), | ||
291 | } | ||
292 | 227 | ||
293 | impl Container { | 228 | fn child_by_source(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> { |
294 | fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option<Container> { | 229 | for container in src.value.ancestors().skip(1) { |
295 | // FIXME: this doesn't try to handle nested declarations | ||
296 | for container in src.value.ancestors() { | ||
297 | let res = match_ast! { | 230 | let res = match_ast! { |
298 | match container { | 231 | match container { |
299 | ast::TraitDef(it) => { | 232 | ast::TraitDef(it) => { |
300 | let c = Trait::from_source(db, src.with_value(it))?; | 233 | let def = Trait::from_source(db, src.with_value(it))?; |
301 | Container::Trait(c) | 234 | def.id.child_by_source(db) |
302 | }, | 235 | }, |
303 | ast::ImplBlock(it) => { | 236 | ast::ImplBlock(it) => { |
304 | let c = ImplBlock::from_source(db, src.with_value(it))?; | 237 | let def = ImplBlock::from_source(db, src.with_value(it))?; |
305 | Container::ImplBlock(c) | 238 | def.id.child_by_source(db) |
306 | }, | 239 | }, |
240 | ast::FnDef(it) => { | ||
241 | let def = Function::from_source(db, src.with_value(it))?; | ||
242 | DefWithBodyId::from(def.id) | ||
243 | .child_by_source(db) | ||
244 | }, | ||
245 | ast::StaticDef(it) => { | ||
246 | let def = Static::from_source(db, src.with_value(it))?; | ||
247 | DefWithBodyId::from(def.id) | ||
248 | .child_by_source(db) | ||
249 | }, | ||
250 | ast::ConstDef(it) => { | ||
251 | let def = Const::from_source(db, src.with_value(it))?; | ||
252 | DefWithBodyId::from(def.id) | ||
253 | .child_by_source(db) | ||
254 | }, | ||
307 | _ => { continue }, | 255 | _ => { continue }, |
308 | } | 256 | } |
309 | }; | 257 | }; |
@@ -312,16 +260,6 @@ impl Container { | |||
312 | 260 | ||
313 | let module_source = ModuleSource::from_child_node(db, src); | 261 | let module_source = ModuleSource::from_child_node(db, src); |
314 | let c = Module::from_definition(db, src.with_value(module_source))?; | 262 | let c = Module::from_definition(db, src.with_value(module_source))?; |
315 | Some(Container::Module(c)) | 263 | Some(c.id.child_by_source(db)) |
316 | } | 264 | } |
317 | } | 265 | } |
318 | |||
319 | /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are | ||
320 | /// equal if they point to exactly the same object. | ||
321 | /// | ||
322 | /// In general, we do not guarantee that we have exactly one instance of a | ||
323 | /// syntax tree for each file. We probably should add such guarantee, but, for | ||
324 | /// the time being, we will use identity-less AstPtr comparison. | ||
325 | fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool { | ||
326 | s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new) | ||
327 | } | ||
diff --git a/crates/ra_hir/src/has_source.rs b/crates/ra_hir/src/has_source.rs new file mode 100644 index 000000000..5541266e2 --- /dev/null +++ b/crates/ra_hir/src/has_source.rs | |||
@@ -0,0 +1,127 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use either::Either; | ||
4 | use hir_def::{ | ||
5 | nameres::ModuleSource, | ||
6 | src::{HasChildSource, HasSource as _}, | ||
7 | Lookup, VariantId, | ||
8 | }; | ||
9 | use ra_syntax::ast; | ||
10 | |||
11 | use crate::{ | ||
12 | db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, MacroDef, Module, | ||
13 | Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, | ||
14 | }; | ||
15 | |||
16 | pub use hir_expand::InFile; | ||
17 | |||
18 | pub trait HasSource { | ||
19 | type Ast; | ||
20 | fn source(self, db: &impl DefDatabase) -> InFile<Self::Ast>; | ||
21 | } | ||
22 | |||
23 | /// NB: Module is !HasSource, because it has two source nodes at the same time: | ||
24 | /// definition and declaration. | ||
25 | impl Module { | ||
26 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | ||
27 | pub fn definition_source(self, db: &impl DefDatabase) -> InFile<ModuleSource> { | ||
28 | let def_map = db.crate_def_map(self.id.krate); | ||
29 | def_map[self.id.local_id].definition_source(db) | ||
30 | } | ||
31 | |||
32 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | ||
33 | /// `None` for the crate root. | ||
34 | pub fn declaration_source(self, db: &impl DefDatabase) -> Option<InFile<ast::Module>> { | ||
35 | let def_map = db.crate_def_map(self.id.krate); | ||
36 | def_map[self.id.local_id].declaration_source(db) | ||
37 | } | ||
38 | } | ||
39 | |||
40 | impl HasSource for StructField { | ||
41 | type Ast = FieldSource; | ||
42 | fn source(self, db: &impl DefDatabase) -> InFile<FieldSource> { | ||
43 | let var = VariantId::from(self.parent); | ||
44 | let src = var.child_source(db); | ||
45 | src.map(|it| match it[self.id].clone() { | ||
46 | Either::Left(it) => FieldSource::Pos(it), | ||
47 | Either::Right(it) => FieldSource::Named(it), | ||
48 | }) | ||
49 | } | ||
50 | } | ||
51 | impl HasSource for Struct { | ||
52 | type Ast = ast::StructDef; | ||
53 | fn source(self, db: &impl DefDatabase) -> InFile<ast::StructDef> { | ||
54 | self.id.lookup(db).source(db) | ||
55 | } | ||
56 | } | ||
57 | impl HasSource for Union { | ||
58 | type Ast = ast::UnionDef; | ||
59 | fn source(self, db: &impl DefDatabase) -> InFile<ast::UnionDef> { | ||
60 | self.id.lookup(db).source(db) | ||
61 | } | ||
62 | } | ||
63 | impl HasSource for Enum { | ||
64 | type Ast = ast::EnumDef; | ||
65 | fn source(self, db: &impl DefDatabase) -> InFile<ast::EnumDef> { | ||
66 | self.id.lookup(db).source(db) | ||
67 | } | ||
68 | } | ||
69 | impl HasSource for EnumVariant { | ||
70 | type Ast = ast::EnumVariant; | ||
71 | fn source(self, db: &impl DefDatabase) -> InFile<ast::EnumVariant> { | ||
72 | self.parent.id.child_source(db).map(|map| map[self.id].clone()) | ||
73 | } | ||
74 | } | ||
75 | impl HasSource for Function { | ||
76 | type Ast = ast::FnDef; | ||
77 | fn source(self, db: &impl DefDatabase) -> InFile<ast::FnDef> { | ||
78 | self.id.lookup(db).source(db) | ||
79 | } | ||
80 | } | ||
81 | impl HasSource for Const { | ||
82 | type Ast = ast::ConstDef; | ||
83 | fn source(self, db: &impl DefDatabase) -> InFile<ast::ConstDef> { | ||
84 | self.id.lookup(db).source(db) | ||
85 | } | ||
86 | } | ||
87 | impl HasSource for Static { | ||
88 | type Ast = ast::StaticDef; | ||
89 | fn source(self, db: &impl DefDatabase) -> InFile<ast::StaticDef> { | ||
90 | self.id.lookup(db).source(db) | ||
91 | } | ||
92 | } | ||
93 | impl HasSource for Trait { | ||
94 | type Ast = ast::TraitDef; | ||
95 | fn source(self, db: &impl DefDatabase) -> InFile<ast::TraitDef> { | ||
96 | self.id.lookup(db).source(db) | ||
97 | } | ||
98 | } | ||
99 | impl HasSource for TypeAlias { | ||
100 | type Ast = ast::TypeAliasDef; | ||
101 | fn source(self, db: &impl DefDatabase) -> InFile<ast::TypeAliasDef> { | ||
102 | self.id.lookup(db).source(db) | ||
103 | } | ||
104 | } | ||
105 | impl HasSource for MacroDef { | ||
106 | type Ast = ast::MacroCall; | ||
107 | fn source(self, db: &impl DefDatabase) -> InFile<ast::MacroCall> { | ||
108 | InFile { | ||
109 | file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id, | ||
110 | value: self.id.ast_id.expect("MacroDef without ast_id").to_node(db), | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | impl HasSource for ImplBlock { | ||
115 | type Ast = ast::ImplBlock; | ||
116 | fn source(self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> { | ||
117 | self.id.lookup(db).source(db) | ||
118 | } | ||
119 | } | ||
120 | |||
121 | impl HasSource for TypeParam { | ||
122 | type Ast = Either<ast::TraitDef, ast::TypeParam>; | ||
123 | fn source(self, db: &impl DefDatabase) -> InFile<Self::Ast> { | ||
124 | let child_source = self.id.parent.child_source(db); | ||
125 | child_source.map(|it| it[self.id.local_id].clone()) | ||
126 | } | ||
127 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 3c12c61f0..0008a8858 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -26,42 +26,38 @@ macro_rules! impl_froms { | |||
26 | } | 26 | } |
27 | } | 27 | } |
28 | 28 | ||
29 | pub mod debug; | ||
30 | |||
31 | pub mod db; | 29 | pub mod db; |
32 | pub mod source_binder; | 30 | pub mod source_binder; |
33 | 31 | ||
34 | mod ty; | ||
35 | pub mod diagnostics; | 32 | pub mod diagnostics; |
36 | 33 | ||
37 | mod from_id; | 34 | mod from_id; |
38 | mod code_model; | 35 | mod code_model; |
39 | 36 | ||
40 | pub mod from_source; | 37 | mod has_source; |
38 | mod from_source; | ||
41 | 39 | ||
42 | pub use crate::{ | 40 | pub use crate::{ |
43 | code_model::{ | 41 | code_model::{ |
44 | src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, | 42 | Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, |
45 | DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam, | 43 | EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Local, MacroDef, |
46 | HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, | 44 | Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, |
47 | Static, Struct, StructField, Trait, Type, TypeAlias, Union, VariantDef, | 45 | TypeParam, Union, VariantDef, |
48 | }, | 46 | }, |
49 | from_source::FromSource, | 47 | from_source::FromSource, |
48 | has_source::HasSource, | ||
50 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 49 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
51 | ty::{ | ||
52 | display::HirDisplay, | ||
53 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, | ||
54 | ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | ||
55 | }, | ||
56 | }; | 50 | }; |
57 | 51 | ||
58 | pub use hir_def::{ | 52 | pub use hir_def::{ |
59 | body::scope::ExprScopes, | 53 | body::scope::ExprScopes, |
60 | builtin_type::BuiltinType, | 54 | builtin_type::BuiltinType, |
61 | docs::Documentation, | 55 | docs::Documentation, |
62 | path::{Path, PathKind}, | 56 | nameres::ModuleSource, |
57 | path::{ModPath, Path, PathKind}, | ||
63 | type_ref::Mutability, | 58 | type_ref::Mutability, |
64 | }; | 59 | }; |
65 | pub use hir_expand::{ | 60 | pub use hir_expand::{ |
66 | either::Either, name::Name, HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Source, | 61 | name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, |
67 | }; | 62 | }; |
63 | pub use hir_ty::{display::HirDisplay, CallableDef}; | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 76c493f1a..85b378483 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -7,19 +7,26 @@ | |||
7 | //! purely for "IDE needs". | 7 | //! purely for "IDE needs". |
8 | use std::sync::Arc; | 8 | use std::sync::Arc; |
9 | 9 | ||
10 | use either::Either; | ||
10 | use hir_def::{ | 11 | use hir_def::{ |
11 | body::{ | 12 | body::{ |
12 | scope::{ExprScopes, ScopeId}, | 13 | scope::{ExprScopes, ScopeId}, |
13 | BodySourceMap, | 14 | BodySourceMap, |
14 | }, | 15 | }, |
15 | expr::{ExprId, PatId}, | 16 | expr::{ExprId, PatId}, |
16 | path::known, | 17 | nameres::ModuleSource, |
18 | path::path, | ||
17 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, | 19 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, |
18 | AssocItemId, DefWithBodyId, | 20 | AssocItemId, DefWithBodyId, |
19 | }; | 21 | }; |
20 | use hir_expand::{ | 22 | use hir_expand::{ |
21 | hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, | 23 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, |
22 | }; | 24 | }; |
25 | use hir_ty::{ | ||
26 | method_resolution::{self, implements_trait}, | ||
27 | Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty, | ||
28 | }; | ||
29 | use ra_prof::profile; | ||
23 | use ra_syntax::{ | 30 | use ra_syntax::{ |
24 | ast::{self, AstNode}, | 31 | ast::{self, AstNode}, |
25 | match_ast, AstPtr, | 32 | match_ast, AstPtr, |
@@ -28,16 +35,12 @@ use ra_syntax::{ | |||
28 | }; | 35 | }; |
29 | 36 | ||
30 | use crate::{ | 37 | use crate::{ |
31 | db::HirDatabase, | 38 | db::HirDatabase, Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, |
32 | ty::{ | 39 | ImplBlock, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, |
33 | method_resolution::{self, implements_trait}, | 40 | TypeParam, |
34 | InEnvironment, TraitEnvironment, Ty, | ||
35 | }, | ||
36 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, | ||
37 | GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, | ||
38 | }; | 41 | }; |
39 | 42 | ||
40 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 43 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> { |
41 | match_ast! { | 44 | match_ast! { |
42 | match (node.value) { | 45 | match (node.value) { |
43 | ast::Module(it) => { | 46 | ast::Module(it) => { |
@@ -45,7 +48,7 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - | |||
45 | Some(crate::Module::from_declaration(db, src)?.id.resolver(db)) | 48 | Some(crate::Module::from_declaration(db, src)?.id.resolver(db)) |
46 | }, | 49 | }, |
47 | ast::SourceFile(it) => { | 50 | ast::SourceFile(it) => { |
48 | let src = node.with_value(crate::ModuleSource::SourceFile(it)); | 51 | let src = node.with_value(ModuleSource::SourceFile(it)); |
49 | Some(crate::Module::from_definition(db, src)?.id.resolver(db)) | 52 | Some(crate::Module::from_definition(db, src)?.id.resolver(db)) |
50 | }, | 53 | }, |
51 | ast::StructDef(it) => { | 54 | ast::StructDef(it) => { |
@@ -56,6 +59,14 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - | |||
56 | let src = node.with_value(it); | 59 | let src = node.with_value(it); |
57 | Some(Enum::from_source(db, src)?.id.resolver(db)) | 60 | Some(Enum::from_source(db, src)?.id.resolver(db)) |
58 | }, | 61 | }, |
62 | ast::ImplBlock(it) => { | ||
63 | let src = node.with_value(it); | ||
64 | Some(ImplBlock::from_source(db, src)?.id.resolver(db)) | ||
65 | }, | ||
66 | ast::TraitDef(it) => { | ||
67 | let src = node.with_value(it); | ||
68 | Some(Trait::from_source(db, src)?.id.resolver(db)) | ||
69 | }, | ||
59 | _ => match node.value.kind() { | 70 | _ => match node.value.kind() { |
60 | FN_DEF | CONST_DEF | STATIC_DEF => { | 71 | FN_DEF | CONST_DEF | STATIC_DEF => { |
61 | let def = def_with_body_from_child_node(db, node)?; | 72 | let def = def_with_body_from_child_node(db, node)?; |
@@ -71,14 +82,16 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - | |||
71 | 82 | ||
72 | fn def_with_body_from_child_node( | 83 | fn def_with_body_from_child_node( |
73 | db: &impl HirDatabase, | 84 | db: &impl HirDatabase, |
74 | child: Source<&SyntaxNode>, | 85 | child: InFile<&SyntaxNode>, |
75 | ) -> Option<DefWithBody> { | 86 | ) -> Option<DefWithBody> { |
76 | child.value.ancestors().find_map(|node| { | 87 | let _p = profile("def_with_body_from_child_node"); |
88 | child.cloned().ancestors_with_macros(db).find_map(|node| { | ||
89 | let n = &node.value; | ||
77 | match_ast! { | 90 | match_ast! { |
78 | match node { | 91 | match n { |
79 | ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, | 92 | ast::FnDef(def) => { return Function::from_source(db, node.with_value(def)).map(DefWithBody::from); }, |
80 | ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, | 93 | ast::ConstDef(def) => { return Const::from_source(db, node.with_value(def)).map(DefWithBody::from); }, |
81 | ast::StaticDef(def) => { return Static::from_source(db, child.with_value(def)).map(DefWithBody::from); }, | 94 | ast::StaticDef(def) => { return Static::from_source(db, node.with_value(def)).map(DefWithBody::from); }, |
82 | _ => { None }, | 95 | _ => { None }, |
83 | } | 96 | } |
84 | } | 97 | } |
@@ -93,7 +106,7 @@ pub struct SourceAnalyzer { | |||
93 | resolver: Resolver, | 106 | resolver: Resolver, |
94 | body_owner: Option<DefWithBody>, | 107 | body_owner: Option<DefWithBody>, |
95 | body_source_map: Option<Arc<BodySourceMap>>, | 108 | body_source_map: Option<Arc<BodySourceMap>>, |
96 | infer: Option<Arc<crate::ty::InferenceResult>>, | 109 | infer: Option<Arc<InferenceResult>>, |
97 | scopes: Option<Arc<ExprScopes>>, | 110 | scopes: Option<Arc<ExprScopes>>, |
98 | } | 111 | } |
99 | 112 | ||
@@ -104,7 +117,7 @@ pub enum PathResolution { | |||
104 | /// A local binding (only value namespace) | 117 | /// A local binding (only value namespace) |
105 | Local(Local), | 118 | Local(Local), |
106 | /// A generic parameter | 119 | /// A generic parameter |
107 | GenericParam(GenericParam), | 120 | TypeParam(TypeParam), |
108 | SelfType(crate::ImplBlock), | 121 | SelfType(crate::ImplBlock), |
109 | Macro(MacroDef), | 122 | Macro(MacroDef), |
110 | AssocItem(crate::AssocItem), | 123 | AssocItem(crate::AssocItem), |
@@ -132,8 +145,8 @@ pub struct ReferenceDescriptor { | |||
132 | pub name: String, | 145 | pub name: String, |
133 | } | 146 | } |
134 | 147 | ||
148 | #[derive(Debug)] | ||
135 | pub struct Expansion { | 149 | pub struct Expansion { |
136 | macro_file_kind: MacroFileKind, | ||
137 | macro_call_id: MacroCallId, | 150 | macro_call_id: MacroCallId, |
138 | } | 151 | } |
139 | 152 | ||
@@ -141,23 +154,24 @@ impl Expansion { | |||
141 | pub fn map_token_down( | 154 | pub fn map_token_down( |
142 | &self, | 155 | &self, |
143 | db: &impl HirDatabase, | 156 | db: &impl HirDatabase, |
144 | token: Source<&SyntaxToken>, | 157 | token: InFile<&SyntaxToken>, |
145 | ) -> Option<Source<SyntaxToken>> { | 158 | ) -> Option<InFile<SyntaxToken>> { |
146 | let exp_info = self.file_id().expansion_info(db)?; | 159 | let exp_info = self.file_id().expansion_info(db)?; |
147 | exp_info.map_token_down(token) | 160 | exp_info.map_token_down(token) |
148 | } | 161 | } |
149 | 162 | ||
150 | pub fn file_id(&self) -> HirFileId { | 163 | pub fn file_id(&self) -> HirFileId { |
151 | self.macro_call_id.as_file(self.macro_file_kind) | 164 | self.macro_call_id.as_file() |
152 | } | 165 | } |
153 | } | 166 | } |
154 | 167 | ||
155 | impl SourceAnalyzer { | 168 | impl SourceAnalyzer { |
156 | pub fn new( | 169 | pub fn new( |
157 | db: &impl HirDatabase, | 170 | db: &impl HirDatabase, |
158 | node: Source<&SyntaxNode>, | 171 | node: InFile<&SyntaxNode>, |
159 | offset: Option<TextUnit>, | 172 | offset: Option<TextUnit>, |
160 | ) -> SourceAnalyzer { | 173 | ) -> SourceAnalyzer { |
174 | let _p = profile("SourceAnalyzer::new"); | ||
161 | let def_with_body = def_with_body_from_child_node(db, node); | 175 | let def_with_body = def_with_body_from_child_node(db, node); |
162 | if let Some(def) = def_with_body { | 176 | if let Some(def) = def_with_body { |
163 | let (_body, source_map) = db.body_with_source_map(def.into()); | 177 | let (_body, source_map) = db.body_with_source_map(def.into()); |
@@ -192,12 +206,12 @@ impl SourceAnalyzer { | |||
192 | } | 206 | } |
193 | 207 | ||
194 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { | 208 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { |
195 | let src = Source { file_id: self.file_id, value: expr }; | 209 | let src = InFile { file_id: self.file_id, value: expr }; |
196 | self.body_source_map.as_ref()?.node_expr(src) | 210 | self.body_source_map.as_ref()?.node_expr(src) |
197 | } | 211 | } |
198 | 212 | ||
199 | fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { | 213 | fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { |
200 | let src = Source { file_id: self.file_id, value: pat }; | 214 | let src = InFile { file_id: self.file_id, value: pat }; |
201 | self.body_source_map.as_ref()?.node_pat(src) | 215 | self.body_source_map.as_ref()?.node_pat(src) |
202 | } | 216 | } |
203 | 217 | ||
@@ -226,7 +240,13 @@ impl SourceAnalyzer { | |||
226 | } | 240 | } |
227 | 241 | ||
228 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { | 242 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { |
229 | let expr_id = self.expr_id(&field.expr()?)?; | 243 | let expr_id = match field.expr() { |
244 | Some(it) => self.expr_id(&it)?, | ||
245 | None => { | ||
246 | let src = InFile { file_id: self.file_id, value: field }; | ||
247 | self.body_source_map.as_ref()?.field_init_shorthand_expr(src)? | ||
248 | } | ||
249 | }; | ||
230 | self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) | 250 | self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) |
231 | } | 251 | } |
232 | 252 | ||
@@ -243,11 +263,11 @@ impl SourceAnalyzer { | |||
243 | pub fn resolve_macro_call( | 263 | pub fn resolve_macro_call( |
244 | &self, | 264 | &self, |
245 | db: &impl HirDatabase, | 265 | db: &impl HirDatabase, |
246 | macro_call: Source<&ast::MacroCall>, | 266 | macro_call: InFile<&ast::MacroCall>, |
247 | ) -> Option<MacroDef> { | 267 | ) -> Option<MacroDef> { |
248 | let hygiene = Hygiene::new(db, macro_call.file_id); | 268 | let hygiene = Hygiene::new(db, macro_call.file_id); |
249 | let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; | 269 | let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; |
250 | self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) | 270 | self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into()) |
251 | } | 271 | } |
252 | 272 | ||
253 | pub fn resolve_hir_path( | 273 | pub fn resolve_hir_path( |
@@ -255,43 +275,42 @@ impl SourceAnalyzer { | |||
255 | db: &impl HirDatabase, | 275 | db: &impl HirDatabase, |
256 | path: &crate::Path, | 276 | path: &crate::Path, |
257 | ) -> Option<PathResolution> { | 277 | ) -> Option<PathResolution> { |
258 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { | 278 | let types = |
259 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 279 | self.resolver.resolve_path_in_type_ns_fully(db, path.mod_path()).map(|ty| match ty { |
260 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { | 280 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
261 | parent: self.resolver.generic_def().unwrap(), | 281 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), |
262 | idx, | 282 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
263 | }), | 283 | PathResolution::Def(Adt::from(it).into()) |
264 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | ||
265 | PathResolution::Def(Adt::from(it).into()) | ||
266 | } | ||
267 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | ||
268 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | ||
269 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | ||
270 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | ||
271 | }); | ||
272 | let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { | ||
273 | let res = match val { | ||
274 | ValueNs::LocalBinding(pat_id) => { | ||
275 | let var = Local { parent: self.body_owner?, pat_id }; | ||
276 | PathResolution::Local(var) | ||
277 | } | 284 | } |
278 | ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), | 285 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), |
279 | ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), | 286 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), |
280 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), | 287 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), |
281 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), | 288 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
282 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | 289 | }); |
283 | }; | 290 | let values = |
284 | Some(res) | 291 | self.resolver.resolve_path_in_value_ns_fully(db, path.mod_path()).and_then(|val| { |
285 | }); | 292 | let res = match val { |
293 | ValueNs::LocalBinding(pat_id) => { | ||
294 | let var = Local { parent: self.body_owner?, pat_id }; | ||
295 | PathResolution::Local(var) | ||
296 | } | ||
297 | ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), | ||
298 | ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), | ||
299 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), | ||
300 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), | ||
301 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | ||
302 | }; | ||
303 | Some(res) | ||
304 | }); | ||
286 | 305 | ||
287 | let items = self | 306 | let items = self |
288 | .resolver | 307 | .resolver |
289 | .resolve_module_path(db, &path) | 308 | .resolve_module_path_in_items(db, path.mod_path()) |
290 | .take_types() | 309 | .take_types() |
291 | .map(|it| PathResolution::Def(it.into())); | 310 | .map(|it| PathResolution::Def(it.into())); |
292 | types.or(values).or(items).or_else(|| { | 311 | types.or(values).or(items).or_else(|| { |
293 | self.resolver | 312 | self.resolver |
294 | .resolve_path_as_macro(db, &path) | 313 | .resolve_path_as_macro(db, path.mod_path()) |
295 | .map(|def| PathResolution::Macro(def.into())) | 314 | .map(|def| PathResolution::Macro(def.into())) |
296 | }) | 315 | }) |
297 | } | 316 | } |
@@ -318,7 +337,7 @@ impl SourceAnalyzer { | |||
318 | let name = name_ref.as_name(); | 337 | let name = name_ref.as_name(); |
319 | let source_map = self.body_source_map.as_ref()?; | 338 | let source_map = self.body_source_map.as_ref()?; |
320 | let scopes = self.scopes.as_ref()?; | 339 | let scopes = self.scopes.as_ref()?; |
321 | let scope = scope_for(scopes, source_map, Source::new(self.file_id, name_ref.syntax()))?; | 340 | let scope = scope_for(scopes, source_map, InFile::new(self.file_id, name_ref.syntax()))?; |
322 | let entry = scopes.resolve_name_in_scope(scope, &name)?; | 341 | let entry = scopes.resolve_name_in_scope(scope, &name)?; |
323 | Some(ScopeEntryWithSyntax { | 342 | Some(ScopeEntryWithSyntax { |
324 | name: entry.name().clone(), | 343 | name: entry.name().clone(), |
@@ -332,10 +351,7 @@ impl SourceAnalyzer { | |||
332 | resolver::ScopeDef::PerNs(it) => it.into(), | 351 | resolver::ScopeDef::PerNs(it) => it.into(), |
333 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), | 352 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), |
334 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), | 353 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), |
335 | resolver::ScopeDef::GenericParam(idx) => { | 354 | resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }), |
336 | let parent = self.resolver.generic_def().unwrap(); | ||
337 | ScopeDef::GenericParam(GenericParam { parent, idx }) | ||
338 | } | ||
339 | resolver::ScopeDef::Local(pat_id) => { | 355 | resolver::ScopeDef::Local(pat_id) => { |
340 | let parent = self.resolver.body_owner().unwrap().into(); | 356 | let parent = self.resolver.body_owner().unwrap().into(); |
341 | ScopeDef::Local(Local { parent, pat_id }) | 357 | ScopeDef::Local(Local { parent, pat_id }) |
@@ -349,7 +365,7 @@ impl SourceAnalyzer { | |||
349 | // should switch to general reference search infra there. | 365 | // should switch to general reference search infra there. |
350 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | 366 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { |
351 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | 367 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); |
352 | let ptr = Either::A(AstPtr::new(&ast::Pat::from(pat.clone()))); | 368 | let ptr = Either::Left(AstPtr::new(&ast::Pat::from(pat.clone()))); |
353 | fn_def | 369 | fn_def |
354 | .syntax() | 370 | .syntax() |
355 | .descendants() | 371 | .descendants() |
@@ -375,7 +391,7 @@ impl SourceAnalyzer { | |||
375 | // There should be no inference vars in types passed here | 391 | // There should be no inference vars in types passed here |
376 | // FIXME check that? | 392 | // FIXME check that? |
377 | // FIXME replace Unknown by bound vars here | 393 | // FIXME replace Unknown by bound vars here |
378 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | 394 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
379 | method_resolution::iterate_method_candidates( | 395 | method_resolution::iterate_method_candidates( |
380 | &canonical, | 396 | &canonical, |
381 | db, | 397 | db, |
@@ -399,7 +415,7 @@ impl SourceAnalyzer { | |||
399 | // There should be no inference vars in types passed here | 415 | // There should be no inference vars in types passed here |
400 | // FIXME check that? | 416 | // FIXME check that? |
401 | // FIXME replace Unknown by bound vars here | 417 | // FIXME replace Unknown by bound vars here |
402 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | 418 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
403 | method_resolution::iterate_method_candidates( | 419 | method_resolution::iterate_method_candidates( |
404 | &canonical, | 420 | &canonical, |
405 | db, | 421 | db, |
@@ -410,24 +426,10 @@ impl SourceAnalyzer { | |||
410 | ) | 426 | ) |
411 | } | 427 | } |
412 | 428 | ||
413 | // pub fn autoderef<'a>( | ||
414 | // &'a self, | ||
415 | // db: &'a impl HirDatabase, | ||
416 | // ty: Ty, | ||
417 | // ) -> impl Iterator<Item = Ty> + 'a { | ||
418 | // // There should be no inference vars in types passed here | ||
419 | // // FIXME check that? | ||
420 | // let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | ||
421 | // let krate = self.resolver.krate(); | ||
422 | // let environment = TraitEnvironment::lower(db, &self.resolver); | ||
423 | // let ty = crate::ty::InEnvironment { value: canonical, environment }; | ||
424 | // crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) | ||
425 | // } | ||
426 | |||
427 | /// Checks that particular type `ty` implements `std::future::Future`. | 429 | /// Checks that particular type `ty` implements `std::future::Future`. |
428 | /// This function is used in `.await` syntax completion. | 430 | /// This function is used in `.await` syntax completion. |
429 | pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool { | 431 | pub fn impls_future(&self, db: &impl HirDatabase, ty: Type) -> bool { |
430 | let std_future_path = known::std_future_future(); | 432 | let std_future_path = path![std::future::Future]; |
431 | 433 | ||
432 | let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { | 434 | let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { |
433 | Some(it) => it.into(), | 435 | Some(it) => it.into(), |
@@ -439,43 +441,40 @@ impl SourceAnalyzer { | |||
439 | _ => return false, | 441 | _ => return false, |
440 | }; | 442 | }; |
441 | 443 | ||
442 | let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; | 444 | let canonical_ty = Canonical { value: ty.ty.value, num_vars: 0 }; |
443 | implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) | 445 | implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) |
444 | } | 446 | } |
445 | 447 | ||
446 | pub fn expand( | 448 | pub fn expand( |
447 | &self, | 449 | &self, |
448 | db: &impl HirDatabase, | 450 | db: &impl HirDatabase, |
449 | macro_call: Source<&ast::MacroCall>, | 451 | macro_call: InFile<&ast::MacroCall>, |
450 | ) -> Option<Expansion> { | 452 | ) -> Option<Expansion> { |
451 | let def = self.resolve_macro_call(db, macro_call)?.id; | 453 | let def = self.resolve_macro_call(db, macro_call)?.id; |
452 | let ast_id = AstId::new( | 454 | let ast_id = AstId::new( |
453 | macro_call.file_id, | 455 | macro_call.file_id, |
454 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | 456 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), |
455 | ); | 457 | ); |
456 | Some(Expansion { | 458 | Some(Expansion { macro_call_id: def.as_call_id(db, MacroCallKind::FnLike(ast_id)) }) |
457 | macro_call_id: def.as_call_id(db, ast_id), | ||
458 | macro_file_kind: to_macro_file_kind(macro_call.value), | ||
459 | }) | ||
460 | } | 459 | } |
461 | } | 460 | } |
462 | 461 | ||
463 | fn scope_for( | 462 | fn scope_for( |
464 | scopes: &ExprScopes, | 463 | scopes: &ExprScopes, |
465 | source_map: &BodySourceMap, | 464 | source_map: &BodySourceMap, |
466 | node: Source<&SyntaxNode>, | 465 | node: InFile<&SyntaxNode>, |
467 | ) -> Option<ScopeId> { | 466 | ) -> Option<ScopeId> { |
468 | node.value | 467 | node.value |
469 | .ancestors() | 468 | .ancestors() |
470 | .filter_map(ast::Expr::cast) | 469 | .filter_map(ast::Expr::cast) |
471 | .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) | 470 | .filter_map(|it| source_map.node_expr(InFile::new(node.file_id, &it))) |
472 | .find_map(|it| scopes.scope_for(it)) | 471 | .find_map(|it| scopes.scope_for(it)) |
473 | } | 472 | } |
474 | 473 | ||
475 | fn scope_for_offset( | 474 | fn scope_for_offset( |
476 | scopes: &ExprScopes, | 475 | scopes: &ExprScopes, |
477 | source_map: &BodySourceMap, | 476 | source_map: &BodySourceMap, |
478 | offset: Source<TextUnit>, | 477 | offset: InFile<TextUnit>, |
479 | ) -> Option<ScopeId> { | 478 | ) -> Option<ScopeId> { |
480 | scopes | 479 | scopes |
481 | .scope_by_expr() | 480 | .scope_by_expr() |
@@ -540,35 +539,3 @@ fn adjust( | |||
540 | }) | 539 | }) |
541 | .map(|(_ptr, scope)| *scope) | 540 | .map(|(_ptr, scope)| *scope) |
542 | } | 541 | } |
543 | |||
544 | /// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to. | ||
545 | /// FIXME: Not completed | ||
546 | fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind { | ||
547 | let syn = macro_call.syntax(); | ||
548 | let parent = match syn.parent() { | ||
549 | Some(it) => it, | ||
550 | None => { | ||
551 | // FIXME: | ||
552 | // If it is root, which means the parent HirFile | ||
553 | // MacroKindFile must be non-items | ||
554 | // return expr now. | ||
555 | return MacroFileKind::Expr; | ||
556 | } | ||
557 | }; | ||
558 | |||
559 | match parent.kind() { | ||
560 | MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items, | ||
561 | LET_STMT => { | ||
562 | // FIXME: Handle Pattern | ||
563 | MacroFileKind::Expr | ||
564 | } | ||
565 | EXPR_STMT => MacroFileKind::Statements, | ||
566 | BLOCK => MacroFileKind::Statements, | ||
567 | ARG_LIST => MacroFileKind::Expr, | ||
568 | TRY_EXPR => MacroFileKind::Expr, | ||
569 | _ => { | ||
570 | // Unknown , Just guess it is `Items` | ||
571 | MacroFileKind::Items | ||
572 | } | ||
573 | } | ||
574 | } | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs deleted file mode 100644 index 4ed69c00d..000000000 --- a/crates/ra_hir/src/ty.rs +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | //! The type system. We currently use this to infer types for completion, hover | ||
2 | //! information and various assists. | ||
3 | |||
4 | pub use hir_ty::*; | ||