diff options
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 85 |
1 files changed, 76 insertions, 9 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index e5bfad3ca..962d5a8c1 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -8,6 +8,7 @@ use std::sync::Arc; | |||
8 | 8 | ||
9 | use hir_def::{ | 9 | use hir_def::{ |
10 | adt::VariantData, | 10 | adt::VariantData, |
11 | body::scope::ExprScopes, | ||
11 | builtin_type::BuiltinType, | 12 | builtin_type::BuiltinType, |
12 | type_ref::{Mutability, TypeRef}, | 13 | type_ref::{Mutability, TypeRef}, |
13 | CrateModuleId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, | 14 | CrateModuleId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, |
@@ -22,8 +23,8 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | |||
22 | use crate::{ | 23 | use crate::{ |
23 | adt::VariantDef, | 24 | adt::VariantDef, |
24 | db::{AstDatabase, DefDatabase, HirDatabase}, | 25 | db::{AstDatabase, DefDatabase, HirDatabase}, |
25 | expr::{validation::ExprValidator, Body, BodySourceMap}, | 26 | expr::{validation::ExprValidator, BindingAnnotation, Body, BodySourceMap, Pat, PatId}, |
26 | generics::HasGenericParams, | 27 | generics::{GenericDef, HasGenericParams}, |
27 | ids::{ | 28 | ids::{ |
28 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, | 29 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, |
29 | TypeAliasId, | 30 | TypeAliasId, |
@@ -32,7 +33,7 @@ use crate::{ | |||
32 | resolve::{Resolver, Scope, TypeNs}, | 33 | resolve::{Resolver, Scope, TypeNs}, |
33 | traits::TraitData, | 34 | traits::TraitData, |
34 | ty::{InferenceResult, Namespace, TraitRef}, | 35 | ty::{InferenceResult, Namespace, TraitRef}, |
35 | Either, HasSource, ImportId, Name, ScopeDef, Ty, | 36 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, |
36 | }; | 37 | }; |
37 | 38 | ||
38 | /// hir::Crate describes a single crate. It's the main interface with which | 39 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -539,6 +540,7 @@ pub trait HasBody: Copy { | |||
539 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>; | 540 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>; |
540 | fn body(self, db: &impl HirDatabase) -> Arc<Body>; | 541 | fn body(self, db: &impl HirDatabase) -> Arc<Body>; |
541 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>; | 542 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>; |
543 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes>; | ||
542 | } | 544 | } |
543 | 545 | ||
544 | impl<T> HasBody for T | 546 | impl<T> HasBody for T |
@@ -550,11 +552,15 @@ where | |||
550 | } | 552 | } |
551 | 553 | ||
552 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | 554 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { |
553 | db.body_hir(self.into()) | 555 | self.into().body(db) |
554 | } | 556 | } |
555 | 557 | ||
556 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | 558 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { |
557 | db.body_with_source_map(self.into()).1 | 559 | self.into().body_source_map(db) |
560 | } | ||
561 | |||
562 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> { | ||
563 | self.into().expr_scopes(db) | ||
558 | } | 564 | } |
559 | } | 565 | } |
560 | 566 | ||
@@ -564,11 +570,15 @@ impl HasBody for DefWithBody { | |||
564 | } | 570 | } |
565 | 571 | ||
566 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | 572 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { |
567 | db.body_hir(self) | 573 | db.body(self.into()) |
568 | } | 574 | } |
569 | 575 | ||
570 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | 576 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { |
571 | db.body_with_source_map(self).1 | 577 | db.body_with_source_map(self.into()).1 |
578 | } | ||
579 | |||
580 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> { | ||
581 | db.expr_scopes(self.into()) | ||
572 | } | 582 | } |
573 | } | 583 | } |
574 | 584 | ||
@@ -662,11 +672,11 @@ impl Function { | |||
662 | } | 672 | } |
663 | 673 | ||
664 | pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | 674 | pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { |
665 | db.body_with_source_map(self.into()).1 | 675 | db.body_with_source_map(self.id.into()).1 |
666 | } | 676 | } |
667 | 677 | ||
668 | pub fn body(self, db: &impl HirDatabase) -> Arc<Body> { | 678 | pub fn body(self, db: &impl HirDatabase) -> Arc<Body> { |
669 | db.body_hir(self.into()) | 679 | db.body(self.id.into()) |
670 | } | 680 | } |
671 | 681 | ||
672 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 682 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
@@ -1070,3 +1080,60 @@ impl AssocItem { | |||
1070 | .expect("AssocItem without container") | 1080 | .expect("AssocItem without container") |
1071 | } | 1081 | } |
1072 | } | 1082 | } |
1083 | |||
1084 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
1085 | pub struct Local { | ||
1086 | pub(crate) parent: DefWithBody, | ||
1087 | pub(crate) pat_id: PatId, | ||
1088 | } | ||
1089 | |||
1090 | impl Local { | ||
1091 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { | ||
1092 | let body = self.parent.body(db); | ||
1093 | match &body[self.pat_id] { | ||
1094 | Pat::Bind { name, .. } => Some(name.clone()), | ||
1095 | _ => None, | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1099 | pub fn is_self(self, db: &impl HirDatabase) -> bool { | ||
1100 | self.name(db) == Some(name::SELF_PARAM) | ||
1101 | } | ||
1102 | |||
1103 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { | ||
1104 | let body = self.parent.body(db); | ||
1105 | match &body[self.pat_id] { | ||
1106 | Pat::Bind { mode, .. } => match mode { | ||
1107 | BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, | ||
1108 | _ => false, | ||
1109 | }, | ||
1110 | _ => false, | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | pub fn parent(self, _db: &impl HirDatabase) -> DefWithBody { | ||
1115 | self.parent | ||
1116 | } | ||
1117 | |||
1118 | pub fn module(self, db: &impl HirDatabase) -> Module { | ||
1119 | self.parent.module(db) | ||
1120 | } | ||
1121 | |||
1122 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | ||
1123 | let infer = db.infer(self.parent); | ||
1124 | infer[self.pat_id].clone() | ||
1125 | } | ||
1126 | |||
1127 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | ||
1128 | let source_map = self.parent.body_source_map(db); | ||
1129 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... | ||
1130 | let root = src.file_syntax(db); | ||
1131 | src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) | ||
1132 | } | ||
1133 | } | ||
1134 | |||
1135 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
1136 | pub struct GenericParam { | ||
1137 | pub(crate) parent: GenericDef, | ||
1138 | pub(crate) idx: u32, | ||
1139 | } | ||