mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-06 03:52:53 +00:00
classify module from declaration
This commit is contained in:
parent
93c179531b
commit
55e1910d00
@ -181,7 +181,6 @@ impl Module {
|
|||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let decl_id = match src.ast {
|
let decl_id = match src.ast {
|
||||||
ModuleSource::Module(ref module) => {
|
ModuleSource::Module(ref module) => {
|
||||||
assert!(!module.has_semi());
|
|
||||||
let ast_id_map = db.ast_id_map(src.file_id);
|
let ast_id_map = db.ast_id_map(src.file_id);
|
||||||
let item_id = ast_id_map.ast_id(module).with_file_id(src.file_id);
|
let item_id = ast_id_map.ast_id(module).with_file_id(src.file_id);
|
||||||
Some(item_id)
|
Some(item_id)
|
||||||
|
@ -232,7 +232,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_find_all_refs_modules() {
|
fn test_find_all_refs_two_modules() {
|
||||||
let code = r#"
|
let code = r#"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
pub mod foo;
|
pub mod foo;
|
||||||
@ -270,6 +270,33 @@ mod tests {
|
|||||||
assert_eq!(refs.len(), 3);
|
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,
|
||||||
|
// which is the whole `foo.rs`, and the second one is in `use foo::Foo`.
|
||||||
|
#[test]
|
||||||
|
fn test_find_all_refs_decl_module() {
|
||||||
|
let code = r#"
|
||||||
|
//- /lib.rs
|
||||||
|
mod foo<|>;
|
||||||
|
|
||||||
|
use foo::Foo;
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
let i = Foo { n: 5 };
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /foo.rs
|
||||||
|
pub 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(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
fn get_all_refs(text: &str) -> ReferenceSearchResult {
|
fn get_all_refs(text: &str) -> ReferenceSearchResult {
|
||||||
let (analysis, position) = single_file_with_position(text);
|
let (analysis, position) = single_file_with_position(text);
|
||||||
analysis.find_all_refs(position).unwrap().unwrap()
|
analysis.find_all_refs(position).unwrap().unwrap()
|
||||||
|
@ -31,9 +31,16 @@ pub(crate) fn classify_name(
|
|||||||
Some(from_struct_field(db, field))
|
Some(from_struct_field(db, field))
|
||||||
},
|
},
|
||||||
ast::Module(it) => {
|
ast::Module(it) => {
|
||||||
let ast = hir::ModuleSource::Module(it);
|
let def = {
|
||||||
let src = hir::Source { file_id, ast };
|
if !it.has_semi() {
|
||||||
let def = hir::Module::from_definition(db, src)?;
|
let ast = hir::ModuleSource::Module(it);
|
||||||
|
let src = hir::Source { file_id, ast };
|
||||||
|
hir::Module::from_definition(db, src)
|
||||||
|
} else {
|
||||||
|
let src = hir::Source { file_id, ast: it };
|
||||||
|
hir::Module::from_declaration(db, src)
|
||||||
|
}
|
||||||
|
}?;
|
||||||
Some(from_module_def(db, def.into(), None))
|
Some(from_module_def(db, def.into(), None))
|
||||||
},
|
},
|
||||||
ast::StructDef(it) => {
|
ast::StructDef(it) => {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use hir::{DefWithBody, HasSource, ModuleSource};
|
use hir::{DefWithBody, HasSource, ModuleSource};
|
||||||
use ra_db::{FileId, SourceDatabase, SourceDatabaseExt};
|
use ra_db::{FileId, SourceDatabase, SourceDatabaseExt};
|
||||||
use ra_syntax::{AstNode, TextRange};
|
use ra_syntax::{AstNode, TextRange};
|
||||||
@ -9,7 +11,7 @@ use crate::db::RootDatabase;
|
|||||||
use super::{NameDefinition, NameKind};
|
use super::{NameDefinition, NameKind};
|
||||||
|
|
||||||
impl NameDefinition {
|
impl NameDefinition {
|
||||||
pub(crate) fn search_scope(&self, db: &RootDatabase) -> Vec<(FileId, Option<TextRange>)> {
|
pub(crate) fn search_scope(&self, db: &RootDatabase) -> HashSet<(FileId, Option<TextRange>)> {
|
||||||
let module_src = self.container.definition_source(db);
|
let module_src = self.container.definition_source(db);
|
||||||
let file_id = module_src.file_id.original_file(db);
|
let file_id = module_src.file_id.original_file(db);
|
||||||
|
|
||||||
@ -19,13 +21,13 @@ impl NameDefinition {
|
|||||||
DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(),
|
DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(),
|
||||||
DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(),
|
DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(),
|
||||||
};
|
};
|
||||||
return vec![(file_id, Some(range))];
|
return [(file_id, Some(range))].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref vis) = self.visibility {
|
if let Some(ref vis) = self.visibility {
|
||||||
let source_root_id = db.file_source_root(file_id);
|
let source_root_id = db.file_source_root(file_id);
|
||||||
let source_root = db.source_root(source_root_id);
|
let source_root = db.source_root(source_root_id);
|
||||||
let mut files = source_root.walk().map(|id| (id.into(), None)).collect::<Vec<_>>();
|
let mut files = source_root.walk().map(|id| (id.into(), None)).collect::<HashSet<_>>();
|
||||||
|
|
||||||
if vis.syntax().to_string().as_str() == "pub(crate)" {
|
if vis.syntax().to_string().as_str() == "pub(crate)" {
|
||||||
return files;
|
return files;
|
||||||
@ -54,6 +56,6 @@ impl NameDefinition {
|
|||||||
ModuleSource::Module(m) => Some(m.syntax().text_range()),
|
ModuleSource::Module(m) => Some(m.syntax().text_range()),
|
||||||
ModuleSource::SourceFile(_) => None,
|
ModuleSource::SourceFile(_) => None,
|
||||||
};
|
};
|
||||||
vec![(file_id, range)]
|
[(file_id, range)].iter().cloned().collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user