diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/tests.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/tests.rs | 784 |
1 files changed, 285 insertions, 499 deletions
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 9b151bb0c..ac9b88520 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -1,34 +1,43 @@ | |||
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; |
4 | use test_utils::{assert_eq_text, covers}; | 8 | use test_utils::covers; |
5 | 9 | use insta::assert_snapshot_matches; | |
6 | use crate::{ | 10 | |
7 | ItemMap, | 11 | use crate::{Crate, mock::{MockDatabase, CrateGraphFixture}, nameres::Resolution}; |
8 | PersistentHirDatabase, | 12 | |
9 | mock::MockDatabase, | 13 | use super::*; |
10 | module_tree::ModuleId, | 14 | |
11 | }; | 15 | fn compute_crate_def_map(fixture: &str, graph: Option<CrateGraphFixture>) -> Arc<CrateDefMap> { |
12 | use super::Resolution; | 16 | let mut db = MockDatabase::with_files(fixture); |
13 | 17 | if let Some(graph) = graph { | |
14 | fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) { | 18 | db.set_crate_graph_from_fixture(graph); |
15 | let (db, pos) = MockDatabase::with_position(fixture); | 19 | } |
16 | let module = crate::source_binder::module_from_position(&db, pos).unwrap(); | 20 | let crate_id = db.crate_graph().iter().next().unwrap(); |
17 | let krate = module.krate(&db).unwrap(); | 21 | let krate = Crate { crate_id }; |
18 | let module_id = module.module_id; | 22 | db.crate_def_map(krate) |
19 | (db.item_map(krate), module_id) | ||
20 | } | 23 | } |
21 | 24 | ||
22 | fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { | 25 | fn render_crate_def_map(map: &CrateDefMap) -> String { |
23 | let mut lines = map[module_id] | 26 | let mut buf = String::new(); |
24 | .items | 27 | go(&mut buf, map, "\ncrate", map.root); |
25 | .iter() | 28 | return buf; |
26 | .map(|(name, res)| format!("{}: {}", name, dump_resolution(res))) | 29 | |
27 | .collect::<Vec<_>>(); | 30 | fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: CrateModuleId) { |
28 | lines.sort(); | 31 | *buf += path; |
29 | let actual = lines.join("\n"); | 32 | *buf += "\n"; |
30 | let expected = expected.trim().lines().map(|it| it.trim()).collect::<Vec<_>>().join("\n"); | 33 | for (name, res) in map.modules[module].scope.items.iter() { |
31 | assert_eq_text!(&expected, &actual); | 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 | } | ||
32 | 41 | ||
33 | fn dump_resolution(resolution: &Resolution) -> &'static str { | 42 | fn dump_resolution(resolution: &Resolution) -> &'static str { |
34 | match (resolution.def.types.is_some(), resolution.def.values.is_some()) { | 43 | match (resolution.def.types.is_some(), resolution.def.values.is_some()) { |
@@ -40,66 +49,112 @@ fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { | |||
40 | } | 49 | } |
41 | } | 50 | } |
42 | 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 | |||
43 | #[test] | 62 | #[test] |
44 | fn item_map_smoke_test() { | 63 | fn crate_def_map_smoke_test() { |
45 | let (item_map, module_id) = item_map( | 64 | let map = def_map( |
46 | " | 65 | " |
47 | //- /lib.rs | 66 | //- /lib.rs |
48 | mod foo; | 67 | mod foo; |
49 | 68 | struct S; | |
50 | use crate::foo::bar::Baz; | 69 | use crate::foo::bar::E; |
51 | <|> | 70 | use self::E::V; |
52 | 71 | ||
53 | //- /foo/mod.rs | 72 | //- /foo/mod.rs |
54 | pub mod bar; | 73 | pub mod bar; |
74 | fn f() {} | ||
55 | 75 | ||
56 | //- /foo/bar.rs | 76 | //- /foo/bar.rs |
57 | pub struct Baz; | 77 | pub struct Baz; |
58 | ", | 78 | enum E { V } |
79 | ", | ||
59 | ); | 80 | ); |
60 | check_module_item_map( | 81 | assert_snapshot_matches!(map, @r###" |
61 | &item_map, | 82 | crate |
62 | module_id, | 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 bogus_paths() { | ||
101 | covers!(bogus_paths); | ||
102 | let map = def_map( | ||
63 | " | 103 | " |
64 | Baz: t v | 104 | //- /lib.rs |
65 | foo: t | 105 | mod foo; |
106 | struct S; | ||
107 | use self; | ||
108 | |||
109 | //- /foo/mod.rs | ||
110 | use super; | ||
111 | use crate; | ||
112 | |||
66 | ", | 113 | ", |
67 | ); | 114 | ); |
115 | assert_snapshot_matches!(map, @r###" | ||
116 | crate | ||
117 | foo: t | ||
118 | S: t v | ||
119 | |||
120 | crate::foo | ||
121 | "### | ||
122 | ) | ||
68 | } | 123 | } |
69 | 124 | ||
70 | #[test] | 125 | #[test] |
71 | fn use_as() { | 126 | fn use_as() { |
72 | let (item_map, module_id) = item_map( | 127 | let map = def_map( |
73 | " | 128 | " |
74 | //- /lib.rs | 129 | //- /lib.rs |
75 | mod foo; | 130 | mod foo; |
76 | 131 | ||
77 | use crate::foo::Baz as Foo; | 132 | use crate::foo::Baz as Foo; |
78 | <|> | ||
79 | 133 | ||
80 | //- /foo/mod.rs | 134 | //- /foo/mod.rs |
81 | pub struct Baz; | 135 | pub struct Baz; |
82 | ", | ||
83 | ); | ||
84 | check_module_item_map( | ||
85 | &item_map, | ||
86 | module_id, | ||
87 | " | ||
88 | Foo: t v | ||
89 | foo: t | ||
90 | ", | 136 | ", |
91 | ); | 137 | ); |
138 | assert_snapshot_matches!(map, | ||
139 | @r###" | ||
140 | crate | ||
141 | Foo: t v | ||
142 | foo: t | ||
143 | |||
144 | crate::foo | ||
145 | Baz: t v | ||
146 | "### | ||
147 | ); | ||
92 | } | 148 | } |
93 | 149 | ||
94 | #[test] | 150 | #[test] |
95 | fn use_trees() { | 151 | fn use_trees() { |
96 | let (item_map, module_id) = item_map( | 152 | let map = def_map( |
97 | " | 153 | " |
98 | //- /lib.rs | 154 | //- /lib.rs |
99 | mod foo; | 155 | mod foo; |
100 | 156 | ||
101 | use crate::foo::bar::{Baz, Quux}; | 157 | use crate::foo::bar::{Baz, Quux}; |
102 | <|> | ||
103 | 158 | ||
104 | //- /foo/mod.rs | 159 | //- /foo/mod.rs |
105 | pub mod bar; | 160 | pub mod bar; |
@@ -107,28 +162,33 @@ fn use_trees() { | |||
107 | //- /foo/bar.rs | 162 | //- /foo/bar.rs |
108 | pub struct Baz; | 163 | pub struct Baz; |
109 | pub enum Quux {}; | 164 | pub enum Quux {}; |
110 | ", | ||
111 | ); | ||
112 | check_module_item_map( | ||
113 | &item_map, | ||
114 | module_id, | ||
115 | " | ||
116 | Baz: t v | ||
117 | Quux: t | ||
118 | foo: t | ||
119 | ", | 165 | ", |
120 | ); | 166 | ); |
167 | assert_snapshot_matches!(map, | ||
168 | @r###" | ||
169 | crate | ||
170 | Quux: t | ||
171 | Baz: t v | ||
172 | foo: t | ||
173 | |||
174 | crate::foo | ||
175 | bar: t | ||
176 | |||
177 | crate::foo::bar | ||
178 | Quux: t | ||
179 | Baz: t v | ||
180 | "### | ||
181 | ); | ||
121 | } | 182 | } |
122 | 183 | ||
123 | #[test] | 184 | #[test] |
124 | fn re_exports() { | 185 | fn re_exports() { |
125 | let (item_map, module_id) = item_map( | 186 | let map = def_map( |
126 | " | 187 | " |
127 | //- /lib.rs | 188 | //- /lib.rs |
128 | mod foo; | 189 | mod foo; |
129 | 190 | ||
130 | use self::foo::Baz; | 191 | use self::foo::Baz; |
131 | <|> | ||
132 | 192 | ||
133 | //- /foo/mod.rs | 193 | //- /foo/mod.rs |
134 | pub mod bar; | 194 | pub mod bar; |
@@ -137,137 +197,73 @@ fn re_exports() { | |||
137 | 197 | ||
138 | //- /foo/bar.rs | 198 | //- /foo/bar.rs |
139 | pub struct Baz; | 199 | pub struct Baz; |
140 | ", | ||
141 | ); | ||
142 | check_module_item_map( | ||
143 | &item_map, | ||
144 | module_id, | ||
145 | " | ||
146 | Baz: t v | ||
147 | foo: t | ||
148 | ", | 200 | ", |
149 | ); | 201 | ); |
150 | } | 202 | assert_snapshot_matches!(map, |
203 | @r###" | ||
204 | crate | ||
205 | Baz: t v | ||
206 | foo: t | ||
151 | 207 | ||
152 | #[test] | 208 | crate::foo |
153 | fn glob_1() { | 209 | bar: t |
154 | let (item_map, module_id) = item_map( | 210 | Baz: t v |
155 | " | ||
156 | //- /lib.rs | ||
157 | mod foo; | ||
158 | use foo::*; | ||
159 | <|> | ||
160 | |||
161 | //- /foo/mod.rs | ||
162 | pub mod bar; | ||
163 | pub use self::bar::Baz; | ||
164 | pub struct Foo; | ||
165 | 211 | ||
166 | //- /foo/bar.rs | 212 | crate::foo::bar |
167 | pub struct Baz; | 213 | Baz: t v |
168 | ", | 214 | "### |
169 | ); | ||
170 | check_module_item_map( | ||
171 | &item_map, | ||
172 | module_id, | ||
173 | " | ||
174 | Baz: t v | ||
175 | Foo: t v | ||
176 | bar: t | ||
177 | foo: t | ||
178 | ", | ||
179 | ); | 215 | ); |
180 | } | 216 | } |
181 | 217 | ||
182 | #[test] | 218 | #[test] |
183 | fn glob_2() { | 219 | fn std_prelude() { |
184 | let (item_map, module_id) = item_map( | 220 | covers!(std_prelude); |
185 | " | 221 | let map = def_map_with_crate_graph( |
186 | //- /lib.rs | ||
187 | mod foo; | ||
188 | use foo::*; | ||
189 | <|> | ||
190 | |||
191 | //- /foo/mod.rs | ||
192 | pub mod bar; | ||
193 | pub use self::bar::*; | ||
194 | pub struct Foo; | ||
195 | |||
196 | //- /foo/bar.rs | ||
197 | pub struct Baz; | ||
198 | pub use super::*; | ||
199 | ", | ||
200 | ); | ||
201 | check_module_item_map( | ||
202 | &item_map, | ||
203 | module_id, | ||
204 | " | 222 | " |
205 | Baz: t v | 223 | //- /main.rs |
206 | Foo: t v | 224 | use Foo::*; |
207 | bar: t | ||
208 | foo: t | ||
209 | ", | ||
210 | ); | ||
211 | } | ||
212 | 225 | ||
213 | #[test] | ||
214 | fn glob_enum() { | ||
215 | covers!(glob_enum); | ||
216 | let (item_map, module_id) = item_map( | ||
217 | " | ||
218 | //- /lib.rs | 226 | //- /lib.rs |
219 | enum Foo { | 227 | mod prelude; |
220 | Bar, Baz | 228 | #[prelude_import] |
221 | } | 229 | use prelude::*; |
222 | use self::Foo::*; | 230 | |
223 | <|> | 231 | //- /prelude.rs |
224 | ", | 232 | pub enum Foo { Bar, Baz }; |
225 | ); | ||
226 | check_module_item_map( | ||
227 | &item_map, | ||
228 | module_id, | ||
229 | " | ||
230 | Bar: t v | ||
231 | Baz: t v | ||
232 | Foo: t | ||
233 | ", | 233 | ", |
234 | crate_graph! { | ||
235 | "main": ("/main.rs", ["test_crate"]), | ||
236 | "test_crate": ("/lib.rs", []), | ||
237 | }, | ||
234 | ); | 238 | ); |
239 | assert_snapshot_matches!(map, @r###" | ||
240 | crate | ||
241 | Bar: t v | ||
242 | Baz: t v | ||
243 | "###); | ||
235 | } | 244 | } |
236 | 245 | ||
237 | #[test] | 246 | #[test] |
238 | fn glob_across_crates() { | 247 | fn can_import_enum_variant() { |
239 | covers!(glob_across_crates); | 248 | covers!(can_import_enum_variant); |
240 | let mut db = MockDatabase::with_files( | 249 | let map = def_map( |
241 | " | 250 | " |
242 | //- /main.rs | ||
243 | use test_crate::*; | ||
244 | |||
245 | //- /lib.rs | 251 | //- /lib.rs |
246 | pub struct Baz; | 252 | enum E { V } |
253 | use self::E::V; | ||
247 | ", | 254 | ", |
248 | ); | 255 | ); |
249 | db.set_crate_graph_from_fixture(crate_graph! { | 256 | assert_snapshot_matches!(map, @r###" |
250 | "main": ("/main.rs", ["test_crate"]), | 257 | crate |
251 | "test_crate": ("/lib.rs", []), | 258 | V: t v |
252 | }); | 259 | E: t |
253 | let main_id = db.file_id_of("/main.rs"); | 260 | "### |
254 | |||
255 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | ||
256 | let krate = module.krate(&db).unwrap(); | ||
257 | let item_map = db.item_map(krate); | ||
258 | |||
259 | check_module_item_map( | ||
260 | &item_map, | ||
261 | module.module_id, | ||
262 | " | ||
263 | Baz: t v | ||
264 | ", | ||
265 | ); | 261 | ); |
266 | } | 262 | } |
267 | 263 | ||
268 | #[test] | 264 | #[test] |
269 | fn edition_2015_imports() { | 265 | fn edition_2015_imports() { |
270 | let mut db = MockDatabase::with_files( | 266 | let map = def_map_with_crate_graph( |
271 | " | 267 | " |
272 | //- /main.rs | 268 | //- /main.rs |
273 | mod foo; | 269 | mod foo; |
@@ -282,31 +278,32 @@ fn edition_2015_imports() { | |||
282 | 278 | ||
283 | //- /lib.rs | 279 | //- /lib.rs |
284 | struct FromLib; | 280 | struct FromLib; |
285 | ", | ||
286 | ); | ||
287 | db.set_crate_graph_from_fixture(crate_graph! { | ||
288 | "main": ("/main.rs", "2015", ["other_crate"]), | ||
289 | "other_crate": ("/lib.rs", "2018", []), | ||
290 | }); | ||
291 | let foo_id = db.file_id_of("/foo.rs"); | ||
292 | |||
293 | let module = crate::source_binder::module_from_file_id(&db, foo_id).unwrap(); | ||
294 | let krate = module.krate(&db).unwrap(); | ||
295 | let item_map = db.item_map(krate); | ||
296 | |||
297 | check_module_item_map( | ||
298 | &item_map, | ||
299 | module.module_id, | ||
300 | " | ||
301 | Bar: t v | ||
302 | FromLib: t v | ||
303 | ", | 281 | ", |
282 | crate_graph! { | ||
283 | "main": ("/main.rs", "2015", ["other_crate"]), | ||
284 | "other_crate": ("/lib.rs", "2018", []), | ||
285 | }, | ||
286 | ); | ||
287 | |||
288 | assert_snapshot_matches!(map, | ||
289 | @r###" | ||
290 | crate | ||
291 | bar: t | ||
292 | foo: t | ||
293 | |||
294 | crate::bar | ||
295 | Bar: t v | ||
296 | |||
297 | crate::foo | ||
298 | FromLib: t v | ||
299 | Bar: t v | ||
300 | "### | ||
304 | ); | 301 | ); |
305 | } | 302 | } |
306 | 303 | ||
307 | #[test] | 304 | #[test] |
308 | fn module_resolution_works_for_non_standard_filenames() { | 305 | fn module_resolution_works_for_non_standard_filenames() { |
309 | let mut db = MockDatabase::with_files( | 306 | let map = def_map_with_crate_graph( |
310 | " | 307 | " |
311 | //- /my_library.rs | 308 | //- /my_library.rs |
312 | mod foo; | 309 | mod foo; |
@@ -315,73 +312,32 @@ fn module_resolution_works_for_non_standard_filenames() { | |||
315 | //- /foo/mod.rs | 312 | //- /foo/mod.rs |
316 | pub struct Bar; | 313 | pub struct Bar; |
317 | ", | 314 | ", |
315 | crate_graph! { | ||
316 | "my_library": ("/my_library.rs", []), | ||
317 | }, | ||
318 | ); | 318 | ); |
319 | db.set_crate_graph_from_fixture(crate_graph! { | ||
320 | "my_library": ("/my_library.rs", []), | ||
321 | }); | ||
322 | let file_id = db.file_id_of("/my_library.rs"); | ||
323 | |||
324 | let module = crate::source_binder::module_from_file_id(&db, file_id).unwrap(); | ||
325 | let krate = module.krate(&db).unwrap(); | ||
326 | let module_id = module.module_id; | ||
327 | let item_map = db.item_map(krate); | ||
328 | check_module_item_map( | ||
329 | &item_map, | ||
330 | module_id, | ||
331 | " | ||
332 | Bar: t v | ||
333 | foo: t | ||
334 | ", | ||
335 | ); | ||
336 | } | ||
337 | 319 | ||
338 | #[test] | 320 | assert_snapshot_matches!(map, |
339 | fn std_prelude() { | 321 | @r###" |
340 | covers!(std_prelude); | 322 | crate |
341 | let mut db = MockDatabase::with_files( | 323 | Bar: t v |
342 | " | 324 | foo: t |
343 | //- /main.rs | ||
344 | use Foo::*; | ||
345 | |||
346 | //- /lib.rs | ||
347 | mod prelude; | ||
348 | #[prelude_import] | ||
349 | use prelude::*; | ||
350 | 325 | ||
351 | //- /prelude.rs | 326 | crate::foo |
352 | pub enum Foo { Bar, Baz }; | 327 | Bar: t v |
353 | ", | 328 | "### |
354 | ); | ||
355 | db.set_crate_graph_from_fixture(crate_graph! { | ||
356 | "main": ("/main.rs", ["test_crate"]), | ||
357 | "test_crate": ("/lib.rs", []), | ||
358 | }); | ||
359 | let main_id = db.file_id_of("/main.rs"); | ||
360 | |||
361 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | ||
362 | let krate = module.krate(&db).unwrap(); | ||
363 | let item_map = db.item_map(krate); | ||
364 | |||
365 | check_module_item_map( | ||
366 | &item_map, | ||
367 | module.module_id, | ||
368 | " | ||
369 | Bar: t v | ||
370 | Baz: t v | ||
371 | ", | ||
372 | ); | 329 | ); |
373 | } | 330 | } |
374 | 331 | ||
375 | #[test] | 332 | #[test] |
376 | fn name_res_works_for_broken_modules() { | 333 | fn name_res_works_for_broken_modules() { |
377 | covers!(name_res_works_for_broken_modules); | 334 | covers!(name_res_works_for_broken_modules); |
378 | let (item_map, module_id) = item_map( | 335 | let map = def_map( |
379 | " | 336 | " |
380 | //- /lib.rs | 337 | //- /lib.rs |
381 | mod foo // no `;`, no body | 338 | mod foo // no `;`, no body |
382 | 339 | ||
383 | use self::foo::Baz; | 340 | use self::foo::Baz; |
384 | <|> | ||
385 | 341 | ||
386 | //- /foo/mod.rs | 342 | //- /foo/mod.rs |
387 | pub mod bar; | 343 | pub mod bar; |
@@ -390,65 +346,47 @@ fn name_res_works_for_broken_modules() { | |||
390 | 346 | ||
391 | //- /foo/bar.rs | 347 | //- /foo/bar.rs |
392 | pub struct Baz; | 348 | pub struct Baz; |
393 | ", | ||
394 | ); | ||
395 | check_module_item_map( | ||
396 | &item_map, | ||
397 | module_id, | ||
398 | " | ||
399 | Baz: _ | ||
400 | ", | 349 | ", |
401 | ); | 350 | ); |
402 | } | 351 | assert_snapshot_matches!(map, |
403 | 352 | @r###" | |
404 | #[test] | 353 | crate |
405 | fn item_map_using_self() { | 354 | Baz: _ |
406 | let (item_map, module_id) = item_map( | 355 | "### |
407 | " | ||
408 | //- /lib.rs | ||
409 | mod foo; | ||
410 | use crate::foo::bar::Baz::{self}; | ||
411 | <|> | ||
412 | //- /foo/mod.rs | ||
413 | pub mod bar; | ||
414 | //- /foo/bar.rs | ||
415 | pub struct Baz; | ||
416 | ", | ||
417 | ); | ||
418 | check_module_item_map( | ||
419 | &item_map, | ||
420 | module_id, | ||
421 | " | ||
422 | Baz: t v | ||
423 | foo: t | ||
424 | ", | ||
425 | ); | 356 | ); |
426 | } | 357 | } |
427 | 358 | ||
428 | #[test] | 359 | #[test] |
429 | fn item_map_enum_importing() { | 360 | fn item_map_using_self() { |
430 | covers!(item_map_enum_importing); | 361 | let map = def_map( |
431 | let (item_map, module_id) = item_map( | ||
432 | " | 362 | " |
433 | //- /lib.rs | 363 | //- /lib.rs |
434 | enum E { V } | 364 | mod foo; |
435 | use self::E::V; | 365 | use crate::foo::bar::Baz::{self}; |
436 | <|> | 366 | //- /foo/mod.rs |
367 | pub mod bar; | ||
368 | //- /foo/bar.rs | ||
369 | pub struct Baz; | ||
437 | ", | 370 | ", |
438 | ); | 371 | ); |
439 | check_module_item_map( | 372 | assert_snapshot_matches!(map, |
440 | &item_map, | 373 | @r###" |
441 | module_id, | 374 | crate |
442 | " | 375 | Baz: t v |
443 | E: t | 376 | foo: t |
444 | V: t v | 377 | |
445 | ", | 378 | crate::foo |
379 | bar: t | ||
380 | |||
381 | crate::foo::bar | ||
382 | Baz: t v | ||
383 | "### | ||
446 | ); | 384 | ); |
447 | } | 385 | } |
448 | 386 | ||
449 | #[test] | 387 | #[test] |
450 | fn item_map_across_crates() { | 388 | fn item_map_across_crates() { |
451 | let mut db = MockDatabase::with_files( | 389 | let map = def_map_with_crate_graph( |
452 | " | 390 | " |
453 | //- /main.rs | 391 | //- /main.rs |
454 | use test_crate::Baz; | 392 | use test_crate::Baz; |
@@ -456,29 +394,23 @@ fn item_map_across_crates() { | |||
456 | //- /lib.rs | 394 | //- /lib.rs |
457 | pub struct Baz; | 395 | pub struct Baz; |
458 | ", | 396 | ", |
397 | crate_graph! { | ||
398 | "main": ("/main.rs", ["test_crate"]), | ||
399 | "test_crate": ("/lib.rs", []), | ||
400 | }, | ||
459 | ); | 401 | ); |
460 | db.set_crate_graph_from_fixture(crate_graph! { | 402 | |
461 | "main": ("/main.rs", ["test_crate"]), | 403 | assert_snapshot_matches!(map, |
462 | "test_crate": ("/lib.rs", []), | 404 | @r###" |
463 | }); | 405 | crate |
464 | let main_id = db.file_id_of("/main.rs"); | 406 | Baz: t v |
465 | 407 | "### | |
466 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | ||
467 | let krate = module.krate(&db).unwrap(); | ||
468 | let item_map = db.item_map(krate); | ||
469 | |||
470 | check_module_item_map( | ||
471 | &item_map, | ||
472 | module.module_id, | ||
473 | " | ||
474 | Baz: t v | ||
475 | ", | ||
476 | ); | 408 | ); |
477 | } | 409 | } |
478 | 410 | ||
479 | #[test] | 411 | #[test] |
480 | fn extern_crate_rename() { | 412 | fn extern_crate_rename() { |
481 | let mut db = MockDatabase::with_files( | 413 | let map = def_map_with_crate_graph( |
482 | " | 414 | " |
483 | //- /main.rs | 415 | //- /main.rs |
484 | extern crate alloc as alloc_crate; | 416 | extern crate alloc as alloc_crate; |
@@ -492,29 +424,23 @@ fn extern_crate_rename() { | |||
492 | //- /lib.rs | 424 | //- /lib.rs |
493 | struct Arc; | 425 | struct Arc; |
494 | ", | 426 | ", |
427 | crate_graph! { | ||
428 | "main": ("/main.rs", ["alloc"]), | ||
429 | "alloc": ("/lib.rs", []), | ||
430 | }, | ||
495 | ); | 431 | ); |
496 | db.set_crate_graph_from_fixture(crate_graph! { | 432 | |
497 | "main": ("/main.rs", ["alloc"]), | 433 | assert_snapshot_matches!(map, |
498 | "alloc": ("/lib.rs", []), | 434 | @r###" |
499 | }); | 435 | crate |
500 | let sync_id = db.file_id_of("/sync.rs"); | 436 | Arc: t v |
501 | 437 | "### | |
502 | let module = crate::source_binder::module_from_file_id(&db, sync_id).unwrap(); | ||
503 | let krate = module.krate(&db).unwrap(); | ||
504 | let item_map = db.item_map(krate); | ||
505 | |||
506 | check_module_item_map( | ||
507 | &item_map, | ||
508 | module.module_id, | ||
509 | " | ||
510 | Arc: t v | ||
511 | ", | ||
512 | ); | 438 | ); |
513 | } | 439 | } |
514 | 440 | ||
515 | #[test] | 441 | #[test] |
516 | fn extern_crate_rename_2015_edition() { | 442 | fn extern_crate_rename_2015_edition() { |
517 | let mut db = MockDatabase::with_files( | 443 | let map = def_map_with_crate_graph( |
518 | " | 444 | " |
519 | //- /main.rs | 445 | //- /main.rs |
520 | extern crate alloc as alloc_crate; | 446 | extern crate alloc as alloc_crate; |
@@ -528,29 +454,23 @@ fn extern_crate_rename_2015_edition() { | |||
528 | //- /lib.rs | 454 | //- /lib.rs |
529 | struct Arc; | 455 | struct Arc; |
530 | ", | 456 | ", |
457 | crate_graph! { | ||
458 | "main": ("/main.rs", "2015", ["alloc"]), | ||
459 | "alloc": ("/lib.rs", []), | ||
460 | }, | ||
531 | ); | 461 | ); |
532 | db.set_crate_graph_from_fixture(crate_graph! { | 462 | |
533 | "main": ("/main.rs", "2015", ["alloc"]), | 463 | assert_snapshot_matches!(map, |
534 | "alloc": ("/lib.rs", []), | 464 | @r###" |
535 | }); | 465 | crate |
536 | let sync_id = db.file_id_of("/sync.rs"); | 466 | Arc: t v |
537 | 467 | "### | |
538 | let module = crate::source_binder::module_from_file_id(&db, sync_id).unwrap(); | ||
539 | let krate = module.krate(&db).unwrap(); | ||
540 | let item_map = db.item_map(krate); | ||
541 | |||
542 | check_module_item_map( | ||
543 | &item_map, | ||
544 | module.module_id, | ||
545 | " | ||
546 | Arc: t v | ||
547 | ", | ||
548 | ); | 468 | ); |
549 | } | 469 | } |
550 | 470 | ||
551 | #[test] | 471 | #[test] |
552 | fn import_across_source_roots() { | 472 | fn import_across_source_roots() { |
553 | let mut db = MockDatabase::with_files( | 473 | let map = def_map_with_crate_graph( |
554 | " | 474 | " |
555 | //- /lib.rs | 475 | //- /lib.rs |
556 | pub mod a { | 476 | pub mod a { |
@@ -564,29 +484,23 @@ fn import_across_source_roots() { | |||
564 | //- /main/main.rs | 484 | //- /main/main.rs |
565 | use test_crate::a::b::C; | 485 | use test_crate::a::b::C; |
566 | ", | 486 | ", |
487 | crate_graph! { | ||
488 | "main": ("/main/main.rs", ["test_crate"]), | ||
489 | "test_crate": ("/lib.rs", []), | ||
490 | }, | ||
567 | ); | 491 | ); |
568 | db.set_crate_graph_from_fixture(crate_graph! { | 492 | |
569 | "main": ("/main/main.rs", ["test_crate"]), | 493 | assert_snapshot_matches!(map, |
570 | "test_crate": ("/lib.rs", []), | 494 | @r###" |
571 | }); | 495 | crate |
572 | let main_id = db.file_id_of("/main/main.rs"); | 496 | C: t v |
573 | 497 | "### | |
574 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | ||
575 | let krate = module.krate(&db).unwrap(); | ||
576 | let item_map = db.item_map(krate); | ||
577 | |||
578 | check_module_item_map( | ||
579 | &item_map, | ||
580 | module.module_id, | ||
581 | " | ||
582 | C: t v | ||
583 | ", | ||
584 | ); | 498 | ); |
585 | } | 499 | } |
586 | 500 | ||
587 | #[test] | 501 | #[test] |
588 | fn reexport_across_crates() { | 502 | fn reexport_across_crates() { |
589 | let mut db = MockDatabase::with_files( | 503 | let map = def_map_with_crate_graph( |
590 | " | 504 | " |
591 | //- /main.rs | 505 | //- /main.rs |
592 | use test_crate::Baz; | 506 | use test_crate::Baz; |
@@ -599,29 +513,23 @@ fn reexport_across_crates() { | |||
599 | //- /foo.rs | 513 | //- /foo.rs |
600 | pub struct Baz; | 514 | pub struct Baz; |
601 | ", | 515 | ", |
516 | crate_graph! { | ||
517 | "main": ("/main.rs", ["test_crate"]), | ||
518 | "test_crate": ("/lib.rs", []), | ||
519 | }, | ||
602 | ); | 520 | ); |
603 | db.set_crate_graph_from_fixture(crate_graph! { | 521 | |
604 | "main": ("/main.rs", ["test_crate"]), | 522 | assert_snapshot_matches!(map, |
605 | "test_crate": ("/lib.rs", []), | 523 | @r###" |
606 | }); | 524 | crate |
607 | let main_id = db.file_id_of("/main.rs"); | 525 | Baz: t v |
608 | 526 | "### | |
609 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | ||
610 | let krate = module.krate(&db).unwrap(); | ||
611 | let item_map = db.item_map(krate); | ||
612 | |||
613 | check_module_item_map( | ||
614 | &item_map, | ||
615 | module.module_id, | ||
616 | " | ||
617 | Baz: t v | ||
618 | ", | ||
619 | ); | 527 | ); |
620 | } | 528 | } |
621 | 529 | ||
622 | #[test] | 530 | #[test] |
623 | fn values_dont_shadow_extern_crates() { | 531 | fn values_dont_shadow_extern_crates() { |
624 | let mut db = MockDatabase::with_files( | 532 | let map = def_map_with_crate_graph( |
625 | " | 533 | " |
626 | //- /main.rs | 534 | //- /main.rs |
627 | fn foo() {} | 535 | fn foo() {} |
@@ -630,139 +538,17 @@ fn values_dont_shadow_extern_crates() { | |||
630 | //- /foo/lib.rs | 538 | //- /foo/lib.rs |
631 | pub struct Bar; | 539 | pub struct Bar; |
632 | ", | 540 | ", |
541 | crate_graph! { | ||
542 | "main": ("/main.rs", ["foo"]), | ||
543 | "foo": ("/foo/lib.rs", []), | ||
544 | }, | ||
633 | ); | 545 | ); |
634 | db.set_crate_graph_from_fixture(crate_graph! { | ||
635 | "main": ("/main.rs", ["foo"]), | ||
636 | "foo": ("/foo/lib.rs", []), | ||
637 | }); | ||
638 | let main_id = db.file_id_of("/main.rs"); | ||
639 | |||
640 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | ||
641 | let krate = module.krate(&db).unwrap(); | ||
642 | let item_map = db.item_map(krate); | ||
643 | |||
644 | check_module_item_map( | ||
645 | &item_map, | ||
646 | module.module_id, | ||
647 | " | ||
648 | Bar: t v | ||
649 | foo: v | ||
650 | ", | ||
651 | ); | ||
652 | } | ||
653 | |||
654 | fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { | ||
655 | let (mut db, pos) = MockDatabase::with_position(initial); | ||
656 | let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap(); | ||
657 | let krate = module.krate(&db).unwrap(); | ||
658 | { | ||
659 | let events = db.log_executed(|| { | ||
660 | db.item_map(krate); | ||
661 | }); | ||
662 | assert!(format!("{:?}", events).contains("item_map")) | ||
663 | } | ||
664 | db.set_file_text(pos.file_id, Arc::new(file_change.to_string())); | ||
665 | |||
666 | { | ||
667 | let events = db.log_executed(|| { | ||
668 | db.item_map(krate); | ||
669 | }); | ||
670 | assert!(!format!("{:?}", events).contains("item_map"), "{:#?}", events) | ||
671 | } | ||
672 | } | ||
673 | |||
674 | #[test] | ||
675 | fn typing_inside_a_function_should_not_invalidate_item_map() { | ||
676 | check_item_map_is_not_recomputed( | ||
677 | " | ||
678 | //- /lib.rs | ||
679 | mod foo;<|> | ||
680 | |||
681 | use crate::foo::bar::Baz; | ||
682 | |||
683 | fn foo() -> i32 { | ||
684 | 1 + 1 | ||
685 | } | ||
686 | //- /foo/mod.rs | ||
687 | pub mod bar; | ||
688 | |||
689 | //- /foo/bar.rs | ||
690 | pub struct Baz; | ||
691 | ", | ||
692 | " | ||
693 | mod foo; | ||
694 | |||
695 | use crate::foo::bar::Baz; | ||
696 | |||
697 | fn foo() -> i32 { 92 } | ||
698 | ", | ||
699 | ); | ||
700 | } | ||
701 | |||
702 | #[test] | ||
703 | fn adding_inner_items_should_not_invalidate_item_map() { | ||
704 | check_item_map_is_not_recomputed( | ||
705 | " | ||
706 | //- /lib.rs | ||
707 | struct S { a: i32} | ||
708 | enum E { A } | ||
709 | trait T { | ||
710 | fn a() {} | ||
711 | } | ||
712 | mod foo;<|> | ||
713 | impl S { | ||
714 | fn a() {} | ||
715 | } | ||
716 | use crate::foo::bar::Baz; | ||
717 | //- /foo/mod.rs | ||
718 | pub mod bar; | ||
719 | |||
720 | //- /foo/bar.rs | ||
721 | pub struct Baz; | ||
722 | ", | ||
723 | " | ||
724 | struct S { a: i32, b: () } | ||
725 | enum E { A, B } | ||
726 | trait T { | ||
727 | fn a() {} | ||
728 | fn b() {} | ||
729 | } | ||
730 | mod foo;<|> | ||
731 | impl S { | ||
732 | fn a() {} | ||
733 | fn b() {} | ||
734 | } | ||
735 | use crate::foo::bar::Baz; | ||
736 | ", | ||
737 | ); | ||
738 | } | ||
739 | 546 | ||
740 | #[test] | 547 | assert_snapshot_matches!(map, |
741 | fn typing_inside_a_function_inside_a_macro_should_not_invalidate_item_map() { | 548 | @r###" |
742 | check_item_map_is_not_recomputed( | 549 | crate |
743 | " | 550 | Bar: t v |
744 | //- /lib.rs | 551 | foo: v |
745 | mod foo; | 552 | "### |
746 | |||
747 | use crate::foo::bar::Baz; | ||
748 | |||
749 | //- /foo/mod.rs | ||
750 | pub mod bar; | ||
751 | |||
752 | //- /foo/bar.rs | ||
753 | <|> | ||
754 | salsa::query_group! { | ||
755 | trait Baz { | ||
756 | fn foo() -> i32 { 1 + 1 } | ||
757 | } | ||
758 | } | ||
759 | ", | ||
760 | " | ||
761 | salsa::query_group! { | ||
762 | trait Baz { | ||
763 | fn foo() -> i32 { 92 } | ||
764 | } | ||
765 | } | ||
766 | ", | ||
767 | ); | 553 | ); |
768 | } | 554 | } |