aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres/crate_def_map
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-03-14 08:53:40 +0000
committerAleksey Kladov <[email protected]>2019-03-17 09:49:07 +0000
commit71e5adf694a4b253bc5bb48be96bb6ba08002d8c (patch)
tree27208afed0ec41b07f8fffa05659259f13fc027c /crates/ra_hir/src/nameres/crate_def_map
parent2195d1db6d70d64383bec82819fab02891d09744 (diff)
move tests over to crate-def-map
Diffstat (limited to 'crates/ra_hir/src/nameres/crate_def_map')
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/collector.rs15
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/tests.rs411
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/tests/globs.rs118
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/tests/incremental.rs123
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/tests/macros.rs94
5 files changed, 686 insertions, 75 deletions
diff --git a/crates/ra_hir/src/nameres/crate_def_map/collector.rs b/crates/ra_hir/src/nameres/crate_def_map/collector.rs
index 2fbfa9e34..68f74b866 100644
--- a/crates/ra_hir/src/nameres/crate_def_map/collector.rs
+++ b/crates/ra_hir/src/nameres/crate_def_map/collector.rs
@@ -85,6 +85,12 @@ where
85 break; 85 break;
86 } 86 }
87 } 87 }
88
89 let unresolved_imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
90 // show unresolved imports in completion, etc
91 for (module_id, import, import_data) in unresolved_imports {
92 self.record_resolved_import(module_id, PerNs::none(), import, &import_data)
93 }
88 } 94 }
89 95
90 fn define_macro(&mut self, name: Name, tt: &tt::Subtree, export: bool) { 96 fn define_macro(&mut self, name: Name, tt: &tt::Subtree, export: bool) {
@@ -415,7 +421,14 @@ where
415 modules[res].parent = Some(self.module_id); 421 modules[res].parent = Some(self.module_id);
416 modules[res].declaration = Some(declaration); 422 modules[res].declaration = Some(declaration);
417 modules[res].definition = definition; 423 modules[res].definition = definition;
418 modules[self.module_id].children.insert(name, res); 424 modules[self.module_id].children.insert(name.clone(), res);
425 let resolution = Resolution {
426 def: PerNs::types(
427 Module { krate: self.def_collector.def_map.krate, module_id: res }.into(),
428 ),
429 import: None,
430 };
431 self.def_collector.update(self.module_id, None, &[(name, resolution)]);
419 res 432 res
420 } 433 }
421 434
diff --git a/crates/ra_hir/src/nameres/crate_def_map/tests.rs b/crates/ra_hir/src/nameres/crate_def_map/tests.rs
index 742a19e5c..36c1d74ce 100644
--- a/crates/ra_hir/src/nameres/crate_def_map/tests.rs
+++ b/crates/ra_hir/src/nameres/crate_def_map/tests.rs
@@ -1,3 +1,7 @@
1mod macros;
2mod globs;
3mod incremental;
4
1use std::sync::Arc; 5use std::sync::Arc;
2 6
3use ra_db::SourceDatabase; 7use ra_db::SourceDatabase;
@@ -62,6 +66,8 @@ fn crate_def_map_smoke_test() {
62 //- /lib.rs 66 //- /lib.rs
63 mod foo; 67 mod foo;
64 struct S; 68 struct S;
69 use crate::foo::bar::E;
70 use self::E::V;
65 71
66 //- /foo/mod.rs 72 //- /foo/mod.rs
67 pub mod bar; 73 pub mod bar;
@@ -74,9 +80,13 @@ fn crate_def_map_smoke_test() {
74 ); 80 );
75 assert_snapshot_matches!(map, @r###" 81 assert_snapshot_matches!(map, @r###"
76crate 82crate
83V: t v
84E: t
85foo: t
77S: t v 86S: t v
78 87
79crate::foo 88crate::foo
89bar: t
80f: v 90f: v
81 91
82crate::foo::bar 92crate::foo::bar
@@ -87,91 +97,96 @@ E: t
87} 97}
88 98
89#[test] 99#[test]
90fn macro_rules_are_globally_visible() { 100fn use_as() {
91 let map = def_map( 101 let map = def_map(
92 " 102 "
93 //- /lib.rs 103 //- /lib.rs
94 macro_rules! structs { 104 mod foo;
95 ($($i:ident),*) => { 105
96 $(struct $i { field: u32 } )* 106 use crate::foo::Baz as Foo;
97 }
98 }
99 structs!(Foo);
100 mod nested;
101 107
102 //- /nested.rs 108 //- /foo/mod.rs
103 structs!(Bar, Baz); 109 pub struct Baz;
104 ", 110 ",
105 ); 111 );
106 assert_snapshot_matches!(map, @r###" 112 assert_snapshot_matches!(map,
113 @r###"
107crate 114crate
108Foo: t v 115Foo: t v
116foo: t
109 117
110crate::nested 118crate::foo
111Bar: t v
112Baz: t v 119Baz: t v
113"###); 120"###
121 );
114} 122}
115 123
116#[test] 124#[test]
117fn macro_rules_can_define_modules() { 125fn use_trees() {
118 let map = def_map( 126 let map = def_map(
119 " 127 "
120 //- /lib.rs 128 //- /lib.rs
121 macro_rules! m { 129 mod foo;
122 ($name:ident) => { mod $name; } 130
123 } 131 use crate::foo::bar::{Baz, Quux};
124 m!(n1); 132
133 //- /foo/mod.rs
134 pub mod bar;
125 135
126 //- /n1.rs 136 //- /foo/bar.rs
127 m!(n2) 137 pub struct Baz;
128 //- /n1/n2.rs 138 pub enum Quux {};
129 struct X;
130 ", 139 ",
131 ); 140 );
132 assert_snapshot_matches!(map, @r###" 141 assert_snapshot_matches!(map,
142 @r###"
133crate 143crate
144Quux: t
145Baz: t v
146foo: t
134 147
135crate::n1 148crate::foo
149bar: t
136 150
137crate::n1::n2 151crate::foo::bar
138X: t v 152Quux: t
139"###); 153Baz: t v
154"###
155 );
140} 156}
141 157
142#[test] 158#[test]
143fn macro_rules_from_other_crates_are_visible() { 159fn re_exports() {
144 let map = def_map_with_crate_graph( 160 let map = def_map(
145 " 161 "
146 //- /main.rs 162 //- /lib.rs
147 foo::structs!(Foo, Bar) 163 mod foo;
148 mod bar;
149 164
150 //- /bar.rs 165 use self::foo::Baz;
151 use crate::*;
152 166
153 //- /lib.rs 167 //- /foo/mod.rs
154 #[macro_export] 168 pub mod bar;
155 macro_rules! structs { 169
156 ($($i:ident),*) => { 170 pub use self::bar::Baz;
157 $(struct $i { field: u32 } )* 171
158 } 172 //- /foo/bar.rs
159 } 173 pub struct Baz;
160 ", 174 ",
161 crate_graph! {
162 "main": ("/main.rs", ["foo"]),
163 "foo": ("/lib.rs", []),
164 },
165 ); 175 );
166 assert_snapshot_matches!(map, @r###" 176 assert_snapshot_matches!(map,
177 @r###"
167crate 178crate
168Foo: t v 179Baz: t v
169Bar: t v 180foo: t
170 181
171crate::bar 182crate::foo
172Foo: t v 183bar: t
173Bar: t v 184Baz: t v
174"###); 185
186crate::foo::bar
187Baz: t v
188"###
189 );
175} 190}
176 191
177#[test] 192#[test]
@@ -203,12 +218,152 @@ Baz: t v
203} 218}
204 219
205#[test] 220#[test]
206fn glob_across_crates() { 221fn can_import_enum_variant() {
207 covers!(glob_across_crates); 222 covers!(can_import_enum_variant);
223 let map = def_map(
224 "
225 //- /lib.rs
226 enum E { V }
227 use self::E::V;
228 ",
229 );
230 assert_snapshot_matches!(map, @r###"
231crate
232V: t v
233E: t
234"###
235 );
236}
237
238#[test]
239fn edition_2015_imports() {
240 let map = def_map_with_crate_graph(
241 "
242 //- /main.rs
243 mod foo;
244 mod bar;
245
246 //- /bar.rs
247 struct Bar;
248
249 //- /foo.rs
250 use bar::Bar;
251 use other_crate::FromLib;
252
253 //- /lib.rs
254 struct FromLib;
255 ",
256 crate_graph! {
257 "main": ("/main.rs", "2015", ["other_crate"]),
258 "other_crate": ("/lib.rs", "2018", []),
259 },
260 );
261
262 assert_snapshot_matches!(map,
263 @r###"
264crate
265bar: t
266foo: t
267
268crate::bar
269Bar: t v
270
271crate::foo
272FromLib: t v
273Bar: t v
274"###
275 );
276}
277
278#[test]
279fn module_resolution_works_for_non_standard_filenames() {
280 let map = def_map_with_crate_graph(
281 "
282 //- /my_library.rs
283 mod foo;
284 use self::foo::Bar;
285
286 //- /foo/mod.rs
287 pub struct Bar;
288 ",
289 crate_graph! {
290 "my_library": ("/my_library.rs", []),
291 },
292 );
293
294 assert_snapshot_matches!(map,
295 @r###"
296crate
297Bar: t v
298foo: t
299
300crate::foo
301Bar: t v
302"###
303 );
304}
305
306#[test]
307fn name_res_works_for_broken_modules() {
308 covers!(name_res_works_for_broken_modules);
309 let map = def_map(
310 "
311 //- /lib.rs
312 mod foo // no `;`, no body
313
314 use self::foo::Baz;
315
316 //- /foo/mod.rs
317 pub mod bar;
318
319 pub use self::bar::Baz;
320
321 //- /foo/bar.rs
322 pub struct Baz;
323 ",
324 );
325 assert_snapshot_matches!(map,
326 @r###"
327crate
328Baz: _
329"###
330 );
331}
332
333#[test]
334fn item_map_using_self() {
335 let map = def_map(
336 "
337 //- /lib.rs
338 mod foo;
339 use crate::foo::bar::Baz::{self};
340 //- /foo/mod.rs
341 pub mod bar;
342 //- /foo/bar.rs
343 pub struct Baz;
344 ",
345 );
346 assert_snapshot_matches!(map,
347 @r###"
348crate
349Baz: t v
350foo: t
351
352crate::foo
353bar: t
354
355crate::foo::bar
356Baz: t v
357"###
358 );
359}
360
361#[test]
362fn item_map_across_crates() {
208 let map = def_map_with_crate_graph( 363 let map = def_map_with_crate_graph(
209 " 364 "
210 //- /main.rs 365 //- /main.rs
211 use test_crate::*; 366 use test_crate::Baz;
212 367
213 //- /lib.rs 368 //- /lib.rs
214 pub struct Baz; 369 pub struct Baz;
@@ -218,7 +373,9 @@ fn glob_across_crates() {
218 "test_crate": ("/lib.rs", []), 373 "test_crate": ("/lib.rs", []),
219 }, 374 },
220 ); 375 );
221 assert_snapshot_matches!(map, @r###" 376
377 assert_snapshot_matches!(map,
378 @r###"
222crate 379crate
223Baz: t v 380Baz: t v
224"### 381"###
@@ -226,40 +383,146 @@ Baz: t v
226} 383}
227 384
228#[test] 385#[test]
229fn item_map_enum_importing() { 386fn extern_crate_rename() {
230 covers!(item_map_enum_importing); 387 let map = def_map_with_crate_graph(
231 let map = def_map(
232 " 388 "
389 //- /main.rs
390 extern crate alloc as alloc_crate;
391
392 mod alloc;
393 mod sync;
394
395 //- /sync.rs
396 use alloc_crate::Arc;
397
233 //- /lib.rs 398 //- /lib.rs
234 enum E { V } 399 struct Arc;
235 use self::E::V;
236 ", 400 ",
401 crate_graph! {
402 "main": ("/main.rs", ["alloc"]),
403 "alloc": ("/lib.rs", []),
404 },
237 ); 405 );
238 assert_snapshot_matches!(map, @r###" 406
407 assert_snapshot_matches!(map,
408 @r###"
239crate 409crate
240V: t v 410Arc: t v
241E: t
242"### 411"###
243 ); 412 );
244} 413}
245 414
246#[test] 415#[test]
247fn glob_enum() { 416fn extern_crate_rename_2015_edition() {
248 covers!(glob_enum); 417 let map = def_map_with_crate_graph(
249 let map = def_map( 418 "
419 //- /main.rs
420 extern crate alloc as alloc_crate;
421
422 mod alloc;
423 mod sync;
424
425 //- /sync.rs
426 use alloc_crate::Arc;
427
428 //- /lib.rs
429 struct Arc;
430 ",
431 crate_graph! {
432 "main": ("/main.rs", "2015", ["alloc"]),
433 "alloc": ("/lib.rs", []),
434 },
435 );
436
437 assert_snapshot_matches!(map,
438 @r###"
439crate
440Arc: t v
441"###
442 );
443}
444
445#[test]
446fn import_across_source_roots() {
447 let map = def_map_with_crate_graph(
250 " 448 "
251 //- /lib.rs 449 //- /lib.rs
252 enum Foo { 450 pub mod a {
253 Bar, Baz 451 pub mod b {
452 pub struct C;
453 }
254 } 454 }
255 use self::Foo::*; 455
456 //- root /main/
457
458 //- /main/main.rs
459 use test_crate::a::b::C;
256 ", 460 ",
461 crate_graph! {
462 "main": ("/main/main.rs", ["test_crate"]),
463 "test_crate": ("/lib.rs", []),
464 },
257 ); 465 );
258 assert_snapshot_matches!(map, @r###" 466
467 assert_snapshot_matches!(map,
468 @r###"
469crate
470C: t v
471"###
472 );
473}
474
475#[test]
476fn reexport_across_crates() {
477 let map = def_map_with_crate_graph(
478 "
479 //- /main.rs
480 use test_crate::Baz;
481
482 //- /lib.rs
483 pub use foo::Baz;
484
485 mod foo;
486
487 //- /foo.rs
488 pub struct Baz;
489 ",
490 crate_graph! {
491 "main": ("/main.rs", ["test_crate"]),
492 "test_crate": ("/lib.rs", []),
493 },
494 );
495
496 assert_snapshot_matches!(map,
497 @r###"
259crate 498crate
260Foo: t
261Bar: t v
262Baz: t v 499Baz: t v
263"### 500"###
264 ); 501 );
265} 502}
503
504#[test]
505fn values_dont_shadow_extern_crates() {
506 let map = def_map_with_crate_graph(
507 "
508 //- /main.rs
509 fn foo() {}
510 use foo::Bar;
511
512 //- /foo/lib.rs
513 pub struct Bar;
514 ",
515 crate_graph! {
516 "main": ("/main.rs", ["foo"]),
517 "foo": ("/foo/lib.rs", []),
518 },
519 );
520
521 assert_snapshot_matches!(map,
522 @r###"
523crate
524Bar: t v
525foo: v
526"###
527 );
528}
diff --git a/crates/ra_hir/src/nameres/crate_def_map/tests/globs.rs b/crates/ra_hir/src/nameres/crate_def_map/tests/globs.rs
new file mode 100644
index 000000000..6e50c7ff6
--- /dev/null
+++ b/crates/ra_hir/src/nameres/crate_def_map/tests/globs.rs
@@ -0,0 +1,118 @@
1use super::*;
2
3#[test]
4fn glob_1() {
5 let map = def_map(
6 "
7 //- /lib.rs
8 mod foo;
9 use foo::*;
10
11 //- /foo/mod.rs
12 pub mod bar;
13 pub use self::bar::Baz;
14 pub struct Foo;
15
16 //- /foo/bar.rs
17 pub struct Baz;
18 ",
19 );
20 assert_snapshot_matches!(map, @r###"
21crate
22bar: t
23Foo: t v
24Baz: t v
25foo: t
26
27crate::foo
28bar: t
29Foo: t v
30Baz: t v
31
32crate::foo::bar
33Baz: t v
34"###
35 );
36}
37
38#[test]
39fn glob_2() {
40 let map = def_map(
41 "
42 //- /lib.rs
43 mod foo;
44 use foo::*;
45
46 //- /foo/mod.rs
47 pub mod bar;
48 pub use self::bar::*;
49 pub struct Foo;
50
51 //- /foo/bar.rs
52 pub struct Baz;
53 pub use super::*;
54 ",
55 );
56 assert_snapshot_matches!(map, @r###"
57crate
58bar: t
59Foo: t v
60Baz: t v
61foo: t
62
63crate::foo
64bar: t
65Foo: t v
66Baz: t v
67
68crate::foo::bar
69bar: t
70Foo: t v
71Baz: t v
72"###
73 );
74}
75
76#[test]
77fn glob_across_crates() {
78 covers!(glob_across_crates);
79 let map = def_map_with_crate_graph(
80 "
81 //- /main.rs
82 use test_crate::*;
83
84 //- /lib.rs
85 pub struct Baz;
86 ",
87 crate_graph! {
88 "main": ("/main.rs", ["test_crate"]),
89 "test_crate": ("/lib.rs", []),
90 },
91 );
92 assert_snapshot_matches!(map, @r###"
93crate
94Baz: t v
95"###
96 );
97}
98
99#[test]
100fn glob_enum() {
101 covers!(glob_enum);
102 let map = def_map(
103 "
104 //- /lib.rs
105 enum Foo {
106 Bar, Baz
107 }
108 use self::Foo::*;
109 ",
110 );
111 assert_snapshot_matches!(map, @r###"
112crate
113Foo: t
114Bar: t v
115Baz: t v
116"###
117 );
118}
diff --git a/crates/ra_hir/src/nameres/crate_def_map/tests/incremental.rs b/crates/ra_hir/src/nameres/crate_def_map/tests/incremental.rs
new file mode 100644
index 000000000..698781923
--- /dev/null
+++ b/crates/ra_hir/src/nameres/crate_def_map/tests/incremental.rs
@@ -0,0 +1,123 @@
1use super::*;
2
3use std::sync::Arc;
4
5use ra_db::SourceDatabase;
6
7fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) {
8 let (mut db, pos) = MockDatabase::with_position(initial);
9 let crate_id = db.crate_graph().iter().next().unwrap();
10 let krate = Crate { crate_id };
11 {
12 let events = db.log_executed(|| {
13 db.crate_def_map(krate);
14 });
15 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
16 }
17 db.set_file_text(pos.file_id, Arc::new(file_change.to_string()));
18
19 {
20 let events = db.log_executed(|| {
21 db.crate_def_map(krate);
22 });
23 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
24 }
25}
26
27#[test]
28fn typing_inside_a_function_should_not_invalidate_def_map() {
29 check_def_map_is_not_recomputed(
30 "
31 //- /lib.rs
32 mod foo;<|>
33
34 use crate::foo::bar::Baz;
35
36 fn foo() -> i32 {
37 1 + 1
38 }
39 //- /foo/mod.rs
40 pub mod bar;
41
42 //- /foo/bar.rs
43 pub struct Baz;
44 ",
45 "
46 mod foo;
47
48 use crate::foo::bar::Baz;
49
50 fn foo() -> i32 { 92 }
51 ",
52 );
53}
54
55#[test]
56fn adding_inner_items_should_not_invalidate_def_map() {
57 check_def_map_is_not_recomputed(
58 "
59 //- /lib.rs
60 struct S { a: i32}
61 enum E { A }
62 trait T {
63 fn a() {}
64 }
65 mod foo;<|>
66 impl S {
67 fn a() {}
68 }
69 use crate::foo::bar::Baz;
70 //- /foo/mod.rs
71 pub mod bar;
72
73 //- /foo/bar.rs
74 pub struct Baz;
75 ",
76 "
77 struct S { a: i32, b: () }
78 enum E { A, B }
79 trait T {
80 fn a() {}
81 fn b() {}
82 }
83 mod foo;<|>
84 impl S {
85 fn a() {}
86 fn b() {}
87 }
88 use crate::foo::bar::Baz;
89 ",
90 );
91}
92
93// It would be awesome to make this work, but it's unclear how
94#[test]
95#[ignore]
96fn typing_inside_a_function_inside_a_macro_should_not_invalidate_def_map() {
97 check_def_map_is_not_recomputed(
98 "
99 //- /lib.rs
100 mod foo;
101
102 use crate::foo::bar::Baz;
103
104 //- /foo/mod.rs
105 pub mod bar;
106
107 //- /foo/bar.rs
108 <|>
109 salsa::query_group! {
110 trait Baz {
111 fn foo() -> i32 { 1 + 1 }
112 }
113 }
114 ",
115 "
116 salsa::query_group! {
117 trait Baz {
118 fn foo() -> i32 { 92 }
119 }
120 }
121 ",
122 );
123}
diff --git a/crates/ra_hir/src/nameres/crate_def_map/tests/macros.rs b/crates/ra_hir/src/nameres/crate_def_map/tests/macros.rs
new file mode 100644
index 000000000..8781b026b
--- /dev/null
+++ b/crates/ra_hir/src/nameres/crate_def_map/tests/macros.rs
@@ -0,0 +1,94 @@
1use super::*;
2
3#[test]
4fn macro_rules_are_globally_visible() {
5 let map = def_map(
6 "
7 //- /lib.rs
8 macro_rules! structs {
9 ($($i:ident),*) => {
10 $(struct $i { field: u32 } )*
11 }
12 }
13 structs!(Foo);
14 mod nested;
15
16 //- /nested.rs
17 structs!(Bar, Baz);
18 ",
19 );
20 assert_snapshot_matches!(map, @r###"
21crate
22nested: t
23Foo: t v
24
25crate::nested
26Bar: t v
27Baz: t v
28"###);
29}
30
31#[test]
32fn macro_rules_can_define_modules() {
33 let map = def_map(
34 "
35 //- /lib.rs
36 macro_rules! m {
37 ($name:ident) => { mod $name; }
38 }
39 m!(n1);
40
41 //- /n1.rs
42 m!(n2)
43 //- /n1/n2.rs
44 struct X;
45 ",
46 );
47 assert_snapshot_matches!(map, @r###"
48crate
49n1: t
50
51crate::n1
52n2: t
53
54crate::n1::n2
55X: t v
56"###);
57}
58
59#[test]
60fn macro_rules_from_other_crates_are_visible() {
61 let map = def_map_with_crate_graph(
62 "
63 //- /main.rs
64 foo::structs!(Foo, Bar)
65 mod bar;
66
67 //- /bar.rs
68 use crate::*;
69
70 //- /lib.rs
71 #[macro_export]
72 macro_rules! structs {
73 ($($i:ident),*) => {
74 $(struct $i { field: u32 } )*
75 }
76 }
77 ",
78 crate_graph! {
79 "main": ("/main.rs", ["foo"]),
80 "foo": ("/lib.rs", []),
81 },
82 );
83 assert_snapshot_matches!(map, @r###"
84crate
85bar: t
86Foo: t v
87Bar: t v
88
89crate::bar
90bar: t
91Foo: t v
92Bar: t v
93"###);
94}