aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/source_binder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r--crates/ra_hir/src/source_binder.rs66
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};
18use rustc_hash::{FxHashMap, FxHashSet}; 18use rustc_hash::FxHashSet;
19 19
20use crate::{ 20use 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> {