aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs127
1 files changed, 53 insertions, 74 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 4578a0ba8..9cbea024a 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -25,7 +25,7 @@ use hir_expand::{
25 MacroDefId, 25 MacroDefId,
26}; 26};
27use hir_ty::expr::ExprValidator; 27use hir_ty::expr::ExprValidator;
28use ra_db::{CrateId, Edition}; 28use ra_db::{CrateId, Edition, FileId};
29use ra_syntax::ast; 29use ra_syntax::ast;
30 30
31use crate::{ 31use crate::{
@@ -40,7 +40,7 @@ use crate::{
40/// root module. 40/// root module.
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
42pub struct Crate { 42pub struct Crate {
43 pub(crate) crate_id: CrateId, 43 pub(crate) id: CrateId,
44} 44}
45 45
46#[derive(Debug)] 46#[derive(Debug)]
@@ -50,33 +50,47 @@ pub struct CrateDependency {
50} 50}
51 51
52impl Crate { 52impl Crate {
53 pub fn crate_id(self) -> CrateId {
54 self.crate_id
55 }
56
57 pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> { 53 pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> {
58 db.crate_graph() 54 db.crate_graph()
59 .dependencies(self.crate_id) 55 .dependencies(self.id)
60 .map(|dep| { 56 .map(|dep| {
61 let krate = Crate { crate_id: dep.crate_id() }; 57 let krate = Crate { id: dep.crate_id() };
62 let name = dep.as_name(); 58 let name = dep.as_name();
63 CrateDependency { krate, name } 59 CrateDependency { krate, name }
64 }) 60 })
65 .collect() 61 .collect()
66 } 62 }
67 63
64 // FIXME: add `transitive_reverse_dependencies`.
65 pub fn reverse_dependencies(self, db: &impl DefDatabase) -> Vec<Crate> {
66 let crate_graph = db.crate_graph();
67 crate_graph
68 .iter()
69 .filter(|&krate| crate_graph.dependencies(krate).any(|it| it.crate_id == self.id))
70 .map(|id| Crate { id })
71 .collect()
72 }
73
68 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { 74 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> {
69 let module_id = db.crate_def_map(self.crate_id).root; 75 let module_id = db.crate_def_map(self.id).root;
70 Some(Module::new(self, module_id)) 76 Some(Module::new(self, module_id))
71 } 77 }
72 78
79 pub fn root_file(self, db: &impl DefDatabase) -> FileId {
80 db.crate_graph().crate_root(self.id)
81 }
82
73 pub fn edition(self, db: &impl DefDatabase) -> Edition { 83 pub fn edition(self, db: &impl DefDatabase) -> Edition {
74 let crate_graph = db.crate_graph(); 84 let crate_graph = db.crate_graph();
75 crate_graph.edition(self.crate_id) 85 crate_graph.edition(self.id)
76 } 86 }
77 87
78 pub fn all(db: &impl DefDatabase) -> Vec<Crate> { 88 pub fn all(db: &impl DefDatabase) -> Vec<Crate> {
79 db.crate_graph().iter().map(|crate_id| Crate { crate_id }).collect() 89 db.crate_graph().iter().map(|id| Crate { id }).collect()
90 }
91
92 pub fn crate_id(self) -> CrateId {
93 self.id
80 } 94 }
81} 95}
82 96
@@ -115,7 +129,7 @@ pub use hir_def::attr::Attrs;
115 129
116impl Module { 130impl Module {
117 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { 131 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
118 Module { id: ModuleId { krate: krate.crate_id, local_id: crate_module_id } } 132 Module { id: ModuleId { krate: krate.id, local_id: crate_module_id } }
119 } 133 }
120 134
121 /// Name of this module. 135 /// Name of this module.
@@ -133,7 +147,7 @@ impl Module {
133 147
134 /// Returns the crate this module is part of. 148 /// Returns the crate this module is part of.
135 pub fn krate(self) -> Crate { 149 pub fn krate(self) -> Crate {
136 Crate { crate_id: self.id.krate } 150 Crate { id: self.id.krate }
137 } 151 }
138 152
139 /// Topmost parent of this module. Every module has a `crate_root`, but some 153 /// Topmost parent of this module. Every module has a `crate_root`, but some
@@ -144,13 +158,6 @@ impl Module {
144 self.with_module_id(def_map.root) 158 self.with_module_id(def_map.root)
145 } 159 }
146 160
147 /// Finds a child module with the specified name.
148 pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> {
149 let def_map = db.crate_def_map(self.id.krate);
150 let child_id = def_map[self.id.local_id].children.get(name)?;
151 Some(self.with_module_id(*child_id))
152 }
153
154 /// Iterates over all child modules. 161 /// Iterates over all child modules.
155 pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { 162 pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
156 let def_map = db.crate_def_map(self.id.krate); 163 let def_map = db.crate_def_map(self.id.krate);
@@ -224,7 +231,7 @@ impl Module {
224 def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() 231 def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect()
225 } 232 }
226 233
227 fn with_module_id(self, module_id: LocalModuleId) -> Module { 234 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module {
228 Module::new(self.krate(), module_id) 235 Module::new(self.krate(), module_id)
229 } 236 }
230} 237}
@@ -251,8 +258,10 @@ impl StructField {
251 self.parent.variant_data(db).fields()[self.id].name.clone() 258 self.parent.variant_data(db).fields()[self.id].name.clone()
252 } 259 }
253 260
254 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 261 pub fn ty(&self, db: &impl HirDatabase) -> Type {
255 db.field_types(self.parent.into())[self.id].clone() 262 let var_id = self.parent.into();
263 let ty = db.field_types(var_id)[self.id].clone();
264 Type::new(db, self.parent.module(db).id.krate.into(), var_id, ty)
256 } 265 }
257 266
258 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { 267 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef {
@@ -287,23 +296,10 @@ impl Struct {
287 .collect() 296 .collect()
288 } 297 }
289 298
290 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
291 db.struct_data(self.id.into())
292 .variant_data
293 .fields()
294 .iter()
295 .find(|(_id, data)| data.name == *name)
296 .map(|(id, _)| StructField { parent: self.into(), id })
297 }
298
299 pub fn ty(self, db: &impl HirDatabase) -> Type { 299 pub fn ty(self, db: &impl HirDatabase) -> Type {
300 Type::from_def(db, self.id.module(db).krate, self.id) 300 Type::from_def(db, self.id.module(db).krate, self.id)
301 } 301 }
302 302
303 pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty {
304 db.value_ty(self.id.into())
305 }
306
307 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 303 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
308 db.struct_data(self.id.into()).variant_data.clone() 304 db.struct_data(self.id.into()).variant_data.clone()
309 } 305 }
@@ -336,15 +332,6 @@ impl Union {
336 .collect() 332 .collect()
337 } 333 }
338 334
339 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
340 db.union_data(self.id)
341 .variant_data
342 .fields()
343 .iter()
344 .find(|(_id, data)| data.name == *name)
345 .map(|(id, _)| StructField { parent: self.into(), id })
346 }
347
348 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 335 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
349 db.union_data(self.id).variant_data.clone() 336 db.union_data(self.id).variant_data.clone()
350 } 337 }
@@ -376,11 +363,6 @@ impl Enum {
376 .collect() 363 .collect()
377 } 364 }
378 365
379 pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
380 let id = db.enum_data(self.id).variant(name)?;
381 Some(EnumVariant { parent: self, id })
382 }
383
384 pub fn ty(self, db: &impl HirDatabase) -> Type { 366 pub fn ty(self, db: &impl HirDatabase) -> Type {
385 Type::from_def(db, self.id.module(db).krate, self.id) 367 Type::from_def(db, self.id.module(db).krate, self.id)
386 } 368 }
@@ -412,14 +394,6 @@ impl EnumVariant {
412 .collect() 394 .collect()
413 } 395 }
414 396
415 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
416 self.variant_data(db)
417 .fields()
418 .iter()
419 .find(|(_id, data)| data.name == *name)
420 .map(|(id, _)| StructField { parent: self.into(), id })
421 }
422
423 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 397 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
424 db.enum_data(self.parent.id).variants[self.id].variant_data.clone() 398 db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
425 } 399 }
@@ -545,10 +519,6 @@ impl Function {
545 db.body(self.id.into()) 519 db.body(self.id.into())
546 } 520 }
547 521
548 pub fn ty(self, db: &impl HirDatabase) -> Ty {
549 db.value_ty(self.id.into())
550 }
551
552 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 522 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
553 db.infer(self.id.into()) 523 db.infer(self.id.into())
554 } 524 }
@@ -878,11 +848,11 @@ pub struct ImplBlock {
878 848
879impl ImplBlock { 849impl ImplBlock {
880 pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { 850 pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> {
881 let impls = db.impls_in_crate(krate.crate_id); 851 let impls = db.impls_in_crate(krate.id);
882 impls.all_impls().map(Self::from).collect() 852 impls.all_impls().map(Self::from).collect()
883 } 853 }
884 pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { 854 pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> {
885 let impls = db.impls_in_crate(krate.crate_id); 855 let impls = db.impls_in_crate(krate.id);
886 impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect() 856 impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect()
887 } 857 }
888 858
@@ -915,7 +885,7 @@ impl ImplBlock {
915 } 885 }
916 886
917 pub fn krate(&self, db: &impl DefDatabase) -> Crate { 887 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
918 Crate { crate_id: self.module(db).id.krate } 888 Crate { id: self.module(db).id.krate }
919 } 889 }
920} 890}
921 891
@@ -926,15 +896,19 @@ pub struct Type {
926} 896}
927 897
928impl Type { 898impl Type {
899 fn new(db: &impl HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
900 let resolver = lexical_env.resolver(db);
901 let environment = TraitEnvironment::lower(db, &resolver);
902 Type { krate, ty: InEnvironment { value: ty, environment } }
903 }
904
929 fn from_def( 905 fn from_def(
930 db: &impl HirDatabase, 906 db: &impl HirDatabase,
931 krate: CrateId, 907 krate: CrateId,
932 def: impl HasResolver + Into<TyDefId>, 908 def: impl HasResolver + Into<TyDefId>,
933 ) -> Type { 909 ) -> Type {
934 let resolver = def.resolver(db);
935 let environment = TraitEnvironment::lower(db, &resolver);
936 let ty = db.ty(def.into()); 910 let ty = db.ty(def.into());
937 Type { krate, ty: InEnvironment { value: ty, environment } } 911 Type::new(db, krate, def, ty)
938 } 912 }
939 913
940 pub fn is_bool(&self) -> bool { 914 pub fn is_bool(&self) -> bool {
@@ -1025,11 +999,16 @@ impl Type {
1025 ) -> Vec<(StructField, Type)> { 999 ) -> Vec<(StructField, Type)> {
1026 // FIXME: check that ty and def match 1000 // FIXME: check that ty and def match
1027 match &self.ty.value { 1001 match &self.ty.value {
1028 Ty::Apply(a_ty) => def 1002 Ty::Apply(a_ty) => {
1029 .fields(db) 1003 let field_types = db.field_types(def.into());
1030 .into_iter() 1004 def.fields(db)
1031 .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters)))) 1005 .into_iter()
1032 .collect(), 1006 .map(|it| {
1007 let ty = field_types[it.id].clone().subst(&a_ty.parameters);
1008 (it, self.derived(ty))
1009 })
1010 .collect()
1011 }
1033 _ => Vec::new(), 1012 _ => Vec::new(),
1034 } 1013 }
1035 } 1014 }
@@ -1053,7 +1032,7 @@ impl Type {
1053 krate: Crate, 1032 krate: Crate,
1054 mut callback: impl FnMut(AssocItem) -> Option<T>, 1033 mut callback: impl FnMut(AssocItem) -> Option<T>,
1055 ) -> Option<T> { 1034 ) -> Option<T> {
1056 for krate in self.ty.value.def_crates(db, krate.crate_id)? { 1035 for krate in self.ty.value.def_crates(db, krate.id)? {
1057 let impls = db.impls_in_crate(krate); 1036 let impls = db.impls_in_crate(krate);
1058 1037
1059 for impl_block in impls.lookup_impl_blocks(&self.ty.value) { 1038 for impl_block in impls.lookup_impl_blocks(&self.ty.value) {