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, 30 insertions, 26 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 52233937c..853d856e7 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -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(field),
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: _ } => Definition::Local(local),
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,69 +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) => {
131 let local = sema.to_def(&it)?;
132
129 if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordFieldPat::cast) { 133 if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordFieldPat::cast) {
130 return Some(Definition::Field( 134 if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
131 sema.resolve_record_field_pat(&record_field_pat)? 135 let field = Definition::Field(field);
132 )); 136 return Some(NameClass::FieldShorthand { local, field });
137 }
133 } 138 }
134 139
135 let local = sema.to_def(&it)?; 140 Some(NameClass::Definition(Definition::Local(local)))
136 Some(Definition::Local(local))
137 }, 141 },
138 ast::RecordFieldDef(it) => { 142 ast::RecordFieldDef(it) => {
139 let field: hir::Field = sema.to_def(&it)?; 143 let field: hir::Field = sema.to_def(&it)?;
140 Some(Definition::Field(field)) 144 Some(NameClass::Definition(Definition::Field(field)))
141 }, 145 },
142 ast::Module(it) => { 146 ast::Module(it) => {
143 let def = sema.to_def(&it)?; 147 let def = sema.to_def(&it)?;
144 Some(Definition::ModuleDef(def.into())) 148 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
145 }, 149 },
146 ast::StructDef(it) => { 150 ast::StructDef(it) => {
147 let def: hir::Struct = sema.to_def(&it)?; 151 let def: hir::Struct = sema.to_def(&it)?;
148 Some(Definition::ModuleDef(def.into())) 152 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
149 }, 153 },
150 ast::UnionDef(it) => { 154 ast::UnionDef(it) => {
151 let def: hir::Union = sema.to_def(&it)?; 155 let def: hir::Union = sema.to_def(&it)?;
152 Some(Definition::ModuleDef(def.into())) 156 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
153 }, 157 },
154 ast::EnumDef(it) => { 158 ast::EnumDef(it) => {
155 let def: hir::Enum = sema.to_def(&it)?; 159 let def: hir::Enum = sema.to_def(&it)?;
156 Some(Definition::ModuleDef(def.into())) 160 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
157 }, 161 },
158 ast::TraitDef(it) => { 162 ast::TraitDef(it) => {
159 let def: hir::Trait = sema.to_def(&it)?; 163 let def: hir::Trait = sema.to_def(&it)?;
160 Some(Definition::ModuleDef(def.into())) 164 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
161 }, 165 },
162 ast::StaticDef(it) => { 166 ast::StaticDef(it) => {
163 let def: hir::Static = sema.to_def(&it)?; 167 let def: hir::Static = sema.to_def(&it)?;
164 Some(Definition::ModuleDef(def.into())) 168 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
165 }, 169 },
166 ast::EnumVariant(it) => { 170 ast::EnumVariant(it) => {
167 let def: hir::EnumVariant = sema.to_def(&it)?; 171 let def: hir::EnumVariant = sema.to_def(&it)?;
168 Some(Definition::ModuleDef(def.into())) 172 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
169 }, 173 },
170 ast::FnDef(it) => { 174 ast::FnDef(it) => {
171 let def: hir::Function = sema.to_def(&it)?; 175 let def: hir::Function = sema.to_def(&it)?;
172 Some(Definition::ModuleDef(def.into())) 176 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
173 }, 177 },
174 ast::ConstDef(it) => { 178 ast::ConstDef(it) => {
175 let def: hir::Const = sema.to_def(&it)?; 179 let def: hir::Const = sema.to_def(&it)?;
176 Some(Definition::ModuleDef(def.into())) 180 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
177 }, 181 },
178 ast::TypeAliasDef(it) => { 182 ast::TypeAliasDef(it) => {
179 let def: hir::TypeAlias = sema.to_def(&it)?; 183 let def: hir::TypeAlias = sema.to_def(&it)?;
180 Some(Definition::ModuleDef(def.into())) 184 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
181 }, 185 },
182 ast::MacroCall(it) => { 186 ast::MacroCall(it) => {
183 let def = sema.to_def(&it)?; 187 let def = sema.to_def(&it)?;
184 Some(Definition::Macro(def)) 188 Some(NameClass::Definition(Definition::Macro(def)))
185 }, 189 },
186 ast::TypeParam(it) => { 190 ast::TypeParam(it) => {
187 let def = sema.to_def(&it)?; 191 let def = sema.to_def(&it)?;
188 Some(Definition::TypeParam(def)) 192 Some(NameClass::Definition(Definition::TypeParam(def)))
189 }, 193 },
190 _ => None, 194 _ => None,
191 } 195 }