diff options
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 65b304b43..cff55b640 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -15,7 +15,7 @@ use ra_syntax::{ | |||
15 | SyntaxKind::*, | 15 | SyntaxKind::*, |
16 | SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, | 16 | SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, |
17 | }; | 17 | }; |
18 | use rustc_hash::{FxHashMap, FxHashSet}; | 18 | use rustc_hash::FxHashSet; |
19 | 19 | ||
20 | use crate::{ | 20 | use crate::{ |
21 | db::HirDatabase, | 21 | db::HirDatabase, |
@@ -27,9 +27,10 @@ use crate::{ | |||
27 | ids::LocationCtx, | 27 | ids::LocationCtx, |
28 | name, | 28 | name, |
29 | path::{PathKind, PathSegment}, | 29 | path::{PathKind, PathSegment}, |
30 | resolve::{ScopeDef, TypeNs, ValueNs}, | ||
30 | ty::method_resolution::implements_trait, | 31 | ty::method_resolution::implements_trait, |
31 | AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HasBody, HirFileId, MacroDef, | 32 | AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HasBody, HirFileId, MacroDef, |
32 | Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty, | 33 | Module, Name, Path, Resolver, Static, Struct, Trait, Ty, |
33 | }; | 34 | }; |
34 | 35 | ||
35 | /// Locates the module by `FileId`. Picks topmost module in the file. | 36 | /// Locates the module by `FileId`. Picks topmost module in the file. |
@@ -301,8 +302,41 @@ impl SourceAnalyzer { | |||
301 | &self, | 302 | &self, |
302 | db: &impl HirDatabase, | 303 | db: &impl HirDatabase, |
303 | path: &crate::Path, | 304 | path: &crate::Path, |
304 | ) -> PerNs<crate::Resolution> { | 305 | ) -> Option<PathResolution> { |
305 | self.resolver.resolve_path_without_assoc_items(db, path) | 306 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { |
307 | TypeNs::SelfType(it) => PathResolution::SelfType(it), | ||
308 | TypeNs::GenericParam(it) => PathResolution::GenericParam(it), | ||
309 | TypeNs::Adt(it) => PathResolution::Def(it.into()), | ||
310 | TypeNs::EnumVariant(it) => PathResolution::Def(it.into()), | ||
311 | TypeNs::TypeAlias(it) => PathResolution::Def(it.into()), | ||
312 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | ||
313 | TypeNs::Trait(it) => PathResolution::Def(it.into()), | ||
314 | }); | ||
315 | let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { | ||
316 | let res = match val { | ||
317 | ValueNs::LocalBinding(it) => { | ||
318 | // We get a `PatId` from resolver, but it actually can only | ||
319 | // point at `BindPat`, and not at the arbitrary pattern. | ||
320 | let pat_ptr = self | ||
321 | .body_source_map | ||
322 | .as_ref()? | ||
323 | .pat_syntax(it)? | ||
324 | .ast // FIXME: ignoring file_id here is definitelly wrong | ||
325 | .map_a(|ptr| ptr.cast::<ast::BindPat>().unwrap()); | ||
326 | PathResolution::LocalBinding(pat_ptr) | ||
327 | } | ||
328 | ValueNs::Function(it) => PathResolution::Def(it.into()), | ||
329 | ValueNs::Const(it) => PathResolution::Def(it.into()), | ||
330 | ValueNs::Static(it) => PathResolution::Def(it.into()), | ||
331 | ValueNs::Struct(it) => PathResolution::Def(it.into()), | ||
332 | ValueNs::EnumVariant(it) => PathResolution::Def(it.into()), | ||
333 | }; | ||
334 | Some(res) | ||
335 | }); | ||
336 | |||
337 | let items = | ||
338 | self.resolver.resolve_module_path(db, &path).take_types().map(PathResolution::Def); | ||
339 | types.or(values).or(items) | ||
306 | } | 340 | } |
307 | 341 | ||
308 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option<PathResolution> { | 342 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option<PathResolution> { |
@@ -319,25 +353,7 @@ impl SourceAnalyzer { | |||
319 | } | 353 | } |
320 | } | 354 | } |
321 | let hir_path = crate::Path::from_ast(path.clone())?; | 355 | let hir_path = crate::Path::from_ast(path.clone())?; |
322 | let res = self.resolver.resolve_path_without_assoc_items(db, &hir_path); | 356 | self.resolve_hir_path(db, &hir_path) |
323 | let res = res.clone().take_types().or_else(|| res.take_values())?; | ||
324 | let res = match res { | ||
325 | crate::Resolution::Def(it) => PathResolution::Def(it), | ||
326 | crate::Resolution::LocalBinding(it) => { | ||
327 | // We get a `PatId` from resolver, but it actually can only | ||
328 | // point at `BindPat`, and not at the arbitrary pattern. | ||
329 | let pat_ptr = self | ||
330 | .body_source_map | ||
331 | .as_ref()? | ||
332 | .pat_syntax(it)? | ||
333 | .ast // FIXME: ignoring file_id here is definitelly wrong | ||
334 | .map_a(|ptr| ptr.cast::<ast::BindPat>().unwrap()); | ||
335 | PathResolution::LocalBinding(pat_ptr) | ||
336 | } | ||
337 | crate::Resolution::GenericParam(it) => PathResolution::GenericParam(it), | ||
338 | crate::Resolution::SelfType(it) => PathResolution::SelfType(it), | ||
339 | }; | ||
340 | Some(res) | ||
341 | } | 357 | } |
342 | 358 | ||
343 | pub fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> { | 359 | pub fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> { |
@@ -360,8 +376,8 @@ impl SourceAnalyzer { | |||
360 | }) | 376 | }) |
361 | } | 377 | } |
362 | 378 | ||
363 | pub fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<crate::Resolution>> { | 379 | pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { |
364 | self.resolver.all_names(db) | 380 | self.resolver.process_all_names(db, f) |
365 | } | 381 | } |
366 | 382 | ||
367 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | 383 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { |