diff options
author | Aleksey Kladov <[email protected]> | 2019-03-14 08:53:40 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-03-17 09:49:07 +0000 |
commit | 71e5adf694a4b253bc5bb48be96bb6ba08002d8c (patch) | |
tree | 27208afed0ec41b07f8fffa05659259f13fc027c /crates/ra_hir/src/nameres/crate_def_map | |
parent | 2195d1db6d70d64383bec82819fab02891d09744 (diff) |
move tests over to crate-def-map
Diffstat (limited to 'crates/ra_hir/src/nameres/crate_def_map')
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 @@ | |||
1 | mod macros; | ||
2 | mod globs; | ||
3 | mod incremental; | ||
4 | |||
1 | use std::sync::Arc; | 5 | use std::sync::Arc; |
2 | 6 | ||
3 | use ra_db::SourceDatabase; | 7 | use 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###" |
76 | crate | 82 | crate |
83 | V: t v | ||
84 | E: t | ||
85 | foo: t | ||
77 | S: t v | 86 | S: t v |
78 | 87 | ||
79 | crate::foo | 88 | crate::foo |
89 | bar: t | ||
80 | f: v | 90 | f: v |
81 | 91 | ||
82 | crate::foo::bar | 92 | crate::foo::bar |
@@ -87,91 +97,96 @@ E: t | |||
87 | } | 97 | } |
88 | 98 | ||
89 | #[test] | 99 | #[test] |
90 | fn macro_rules_are_globally_visible() { | 100 | fn 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###" | ||
107 | crate | 114 | crate |
108 | Foo: t v | 115 | Foo: t v |
116 | foo: t | ||
109 | 117 | ||
110 | crate::nested | 118 | crate::foo |
111 | Bar: t v | ||
112 | Baz: t v | 119 | Baz: t v |
113 | "###); | 120 | "### |
121 | ); | ||
114 | } | 122 | } |
115 | 123 | ||
116 | #[test] | 124 | #[test] |
117 | fn macro_rules_can_define_modules() { | 125 | fn 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###" | ||
133 | crate | 143 | crate |
144 | Quux: t | ||
145 | Baz: t v | ||
146 | foo: t | ||
134 | 147 | ||
135 | crate::n1 | 148 | crate::foo |
149 | bar: t | ||
136 | 150 | ||
137 | crate::n1::n2 | 151 | crate::foo::bar |
138 | X: t v | 152 | Quux: t |
139 | "###); | 153 | Baz: t v |
154 | "### | ||
155 | ); | ||
140 | } | 156 | } |
141 | 157 | ||
142 | #[test] | 158 | #[test] |
143 | fn macro_rules_from_other_crates_are_visible() { | 159 | fn 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###" | ||
167 | crate | 178 | crate |
168 | Foo: t v | 179 | Baz: t v |
169 | Bar: t v | 180 | foo: t |
170 | 181 | ||
171 | crate::bar | 182 | crate::foo |
172 | Foo: t v | 183 | bar: t |
173 | Bar: t v | 184 | Baz: t v |
174 | "###); | 185 | |
186 | crate::foo::bar | ||
187 | Baz: 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] |
206 | fn glob_across_crates() { | 221 | fn 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###" | ||
231 | crate | ||
232 | V: t v | ||
233 | E: t | ||
234 | "### | ||
235 | ); | ||
236 | } | ||
237 | |||
238 | #[test] | ||
239 | fn 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###" | ||
264 | crate | ||
265 | bar: t | ||
266 | foo: t | ||
267 | |||
268 | crate::bar | ||
269 | Bar: t v | ||
270 | |||
271 | crate::foo | ||
272 | FromLib: t v | ||
273 | Bar: t v | ||
274 | "### | ||
275 | ); | ||
276 | } | ||
277 | |||
278 | #[test] | ||
279 | fn 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###" | ||
296 | crate | ||
297 | Bar: t v | ||
298 | foo: t | ||
299 | |||
300 | crate::foo | ||
301 | Bar: t v | ||
302 | "### | ||
303 | ); | ||
304 | } | ||
305 | |||
306 | #[test] | ||
307 | fn 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###" | ||
327 | crate | ||
328 | Baz: _ | ||
329 | "### | ||
330 | ); | ||
331 | } | ||
332 | |||
333 | #[test] | ||
334 | fn 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###" | ||
348 | crate | ||
349 | Baz: t v | ||
350 | foo: t | ||
351 | |||
352 | crate::foo | ||
353 | bar: t | ||
354 | |||
355 | crate::foo::bar | ||
356 | Baz: t v | ||
357 | "### | ||
358 | ); | ||
359 | } | ||
360 | |||
361 | #[test] | ||
362 | fn 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###" | ||
222 | crate | 379 | crate |
223 | Baz: t v | 380 | Baz: t v |
224 | "### | 381 | "### |
@@ -226,40 +383,146 @@ Baz: t v | |||
226 | } | 383 | } |
227 | 384 | ||
228 | #[test] | 385 | #[test] |
229 | fn item_map_enum_importing() { | 386 | fn 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###" | ||
239 | crate | 409 | crate |
240 | V: t v | 410 | Arc: t v |
241 | E: t | ||
242 | "### | 411 | "### |
243 | ); | 412 | ); |
244 | } | 413 | } |
245 | 414 | ||
246 | #[test] | 415 | #[test] |
247 | fn glob_enum() { | 416 | fn 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###" | ||
439 | crate | ||
440 | Arc: t v | ||
441 | "### | ||
442 | ); | ||
443 | } | ||
444 | |||
445 | #[test] | ||
446 | fn 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###" | ||
469 | crate | ||
470 | C: t v | ||
471 | "### | ||
472 | ); | ||
473 | } | ||
474 | |||
475 | #[test] | ||
476 | fn 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###" | ||
259 | crate | 498 | crate |
260 | Foo: t | ||
261 | Bar: t v | ||
262 | Baz: t v | 499 | Baz: t v |
263 | "### | 500 | "### |
264 | ); | 501 | ); |
265 | } | 502 | } |
503 | |||
504 | #[test] | ||
505 | fn 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###" | ||
523 | crate | ||
524 | Bar: t v | ||
525 | foo: 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 @@ | |||
1 | use super::*; | ||
2 | |||
3 | #[test] | ||
4 | fn 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###" | ||
21 | crate | ||
22 | bar: t | ||
23 | Foo: t v | ||
24 | Baz: t v | ||
25 | foo: t | ||
26 | |||
27 | crate::foo | ||
28 | bar: t | ||
29 | Foo: t v | ||
30 | Baz: t v | ||
31 | |||
32 | crate::foo::bar | ||
33 | Baz: t v | ||
34 | "### | ||
35 | ); | ||
36 | } | ||
37 | |||
38 | #[test] | ||
39 | fn 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###" | ||
57 | crate | ||
58 | bar: t | ||
59 | Foo: t v | ||
60 | Baz: t v | ||
61 | foo: t | ||
62 | |||
63 | crate::foo | ||
64 | bar: t | ||
65 | Foo: t v | ||
66 | Baz: t v | ||
67 | |||
68 | crate::foo::bar | ||
69 | bar: t | ||
70 | Foo: t v | ||
71 | Baz: t v | ||
72 | "### | ||
73 | ); | ||
74 | } | ||
75 | |||
76 | #[test] | ||
77 | fn 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###" | ||
93 | crate | ||
94 | Baz: t v | ||
95 | "### | ||
96 | ); | ||
97 | } | ||
98 | |||
99 | #[test] | ||
100 | fn 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###" | ||
112 | crate | ||
113 | Foo: t | ||
114 | Bar: t v | ||
115 | Baz: 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 @@ | |||
1 | use super::*; | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use ra_db::SourceDatabase; | ||
6 | |||
7 | fn 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] | ||
28 | fn 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] | ||
56 | fn 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] | ||
96 | fn 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 @@ | |||
1 | use super::*; | ||
2 | |||
3 | #[test] | ||
4 | fn 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###" | ||
21 | crate | ||
22 | nested: t | ||
23 | Foo: t v | ||
24 | |||
25 | crate::nested | ||
26 | Bar: t v | ||
27 | Baz: t v | ||
28 | "###); | ||
29 | } | ||
30 | |||
31 | #[test] | ||
32 | fn 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###" | ||
48 | crate | ||
49 | n1: t | ||
50 | |||
51 | crate::n1 | ||
52 | n2: t | ||
53 | |||
54 | crate::n1::n2 | ||
55 | X: t v | ||
56 | "###); | ||
57 | } | ||
58 | |||
59 | #[test] | ||
60 | fn 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###" | ||
84 | crate | ||
85 | bar: t | ||
86 | Foo: t v | ||
87 | Bar: t v | ||
88 | |||
89 | crate::bar | ||
90 | bar: t | ||
91 | Foo: t v | ||
92 | Bar: t v | ||
93 | "###); | ||
94 | } | ||