aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/Cargo.toml2
-rw-r--r--crates/ra_hir/src/code_model.rs409
-rw-r--r--crates/ra_hir/src/code_model/src.rs128
-rw-r--r--crates/ra_hir/src/db.rs4
-rw-r--r--crates/ra_hir/src/debug.rs94
-rw-r--r--crates/ra_hir/src/from_id.rs14
-rw-r--r--crates/ra_hir/src/from_source.rs362
-rw-r--r--crates/ra_hir/src/has_source.rs127
-rw-r--r--crates/ra_hir/src/lib.rs26
-rw-r--r--crates/ra_hir/src/source_binder.rs213
-rw-r--r--crates/ra_hir/src/ty.rs4
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]
11log = "0.4.5" 11log = "0.4.5"
12rustc-hash = "1.0" 12rustc-hash = "1.0"
13either = "1.5"
13 14
14ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
15ra_db = { path = "../ra_db" } 16ra_db = { path = "../ra_db" }
17ra_prof = { path = "../ra_prof" }
16hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } 18hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
17hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } 19hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
18hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } 20hir_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
3pub(crate) mod src;
4
5use std::sync::Arc; 2use std::sync::Arc;
6 3
4use either::Either;
7use hir_def::{ 5use 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};
20use hir_expand::{ 18use hir_expand::{
21 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
22 name::{self, AsName}, 20 name::{name, AsName},
23 AstId, MacroDefId, 21 MacroDefId,
22};
23use hir_ty::{
24 autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment,
25 TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk,
24}; 26};
25use hir_ty::expr::ExprValidator; 27use ra_db::{CrateId, Edition, FileId};
26use ra_db::{CrateId, Edition, FileId, FilePosition}; 28use ra_syntax::ast;
27use ra_syntax::{ast, AstNode, SyntaxNode};
28 29
29use crate::{ 30use 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)]
40pub struct Crate { 39pub 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
50impl Crate { 49impl 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
81pub enum ModuleSource {
82 SourceFile(ast::SourceFile),
83 Module(ast::Module),
84}
85 70
86impl 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
172impl Module { 123impl 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
288pub 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)]
294pub struct StructField { 231pub 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
324impl Struct { 263impl 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
414impl Enum { 331impl 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
715impl Trait { 547impl 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
794impl MacroDef {}
795
796pub enum Container {
797 Trait(Trait),
798 ImplBlock(ImplBlock),
799}
800impl_froms!(Container: Trait, ImplBlock);
801
802#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 602#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
803pub enum AssocItem { 603pub 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)]
913pub struct GenericParam { 706pub struct TypeParam {
914 pub(crate) parent: GenericDefId, 707 pub(crate) id: TypeParamId,
915 pub(crate) idx: u32, 708}
709
710impl 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
923impl ImplBlock { 726impl 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
972impl Type { 778impl 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 {
1155pub enum ScopeDef { 964pub 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
3use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId};
4use hir_expand::either::Either;
5use ra_syntax::ast;
6
7use crate::{
8 db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef,
9 Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
10};
11
12pub use hir_expand::Source;
13
14pub 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.
21impl 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
40impl 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}
51impl 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}
57impl 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}
63impl 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}
69impl 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}
75impl 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}
81impl 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}
87impl 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}
93impl 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}
99impl 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}
105impl 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}
111impl 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}
117impl 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};
10pub use hir_expand::db::{ 10pub 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
23use std::fmt;
24
25use hir_expand::HirFileId;
26use ra_db::{CrateId, FileId};
27
28use crate::{db::HirDatabase, Crate, Module, Name};
29
30impl 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
36impl 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
42pub 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
51pub 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
57impl<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
84fn 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
11use crate::{ 11use 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
16impl From<ra_db::CrateId> for Crate {
17 fn from(crate_id: ra_db::CrateId) -> Self {
18 Crate { crate_id }
19 }
20}
21
22macro_rules! from_id { 16macro_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
32from_id![ 31from_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
3use hir_def::{AstItemDef, LocationCtx, ModuleId}; 4use 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};
4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 9use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
10use ra_db::FileId;
11use ra_prof::profile;
5use ra_syntax::{ 12use 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
10use crate::{ 17use 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
17pub trait FromSource: Sized { 23pub 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
22impl FromSource for Struct { 28pub 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}
29impl 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}
36impl 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}
43impl 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}
50impl 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
77impl FromSource for Const { 34impl<T: FromSourceByContainer> FromSource for T
78 type Ast = ast::ConstDef; 35where
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}
103impl 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
121impl FromSource for TypeAlias { 47macro_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
57from_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
148impl FromSource for MacroDef { 69impl 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
164impl 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
172impl FromSource for EnumVariant { 85impl 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
182impl FromSource for StructField { 98impl 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
208impl Local { 129impl 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
150impl 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
229impl Module { 172impl 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
274fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: Source<N>) -> Option<DEF> 224fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap {
275where 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
287enum Container {
288 Trait(Trait),
289 ImplBlock(ImplBlock),
290 Module(Module),
291}
292 227
293impl 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.
325fn 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
3use either::Either;
4use hir_def::{
5 nameres::ModuleSource,
6 src::{HasChildSource, HasSource as _},
7 Lookup, VariantId,
8};
9use ra_syntax::ast;
10
11use crate::{
12 db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, MacroDef, Module,
13 Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union,
14};
15
16pub use hir_expand::InFile;
17
18pub 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.
25impl 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
40impl 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}
51impl 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}
57impl 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}
63impl 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}
69impl 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}
75impl 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}
81impl 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}
87impl 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}
93impl 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}
99impl 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}
105impl 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}
114impl 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
121impl 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
29pub mod debug;
30
31pub mod db; 29pub mod db;
32pub mod source_binder; 30pub mod source_binder;
33 31
34mod ty;
35pub mod diagnostics; 32pub mod diagnostics;
36 33
37mod from_id; 34mod from_id;
38mod code_model; 35mod code_model;
39 36
40pub mod from_source; 37mod has_source;
38mod from_source;
41 39
42pub use crate::{ 40pub 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
58pub use hir_def::{ 52pub 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};
65pub use hir_expand::{ 60pub 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};
63pub 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".
8use std::sync::Arc; 8use std::sync::Arc;
9 9
10use either::Either;
10use hir_def::{ 11use 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};
20use hir_expand::{ 22use hir_expand::{
21 hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, 23 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
22}; 24};
25use hir_ty::{
26 method_resolution::{self, implements_trait},
27 Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty,
28};
29use ra_prof::profile;
23use ra_syntax::{ 30use 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
30use crate::{ 37use 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
40fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 43fn 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
72fn def_with_body_from_child_node( 83fn 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)]
135pub struct Expansion { 149pub 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
155impl SourceAnalyzer { 168impl 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
463fn scope_for( 462fn 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
475fn scope_for_offset( 474fn 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
546fn 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
4pub use hir_ty::*;