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.rs55
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};
22use crate::{ 22use 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)]
1075pub struct Local {
1076 pub(crate) parent: DefWithBody,
1077 pub(crate) pat_id: PatId,
1078}
1079
1080impl 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}