diff options
Diffstat (limited to 'crates/ra_ide_db/src/defs.rs')
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 91 |
1 files changed, 62 insertions, 29 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index bc6e89cbc..80c99935d 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs | |||
@@ -136,7 +136,7 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option | |||
136 | 136 | ||
137 | match_ast! { | 137 | match_ast! { |
138 | match parent { | 138 | match parent { |
139 | ast::Alias(it) => { | 139 | ast::Rename(it) => { |
140 | let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; | 140 | let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; |
141 | let path = use_tree.path()?; | 141 | let path = use_tree.path()?; |
142 | let path_segment = path.segment()?; | 142 | let path_segment = path.segment()?; |
@@ -159,7 +159,7 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option | |||
159 | 159 | ||
160 | Some(NameClass::Definition(Definition::Local(local))) | 160 | Some(NameClass::Definition(Definition::Local(local))) |
161 | }, | 161 | }, |
162 | ast::RecordFieldDef(it) => { | 162 | ast::RecordField(it) => { |
163 | let field: hir::Field = sema.to_def(&it)?; | 163 | let field: hir::Field = sema.to_def(&it)?; |
164 | Some(NameClass::Definition(Definition::Field(field))) | 164 | Some(NameClass::Definition(Definition::Field(field))) |
165 | }, | 165 | }, |
@@ -167,39 +167,39 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option | |||
167 | let def = sema.to_def(&it)?; | 167 | let def = sema.to_def(&it)?; |
168 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 168 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
169 | }, | 169 | }, |
170 | ast::StructDef(it) => { | 170 | ast::Struct(it) => { |
171 | let def: hir::Struct = sema.to_def(&it)?; | 171 | let def: hir::Struct = sema.to_def(&it)?; |
172 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 172 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
173 | }, | 173 | }, |
174 | ast::UnionDef(it) => { | 174 | ast::Union(it) => { |
175 | let def: hir::Union = sema.to_def(&it)?; | 175 | let def: hir::Union = sema.to_def(&it)?; |
176 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 176 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
177 | }, | 177 | }, |
178 | ast::EnumDef(it) => { | 178 | ast::Enum(it) => { |
179 | let def: hir::Enum = sema.to_def(&it)?; | 179 | let def: hir::Enum = sema.to_def(&it)?; |
180 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 180 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
181 | }, | 181 | }, |
182 | ast::TraitDef(it) => { | 182 | ast::Trait(it) => { |
183 | let def: hir::Trait = sema.to_def(&it)?; | 183 | let def: hir::Trait = sema.to_def(&it)?; |
184 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 184 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
185 | }, | 185 | }, |
186 | ast::StaticDef(it) => { | 186 | ast::Static(it) => { |
187 | let def: hir::Static = sema.to_def(&it)?; | 187 | let def: hir::Static = sema.to_def(&it)?; |
188 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 188 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
189 | }, | 189 | }, |
190 | ast::EnumVariant(it) => { | 190 | ast::Variant(it) => { |
191 | let def: hir::EnumVariant = sema.to_def(&it)?; | 191 | let def: hir::EnumVariant = sema.to_def(&it)?; |
192 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 192 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
193 | }, | 193 | }, |
194 | ast::FnDef(it) => { | 194 | ast::Fn(it) => { |
195 | let def: hir::Function = sema.to_def(&it)?; | 195 | let def: hir::Function = sema.to_def(&it)?; |
196 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 196 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
197 | }, | 197 | }, |
198 | ast::ConstDef(it) => { | 198 | ast::Const(it) => { |
199 | let def: hir::Const = sema.to_def(&it)?; | 199 | let def: hir::Const = sema.to_def(&it)?; |
200 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 200 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
201 | }, | 201 | }, |
202 | ast::TypeAliasDef(it) => { | 202 | ast::TypeAlias(it) => { |
203 | let def: hir::TypeAlias = sema.to_def(&it)?; | 203 | let def: hir::TypeAlias = sema.to_def(&it)?; |
204 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 204 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
205 | }, | 205 | }, |
@@ -253,7 +253,7 @@ pub fn classify_name_ref( | |||
253 | } | 253 | } |
254 | } | 254 | } |
255 | 255 | ||
256 | if let Some(record_field) = ast::RecordField::for_field_name(name_ref) { | 256 | if let Some(record_field) = ast::RecordExprField::for_field_name(name_ref) { |
257 | if let Some((field, local)) = sema.resolve_record_field(&record_field) { | 257 | if let Some((field, local)) = sema.resolve_record_field(&record_field) { |
258 | let field = Definition::Field(field); | 258 | let field = Definition::Field(field); |
259 | let res = match local { | 259 | let res = match local { |
@@ -271,28 +271,61 @@ pub fn classify_name_ref( | |||
271 | } | 271 | } |
272 | } | 272 | } |
273 | 273 | ||
274 | if ast::AssocTypeArg::cast(parent.clone()).is_some() { | ||
275 | // `Trait<Assoc = Ty>` | ||
276 | // ^^^^^ | ||
277 | let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?; | ||
278 | let resolved = sema.resolve_path(&path)?; | ||
279 | if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved { | ||
280 | if let Some(ty) = tr | ||
281 | .items(sema.db) | ||
282 | .iter() | ||
283 | .filter_map(|assoc| match assoc { | ||
284 | hir::AssocItem::TypeAlias(it) => Some(*it), | ||
285 | _ => None, | ||
286 | }) | ||
287 | .find(|alias| alias.name(sema.db).to_string() == **name_ref.text()) | ||
288 | { | ||
289 | return Some(NameRefClass::Definition(Definition::ModuleDef( | ||
290 | ModuleDef::TypeAlias(ty), | ||
291 | ))); | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | |||
274 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { | 296 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { |
275 | if let Some(macro_def) = sema.resolve_macro_call(¯o_call) { | 297 | if let Some(path) = macro_call.path() { |
276 | return Some(NameRefClass::Definition(Definition::Macro(macro_def))); | 298 | if path.qualifier().is_none() { |
299 | // Only use this to resolve single-segment macro calls like `foo!()`. Multi-segment | ||
300 | // paths are handled below (allowing `log<|>::info!` to resolve to the log crate). | ||
301 | if let Some(macro_def) = sema.resolve_macro_call(¯o_call) { | ||
302 | return Some(NameRefClass::Definition(Definition::Macro(macro_def))); | ||
303 | } | ||
304 | } | ||
277 | } | 305 | } |
278 | } | 306 | } |
279 | 307 | ||
280 | let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?; | 308 | let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?; |
281 | let resolved = sema.resolve_path(&path)?; | 309 | let resolved = sema.resolve_path(&path)?; |
282 | let res = match resolved { | 310 | Some(NameRefClass::Definition(resolved.into())) |
283 | PathResolution::Def(def) => Definition::ModuleDef(def), | 311 | } |
284 | PathResolution::AssocItem(item) => { | 312 | |
285 | let def = match item { | 313 | impl From<PathResolution> for Definition { |
286 | hir::AssocItem::Function(it) => it.into(), | 314 | fn from(path_resolution: PathResolution) -> Self { |
287 | hir::AssocItem::Const(it) => it.into(), | 315 | match path_resolution { |
288 | hir::AssocItem::TypeAlias(it) => it.into(), | 316 | PathResolution::Def(def) => Definition::ModuleDef(def), |
289 | }; | 317 | PathResolution::AssocItem(item) => { |
290 | Definition::ModuleDef(def) | 318 | let def = match item { |
319 | hir::AssocItem::Function(it) => it.into(), | ||
320 | hir::AssocItem::Const(it) => it.into(), | ||
321 | hir::AssocItem::TypeAlias(it) => it.into(), | ||
322 | }; | ||
323 | Definition::ModuleDef(def) | ||
324 | } | ||
325 | PathResolution::Local(local) => Definition::Local(local), | ||
326 | PathResolution::TypeParam(par) => Definition::TypeParam(par), | ||
327 | PathResolution::Macro(def) => Definition::Macro(def), | ||
328 | PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), | ||
291 | } | 329 | } |
292 | PathResolution::Local(local) => Definition::Local(local), | 330 | } |
293 | PathResolution::TypeParam(par) => Definition::TypeParam(par), | ||
294 | PathResolution::Macro(def) => Definition::Macro(def), | ||
295 | PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), | ||
296 | }; | ||
297 | Some(NameRefClass::Definition(res)) | ||
298 | } | 331 | } |