aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db/src/defs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_db/src/defs.rs')
-rw-r--r--crates/ra_ide_db/src/defs.rs56
1 files changed, 33 insertions, 23 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 8b06cbfc5..1826f3ac6 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -18,7 +18,7 @@ use ra_syntax::{
18use crate::RootDatabase; 18use crate::RootDatabase;
19 19
20// FIXME: a more precise name would probably be `Symbol`? 20// FIXME: a more precise name would probably be `Symbol`?
21#[derive(Debug, PartialEq, Eq)] 21#[derive(Debug, PartialEq, Eq, Copy, Clone)]
22pub enum Definition { 22pub enum Definition {
23 Macro(MacroDef), 23 Macro(MacroDef),
24 Field(Field), 24 Field(Field),
@@ -82,6 +82,10 @@ pub enum NameClass {
82 Definition(Definition), 82 Definition(Definition),
83 /// `None` in `if let None = Some(82) {}` 83 /// `None` in `if let None = Some(82) {}`
84 ConstReference(Definition), 84 ConstReference(Definition),
85 FieldShorthand {
86 local: Local,
87 field: Definition,
88 },
85} 89}
86 90
87impl NameClass { 91impl NameClass {
@@ -89,12 +93,14 @@ impl NameClass {
89 match self { 93 match self {
90 NameClass::Definition(it) => Some(it), 94 NameClass::Definition(it) => Some(it),
91 NameClass::ConstReference(_) => None, 95 NameClass::ConstReference(_) => None,
96 NameClass::FieldShorthand { local, field: _ } => Some(Definition::Local(local)),
92 } 97 }
93 } 98 }
94 99
95 pub fn definition(self) -> Definition { 100 pub fn definition(self) -> Definition {
96 match self { 101 match self {
97 NameClass::Definition(it) | NameClass::ConstReference(it) => it, 102 NameClass::Definition(it) | NameClass::ConstReference(it) => it,
103 NameClass::FieldShorthand { local: _, field } => field,
98 } 104 }
99 } 105 }
100} 106}
@@ -102,18 +108,14 @@ impl NameClass {
102pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> { 108pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> {
103 let _p = profile("classify_name"); 109 let _p = profile("classify_name");
104 110
105 if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) { 111 let parent = name.syntax().parent()?;
112
113 if let Some(bind_pat) = ast::BindPat::cast(parent.clone()) {
106 if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) { 114 if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
107 return Some(NameClass::ConstReference(Definition::ModuleDef(def))); 115 return Some(NameClass::ConstReference(Definition::ModuleDef(def)));
108 } 116 }
109 } 117 }
110 118
111 classify_name_inner(sema, name).map(NameClass::Definition)
112}
113
114fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Definition> {
115 let parent = name.syntax().parent()?;
116
117 match_ast! { 119 match_ast! {
118 match parent { 120 match parent {
119 ast::Alias(it) => { 121 ast::Alias(it) => {
@@ -123,63 +125,71 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
123 let name_ref = path_segment.name_ref()?; 125 let name_ref = path_segment.name_ref()?;
124 let name_ref_class = classify_name_ref(sema, &name_ref)?; 126 let name_ref_class = classify_name_ref(sema, &name_ref)?;
125 127
126 Some(name_ref_class.definition()) 128 Some(NameClass::Definition(name_ref_class.definition()))
127 }, 129 },
128 ast::BindPat(it) => { 130 ast::BindPat(it) => {
129 let local = sema.to_def(&it)?; 131 let local = sema.to_def(&it)?;
130 Some(Definition::Local(local)) 132
133 if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordFieldPat::cast) {
134 if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
135 let field = Definition::Field(field);
136 return Some(NameClass::FieldShorthand { local, field });
137 }
138 }
139
140 Some(NameClass::Definition(Definition::Local(local)))
131 }, 141 },
132 ast::RecordFieldDef(it) => { 142 ast::RecordFieldDef(it) => {
133 let field: hir::Field = sema.to_def(&it)?; 143 let field: hir::Field = sema.to_def(&it)?;
134 Some(Definition::Field(field)) 144 Some(NameClass::Definition(Definition::Field(field)))
135 }, 145 },
136 ast::Module(it) => { 146 ast::Module(it) => {
137 let def = sema.to_def(&it)?; 147 let def = sema.to_def(&it)?;
138 Some(Definition::ModuleDef(def.into())) 148 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
139 }, 149 },
140 ast::StructDef(it) => { 150 ast::StructDef(it) => {
141 let def: hir::Struct = sema.to_def(&it)?; 151 let def: hir::Struct = sema.to_def(&it)?;
142 Some(Definition::ModuleDef(def.into())) 152 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
143 }, 153 },
144 ast::UnionDef(it) => { 154 ast::UnionDef(it) => {
145 let def: hir::Union = sema.to_def(&it)?; 155 let def: hir::Union = sema.to_def(&it)?;
146 Some(Definition::ModuleDef(def.into())) 156 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
147 }, 157 },
148 ast::EnumDef(it) => { 158 ast::EnumDef(it) => {
149 let def: hir::Enum = sema.to_def(&it)?; 159 let def: hir::Enum = sema.to_def(&it)?;
150 Some(Definition::ModuleDef(def.into())) 160 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
151 }, 161 },
152 ast::TraitDef(it) => { 162 ast::TraitDef(it) => {
153 let def: hir::Trait = sema.to_def(&it)?; 163 let def: hir::Trait = sema.to_def(&it)?;
154 Some(Definition::ModuleDef(def.into())) 164 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
155 }, 165 },
156 ast::StaticDef(it) => { 166 ast::StaticDef(it) => {
157 let def: hir::Static = sema.to_def(&it)?; 167 let def: hir::Static = sema.to_def(&it)?;
158 Some(Definition::ModuleDef(def.into())) 168 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
159 }, 169 },
160 ast::EnumVariant(it) => { 170 ast::EnumVariant(it) => {
161 let def: hir::EnumVariant = sema.to_def(&it)?; 171 let def: hir::EnumVariant = sema.to_def(&it)?;
162 Some(Definition::ModuleDef(def.into())) 172 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
163 }, 173 },
164 ast::FnDef(it) => { 174 ast::FnDef(it) => {
165 let def: hir::Function = sema.to_def(&it)?; 175 let def: hir::Function = sema.to_def(&it)?;
166 Some(Definition::ModuleDef(def.into())) 176 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
167 }, 177 },
168 ast::ConstDef(it) => { 178 ast::ConstDef(it) => {
169 let def: hir::Const = sema.to_def(&it)?; 179 let def: hir::Const = sema.to_def(&it)?;
170 Some(Definition::ModuleDef(def.into())) 180 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
171 }, 181 },
172 ast::TypeAliasDef(it) => { 182 ast::TypeAliasDef(it) => {
173 let def: hir::TypeAlias = sema.to_def(&it)?; 183 let def: hir::TypeAlias = sema.to_def(&it)?;
174 Some(Definition::ModuleDef(def.into())) 184 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
175 }, 185 },
176 ast::MacroCall(it) => { 186 ast::MacroCall(it) => {
177 let def = sema.to_def(&it)?; 187 let def = sema.to_def(&it)?;
178 Some(Definition::Macro(def)) 188 Some(NameClass::Definition(Definition::Macro(def)))
179 }, 189 },
180 ast::TypeParam(it) => { 190 ast::TypeParam(it) => {
181 let def = sema.to_def(&it)?; 191 let def = sema.to_def(&it)?;
182 Some(Definition::TypeParam(def)) 192 Some(NameClass::Definition(Definition::TypeParam(def)))
183 }, 193 },
184 _ => None, 194 _ => None,
185 } 195 }