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.rs128
1 files changed, 51 insertions, 77 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 9f06b147c..534f1f8e9 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -6,15 +6,14 @@ 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,
13 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
14 type_ref::TypeRef, 13 type_ref::TypeRef,
15 AstItemDef, ConstId, ContainerId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, 14 AstItemDef, ConstId, ContainerId, EnumId, FunctionId, GenericDefId, HasModule, ImplId,
16 LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, 15 LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId,
17 TraitId, TypeAliasId, UnionId, 16 StaticId, StructId, TraitId, TypeAliasId, UnionId,
18}; 17};
19use hir_expand::{ 18use hir_expand::{
20 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -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
@@ -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
@@ -948,16 +897,6 @@ impl_froms!(
948 Const 897 Const
949); 898);
950 899
951impl From<AssocItem> for GenericDef {
952 fn from(item: AssocItem) -> Self {
953 match item {
954 AssocItem::Function(f) => f.into(),
955 AssocItem::Const(c) => c.into(),
956 AssocItem::TypeAlias(t) => t.into(),
957 }
958 }
959}
960
961#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 900#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
962pub struct Local { 901pub struct Local {
963 pub(crate) parent: DefWithBody, 902 pub(crate) parent: DefWithBody,
@@ -966,7 +905,7 @@ pub struct Local {
966 905
967impl Local { 906impl Local {
968 pub fn name(self, db: &impl HirDatabase) -> Option<Name> { 907 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
969 let body = self.parent.body(db); 908 let body = db.body(self.parent.into());
970 match &body[self.pat_id] { 909 match &body[self.pat_id] {
971 Pat::Bind { name, .. } => Some(name.clone()), 910 Pat::Bind { name, .. } => Some(name.clone()),
972 _ => None, 911 _ => None,
@@ -978,7 +917,7 @@ impl Local {
978 } 917 }
979 918
980 pub fn is_mut(self, db: &impl HirDatabase) -> bool { 919 pub fn is_mut(self, db: &impl HirDatabase) -> bool {
981 let body = self.parent.body(db); 920 let body = db.body(self.parent.into());
982 match &body[self.pat_id] { 921 match &body[self.pat_id] {
983 Pat::Bind { mode, .. } => match mode { 922 Pat::Bind { mode, .. } => match mode {
984 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, 923 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
@@ -1002,7 +941,7 @@ impl Local {
1002 } 941 }
1003 942
1004 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { 943 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> {
1005 let source_map = self.parent.body_source_map(db); 944 let (_body, source_map) = db.body_with_source_map(self.parent.into());
1006 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... 945 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
1007 let root = src.file_syntax(db); 946 let root = src.file_syntax(db);
1008 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) 947 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root)))
@@ -1011,7 +950,7 @@ impl Local {
1011 950
1012#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 951#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1013pub struct GenericParam { 952pub struct GenericParam {
1014 pub(crate) parent: GenericDef, 953 pub(crate) parent: GenericDefId,
1015 pub(crate) idx: u32, 954 pub(crate) idx: u32,
1016} 955}
1017 956
@@ -1020,6 +959,41 @@ pub struct ImplBlock {
1020 pub(crate) id: ImplId, 959 pub(crate) id: ImplId,
1021} 960}
1022 961
962impl ImplBlock {
963 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
964 db.impl_data(self.id).target_trait.clone()
965 }
966
967 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
968 db.impl_data(self.id).target_type.clone()
969 }
970
971 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
972 Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db))
973 }
974
975 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
976 let target_ty = self.target_ty(db);
977 TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty))
978 }
979
980 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
981 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
982 }
983
984 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
985 db.impl_data(self.id).is_negative
986 }
987
988 pub fn module(&self, db: &impl DefDatabase) -> Module {
989 self.id.module(db).into()
990 }
991
992 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
993 Crate { crate_id: self.module(db).id.krate }
994 }
995}
996
1023/// For IDE only 997/// For IDE only
1024pub enum ScopeDef { 998pub enum ScopeDef {
1025 ModuleDef(ModuleDef), 999 ModuleDef(ModuleDef),