diff options
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 128 |
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 | ||
7 | use hir_def::{ | 7 | use 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 | }; |
19 | use hir_expand::{ | 18 | use 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 | ||
303 | impl StructField { | 302 | impl 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 | ||
563 | pub 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 | |||
570 | impl<T> HasBody for T | ||
571 | where | ||
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 | |||
591 | impl 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)] |
610 | pub struct Function { | 559 | pub 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 | ||
951 | impl 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)] |
962 | pub struct Local { | 901 | pub struct Local { |
963 | pub(crate) parent: DefWithBody, | 902 | pub(crate) parent: DefWithBody, |
@@ -966,7 +905,7 @@ pub struct Local { | |||
966 | 905 | ||
967 | impl Local { | 906 | impl 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)] |
1013 | pub struct GenericParam { | 952 | pub 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 | ||
962 | impl 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 |
1024 | pub enum ScopeDef { | 998 | pub enum ScopeDef { |
1025 | ModuleDef(ModuleDef), | 999 | ModuleDef(ModuleDef), |