support items that visible to the parent module

This commit is contained in:
Ekaterina Babshukova 2019-10-16 16:49:35 +03:00
parent 55e1910d00
commit b5a3ee93e2
3 changed files with 68 additions and 5 deletions

View file

@ -270,9 +270,8 @@ mod tests {
assert_eq!(refs.len(), 3);
}
// `mod foo;` is not in the results because `foo` is an `ast::Name`.
// So, there are two references: the first one is a definition of the `foo` module,
// So, there are two references: the first one is a definition of the `foo` module,
// which is the whole `foo.rs`, and the second one is in `use foo::Foo`.
#[test]
fn test_find_all_refs_decl_module() {
@ -297,6 +296,31 @@ mod tests {
assert_eq!(refs.len(), 2);
}
#[test]
fn test_find_all_refs_super_mod_vis() {
let code = r#"
//- /lib.rs
mod foo;
//- /foo.rs
mod some;
use some::Foo;
fn f() {
let i = Foo { n: 5 };
}
//- /foo/some.rs
pub(super) struct Foo<|> {
pub n: u32,
}
"#;
let (analysis, pos) = analysis_and_position(code);
let refs = analysis.find_all_refs(pos).unwrap().unwrap();
assert_eq!(refs.len(), 3);
}
fn get_all_refs(text: &str) -> ReferenceSearchResult {
let (analysis, position) = single_file_with_position(text);
analysis.find_all_refs(position).unwrap().unwrap()

View file

@ -152,6 +152,7 @@ pub(crate) fn classify_name_ref(
AssocItem(item) => Some(from_assoc_item(db, item)),
LocalBinding(Either::A(pat)) => from_pat(db, file_id, pat),
LocalBinding(Either::B(par)) => {
// Not really supported
let kind = NameKind::SelfParam(par);
Some(NameDefinition { kind, container, visibility })
}

View file

@ -25,14 +25,53 @@ impl NameDefinition {
}
if let Some(ref vis) = self.visibility {
let vis = vis.syntax().to_string();
// FIXME: add "pub(in path)"
if vis.as_str() == "pub(super)" {
if let Some(parent_module) = self.container.parent(db) {
let mut files = HashSet::new();
let parent_src = parent_module.definition_source(db);
let file_id = parent_src.file_id.original_file(db);
match parent_src.ast {
ModuleSource::Module(m) => {
let range = Some(m.syntax().text_range());
files.insert((file_id, range));
}
ModuleSource::SourceFile(_) => {
files.insert((file_id, None));
files.extend(
parent_module
.children(db)
.map(|m| {
let src = m.definition_source(db);
(src.file_id.original_file(db), None)
})
.collect::<HashSet<_>>(),
);
}
}
return files;
} else {
let range = match module_src.ast {
ModuleSource::Module(m) => Some(m.syntax().text_range()),
ModuleSource::SourceFile(_) => None,
};
return [(file_id, range)].iter().cloned().collect();
}
}
let source_root_id = db.file_source_root(file_id);
let source_root = db.source_root(source_root_id);
let mut files = source_root.walk().map(|id| (id.into(), None)).collect::<HashSet<_>>();
if vis.syntax().to_string().as_str() == "pub(crate)" {
if vis.as_str() == "pub(crate)" {
return files;
}
if vis.syntax().to_string().as_str() == "pub" {
if vis.as_str() == "pub" {
let krate = self.container.krate(db).unwrap();
let crate_graph = db.crate_graph();
@ -49,7 +88,6 @@ impl NameDefinition {
return files;
}
// FIXME: "pub(super)", "pub(in path)"
}
let range = match module_src.ast {