v / vlib / v2 / builder / parse_test.v
795 lines · 719 sloc · 19.86 KB · d358576851079d4716834cc86627307d28acd1ae
Raw
1// vtest build: macos
2module builder
3
4import os
5import v2.ast
6import v2.pref
7
8fn parse_files_for_parse_test(mut b Builder, paths []string) []ast.File {
9 b.parse_files(paths)
10 b.flat = b.flat_builder.flat
11 return b.flat.to_files()
12}
13
14fn test_parse_files_keeps_single_file_inputs_isolated() {
15 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_parse_single_${os.getpid()}')
16 os.rmdir_all(tmp_dir) or {}
17 os.mkdir_all(tmp_dir) or { panic(err) }
18 defer {
19 os.rmdir_all(tmp_dir) or {}
20 }
21
22 entry_file := os.join_path(tmp_dir, 'hello.v')
23 sibling_file := os.join_path(tmp_dir, 'extra.v')
24 os.write_file(entry_file, 'module main\nfn main() {}\n') or { panic(err) }
25 os.write_file(sibling_file, 'module main\nfn extra() {}\n') or { panic(err) }
26
27 mut prefs := pref.new_preferences()
28 prefs.skip_builtin = true
29 prefs.skip_imports = true
30 mut b := new_builder(&prefs)
31 files := parse_files_for_parse_test(mut b, [entry_file])
32
33 assert files.len == 1
34}
35
36fn test_parse_files_expands_directory_inputs() {
37 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_parse_dir_${os.getpid()}')
38 os.rmdir_all(tmp_dir) or {}
39 os.mkdir_all(tmp_dir) or { panic(err) }
40 defer {
41 os.rmdir_all(tmp_dir) or {}
42 }
43
44 entry_file := os.join_path(tmp_dir, 'hello.v')
45 sibling_file := os.join_path(tmp_dir, 'extra.v')
46 os.write_file(entry_file, 'module main\nfn main() {}\n') or { panic(err) }
47 os.write_file(sibling_file, 'module main\nfn extra() {}\n') or { panic(err) }
48
49 mut prefs := pref.new_preferences()
50 prefs.skip_builtin = true
51 prefs.skip_imports = true
52 mut b := new_builder(&prefs)
53 files := parse_files_for_parse_test(mut b, [tmp_dir])
54
55 assert files.len == 2
56}
57
58fn test_parse_files_expands_same_module_subdirectories() {
59 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_parse_dir_recursive_${os.getpid()}')
60 os.rmdir_all(tmp_dir) or {}
61 os.mkdir_all(os.join_path(tmp_dir, 'user')) or { panic(err) }
62 os.mkdir_all(os.join_path(tmp_dir, 'api')) or { panic(err) }
63 os.mkdir_all(os.join_path(tmp_dir, 'nested_app')) or { panic(err) }
64 defer {
65 os.rmdir_all(tmp_dir) or {}
66 }
67
68 entry_file := os.join_path(tmp_dir, 'main.v')
69 user_file := os.join_path(tmp_dir, 'user', 'user.v')
70 api_file := os.join_path(tmp_dir, 'api', 'api.v')
71 nested_file := os.join_path(tmp_dir, 'nested_app', 'main.v')
72 os.write_file(entry_file, 'module main\nfn main() {}\n') or { panic(err) }
73 os.write_file(user_file, 'module main\nstruct User {}\n') or { panic(err) }
74 os.write_file(api_file, 'module api\nstruct Payload {}\n') or { panic(err) }
75 os.write_file(os.join_path(tmp_dir, 'nested_app', 'v.mod'), 'Module { name: "nested" }\n') or {
76 panic(err)
77 }
78 os.write_file(nested_file, 'module main\nfn nested_main() {}\n') or { panic(err) }
79
80 mut prefs := pref.new_preferences()
81 prefs.skip_builtin = true
82 prefs.skip_imports = true
83 mut b := new_builder(&prefs)
84 files := parse_files_for_parse_test(mut b, [tmp_dir])
85 names := files.map(os.file_name(it.name))
86
87 assert files.len == 2
88 assert 'main.v' in names
89 assert 'user.v' in names
90}
91
92fn test_parse_files_expands_implicit_main_subdirectories() {
93 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_parse_dir_implicit_main_${os.getpid()}')
94 os.rmdir_all(tmp_dir) or {}
95 os.mkdir_all(os.join_path(tmp_dir, 'heroes')) or { panic(err) }
96 defer {
97 os.rmdir_all(tmp_dir) or {}
98 }
99
100 entry_file := os.join_path(tmp_dir, 'main.v')
101 hero_file := os.join_path(tmp_dir, 'heroes', 'hero.v')
102 os.write_file(entry_file, 'fn main() {}\n') or { panic(err) }
103 os.write_file(hero_file, 'struct HeroEffect {}\n') or { panic(err) }
104
105 mut prefs := pref.new_preferences()
106 prefs.skip_builtin = true
107 prefs.skip_imports = true
108 mut b := new_builder(&prefs)
109 files := parse_files_for_parse_test(mut b, [tmp_dir])
110 names := files.map(os.file_name(it.name))
111
112 assert files.len == 2
113 assert 'main.v' in names
114 assert 'hero.v' in names
115}
116
117fn test_parse_files_skips_block_commented_non_main_subdirectories() {
118 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_parse_dir_block_comment_mod_${os.getpid()}')
119 os.rmdir_all(tmp_dir) or {}
120 os.mkdir_all(os.join_path(tmp_dir, 'api')) or { panic(err) }
121 defer {
122 os.rmdir_all(tmp_dir) or {}
123 }
124
125 entry_file := os.join_path(tmp_dir, 'main.v')
126 api_file := os.join_path(tmp_dir, 'api', 'api.v')
127 os.write_file(entry_file, 'module main\nfn main() {}\n') or { panic(err) }
128 os.write_file(api_file, '/* license header */\nmodule api\nstruct Payload {}\n') or {
129 panic(err)
130 }
131
132 mut prefs := pref.new_preferences()
133 prefs.skip_builtin = true
134 prefs.skip_imports = true
135 mut b := new_builder(&prefs)
136 files := parse_files_for_parse_test(mut b, [tmp_dir])
137 names := files.map(os.file_name(it.name))
138
139 assert files.len == 1
140 assert 'main.v' in names
141 assert 'api.v' !in names
142}
143
144fn test_virtual_main_modules_skip_groups_with_executable_main_from_paths() {
145 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_virtual_paths_main_${os.getpid()}')
146 os.rmdir_all(tmp_dir) or {}
147 os.mkdir_all(os.join_path(tmp_dir, 'admin')) or { panic(err) }
148 os.mkdir_all(os.join_path(tmp_dir, 'tests')) or { panic(err) }
149 defer {
150 os.rmdir_all(tmp_dir) or {}
151 }
152
153 main_file := os.join_path(tmp_dir, 'main.v')
154 admin_file := os.join_path(tmp_dir, 'admin', 'admin.v')
155 test_file := os.join_path(tmp_dir, 'tests', 'first_run.v')
156 os.write_file(main_file, 'module main\nfn main() {}\n') or { panic(err) }
157 os.write_file(admin_file, 'module main\nfn admin_route() {}\n') or { panic(err) }
158 os.write_file(test_file, 'module main\nfn main() {}\n') or { panic(err) }
159
160 mut prefs := pref.new_preferences()
161 prefs.skip_builtin = true
162 prefs.skip_imports = true
163 mut b := new_builder(&prefs)
164 b.user_files = [tmp_dir]
165 groups := b.collect_virtual_main_modules_from_paths([main_file, admin_file, test_file])
166 names := groups.map(it.name)
167
168 assert names == ['admin']
169}
170
171fn test_virtual_main_modules_skip_groups_with_attributed_executable_main_from_paths() {
172 tmp_dir := os.join_path(os.temp_dir(),
173 'v2_builder_virtual_paths_attributed_main_${os.getpid()}')
174 os.rmdir_all(tmp_dir) or {}
175 os.mkdir_all(os.join_path(tmp_dir, 'admin')) or { panic(err) }
176 defer {
177 os.rmdir_all(tmp_dir) or {}
178 }
179
180 main_file := os.join_path(tmp_dir, 'main.v')
181 admin_file := os.join_path(tmp_dir, 'admin', 'admin.v')
182 os.write_file(main_file, 'module main\nfn main() {}\n') or { panic(err) }
183 os.write_file(admin_file, 'module main\n@[console] fn main() {}\n') or { panic(err) }
184
185 mut prefs := pref.new_preferences()
186 prefs.skip_builtin = true
187 prefs.skip_imports = true
188 mut b := new_builder(&prefs)
189 b.user_files = [tmp_dir]
190 groups := b.collect_virtual_main_modules_from_paths([main_file, admin_file])
191
192 assert groups.len == 0
193}
194
195fn test_virtual_main_modules_skip_groups_with_executable_main_from_ast() {
196 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_virtual_ast_main_${os.getpid()}')
197 os.rmdir_all(tmp_dir) or {}
198 os.mkdir_all(os.join_path(tmp_dir, 'admin')) or { panic(err) }
199 os.mkdir_all(os.join_path(tmp_dir, 'tests')) or { panic(err) }
200 defer {
201 os.rmdir_all(tmp_dir) or {}
202 }
203
204 os.write_file(os.join_path(tmp_dir, 'main.v'), 'module main\nfn main() {}\n') or { panic(err) }
205 os.write_file(os.join_path(tmp_dir, 'admin', 'admin.v'), 'module main\nfn admin_route() {}\n') or {
206 panic(err)
207 }
208 os.write_file(os.join_path(tmp_dir, 'tests', 'first_run.v'), 'module main\nfn main() {}\n') or {
209 panic(err)
210 }
211
212 mut prefs := pref.new_preferences()
213 prefs.skip_builtin = true
214 prefs.skip_imports = true
215 mut b := new_builder(&prefs)
216 b.user_files = [tmp_dir]
217 b.files = parse_files_for_parse_test(mut b, [tmp_dir])
218 groups := b.collect_virtual_main_modules()
219 names := groups.map(it.name)
220
221 assert names == ['admin']
222}
223
224fn test_parse_files_expands_non_main_module_files() {
225 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_parse_module_${os.getpid()}')
226 os.rmdir_all(tmp_dir) or {}
227 os.mkdir_all(tmp_dir) or { panic(err) }
228 defer {
229 os.rmdir_all(tmp_dir) or {}
230 }
231
232 entry_file := os.join_path(tmp_dir, 'math_test.v')
233 sibling_file := os.join_path(tmp_dir, 'math.v')
234 os.write_file(entry_file, 'module math\nconst x = twice(21)\n') or { panic(err) }
235 os.write_file(sibling_file, 'module math\nfn twice(v int) int { return v * 2 }\n') or {
236 panic(err)
237 }
238
239 mut prefs := pref.new_preferences()
240 prefs.skip_builtin = true
241 prefs.skip_imports = true
242 mut b := new_builder(&prefs)
243 files := parse_files_for_parse_test(mut b, [entry_file])
244
245 assert files.len == 2
246}
247
248fn test_parse_files_resolves_project_root_sibling_import_from_nested_module_file() {
249 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_parse_nested_import_${os.getpid()}')
250 flags_dir := os.join_path(tmp_dir, 'core', 'flags')
251 ignore_dir := os.join_path(tmp_dir, 'ignore')
252 os.rmdir_all(tmp_dir) or {}
253 os.mkdir_all(flags_dir) or { panic(err) }
254 os.mkdir_all(ignore_dir) or { panic(err) }
255 defer {
256 os.rmdir_all(tmp_dir) or {}
257 }
258
259 entry_file := os.join_path(flags_dir, 'complete_test.v')
260 ignore_file := os.join_path(ignore_dir, 'lib.v')
261 os.write_file(os.join_path(tmp_dir, 'v.mod'), "Module { name: 'nested_import' }\n") or {
262 panic(err)
263 }
264 os.write_file(entry_file, 'module flags\nimport ignore\nfn test_use_import() {}\n') or {
265 panic(err)
266 }
267 os.write_file(ignore_file, 'module ignore\npub struct Marker {}\n') or { panic(err) }
268
269 mut prefs := pref.new_preferences()
270 prefs.skip_builtin = true
271 mut b := new_builder(&prefs)
272 files := parse_files_for_parse_test(mut b, [entry_file])
273 names := files.map(os.file_name(it.name))
274
275 assert 'complete_test.v' in names
276 assert 'lib.v' in names
277}
278
279fn test_parse_files_prefers_project_root_module_over_vlib_module() {
280 tmp_dir := os.join_path(os.temp_dir(), 'v2_builder_parse_local_shadow_${os.getpid()}')
281 app_dir := os.join_path(tmp_dir, 'app')
282 regex_dir := os.join_path(tmp_dir, 'regex')
283 os.rmdir_all(tmp_dir) or {}
284 os.mkdir_all(app_dir) or { panic(err) }
285 os.mkdir_all(regex_dir) or { panic(err) }
286 defer {
287 os.rmdir_all(tmp_dir) or {}
288 }
289
290 entry_file := os.join_path(app_dir, 'main.v')
291 local_regex_file := os.join_path(regex_dir, 'local_regex.v')
292 os.write_file(os.join_path(tmp_dir, 'v.mod'), "Module { name: 'local_shadow' }\n") or {
293 panic(err)
294 }
295 os.write_file(entry_file, 'module main\nimport regex\nfn main() {}\n') or { panic(err) }
296 os.write_file(local_regex_file, 'module regex\npub struct RegexMatcher {}\n') or { panic(err) }
297
298 mut prefs := pref.new_preferences()
299 prefs.skip_builtin = true
300 mut b := new_builder(&prefs)
301 files := parse_files_for_parse_test(mut b, [entry_file])
302
303 assert files.any(it.name == local_regex_file)
304}
305
306fn test_active_file_imports_follow_comptime_else_branch() {
307 file := ast.File{
308 mod: 'main'
309 name: 'main.v'
310 stmts: [
311 ast.Stmt(ast.ExprStmt{
312 expr: ast.ComptimeExpr{
313 expr: ast.IfExpr{
314 cond: ast.Ident{
315 name: 'linux'
316 }
317 stmts: [
318 ast.Stmt(ast.ImportStmt{
319 name: 'net.openssl'
320 alias: 'openssl'
321 }),
322 ]
323 else_expr: ast.IfExpr{
324 cond: ast.empty_expr
325 stmts: [
326 ast.Stmt(ast.ImportStmt{
327 name: 'net.mbedtls'
328 alias: 'mbedtls'
329 }),
330 ]
331 }
332 }
333 }
334 }),
335 ]
336 }
337 imports := active_file_imports(file, [], 'mac')
338
339 assert imports.len == 1
340 assert imports[0].name == 'net.mbedtls'
341}
342
343fn test_active_file_imports_skips_sync_for_channel_in_inactive_comptime_branch() {
344 file := ast.File{
345 mod: 'main'
346 name: 'main.v'
347 stmts: [
348 ast.Stmt(ast.ExprStmt{
349 expr: ast.ComptimeExpr{
350 expr: ast.IfExpr{
351 cond: ast.Ident{
352 name: 'windows'
353 }
354 stmts: [
355 ast.Stmt(ast.ExprStmt{
356 expr: ast.Type(ast.ChannelType{
357 elem_type: ast.Expr(ast.Ident{
358 name: 'int'
359 })
360 })
361 }),
362 ]
363 }
364 }
365 }),
366 ]
367 }
368 linux_imports := active_file_imports(file, [], 'linux').map(it.name)
369 windows_imports := active_file_imports(file, [], 'windows').map(it.name)
370
371 assert 'sync' !in linux_imports
372 assert 'sync' in windows_imports
373}
374
375fn test_active_file_imports_skips_sync_for_channel_in_sync_module() {
376 file := ast.File{
377 mod: 'sync'
378 name: 'cond.v'
379 stmts: [
380 ast.Stmt(ast.ModuleStmt{
381 name: 'sync'
382 }),
383 ast.Stmt(ast.StructDecl{
384 name: 'Cond'
385 fields: [
386 ast.FieldDecl{
387 name: 'waiters'
388 typ: ast.Type(ast.ArrayType{
389 elem_type: ast.Expr(ast.Type(ast.ChannelType{
390 elem_type: ast.Expr(ast.Ident{
391 name: 'bool'
392 })
393 }))
394 })
395 },
396 ]
397 }),
398 ]
399 }
400 imports := active_file_imports(file, [], 'mac').map(it.name)
401 mut flat_builder := ast.new_flat_builder()
402 flat_builder.append_file(file)
403 flat_imports := active_file_imports_from_flat(&flat_builder.flat, flat_builder.flat.files[0],
404 [], [], 'mac').map(it.name)
405
406 assert 'sync' !in imports
407 assert 'sync' !in flat_imports
408}
409
410fn test_active_file_imports_adds_sync_for_channel_in_if_condition() {
411 file := ast.File{
412 mod: 'main'
413 name: 'main.v'
414 stmts: [
415 ast.Stmt(ast.ExprStmt{
416 expr: ast.IfExpr{
417 cond: ast.CallExpr{
418 lhs: ast.Expr(ast.Ident{
419 name: 'takes_chan'
420 })
421 args: [
422 ast.Expr(ast.Type(ast.ChannelType{
423 elem_type: ast.Expr(ast.Ident{
424 name: 'int'
425 })
426 })),
427 ]
428 }
429 }
430 }),
431 ]
432 }
433 imports := active_file_imports(file, [], 'mac')
434
435 assert imports.any(it.name == 'sync')
436}
437
438fn test_active_file_imports_adds_sync_for_channel_in_for_condition() {
439 file := ast.File{
440 mod: 'main'
441 name: 'main.v'
442 stmts: [
443 ast.Stmt(ast.ForStmt{
444 cond: ast.CallExpr{
445 lhs: ast.Expr(ast.Ident{
446 name: 'takes_chan'
447 })
448 args: [
449 ast.Expr(ast.Type(ast.ChannelType{
450 elem_type: ast.Expr(ast.Ident{
451 name: 'int'
452 })
453 })),
454 ]
455 }
456 }),
457 ]
458 }
459 imports := active_file_imports(file, [], 'mac')
460
461 assert imports.any(it.name == 'sync')
462}
463
464fn test_active_file_imports_adds_sync_for_channel_in_assert_expr() {
465 file := ast.File{
466 mod: 'main'
467 name: 'main.v'
468 stmts: [
469 ast.Stmt(ast.AssertStmt{
470 expr: ast.CallExpr{
471 lhs: ast.Expr(ast.Ident{
472 name: 'takes_chan'
473 })
474 args: [
475 ast.Expr(ast.Type(ast.ChannelType{
476 elem_type: ast.Expr(ast.Ident{
477 name: 'int'
478 })
479 })),
480 ]
481 }
482 }),
483 ]
484 }
485 imports := active_file_imports(file, [], 'mac')
486
487 assert imports.any(it.name == 'sync')
488}
489
490fn test_active_file_imports_adds_sync_for_channel_in_array_literal() {
491 file := ast.File{
492 mod: 'main'
493 name: 'main.v'
494 stmts: [
495 ast.Stmt(ast.ExprStmt{
496 expr: ast.ArrayInitExpr{
497 exprs: [
498 ast.Expr(ast.Type(ast.ChannelType{
499 elem_type: ast.Expr(ast.Ident{
500 name: 'int'
501 })
502 })),
503 ]
504 }
505 }),
506 ]
507 }
508 imports := active_file_imports(file, [], 'mac')
509
510 assert imports.any(it.name == 'sync')
511}
512
513fn test_active_file_imports_adds_sync_for_channel_in_match_condition() {
514 file := ast.File{
515 mod: 'main'
516 name: 'main.v'
517 stmts: [
518 ast.Stmt(ast.ExprStmt{
519 expr: ast.MatchExpr{
520 expr: ast.Expr(ast.Ident{
521 name: 'value'
522 })
523 branches: [
524 ast.MatchBranch{
525 cond: [
526 ast.Expr(ast.Type(ast.ChannelType{
527 elem_type: ast.Expr(ast.Ident{
528 name: 'int'
529 })
530 })),
531 ]
532 },
533 ]
534 }
535 }),
536 ]
537 }
538 imports := active_file_imports(file, [], 'mac')
539
540 assert imports.any(it.name == 'sync')
541}
542
543fn test_active_file_imports_adds_sync_for_nested_channel_in_infix_expr() {
544 file := ast.File{
545 mod: 'main'
546 name: 'main.v'
547 stmts: [
548 ast.Stmt(ast.ExprStmt{
549 expr: ast.IfExpr{
550 cond: ast.InfixExpr{
551 op: .and
552 lhs: ast.Expr(ast.Ident{
553 name: 'ok'
554 })
555 rhs: ast.Expr(ast.CallExpr{
556 lhs: ast.Expr(ast.Ident{
557 name: 'takes_chan'
558 })
559 args: [
560 ast.Expr(ast.Type(ast.ChannelType{
561 elem_type: ast.Expr(ast.Ident{
562 name: 'int'
563 })
564 })),
565 ]
566 })
567 }
568 }
569 }),
570 ]
571 }
572 imports := active_file_imports(file, [], 'mac')
573
574 assert imports.any(it.name == 'sync')
575}
576
577fn test_active_file_imports_adds_sync_for_channel_in_call_callee_generic_args() {
578 file := ast.File{
579 mod: 'main'
580 name: 'main.v'
581 stmts: [
582 ast.Stmt(ast.ExprStmt{
583 expr: ast.CallExpr{
584 lhs: ast.Expr(ast.GenericArgs{
585 lhs: ast.Expr(ast.Ident{
586 name: 'make_value'
587 })
588 args: [
589 ast.Expr(ast.Type(ast.ChannelType{
590 elem_type: ast.Expr(ast.Ident{
591 name: 'int'
592 })
593 })),
594 ]
595 })
596 }
597 }),
598 ]
599 }
600 imports := active_file_imports(file, [], 'mac')
601
602 assert imports.any(it.name == 'sync')
603}
604
605fn test_active_file_imports_adds_sync_for_channel_in_modifier_expr_operand() {
606 file := ast.File{
607 mod: 'main'
608 name: 'main.v'
609 stmts: [
610 ast.Stmt(ast.ExprStmt{
611 expr: ast.CallExpr{
612 lhs: ast.Expr(ast.Ident{
613 name: 'use'
614 })
615 args: [
616 ast.Expr(ast.ModifierExpr{
617 kind: .key_mut
618 expr: ast.IndexExpr{
619 lhs: ast.Expr(ast.Ident{
620 name: 'arr'
621 })
622 expr: ast.Expr(ast.CallExpr{
623 lhs: ast.Expr(ast.Ident{
624 name: 'idx'
625 })
626 args: [
627 ast.Expr(ast.Type(ast.ChannelType{
628 elem_type: ast.Expr(ast.Ident{
629 name: 'int'
630 })
631 })),
632 ]
633 })
634 }
635 }),
636 ]
637 }
638 }),
639 ]
640 }
641 imports := active_file_imports(file, [], 'mac')
642
643 assert imports.any(it.name == 'sync')
644}
645
646fn test_active_file_imports_adds_sync_for_channel_in_assign_lhs() {
647 file := ast.File{
648 mod: 'main'
649 name: 'main.v'
650 stmts: [
651 ast.Stmt(ast.AssignStmt{
652 lhs: [
653 ast.Expr(ast.IndexExpr{
654 lhs: ast.Expr(ast.Ident{
655 name: 'arr'
656 })
657 expr: ast.Expr(ast.CallExpr{
658 lhs: ast.Expr(ast.Ident{
659 name: 'idx'
660 })
661 args: [
662 ast.Expr(ast.Type(ast.ChannelType{
663 elem_type: ast.Expr(ast.Ident{
664 name: 'int'
665 })
666 })),
667 ]
668 })
669 }),
670 ]
671 rhs: [
672 ast.Expr(ast.BasicLiteral{
673 kind: .number
674 value: '0'
675 }),
676 ]
677 }),
678 ]
679 }
680 imports := active_file_imports(file, [], 'mac')
681
682 assert imports.any(it.name == 'sync')
683}
684
685fn test_active_file_imports_adds_sync_for_channel_in_labelled_loop() {
686 file := ast.File{
687 mod: 'main'
688 name: 'main.v'
689 stmts: [
690 ast.Stmt(ast.LabelStmt{
691 name: 'outer'
692 stmt: ast.Stmt(ast.ForStmt{
693 stmts: [
694 ast.Stmt(ast.AssignStmt{
695 lhs: [
696 ast.Expr(ast.Ident{
697 name: '_'
698 }),
699 ]
700 rhs: [
701 ast.Expr(ast.Type(ast.ChannelType{
702 elem_type: ast.Expr(ast.Ident{
703 name: 'int'
704 })
705 })),
706 ]
707 }),
708 ]
709 })
710 }),
711 ]
712 }
713 imports := active_file_imports(file, [], 'mac')
714
715 assert imports.any(it.name == 'sync')
716}
717
718fn test_active_file_imports_ignores_channel_in_inactive_attributed_fn_body() {
719 file := ast.File{
720 mod: 'main'
721 name: 'main.v'
722 stmts: [
723 ast.Stmt(ast.FnDecl{
724 name: 'debug'
725 typ: ast.FnType{}
726 attributes: [
727 ast.Attribute{
728 name: 'if'
729 comptime_cond: ast.Expr(ast.Ident{
730 name: 'windows'
731 })
732 },
733 ]
734 stmts: [
735 ast.Stmt(ast.AssignStmt{
736 lhs: [
737 ast.Expr(ast.Ident{
738 name: '_'
739 }),
740 ]
741 rhs: [
742 ast.Expr(ast.Type(ast.ChannelType{
743 elem_type: ast.Expr(ast.Ident{
744 name: 'int'
745 })
746 })),
747 ]
748 }),
749 ]
750 }),
751 ]
752 }
753 imports := active_file_imports(file, [], 'mac')
754
755 assert !imports.any(it.name == 'sync')
756}
757
758fn test_active_file_imports_skip_pkgconfig_branch_when_disabled() {
759 if !pref.comptime_pkgconfig_value('sqlite3') {
760 return
761 }
762 file := ast.File{
763 mod: 'main'
764 name: 'main.v'
765 stmts: [
766 ast.Stmt(ast.ExprStmt{
767 expr: ast.ComptimeExpr{
768 expr: ast.IfExpr{
769 cond: ast.CallExpr{
770 lhs: ast.Expr(ast.Ident{
771 name: 'pkgconfig'
772 })
773 args: [
774 ast.Expr(ast.StringLiteral{
775 kind: .v
776 value: "'sqlite3'"
777 }),
778 ]
779 }
780 stmts: [
781 ast.Stmt(ast.ImportStmt{
782 name: 'db.sqlite'
783 }),
784 ]
785 }
786 }
787 }),
788 ]
789 }
790 native_imports := active_file_imports_with_options(file, [], [], 'mac', true).map(it.name)
791 cross_imports := active_file_imports_with_options(file, [], [], 'mac', false).map(it.name)
792
793 assert 'db.sqlite' in native_imports
794 assert 'db.sqlite' !in cross_imports
795}
796