diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/mods.rs | 505 |
2 files changed, 521 insertions, 4 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 552a1b6d9..7eee3cb38 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -84,7 +84,7 @@ struct DefCollector<DB> { | |||
84 | global_macro_scope: FxHashMap<Name, MacroDefId>, | 84 | global_macro_scope: FxHashMap<Name, MacroDefId>, |
85 | 85 | ||
86 | /// Some macro use `$tt:tt which mean we have to handle the macro perfectly | 86 | /// Some macro use `$tt:tt which mean we have to handle the macro perfectly |
87 | /// To prevent stackoverflow, we add a deep counter here for prevent that. | 87 | /// To prevent stack overflow, we add a deep counter here for prevent that. |
88 | macro_stack_monitor: MacroStackMonitor, | 88 | macro_stack_monitor: MacroStackMonitor, |
89 | } | 89 | } |
90 | 90 | ||
@@ -497,7 +497,7 @@ where | |||
497 | 497 | ||
498 | fn collect_module(&mut self, module: &raw::ModuleData) { | 498 | fn collect_module(&mut self, module: &raw::ModuleData) { |
499 | match module { | 499 | match module { |
500 | // inline module, just recurse | 500 | // inline module, just recursive |
501 | raw::ModuleData::Definition { name, items, ast_id } => { | 501 | raw::ModuleData::Definition { name, items, ast_id } => { |
502 | let module_id = | 502 | let module_id = |
503 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); | 503 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); |
@@ -509,7 +509,7 @@ where | |||
509 | } | 509 | } |
510 | .collect(&*items); | 510 | .collect(&*items); |
511 | } | 511 | } |
512 | // out of line module, resolve, parse and recurse | 512 | // out of line module, resolve, parse and recursive |
513 | raw::ModuleData::Declaration { name, ast_id, attr_path } => { | 513 | raw::ModuleData::Declaration { name, ast_id, attr_path } => { |
514 | let ast_id = ast_id.with_file_id(self.file_id); | 514 | let ast_id = ast_id.with_file_id(self.file_id); |
515 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); | 515 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); |
@@ -649,7 +649,8 @@ fn resolve_submodule( | |||
649 | let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name)); | 649 | let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name)); |
650 | let mut candidates = ArrayVec::<[_; 3]>::new(); | 650 | let mut candidates = ArrayVec::<[_; 3]>::new(); |
651 | let file_attr_mod = attr_path.map(|file_path| { | 651 | let file_attr_mod = attr_path.map(|file_path| { |
652 | let file_attr_mod = dir_path.join(file_path.to_string()); | 652 | let file_path = normalize_attribute_path(file_path); |
653 | let file_attr_mod = dir_path.join(file_path).normalize(); | ||
653 | candidates.push(file_attr_mod.clone()); | 654 | candidates.push(file_attr_mod.clone()); |
654 | 655 | ||
655 | file_attr_mod | 656 | file_attr_mod |
@@ -675,6 +676,17 @@ fn resolve_submodule( | |||
675 | } | 676 | } |
676 | } | 677 | } |
677 | 678 | ||
679 | fn normalize_attribute_path(file_path: &SmolStr) -> String { | ||
680 | let current_dir = "./"; | ||
681 | |||
682 | let separator = |path: &str| path.replace("\\", "/"); | ||
683 | if file_path.starts_with(current_dir) { | ||
684 | separator(&file_path[current_dir.len()..]) | ||
685 | } else { | ||
686 | separator(file_path.as_str()) | ||
687 | } | ||
688 | } | ||
689 | |||
678 | #[cfg(test)] | 690 | #[cfg(test)] |
679 | mod tests { | 691 | mod tests { |
680 | use ra_db::SourceDatabase; | 692 | use ra_db::SourceDatabase; |
diff --git a/crates/ra_hir/src/nameres/tests/mods.rs b/crates/ra_hir/src/nameres/tests/mods.rs index 7c8c832fc..c36054c4b 100644 --- a/crates/ra_hir/src/nameres/tests/mods.rs +++ b/crates/ra_hir/src/nameres/tests/mods.rs | |||
@@ -173,6 +173,511 @@ fn module_resolution_module_with_path_non_crate_root() { | |||
173 | } | 173 | } |
174 | 174 | ||
175 | #[test] | 175 | #[test] |
176 | fn module_resolution_module_decl_path_super() { | ||
177 | let map = def_map_with_crate_graph( | ||
178 | " | ||
179 | //- /main.rs | ||
180 | #[path = \"bar/baz/module.rs\"] | ||
181 | mod foo; | ||
182 | pub struct Baz; | ||
183 | |||
184 | //- /bar/baz/module.rs | ||
185 | use super::Baz; | ||
186 | ", | ||
187 | crate_graph! { | ||
188 | "main": ("/main.rs", []), | ||
189 | }, | ||
190 | ); | ||
191 | |||
192 | assert_snapshot_matches!(map, @r###" | ||
193 | ⋮crate | ||
194 | ⋮Baz: t v | ||
195 | ⋮foo: t | ||
196 | ⋮ | ||
197 | ⋮crate::foo | ||
198 | ⋮Baz: t v | ||
199 | "###); | ||
200 | } | ||
201 | |||
202 | #[test] | ||
203 | fn module_resolution_explicit_path_mod_rs() { | ||
204 | let map = def_map_with_crate_graph( | ||
205 | " | ||
206 | //- /main.rs | ||
207 | #[path = \"module/mod.rs\"] | ||
208 | mod foo; | ||
209 | |||
210 | //- /module/mod.rs | ||
211 | pub struct Baz; | ||
212 | ", | ||
213 | crate_graph! { | ||
214 | "main": ("/main.rs", []), | ||
215 | }, | ||
216 | ); | ||
217 | |||
218 | assert_snapshot_matches!(map, @r###" | ||
219 | ⋮crate | ||
220 | ⋮foo: t | ||
221 | ⋮ | ||
222 | ⋮crate::foo | ||
223 | ⋮Baz: t v | ||
224 | "###); | ||
225 | } | ||
226 | |||
227 | #[test] | ||
228 | fn module_resolution_relative_path() { | ||
229 | let map = def_map_with_crate_graph( | ||
230 | " | ||
231 | //- /main.rs | ||
232 | mod foo; | ||
233 | |||
234 | //- /foo.rs | ||
235 | #[path = \"./sub.rs\"] | ||
236 | pub mod foo_bar; | ||
237 | |||
238 | //- /sub.rs | ||
239 | pub struct Baz; | ||
240 | ", | ||
241 | crate_graph! { | ||
242 | "main": ("/main.rs", []), | ||
243 | }, | ||
244 | ); | ||
245 | |||
246 | assert_snapshot_matches!(map, @r###" | ||
247 | ⋮crate | ||
248 | ⋮foo: t | ||
249 | ⋮ | ||
250 | ⋮crate::foo | ||
251 | ⋮foo_bar: t | ||
252 | ⋮ | ||
253 | ⋮crate::foo::foo_bar | ||
254 | ⋮Baz: t v | ||
255 | "###); | ||
256 | } | ||
257 | |||
258 | #[test] | ||
259 | fn module_resolution_relative_path_2() { | ||
260 | let map = def_map_with_crate_graph( | ||
261 | " | ||
262 | //- /main.rs | ||
263 | mod foo; | ||
264 | |||
265 | //- /foo/mod.rs | ||
266 | #[path=\"../sub.rs\"] | ||
267 | pub mod foo_bar; | ||
268 | |||
269 | //- /sub.rs | ||
270 | pub struct Baz; | ||
271 | ", | ||
272 | crate_graph! { | ||
273 | "main": ("/main.rs", []), | ||
274 | }, | ||
275 | ); | ||
276 | |||
277 | assert_snapshot_matches!(map, @r###" | ||
278 | ⋮crate | ||
279 | ⋮foo: t | ||
280 | ⋮ | ||
281 | ⋮crate::foo | ||
282 | ⋮foo_bar: t | ||
283 | ⋮ | ||
284 | ⋮crate::foo::foo_bar | ||
285 | ⋮Baz: t v | ||
286 | "###); | ||
287 | } | ||
288 | |||
289 | #[test] | ||
290 | fn module_resolution_explicit_path_mod_rs_2() { | ||
291 | let map = def_map_with_crate_graph( | ||
292 | " | ||
293 | //- /main.rs | ||
294 | #[path = \"module/bar/mod.rs\"] | ||
295 | mod foo; | ||
296 | |||
297 | //- /module/bar/mod.rs | ||
298 | pub struct Baz; | ||
299 | ", | ||
300 | crate_graph! { | ||
301 | "main": ("/main.rs", []), | ||
302 | }, | ||
303 | ); | ||
304 | |||
305 | assert_snapshot_matches!(map, @r###" | ||
306 | ⋮crate | ||
307 | ⋮foo: t | ||
308 | ⋮ | ||
309 | ⋮crate::foo | ||
310 | ⋮Baz: t v | ||
311 | "###); | ||
312 | } | ||
313 | |||
314 | #[test] | ||
315 | fn module_resolution_explicit_path_mod_rs_with_win_separator() { | ||
316 | let map = def_map_with_crate_graph( | ||
317 | " | ||
318 | //- /main.rs | ||
319 | #[path = \"module\\bar\\mod.rs\"] | ||
320 | mod foo; | ||
321 | |||
322 | //- /module/bar/mod.rs | ||
323 | pub struct Baz; | ||
324 | ", | ||
325 | crate_graph! { | ||
326 | "main": ("/main.rs", []), | ||
327 | }, | ||
328 | ); | ||
329 | |||
330 | assert_snapshot_matches!(map, @r###" | ||
331 | ⋮crate | ||
332 | ⋮foo: t | ||
333 | ⋮ | ||
334 | ⋮crate::foo | ||
335 | ⋮Baz: t v | ||
336 | "###); | ||
337 | } | ||
338 | |||
339 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
340 | #[test] | ||
341 | #[ignore] | ||
342 | fn module_resolution_decl_inside_inline_module() { | ||
343 | let map = def_map_with_crate_graph( | ||
344 | " | ||
345 | //- /main.rs | ||
346 | #[path = \"models\"] | ||
347 | mod foo { | ||
348 | mod bar; | ||
349 | } | ||
350 | |||
351 | //- /models/bar.rs | ||
352 | pub struct Baz; | ||
353 | ", | ||
354 | crate_graph! { | ||
355 | "main": ("/main.rs", []), | ||
356 | }, | ||
357 | ); | ||
358 | |||
359 | assert_snapshot_matches!(map, @r###" | ||
360 | ⋮crate | ||
361 | ⋮foo: t | ||
362 | ⋮ | ||
363 | ⋮crate::foo | ||
364 | ⋮bar: t | ||
365 | ⋮ | ||
366 | ⋮crate::foo::bar | ||
367 | ⋮Baz: t v | ||
368 | "###); | ||
369 | } | ||
370 | |||
371 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
372 | #[test] | ||
373 | #[ignore] | ||
374 | fn module_resolution_decl_inside_inline_module_2() { | ||
375 | let map = def_map_with_crate_graph( | ||
376 | " | ||
377 | //- /main.rs | ||
378 | #[path = \"models/db\"] | ||
379 | mod foo { | ||
380 | mod bar; | ||
381 | } | ||
382 | |||
383 | //- /models/db/bar.rs | ||
384 | pub struct Baz; | ||
385 | ", | ||
386 | crate_graph! { | ||
387 | "main": ("/main.rs", []), | ||
388 | }, | ||
389 | ); | ||
390 | |||
391 | assert_snapshot_matches!(map, @r###" | ||
392 | ⋮crate | ||
393 | ⋮foo: t | ||
394 | ⋮ | ||
395 | ⋮crate::foo | ||
396 | ⋮bar: t | ||
397 | ⋮ | ||
398 | ⋮crate::foo::bar | ||
399 | ⋮Baz: t v | ||
400 | "###); | ||
401 | } | ||
402 | |||
403 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
404 | #[test] | ||
405 | #[ignore] | ||
406 | fn module_resolution_decl_inside_inline_module_3() { | ||
407 | let map = def_map_with_crate_graph( | ||
408 | " | ||
409 | //- /main.rs | ||
410 | #[path = \"models/db\"] | ||
411 | mod foo { | ||
412 | #[path = \"users.rs\"] | ||
413 | mod bar; | ||
414 | } | ||
415 | |||
416 | //- /models/db/users.rs | ||
417 | pub struct Baz; | ||
418 | ", | ||
419 | crate_graph! { | ||
420 | "main": ("/main.rs", []), | ||
421 | }, | ||
422 | ); | ||
423 | |||
424 | assert_snapshot_matches!(map, @r###" | ||
425 | ⋮crate | ||
426 | ⋮foo: t | ||
427 | ⋮ | ||
428 | ⋮crate::foo | ||
429 | ⋮bar: t | ||
430 | ⋮ | ||
431 | ⋮crate::foo::bar | ||
432 | ⋮Baz: t v | ||
433 | "###); | ||
434 | } | ||
435 | |||
436 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
437 | #[test] | ||
438 | #[ignore] | ||
439 | fn module_resolution_decl_inside_inline_module_empty_path() { | ||
440 | let map = def_map_with_crate_graph( | ||
441 | " | ||
442 | //- /main.rs | ||
443 | #[path = \"\"] | ||
444 | mod foo { | ||
445 | #[path = \"users.rs\"] | ||
446 | mod bar; | ||
447 | } | ||
448 | |||
449 | //- /users.rs | ||
450 | pub struct Baz; | ||
451 | ", | ||
452 | crate_graph! { | ||
453 | "main": ("/main.rs", []), | ||
454 | }, | ||
455 | ); | ||
456 | |||
457 | assert_snapshot_matches!(map, @r###" | ||
458 | ⋮crate | ||
459 | ⋮foo: t | ||
460 | ⋮ | ||
461 | ⋮crate::foo | ||
462 | ⋮bar: t | ||
463 | ⋮ | ||
464 | ⋮crate::foo::bar | ||
465 | ⋮Baz: t v | ||
466 | "###); | ||
467 | } | ||
468 | |||
469 | #[test] | ||
470 | fn module_resolution_decl_empty_path() { | ||
471 | let map = def_map_with_crate_graph( | ||
472 | " | ||
473 | //- /main.rs | ||
474 | #[path = \"\"] | ||
475 | mod foo; | ||
476 | |||
477 | //- /foo.rs | ||
478 | pub struct Baz; | ||
479 | ", | ||
480 | crate_graph! { | ||
481 | "main": ("/main.rs", []), | ||
482 | }, | ||
483 | ); | ||
484 | |||
485 | assert_snapshot_matches!(map, @r###" | ||
486 | ⋮crate | ||
487 | ⋮foo: t | ||
488 | ⋮ | ||
489 | ⋮crate::foo | ||
490 | ⋮Baz: t v | ||
491 | "###); | ||
492 | } | ||
493 | |||
494 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
495 | #[test] | ||
496 | #[ignore] | ||
497 | fn module_resolution_decl_inside_inline_module_relative_path() { | ||
498 | let map = def_map_with_crate_graph( | ||
499 | " | ||
500 | //- /main.rs | ||
501 | #[path = \"./models\"] | ||
502 | mod foo { | ||
503 | mod bar; | ||
504 | } | ||
505 | |||
506 | //- /models/bar.rs | ||
507 | pub struct Baz; | ||
508 | ", | ||
509 | crate_graph! { | ||
510 | "main": ("/main.rs", []), | ||
511 | }, | ||
512 | ); | ||
513 | |||
514 | assert_snapshot_matches!(map, @r###" | ||
515 | ⋮crate | ||
516 | ⋮foo: t | ||
517 | ⋮ | ||
518 | ⋮crate::foo | ||
519 | ⋮bar: t | ||
520 | ⋮ | ||
521 | ⋮crate::foo::bar | ||
522 | ⋮Baz: t v | ||
523 | "###); | ||
524 | } | ||
525 | |||
526 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
527 | #[test] | ||
528 | #[ignore] | ||
529 | fn module_resolution_decl_inside_inline_module_in_crate_root() { | ||
530 | let map = def_map_with_crate_graph( | ||
531 | " | ||
532 | //- /main.rs | ||
533 | mod foo { | ||
534 | #[path = \"baz.rs\"] | ||
535 | mod bar; | ||
536 | } | ||
537 | use self::foo::bar::Baz; | ||
538 | |||
539 | //- /foo/baz.rs | ||
540 | pub struct Baz; | ||
541 | ", | ||
542 | crate_graph! { | ||
543 | "main": ("/main.rs", []), | ||
544 | }, | ||
545 | ); | ||
546 | |||
547 | assert_snapshot_matches!(map, @r###" | ||
548 | ⋮crate | ||
549 | ⋮Baz: t v | ||
550 | ⋮foo: t | ||
551 | ⋮ | ||
552 | ⋮crate::foo | ||
553 | ⋮bar: t | ||
554 | ⋮ | ||
555 | ⋮crate::foo::bar | ||
556 | ⋮Baz: t v | ||
557 | "###); | ||
558 | } | ||
559 | |||
560 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
561 | #[test] | ||
562 | #[ignore] | ||
563 | fn module_resolution_decl_inside_inline_module_in_mod_rs() { | ||
564 | let map = def_map_with_crate_graph( | ||
565 | " | ||
566 | //- /main.rs | ||
567 | mod foo; | ||
568 | |||
569 | //- /foo/mod.rs | ||
570 | mod bar { | ||
571 | #[path = \"qwe.rs\"] | ||
572 | pub mod baz; | ||
573 | } | ||
574 | use self::bar::baz::Baz; | ||
575 | |||
576 | //- /foo/bar/qwe.rs | ||
577 | pub struct Baz; | ||
578 | ", | ||
579 | crate_graph! { | ||
580 | "main": ("/main.rs", []), | ||
581 | }, | ||
582 | ); | ||
583 | |||
584 | assert_snapshot_matches!(map, @r###" | ||
585 | ⋮crate | ||
586 | ⋮foo: t | ||
587 | ⋮ | ||
588 | ⋮crate::foo | ||
589 | ⋮Baz: t v | ||
590 | ⋮bar: t | ||
591 | ⋮ | ||
592 | ⋮crate::foo::bar | ||
593 | ⋮baz: t | ||
594 | ⋮ | ||
595 | ⋮crate::foo::bar::baz | ||
596 | ⋮Baz: t v | ||
597 | "###); | ||
598 | } | ||
599 | |||
600 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
601 | #[test] | ||
602 | #[ignore] | ||
603 | fn module_resolution_decl_inside_inline_module_in_non_crate_root() { | ||
604 | let map = def_map_with_crate_graph( | ||
605 | " | ||
606 | //- /main.rs | ||
607 | mod foo; | ||
608 | |||
609 | //- /foo.rs | ||
610 | mod bar { | ||
611 | #[path = \"qwe.rs\"] | ||
612 | pub mod baz; | ||
613 | } | ||
614 | use self::bar::baz::Baz; | ||
615 | |||
616 | //- /foo/bar/qwe.rs | ||
617 | pub struct Baz; | ||
618 | ", | ||
619 | crate_graph! { | ||
620 | "main": ("/main.rs", []), | ||
621 | }, | ||
622 | ); | ||
623 | |||
624 | assert_snapshot_matches!(map, @r###" | ||
625 | ⋮crate | ||
626 | ⋮foo: t | ||
627 | ⋮ | ||
628 | ⋮crate::foo | ||
629 | ⋮Baz: t v | ||
630 | ⋮bar: t | ||
631 | ⋮ | ||
632 | ⋮crate::foo::bar | ||
633 | ⋮baz: t | ||
634 | ⋮ | ||
635 | ⋮crate::foo::bar::baz | ||
636 | ⋮Baz: t v | ||
637 | "###); | ||
638 | } | ||
639 | |||
640 | // FIXME: issue #1510. not support out-of-line modules inside inline. | ||
641 | #[test] | ||
642 | #[ignore] | ||
643 | fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() { | ||
644 | let map = def_map_with_crate_graph( | ||
645 | " | ||
646 | //- /main.rs | ||
647 | mod foo; | ||
648 | |||
649 | //- /foo.rs | ||
650 | #[path = \"bar\"] | ||
651 | mod bar { | ||
652 | pub mod baz; | ||
653 | } | ||
654 | use self::bar::baz::Baz; | ||
655 | |||
656 | //- /bar/baz.rs | ||
657 | pub struct Baz; | ||
658 | ", | ||
659 | crate_graph! { | ||
660 | "main": ("/main.rs", []), | ||
661 | }, | ||
662 | ); | ||
663 | |||
664 | assert_snapshot_matches!(map, @r###" | ||
665 | ⋮crate | ||
666 | ⋮foo: t | ||
667 | ⋮ | ||
668 | ⋮crate::foo | ||
669 | ⋮Baz: t v | ||
670 | ⋮bar: t | ||
671 | ⋮ | ||
672 | ⋮crate::foo::bar | ||
673 | ⋮baz: t | ||
674 | ⋮ | ||
675 | ⋮crate::foo::bar::baz | ||
676 | ⋮Baz: t v | ||
677 | "###); | ||
678 | } | ||
679 | |||
680 | #[test] | ||
176 | fn unresolved_module_diagnostics() { | 681 | fn unresolved_module_diagnostics() { |
177 | let diagnostics = MockDatabase::with_files( | 682 | let diagnostics = MockDatabase::with_files( |
178 | r" | 683 | r" |