) -> Option<Self> {
let decl_id = match src.ast {
ModuleSource::Module(ref module) => {
- assert!(!module.has_semi());
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);
Some(item_id)
}
#[test]
- fn test_find_all_refs_modules() {
+ fn test_find_all_refs_two_modules() {
let code = r#"
//- /lib.rs
pub mod foo;
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 {
let (analysis, position) = single_file_with_position(text);
analysis.find_all_refs(position).unwrap().unwrap()
Some(from_struct_field(db, field))
},
ast::Module(it) => {
- let ast = hir::ModuleSource::Module(it);
- let src = hir::Source { file_id, ast };
- let def = hir::Module::from_definition(db, src)?;
+ let def = {
+ if !it.has_semi() {
+ 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))
},
ast::StructDef(it) => {
//! FIXME: write short doc here
+use std::collections::HashSet;
+
use hir::{DefWithBody, HasSource, ModuleSource};
use ra_db::{FileId, SourceDatabase, SourceDatabaseExt};
use ra_syntax::{AstNode, TextRange};
use super::{NameDefinition, NameKind};
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 file_id = module_src.file_id.original_file(db);
DefWithBody::Const(c) => c.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 {
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::<Vec<_>>();
+ let mut files = source_root.walk().map(|id| (id.into(), None)).collect::<HashSet<_>>();
if vis.syntax().to_string().as_str() == "pub(crate)" {
return files;
ModuleSource::Module(m) => Some(m.syntax().text_range()),
ModuleSource::SourceFile(_) => None,
};
- vec![(file_id, range)]
+ [(file_id, range)].iter().cloned().collect()
}
}