Skip to content

Commit 8579a9b

Browse files
committed
Added support attribute path in resolusion module fn
1 parent 35a0f04 commit 8579a9b

File tree

2 files changed

+119
-5
lines changed

2 files changed

+119
-5
lines changed

crates/ra_hir/src/nameres/collector.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use arrayvec::ArrayVec;
22
use ra_db::FileId;
3-
use ra_syntax::ast;
3+
use ra_syntax::{ast, SmolStr};
44
use relative_path::RelativePathBuf;
55
use rustc_hash::FxHashMap;
66
use test_utils::tested_by;
@@ -509,10 +509,16 @@ where
509509
.collect(&*items);
510510
}
511511
// out of line module, resolve, parse and recurse
512-
raw::ModuleData::Declaration { name, ast_id, .. } => {
512+
raw::ModuleData::Declaration { name, ast_id, attr_path } => {
513513
let ast_id = ast_id.with_file_id(self.file_id);
514514
let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none();
515-
match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) {
515+
match resolve_submodule(
516+
self.def_collector.db,
517+
self.file_id,
518+
name,
519+
is_root,
520+
attr_path.as_ref(),
521+
) {
516522
Ok(file_id) => {
517523
let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
518524
let raw_items = self.def_collector.db.raw_items(file_id.into());
@@ -626,6 +632,7 @@ fn resolve_submodule(
626632
file_id: HirFileId,
627633
name: &Name,
628634
is_root: bool,
635+
attr_path: Option<&SmolStr>,
629636
) -> Result<FileId, RelativePathBuf> {
630637
// FIXME: handle submodules of inline modules properly
631638
let file_id = file_id.original_file(db);
@@ -639,7 +646,13 @@ fn resolve_submodule(
639646
let file_mod = dir_path.join(format!("{}.rs", name));
640647
let dir_mod = dir_path.join(format!("{}/mod.rs", name));
641648
let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
642-
let mut candidates = ArrayVec::<[_; 2]>::new();
649+
let mut candidates = ArrayVec::<[_; 3]>::new();
650+
let file_attr_mod = attr_path.map(|file_path| {
651+
let file_attr_mod = dir_path.join(file_path.to_string());
652+
candidates.push(file_attr_mod.clone());
653+
654+
file_attr_mod
655+
});
643656
if is_dir_owner {
644657
candidates.push(file_mod.clone());
645658
candidates.push(dir_mod);
@@ -651,7 +664,13 @@ fn resolve_submodule(
651664
// FIXME: handle ambiguity
652665
match points_to.next() {
653666
Some(file_id) => Ok(file_id),
654-
None => Err(if is_dir_owner { file_mod } else { file_dir_mod }),
667+
None => {
668+
if let Some(file_attr_mod) = file_attr_mod {
669+
Err(file_attr_mod)
670+
} else {
671+
Err(if is_dir_owner { file_mod } else { file_dir_mod })
672+
}
673+
}
655674
}
656675
}
657676

crates/ra_hir/src/nameres/tests.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,101 @@ fn module_resolution_works_for_raw_modules() {
364364
"###);
365365
}
366366

367+
#[test]
368+
fn module_resolution_decl_path() {
369+
let map = def_map_with_crate_graph(
370+
"
371+
//- /library.rs
372+
#[path = \"bar/baz/foo.rs\"]
373+
mod foo;
374+
use self::foo::Bar;
375+
376+
//- /bar/baz/foo.rs
377+
pub struct Bar;
378+
",
379+
crate_graph! {
380+
"library": ("/library.rs", []),
381+
},
382+
);
383+
384+
assert_snapshot_matches!(map, @r###"
385+
⋮crate
386+
⋮Bar: t v
387+
⋮foo: t
388+
389+
⋮crate::foo
390+
⋮Bar: t v
391+
"###);
392+
}
393+
394+
#[test]
395+
fn module_resolution_module_with_path_in_mod_rs() {
396+
let map = def_map_with_crate_graph(
397+
"
398+
//- /main.rs
399+
mod foo;
400+
401+
//- /foo/mod.rs
402+
#[path = \"baz.rs\"]
403+
pub mod bar;
404+
405+
use self::bar::Baz;
406+
407+
//- /foo/baz.rs
408+
pub struct Baz;
409+
",
410+
crate_graph! {
411+
"main": ("/main.rs", []),
412+
},
413+
);
414+
415+
assert_snapshot_matches!(map, @r###"
416+
⋮crate
417+
⋮foo: t
418+
419+
⋮crate::foo
420+
⋮Baz: t v
421+
⋮bar: t
422+
423+
⋮crate::foo::bar
424+
⋮Baz: t v
425+
"###);
426+
}
427+
428+
#[test]
429+
fn module_resolution_module_with_path_non_crate_root() {
430+
let map = def_map_with_crate_graph(
431+
"
432+
//- /main.rs
433+
mod foo;
434+
435+
//- /foo.rs
436+
#[path = \"baz.rs\"]
437+
pub mod bar;
438+
439+
use self::bar::Baz;
440+
441+
//- /baz.rs
442+
pub struct Baz;
443+
",
444+
crate_graph! {
445+
"main": ("/main.rs", []),
446+
},
447+
);
448+
449+
assert_snapshot_matches!(map, @r###"
450+
⋮crate
451+
⋮foo: t
452+
453+
⋮crate::foo
454+
⋮Baz: t v
455+
⋮bar: t
456+
457+
⋮crate::foo::bar
458+
⋮Baz: t v
459+
"###);
460+
}
461+
367462
#[test]
368463
fn name_res_works_for_broken_modules() {
369464
covers!(name_res_works_for_broken_modules);

0 commit comments

Comments
 (0)