aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/nameres/collector.rs22
-rw-r--r--crates/ra_hir/src/nameres/tests/mods.rs523
2 files changed, 534 insertions, 11 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 552a1b6d9..7f765caf3 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -1,3 +1,5 @@
1use std::borrow::Cow;
2
1use arrayvec::ArrayVec; 3use arrayvec::ArrayVec;
2use ra_db::FileId; 4use ra_db::FileId;
3use ra_syntax::{ast, SmolStr}; 5use ra_syntax::{ast, SmolStr};
@@ -84,7 +86,7 @@ struct DefCollector<DB> {
84 global_macro_scope: FxHashMap<Name, MacroDefId>, 86 global_macro_scope: FxHashMap<Name, MacroDefId>,
85 87
86 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly 88 /// 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. 89 /// To prevent stack overflow, we add a deep counter here for prevent that.
88 macro_stack_monitor: MacroStackMonitor, 90 macro_stack_monitor: MacroStackMonitor,
89} 91}
90 92
@@ -649,7 +651,8 @@ fn resolve_submodule(
649 let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name)); 651 let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
650 let mut candidates = ArrayVec::<[_; 3]>::new(); 652 let mut candidates = ArrayVec::<[_; 3]>::new();
651 let file_attr_mod = attr_path.map(|file_path| { 653 let file_attr_mod = attr_path.map(|file_path| {
652 let file_attr_mod = dir_path.join(file_path.to_string()); 654 let file_path = normalize_attribute_path(file_path);
655 let file_attr_mod = dir_path.join(file_path.as_ref()).normalize();
653 candidates.push(file_attr_mod.clone()); 656 candidates.push(file_attr_mod.clone());
654 657
655 file_attr_mod 658 file_attr_mod
@@ -675,6 +678,21 @@ fn resolve_submodule(
675 } 678 }
676} 679}
677 680
681fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> {
682 let current_dir = "./";
683 let windows_path_separator = r#"\"#;
684 let current_dir_normalize = if file_path.starts_with(current_dir) {
685 &file_path[current_dir.len()..]
686 } else {
687 file_path.as_str()
688 };
689 if current_dir_normalize.contains(windows_path_separator) {
690 Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/"))
691 } else {
692 Cow::Borrowed(current_dir_normalize)
693 }
694}
695
678#[cfg(test)] 696#[cfg(test)]
679mod tests { 697mod tests {
680 use ra_db::SourceDatabase; 698 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..d714a3276 100644
--- a/crates/ra_hir/src/nameres/tests/mods.rs
+++ b/crates/ra_hir/src/nameres/tests/mods.rs
@@ -80,15 +80,15 @@ fn module_resolution_works_for_raw_modules() {
80#[test] 80#[test]
81fn module_resolution_decl_path() { 81fn module_resolution_decl_path() {
82 let map = def_map_with_crate_graph( 82 let map = def_map_with_crate_graph(
83 " 83 r###"
84 //- /library.rs 84 //- /library.rs
85 #[path = \"bar/baz/foo.rs\"] 85 #[path = "bar/baz/foo.rs"]
86 mod foo; 86 mod foo;
87 use self::foo::Bar; 87 use self::foo::Bar;
88 88
89 //- /bar/baz/foo.rs 89 //- /bar/baz/foo.rs
90 pub struct Bar; 90 pub struct Bar;
91 ", 91 "###,
92 crate_graph! { 92 crate_graph! {
93 "library": ("/library.rs", []), 93 "library": ("/library.rs", []),
94 }, 94 },
@@ -107,19 +107,19 @@ fn module_resolution_decl_path() {
107#[test] 107#[test]
108fn module_resolution_module_with_path_in_mod_rs() { 108fn module_resolution_module_with_path_in_mod_rs() {
109 let map = def_map_with_crate_graph( 109 let map = def_map_with_crate_graph(
110 " 110 r###"
111 //- /main.rs 111 //- /main.rs
112 mod foo; 112 mod foo;
113 113
114 //- /foo/mod.rs 114 //- /foo/mod.rs
115 #[path = \"baz.rs\"] 115 #[path = "baz.rs"]
116 pub mod bar; 116 pub mod bar;
117 117
118 use self::bar::Baz; 118 use self::bar::Baz;
119 119
120 //- /foo/baz.rs 120 //- /foo/baz.rs
121 pub struct Baz; 121 pub struct Baz;
122 ", 122 "###,
123 crate_graph! { 123 crate_graph! {
124 "main": ("/main.rs", []), 124 "main": ("/main.rs", []),
125 }, 125 },
@@ -141,19 +141,19 @@ fn module_resolution_module_with_path_in_mod_rs() {
141#[test] 141#[test]
142fn module_resolution_module_with_path_non_crate_root() { 142fn module_resolution_module_with_path_non_crate_root() {
143 let map = def_map_with_crate_graph( 143 let map = def_map_with_crate_graph(
144 " 144 r###"
145 //- /main.rs 145 //- /main.rs
146 mod foo; 146 mod foo;
147 147
148 //- /foo.rs 148 //- /foo.rs
149 #[path = \"baz.rs\"] 149 #[path = "baz.rs"]
150 pub mod bar; 150 pub mod bar;
151 151
152 use self::bar::Baz; 152 use self::bar::Baz;
153 153
154 //- /baz.rs 154 //- /baz.rs
155 pub struct Baz; 155 pub struct Baz;
156 ", 156 "###,
157 crate_graph! { 157 crate_graph! {
158 "main": ("/main.rs", []), 158 "main": ("/main.rs", []),
159 }, 159 },
@@ -173,6 +173,511 @@ fn module_resolution_module_with_path_non_crate_root() {
173} 173}
174 174
175#[test] 175#[test]
176fn module_resolution_module_decl_path_super() {
177 let map = def_map_with_crate_graph(
178 r###"
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]
203fn module_resolution_explicit_path_mod_rs() {
204 let map = def_map_with_crate_graph(
205 r###"
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]
228fn module_resolution_relative_path() {
229 let map = def_map_with_crate_graph(
230 r###"
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]
259fn module_resolution_relative_path_2() {
260 let map = def_map_with_crate_graph(
261 r###"
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]
290fn module_resolution_explicit_path_mod_rs_2() {
291 let map = def_map_with_crate_graph(
292 r###"
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]
315fn module_resolution_explicit_path_mod_rs_with_win_separator() {
316 let map = def_map_with_crate_graph(
317 r###"
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]
342fn module_resolution_decl_inside_inline_module() {
343 let map = def_map_with_crate_graph(
344 r###"
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]
374fn module_resolution_decl_inside_inline_module_2() {
375 let map = def_map_with_crate_graph(
376 r###"
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]
406fn module_resolution_decl_inside_inline_module_3() {
407 let map = def_map_with_crate_graph(
408 r###"
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]
439fn module_resolution_decl_inside_inline_module_empty_path() {
440 let map = def_map_with_crate_graph(
441 r###"
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]
470fn module_resolution_decl_empty_path() {
471 let map = def_map_with_crate_graph(
472 r###"
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]
497fn module_resolution_decl_inside_inline_module_relative_path() {
498 let map = def_map_with_crate_graph(
499 r###"
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]
529fn module_resolution_decl_inside_inline_module_in_crate_root() {
530 let map = def_map_with_crate_graph(
531 r###"
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]
563fn module_resolution_decl_inside_inline_module_in_mod_rs() {
564 let map = def_map_with_crate_graph(
565 r###"
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]
603fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
604 let map = def_map_with_crate_graph(
605 r###"
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]
643fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
644 let map = def_map_with_crate_graph(
645 r###"
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]
176fn unresolved_module_diagnostics() { 681fn unresolved_module_diagnostics() {
177 let diagnostics = MockDatabase::with_files( 682 let diagnostics = MockDatabase::with_files(
178 r" 683 r"