diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/tests.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/tests.rs | 528 |
1 files changed, 528 insertions, 0 deletions
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs new file mode 100644 index 000000000..36c1d74ce --- /dev/null +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -0,0 +1,528 @@ | |||
1 | mod macros; | ||
2 | mod globs; | ||
3 | mod incremental; | ||
4 | |||
5 | use std::sync::Arc; | ||
6 | |||
7 | use ra_db::SourceDatabase; | ||
8 | use test_utils::covers; | ||
9 | use insta::assert_snapshot_matches; | ||
10 | |||
11 | use crate::{Crate, mock::{MockDatabase, CrateGraphFixture}, nameres::Resolution}; | ||
12 | |||
13 | use super::*; | ||
14 | |||
15 | fn compute_crate_def_map(fixture: &str, graph: Option<CrateGraphFixture>) -> Arc<CrateDefMap> { | ||
16 | let mut db = MockDatabase::with_files(fixture); | ||
17 | if let Some(graph) = graph { | ||
18 | db.set_crate_graph_from_fixture(graph); | ||
19 | } | ||
20 | let crate_id = db.crate_graph().iter().next().unwrap(); | ||
21 | let krate = Crate { crate_id }; | ||
22 | db.crate_def_map(krate) | ||
23 | } | ||
24 | |||
25 | fn render_crate_def_map(map: &CrateDefMap) -> String { | ||
26 | let mut buf = String::new(); | ||
27 | go(&mut buf, map, "\ncrate", map.root); | ||
28 | return buf; | ||
29 | |||
30 | fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: ModuleId) { | ||
31 | *buf += path; | ||
32 | *buf += "\n"; | ||
33 | for (name, res) in map.modules[module].scope.items.iter() { | ||
34 | *buf += &format!("{}: {}\n", name, dump_resolution(res)) | ||
35 | } | ||
36 | for (name, child) in map.modules[module].children.iter() { | ||
37 | let path = path.to_string() + &format!("::{}", name); | ||
38 | go(buf, map, &path, *child); | ||
39 | } | ||
40 | } | ||
41 | |||
42 | fn dump_resolution(resolution: &Resolution) -> &'static str { | ||
43 | match (resolution.def.types.is_some(), resolution.def.values.is_some()) { | ||
44 | (true, true) => "t v", | ||
45 | (true, false) => "t", | ||
46 | (false, true) => "v", | ||
47 | (false, false) => "_", | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | |||
52 | fn def_map(fixtute: &str) -> String { | ||
53 | let dm = compute_crate_def_map(fixtute, None); | ||
54 | render_crate_def_map(&dm) | ||
55 | } | ||
56 | |||
57 | fn def_map_with_crate_graph(fixtute: &str, graph: CrateGraphFixture) -> String { | ||
58 | let dm = compute_crate_def_map(fixtute, Some(graph)); | ||
59 | render_crate_def_map(&dm) | ||
60 | } | ||
61 | |||
62 | #[test] | ||
63 | fn crate_def_map_smoke_test() { | ||
64 | let map = def_map( | ||
65 | " | ||
66 | //- /lib.rs | ||
67 | mod foo; | ||
68 | struct S; | ||
69 | use crate::foo::bar::E; | ||
70 | use self::E::V; | ||
71 | |||
72 | //- /foo/mod.rs | ||
73 | pub mod bar; | ||
74 | fn f() {} | ||
75 | |||
76 | //- /foo/bar.rs | ||
77 | pub struct Baz; | ||
78 | enum E { V } | ||
79 | ", | ||
80 | ); | ||
81 | assert_snapshot_matches!(map, @r###" | ||
82 | crate | ||
83 | V: t v | ||
84 | E: t | ||
85 | foo: t | ||
86 | S: t v | ||
87 | |||
88 | crate::foo | ||
89 | bar: t | ||
90 | f: v | ||
91 | |||
92 | crate::foo::bar | ||
93 | Baz: t v | ||
94 | E: t | ||
95 | "### | ||
96 | ) | ||
97 | } | ||
98 | |||
99 | #[test] | ||
100 | fn use_as() { | ||
101 | let map = def_map( | ||
102 | " | ||
103 | //- /lib.rs | ||
104 | mod foo; | ||
105 | |||
106 | use crate::foo::Baz as Foo; | ||
107 | |||
108 | //- /foo/mod.rs | ||
109 | pub struct Baz; | ||
110 | ", | ||
111 | ); | ||
112 | assert_snapshot_matches!(map, | ||
113 | @r###" | ||
114 | crate | ||
115 | Foo: t v | ||
116 | foo: t | ||
117 | |||
118 | crate::foo | ||
119 | Baz: t v | ||
120 | "### | ||
121 | ); | ||
122 | } | ||
123 | |||
124 | #[test] | ||
125 | fn use_trees() { | ||
126 | let map = def_map( | ||
127 | " | ||
128 | //- /lib.rs | ||
129 | mod foo; | ||
130 | |||
131 | use crate::foo::bar::{Baz, Quux}; | ||
132 | |||
133 | //- /foo/mod.rs | ||
134 | pub mod bar; | ||
135 | |||
136 | //- /foo/bar.rs | ||
137 | pub struct Baz; | ||
138 | pub enum Quux {}; | ||
139 | ", | ||
140 | ); | ||
141 | assert_snapshot_matches!(map, | ||
142 | @r###" | ||
143 | crate | ||
144 | Quux: t | ||
145 | Baz: t v | ||
146 | foo: t | ||
147 | |||
148 | crate::foo | ||
149 | bar: t | ||
150 | |||
151 | crate::foo::bar | ||
152 | Quux: t | ||
153 | Baz: t v | ||
154 | "### | ||
155 | ); | ||
156 | } | ||
157 | |||
158 | #[test] | ||
159 | fn re_exports() { | ||
160 | let map = def_map( | ||
161 | " | ||
162 | //- /lib.rs | ||
163 | mod foo; | ||
164 | |||
165 | use self::foo::Baz; | ||
166 | |||
167 | //- /foo/mod.rs | ||
168 | pub mod bar; | ||
169 | |||
170 | pub use self::bar::Baz; | ||
171 | |||
172 | //- /foo/bar.rs | ||
173 | pub struct Baz; | ||
174 | ", | ||
175 | ); | ||
176 | assert_snapshot_matches!(map, | ||
177 | @r###" | ||
178 | crate | ||
179 | Baz: t v | ||
180 | foo: t | ||
181 | |||
182 | crate::foo | ||
183 | bar: t | ||
184 | Baz: t v | ||
185 | |||
186 | crate::foo::bar | ||
187 | Baz: t v | ||
188 | "### | ||
189 | ); | ||
190 | } | ||
191 | |||
192 | #[test] | ||
193 | fn std_prelude() { | ||
194 | covers!(std_prelude); | ||
195 | let map = def_map_with_crate_graph( | ||
196 | " | ||
197 | //- /main.rs | ||
198 | use Foo::*; | ||
199 | |||
200 | //- /lib.rs | ||
201 | mod prelude; | ||
202 | #[prelude_import] | ||
203 | use prelude::*; | ||
204 | |||
205 | //- /prelude.rs | ||
206 | pub enum Foo { Bar, Baz }; | ||
207 | ", | ||
208 | crate_graph! { | ||
209 | "main": ("/main.rs", ["test_crate"]), | ||
210 | "test_crate": ("/lib.rs", []), | ||
211 | }, | ||
212 | ); | ||
213 | assert_snapshot_matches!(map, @r###" | ||
214 | crate | ||
215 | Bar: t v | ||
216 | Baz: t v | ||
217 | "###); | ||
218 | } | ||
219 | |||
220 | #[test] | ||
221 | fn can_import_enum_variant() { | ||
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() { | ||
363 | let map = def_map_with_crate_graph( | ||
364 | " | ||
365 | //- /main.rs | ||
366 | use test_crate::Baz; | ||
367 | |||
368 | //- /lib.rs | ||
369 | pub struct Baz; | ||
370 | ", | ||
371 | crate_graph! { | ||
372 | "main": ("/main.rs", ["test_crate"]), | ||
373 | "test_crate": ("/lib.rs", []), | ||
374 | }, | ||
375 | ); | ||
376 | |||
377 | assert_snapshot_matches!(map, | ||
378 | @r###" | ||
379 | crate | ||
380 | Baz: t v | ||
381 | "### | ||
382 | ); | ||
383 | } | ||
384 | |||
385 | #[test] | ||
386 | fn extern_crate_rename() { | ||
387 | let map = def_map_with_crate_graph( | ||
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 | |||
398 | //- /lib.rs | ||
399 | struct Arc; | ||
400 | ", | ||
401 | crate_graph! { | ||
402 | "main": ("/main.rs", ["alloc"]), | ||
403 | "alloc": ("/lib.rs", []), | ||
404 | }, | ||
405 | ); | ||
406 | |||
407 | assert_snapshot_matches!(map, | ||
408 | @r###" | ||
409 | crate | ||
410 | Arc: t v | ||
411 | "### | ||
412 | ); | ||
413 | } | ||
414 | |||
415 | #[test] | ||
416 | fn extern_crate_rename_2015_edition() { | ||
417 | let map = def_map_with_crate_graph( | ||
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( | ||
448 | " | ||
449 | //- /lib.rs | ||
450 | pub mod a { | ||
451 | pub mod b { | ||
452 | pub struct C; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | //- root /main/ | ||
457 | |||
458 | //- /main/main.rs | ||
459 | use test_crate::a::b::C; | ||
460 | ", | ||
461 | crate_graph! { | ||
462 | "main": ("/main/main.rs", ["test_crate"]), | ||
463 | "test_crate": ("/lib.rs", []), | ||
464 | }, | ||
465 | ); | ||
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###" | ||
498 | crate | ||
499 | Baz: t v | ||
500 | "### | ||
501 | ); | ||
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 | } | ||