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.rs114
1 files changed, 49 insertions, 65 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index b3e2ff1c2..3f44a50c4 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -6,7 +6,6 @@ use std::sync::Arc;
6 6
7use hir_def::{ 7use hir_def::{
8 adt::VariantData, 8 adt::VariantData,
9 body::scope::ExprScopes,
10 builtin_type::BuiltinType, 9 builtin_type::BuiltinType,
11 docs::Documentation, 10 docs::Documentation,
12 per_ns::PerNs, 11 per_ns::PerNs,
@@ -28,7 +27,7 @@ use crate::{
28 db::{DefDatabase, HirDatabase}, 27 db::{DefDatabase, HirDatabase},
29 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 28 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
30 ty::{InferenceResult, Namespace, TraitRef}, 29 ty::{InferenceResult, Namespace, TraitRef},
31 Either, HasSource, Name, Source, Ty, 30 Either, Name, Source, Ty,
32}; 31};
33 32
34/// hir::Crate describes a single crate. It's the main interface with which 33/// hir::Crate describes a single crate. It's the main interface with which
@@ -62,7 +61,7 @@ impl Crate {
62 } 61 }
63 62
64 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { 63 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> {
65 let module_id = db.crate_def_map(self.crate_id).root(); 64 let module_id = db.crate_def_map(self.crate_id).root;
66 Some(Module::new(self, module_id)) 65 Some(Module::new(self, module_id))
67 } 66 }
68 67
@@ -195,7 +194,7 @@ impl Module {
195 /// in the module tree of any target in `Cargo.toml`. 194 /// in the module tree of any target in `Cargo.toml`.
196 pub fn crate_root(self, db: &impl DefDatabase) -> Module { 195 pub fn crate_root(self, db: &impl DefDatabase) -> Module {
197 let def_map = db.crate_def_map(self.id.krate); 196 let def_map = db.crate_def_map(self.id.krate);
198 self.with_module_id(def_map.root()) 197 self.with_module_id(def_map.root)
199 } 198 }
200 199
201 /// Finds a child module with the specified name. 200 /// Finds a child module with the specified name.
@@ -302,11 +301,11 @@ pub enum FieldSource {
302 301
303impl StructField { 302impl StructField {
304 pub fn name(&self, db: &impl HirDatabase) -> Name { 303 pub fn name(&self, db: &impl HirDatabase) -> Name {
305 self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() 304 self.parent.variant_data(db).fields()[self.id].name.clone()
306 } 305 }
307 306
308 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 307 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
309 db.type_for_field(*self) 308 db.field_types(self.parent.into())[self.id].clone()
310 } 309 }
311 310
312 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { 311 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef {
@@ -336,8 +335,7 @@ impl Struct {
336 db.struct_data(self.id.into()) 335 db.struct_data(self.id.into())
337 .variant_data 336 .variant_data
338 .fields() 337 .fields()
339 .into_iter() 338 .iter()
340 .flat_map(|it| it.iter())
341 .map(|(id, _)| StructField { parent: self.into(), id }) 339 .map(|(id, _)| StructField { parent: self.into(), id })
342 .collect() 340 .collect()
343 } 341 }
@@ -346,8 +344,7 @@ impl Struct {
346 db.struct_data(self.id.into()) 344 db.struct_data(self.id.into())
347 .variant_data 345 .variant_data
348 .fields() 346 .fields()
349 .into_iter() 347 .iter()
350 .flat_map(|it| it.iter())
351 .find(|(_id, data)| data.name == *name) 348 .find(|(_id, data)| data.name == *name)
352 .map(|(id, _)| StructField { parent: self.into(), id }) 349 .map(|(id, _)| StructField { parent: self.into(), id })
353 } 350 }
@@ -444,8 +441,7 @@ impl EnumVariant {
444 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 441 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
445 self.variant_data(db) 442 self.variant_data(db)
446 .fields() 443 .fields()
447 .into_iter() 444 .iter()
448 .flat_map(|it| it.iter())
449 .map(|(id, _)| StructField { parent: self.into(), id }) 445 .map(|(id, _)| StructField { parent: self.into(), id })
450 .collect() 446 .collect()
451 } 447 }
@@ -453,8 +449,7 @@ impl EnumVariant {
453 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 449 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
454 self.variant_data(db) 450 self.variant_data(db)
455 .fields() 451 .fields()
456 .into_iter() 452 .iter()
457 .flat_map(|it| it.iter())
458 .find(|(_id, data)| data.name == *name) 453 .find(|(_id, data)| data.name == *name)
459 .map(|(id, _)| StructField { parent: self.into(), id }) 454 .map(|(id, _)| StructField { parent: self.into(), id })
460 } 455 }
@@ -510,7 +505,7 @@ impl VariantDef {
510 } 505 }
511 } 506 }
512 507
513 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 508 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
514 match self { 509 match self {
515 VariantDef::Struct(it) => it.field(db, name), 510 VariantDef::Struct(it) => it.field(db, name),
516 VariantDef::EnumVariant(it) => it.field(db, name), 511 VariantDef::EnumVariant(it) => it.field(db, name),
@@ -560,52 +555,6 @@ impl DefWithBody {
560 } 555 }
561} 556}
562 557
563pub trait HasBody: Copy {
564 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>;
565 fn body(self, db: &impl HirDatabase) -> Arc<Body>;
566 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>;
567 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes>;
568}
569
570impl<T> HasBody for T
571where
572 T: Into<DefWithBody> + Copy + HasSource,
573{
574 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
575 db.infer(self.into())
576 }
577
578 fn body(self, db: &impl HirDatabase) -> Arc<Body> {
579 self.into().body(db)
580 }
581
582 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
583 self.into().body_source_map(db)
584 }
585
586 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
587 self.into().expr_scopes(db)
588 }
589}
590
591impl HasBody for DefWithBody {
592 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
593 db.infer(self)
594 }
595
596 fn body(self, db: &impl HirDatabase) -> Arc<Body> {
597 db.body(self.into())
598 }
599
600 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
601 db.body_with_source_map(self.into()).1
602 }
603
604 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
605 db.expr_scopes(self.into())
606 }
607}
608
609#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 558#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
610pub struct Function { 559pub struct Function {
611 pub(crate) id: FunctionId, 560 pub(crate) id: FunctionId,
@@ -632,7 +581,7 @@ impl Function {
632 db.function_data(self.id).params.clone() 581 db.function_data(self.id).params.clone()
633 } 582 }
634 583
635 pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { 584 pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
636 db.body_with_source_map(self.id.into()).1 585 db.body_with_source_map(self.id.into()).1
637 } 586 }
638 587
@@ -966,7 +915,7 @@ pub struct Local {
966 915
967impl Local { 916impl Local {
968 pub fn name(self, db: &impl HirDatabase) -> Option<Name> { 917 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
969 let body = self.parent.body(db); 918 let body = db.body(self.parent.into());
970 match &body[self.pat_id] { 919 match &body[self.pat_id] {
971 Pat::Bind { name, .. } => Some(name.clone()), 920 Pat::Bind { name, .. } => Some(name.clone()),
972 _ => None, 921 _ => None,
@@ -978,7 +927,7 @@ impl Local {
978 } 927 }
979 928
980 pub fn is_mut(self, db: &impl HirDatabase) -> bool { 929 pub fn is_mut(self, db: &impl HirDatabase) -> bool {
981 let body = self.parent.body(db); 930 let body = db.body(self.parent.into());
982 match &body[self.pat_id] { 931 match &body[self.pat_id] {
983 Pat::Bind { mode, .. } => match mode { 932 Pat::Bind { mode, .. } => match mode {
984 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, 933 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
@@ -1002,7 +951,7 @@ impl Local {
1002 } 951 }
1003 952
1004 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { 953 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> {
1005 let source_map = self.parent.body_source_map(db); 954 let (_body, source_map) = db.body_with_source_map(self.parent.into());
1006 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... 955 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
1007 let root = src.file_syntax(db); 956 let root = src.file_syntax(db);
1008 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) 957 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root)))
@@ -1020,6 +969,41 @@ pub struct ImplBlock {
1020 pub(crate) id: ImplId, 969 pub(crate) id: ImplId,
1021} 970}
1022 971
972impl ImplBlock {
973 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
974 db.impl_data(self.id).target_trait.clone()
975 }
976
977 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
978 db.impl_data(self.id).target_type.clone()
979 }
980
981 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
982 Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db))
983 }
984
985 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
986 let target_ty = self.target_ty(db);
987 TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty))
988 }
989
990 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
991 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
992 }
993
994 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
995 db.impl_data(self.id).is_negative
996 }
997
998 pub fn module(&self, db: &impl DefDatabase) -> Module {
999 self.id.module(db).into()
1000 }
1001
1002 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
1003 Crate { crate_id: self.module(db).id.krate }
1004 }
1005}
1006
1023/// For IDE only 1007/// For IDE only
1024pub enum ScopeDef { 1008pub enum ScopeDef {
1025 ModuleDef(ModuleDef), 1009 ModuleDef(ModuleDef),