diff options
-rw-r--r-- | crates/ra_hir/src/module_tree.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests.rs | 36 | ||||
-rw-r--r-- | crates/ra_ide_api/tests/test/main.rs | 12 | ||||
-rw-r--r-- | crates/ra_syntax/src/algo.rs | 4 |
4 files changed, 48 insertions, 10 deletions
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index d1dc3fa4b..893c375b5 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs | |||
@@ -172,6 +172,7 @@ impl ModuleTree { | |||
172 | file_id: HirFileId, | 172 | file_id: HirFileId, |
173 | decl_id: Option<SourceFileItemId>, | 173 | decl_id: Option<SourceFileItemId>, |
174 | ) -> ModuleId { | 174 | ) -> ModuleId { |
175 | let is_root = parent.is_none(); | ||
175 | let id = self.alloc_mod(ModuleData { | 176 | let id = self.alloc_mod(ModuleData { |
176 | file_id, | 177 | file_id, |
177 | decl_id, | 178 | decl_id, |
@@ -191,7 +192,7 @@ impl ModuleTree { | |||
191 | }); | 192 | }); |
192 | 193 | ||
193 | let (points_to, problem) = if sub.is_declaration { | 194 | let (points_to, problem) = if sub.is_declaration { |
194 | let (points_to, problem) = resolve_submodule(db, file_id, &sub.name); | 195 | let (points_to, problem) = resolve_submodule(db, file_id, &sub.name, is_root); |
195 | let points_to = points_to | 196 | let points_to = points_to |
196 | .into_iter() | 197 | .into_iter() |
197 | .map(|file_id| { | 198 | .map(|file_id| { |
@@ -295,6 +296,7 @@ fn resolve_submodule( | |||
295 | db: &impl HirDatabase, | 296 | db: &impl HirDatabase, |
296 | file_id: HirFileId, | 297 | file_id: HirFileId, |
297 | name: &Name, | 298 | name: &Name, |
299 | is_root: bool, | ||
298 | ) -> (Vec<FileId>, Option<Problem>) { | 300 | ) -> (Vec<FileId>, Option<Problem>) { |
299 | // FIXME: handle submodules of inline modules properly | 301 | // FIXME: handle submodules of inline modules properly |
300 | let file_id = file_id.original_file(db); | 302 | let file_id = file_id.original_file(db); |
@@ -303,7 +305,7 @@ fn resolve_submodule( | |||
303 | let root = RelativePathBuf::default(); | 305 | let root = RelativePathBuf::default(); |
304 | let dir_path = path.parent().unwrap_or(&root); | 306 | let dir_path = path.parent().unwrap_or(&root); |
305 | let mod_name = path.file_stem().unwrap_or("unknown"); | 307 | let mod_name = path.file_stem().unwrap_or("unknown"); |
306 | let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; | 308 | let is_dir_owner = is_root || mod_name == "mod"; |
307 | 309 | ||
308 | let file_mod = dir_path.join(format!("{}.rs", name)); | 310 | let file_mod = dir_path.join(format!("{}.rs", name)); |
309 | let dir_mod = dir_path.join(format!("{}/mod.rs", name)); | 311 | let dir_mod = dir_path.join(format!("{}/mod.rs", name)); |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index e72781f51..3d420467c 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -19,6 +19,20 @@ fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) { | |||
19 | (db.item_map(krate.crate_id), module_id) | 19 | (db.item_map(krate.crate_id), module_id) |
20 | } | 20 | } |
21 | 21 | ||
22 | /// Sets the crate root to the file of the cursor marker | ||
23 | fn item_map_custom_crate_root(fixture: &str) -> (Arc<ItemMap>, ModuleId) { | ||
24 | let (mut db, pos) = MockDatabase::with_position(fixture); | ||
25 | |||
26 | let mut crate_graph = CrateGraph::default(); | ||
27 | crate_graph.add_crate_root(pos.file_id); | ||
28 | db.set_crate_graph(Arc::new(crate_graph)); | ||
29 | |||
30 | let module = crate::source_binder::module_from_position(&db, pos).unwrap(); | ||
31 | let krate = module.krate(&db).unwrap(); | ||
32 | let module_id = module.module_id; | ||
33 | (db.item_map(krate.crate_id), module_id) | ||
34 | } | ||
35 | |||
22 | fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { | 36 | fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { |
23 | let mut lines = map[module_id] | 37 | let mut lines = map[module_id] |
24 | .items | 38 | .items |
@@ -134,6 +148,28 @@ fn re_exports() { | |||
134 | } | 148 | } |
135 | 149 | ||
136 | #[test] | 150 | #[test] |
151 | fn module_resolution_works_for_non_standard_filenames() { | ||
152 | let (item_map, module_id) = item_map_custom_crate_root( | ||
153 | " | ||
154 | //- /my_library.rs | ||
155 | mod foo; | ||
156 | use self::foo::Bar; | ||
157 | <|> | ||
158 | //- /foo/mod.rs | ||
159 | pub struct Bar; | ||
160 | ", | ||
161 | ); | ||
162 | check_module_item_map( | ||
163 | &item_map, | ||
164 | module_id, | ||
165 | " | ||
166 | Bar: t v | ||
167 | foo: t | ||
168 | ", | ||
169 | ); | ||
170 | } | ||
171 | |||
172 | #[test] | ||
137 | fn name_res_works_for_broken_modules() { | 173 | fn name_res_works_for_broken_modules() { |
138 | covers!(name_res_works_for_broken_modules); | 174 | covers!(name_res_works_for_broken_modules); |
139 | let (item_map, module_id) = item_map( | 175 | let (item_map, module_id) = item_map( |
diff --git a/crates/ra_ide_api/tests/test/main.rs b/crates/ra_ide_api/tests/test/main.rs index 756075190..c2cb38f7e 100644 --- a/crates/ra_ide_api/tests/test/main.rs +++ b/crates/ra_ide_api/tests/test/main.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use insta::assert_debug_snapshot_matches; | ||
1 | use ra_ide_api::{ | 2 | use ra_ide_api::{ |
2 | AnalysisChange, | 3 | mock_analysis::{single_file, single_file_with_position, MockAnalysis}, |
3 | CrateGraph, FileId, mock_analysis::{MockAnalysis, single_file, single_file_with_position}, Query, | 4 | AnalysisChange, CrateGraph, FileId, Query, |
4 | }; | 5 | }; |
5 | use ra_syntax::TextRange; | 6 | use ra_syntax::TextRange; |
6 | use insta::assert_debug_snapshot_matches; | ||
7 | 7 | ||
8 | #[test] | 8 | #[test] |
9 | fn test_unresolved_module_diagnostic() { | 9 | fn test_unresolved_module_diagnostic() { |
@@ -26,12 +26,12 @@ fn test_resolve_crate_root() { | |||
26 | " | 26 | " |
27 | //- /bar.rs | 27 | //- /bar.rs |
28 | mod foo; | 28 | mod foo; |
29 | //- /bar/foo.rs | 29 | //- /foo.rs |
30 | // emtpy <|> | 30 | // empty <|> |
31 | ", | 31 | ", |
32 | ); | 32 | ); |
33 | let root_file = mock.id_of("/bar.rs"); | 33 | let root_file = mock.id_of("/bar.rs"); |
34 | let mod_file = mock.id_of("/bar/foo.rs"); | 34 | let mod_file = mock.id_of("/foo.rs"); |
35 | let mut host = mock.analysis_host(); | 35 | let mut host = mock.analysis_host(); |
36 | assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); | 36 | assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); |
37 | 37 | ||
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs index 45747e21d..99b0983b0 100644 --- a/crates/ra_syntax/src/algo.rs +++ b/crates/ra_syntax/src/algo.rs | |||
@@ -17,14 +17,14 @@ pub fn find_leaf_at_offset(node: &SyntaxNode, offset: TextUnit) -> LeafAtOffset< | |||
17 | } | 17 | } |
18 | 18 | ||
19 | /// Finds a node of specific Ast type at offset. Note that this is slightly | 19 | /// Finds a node of specific Ast type at offset. Note that this is slightly |
20 | /// impercise: if the cursor is strictly betwen two nodes of the desired type, | 20 | /// imprecise: if the cursor is strictly between two nodes of the desired type, |
21 | /// as in | 21 | /// as in |
22 | /// | 22 | /// |
23 | /// ```no-run | 23 | /// ```no-run |
24 | /// struct Foo {}|struct Bar; | 24 | /// struct Foo {}|struct Bar; |
25 | /// ``` | 25 | /// ``` |
26 | /// | 26 | /// |
27 | /// then the left node will be silently prefered. | 27 | /// then the left node will be silently preferred. |
28 | pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextUnit) -> Option<&N> { | 28 | pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextUnit) -> Option<&N> { |
29 | find_leaf_at_offset(syntax, offset).find_map(|leaf| leaf.ancestors().find_map(N::cast)) | 29 | find_leaf_at_offset(syntax, offset).find_map(|leaf| leaf.ancestors().find_map(N::cast)) |
30 | } | 30 | } |