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