diff options
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 114 |
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 | ||
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, |
@@ -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 | ||
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 | ||
@@ -966,7 +915,7 @@ pub struct Local { | |||
966 | 915 | ||
967 | impl Local { | 916 | impl 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 | ||
972 | impl 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 |
1024 | pub enum ScopeDef { | 1008 | pub enum ScopeDef { |
1025 | ModuleDef(ModuleDef), | 1009 | ModuleDef(ModuleDef), |