diff options
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index e5bfad3ca..09c4e97fa 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -22,7 +22,7 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | |||
22 | use crate::{ | 22 | use crate::{ |
23 | adt::VariantDef, | 23 | adt::VariantDef, |
24 | db::{AstDatabase, DefDatabase, HirDatabase}, | 24 | db::{AstDatabase, DefDatabase, HirDatabase}, |
25 | expr::{validation::ExprValidator, Body, BodySourceMap}, | 25 | expr::{validation::ExprValidator, BindingAnnotation, Body, BodySourceMap, Pat, PatId}, |
26 | generics::HasGenericParams, | 26 | generics::HasGenericParams, |
27 | ids::{ | 27 | ids::{ |
28 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, | 28 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, |
@@ -32,7 +32,7 @@ use crate::{ | |||
32 | resolve::{Resolver, Scope, TypeNs}, | 32 | resolve::{Resolver, Scope, TypeNs}, |
33 | traits::TraitData, | 33 | traits::TraitData, |
34 | ty::{InferenceResult, Namespace, TraitRef}, | 34 | ty::{InferenceResult, Namespace, TraitRef}, |
35 | Either, HasSource, ImportId, Name, ScopeDef, Ty, | 35 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, |
36 | }; | 36 | }; |
37 | 37 | ||
38 | /// hir::Crate describes a single crate. It's the main interface with which | 38 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -1070,3 +1070,54 @@ impl AssocItem { | |||
1070 | .expect("AssocItem without container") | 1070 | .expect("AssocItem without container") |
1071 | } | 1071 | } |
1072 | } | 1072 | } |
1073 | |||
1074 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
1075 | pub struct Local { | ||
1076 | pub(crate) parent: DefWithBody, | ||
1077 | pub(crate) pat_id: PatId, | ||
1078 | } | ||
1079 | |||
1080 | impl Local { | ||
1081 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { | ||
1082 | let body = db.body_hir(self.parent); | ||
1083 | match &body[self.pat_id] { | ||
1084 | Pat::Bind { name, .. } => Some(name.clone()), | ||
1085 | _ => None, | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | pub fn is_self(self, db: &impl HirDatabase) -> bool { | ||
1090 | self.name(db) == Some(name::SELF_PARAM) | ||
1091 | } | ||
1092 | |||
1093 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { | ||
1094 | let body = db.body_hir(self.parent); | ||
1095 | match &body[self.pat_id] { | ||
1096 | Pat::Bind { mode, .. } => match mode { | ||
1097 | BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, | ||
1098 | _ => false, | ||
1099 | }, | ||
1100 | _ => false, | ||
1101 | } | ||
1102 | } | ||
1103 | |||
1104 | pub fn parent(self, _db: &impl HirDatabase) -> DefWithBody { | ||
1105 | self.parent | ||
1106 | } | ||
1107 | |||
1108 | pub fn module(self, db: &impl HirDatabase) -> Module { | ||
1109 | self.parent.module(db) | ||
1110 | } | ||
1111 | |||
1112 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | ||
1113 | let infer = db.infer(self.parent); | ||
1114 | infer[self.pat_id].clone() | ||
1115 | } | ||
1116 | |||
1117 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | ||
1118 | let (_body, source_map) = db.body_with_source_map(self.parent); | ||
1119 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... | ||
1120 | let root = src.file_syntax(db); | ||
1121 | src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) | ||
1122 | } | ||
1123 | } | ||