v / vlib / v2 / builder / flag_target_test.v
608 lines · 558 sloc · 20.16 KB · 3dd96de45339a469cb83ffacc0e50b017468e032
Raw
1module builder
2
3import os
4import v2.ast
5import v2.pref
6
7fn collect_cflags_for_test_source(source string, mut prefs pref.Preferences) string {
8 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_builder_flag_target_${os.getpid()}')
9 os.mkdir_all(tmp_dir) or { panic(err) }
10 defer {
11 os.rmdir_all(tmp_dir) or {}
12 }
13 source_path := os.join_path(tmp_dir, 'main.v')
14 os.write_file(source_path, source) or { panic(err) }
15 prefs.skip_builtin = true
16 mut b := new_builder(&prefs)
17 b.files = [
18 ast.File{
19 name: source_path
20 },
21 ]
22 return b.collect_cflags_from_sources()
23}
24
25fn collect_cflags_for_flat_only_test_source(source string, mut prefs pref.Preferences) string {
26 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_builder_flag_target_flat_${os.getpid()}')
27 os.mkdir_all(tmp_dir) or { panic(err) }
28 defer {
29 os.rmdir_all(tmp_dir) or {}
30 }
31 source_path := os.join_path(tmp_dir, 'main.v')
32 os.write_file(source_path, source) or { panic(err) }
33 prefs.skip_builtin = true
34 mut b := new_builder(&prefs)
35 b.flat = ast.flatten_files([
36 ast.File{
37 name: source_path
38 mod: 'main'
39 },
40 ])
41 b.files = []ast.File{}
42 return b.collect_cflags_from_sources()
43}
44
45fn freestanding_test_call_name(name string, user_defines []string) string {
46 return freestanding_test_call_name_with_hooks(name, user_defines, [])
47}
48
49fn freestanding_test_call_name_with_hooks(name string, user_defines []string, hooks []string) string {
50 return freestanding_restricted_call_in_expr(ast.Expr(ast.CallExpr{
51 lhs: ast.Expr(ast.Ident{
52 name: name
53 })
54 }), FreestandingScanContext{
55 user_defines: user_defines
56 target_os: 'linux'
57 freestanding_hooks: hooks
58 })
59}
60
61fn test_flag_directives_match_cross_and_freestanding_preferences() {
62 mut cross_prefs := pref.new_preferences()
63 cross_prefs.target_os = 'cross'
64 cross_prefs.user_defines = ['cross']
65 cross_flag := parse_flag_directive_line_with_pref('#flag cross -DCROSS_DIRECT',
66 '/tmp/source.v', &cross_prefs) or { '' }
67 linux_flag := parse_flag_directive_line_with_pref('#flag linux -DLINUX_DIRECT',
68 '/tmp/source.v', &cross_prefs) or { '' }
69 assert cross_flag == '-DCROSS_DIRECT'
70 assert linux_flag == ''
71
72 mut free_prefs := pref.new_preferences()
73 free_prefs.target_os = 'linux'
74 free_prefs.user_defines = ['freestanding']
75 free_flag := parse_flag_directive_line_with_pref('#flag freestanding -DFREE_DIRECT',
76 '/tmp/source.v', &free_prefs) or { '' }
77 linux_in_free_flag := parse_flag_directive_line_with_pref('#flag linux -DLINUX_DIRECT',
78 '/tmp/source.v', &free_prefs) or { '' }
79 assert free_flag == '-DFREE_DIRECT'
80 assert linux_in_free_flag == '-DLINUX_DIRECT'
81}
82
83fn test_comptime_flag_blocks_match_cross_and_freestanding_preferences() {
84 mut cross_prefs := pref.new_preferences()
85 cross_prefs.target_os = 'cross'
86 cross_prefs.user_defines = ['cross']
87 assert comptime_cond_matches_with_pref('cross', &cross_prefs)
88 assert !comptime_cond_matches_with_pref('linux', &cross_prefs)
89 assert !comptime_cond_matches_with_pref('linux ?', &cross_prefs)
90 assert comptime_cond_matches_with_pref('cross && !linux', &cross_prefs)
91
92 mut optional_linux_prefs := pref.new_preferences()
93 optional_linux_prefs.target_os = 'cross'
94 optional_linux_prefs.user_defines = ['cross', 'linux']
95 optional_linux_prefs.explicit_user_defines = ['linux']
96 assert comptime_cond_matches_with_pref('linux ?', &optional_linux_prefs)
97
98 mut linux_prefs := pref.new_preferences()
99 linux_prefs.target_os = 'linux'
100 assert comptime_cond_matches_with_pref('linux', &linux_prefs)
101 assert !comptime_cond_matches_with_pref('linux ?', &linux_prefs)
102 assert !comptime_cond_matches_with_pref('linux ? || windows', &linux_prefs)
103 linux_prefs.user_defines = ['linux']
104 linux_prefs.explicit_user_defines = ['linux']
105 assert comptime_cond_matches_with_pref('linux ?', &linux_prefs)
106 assert comptime_cond_matches_with_pref('linux ? || windows', &linux_prefs)
107
108 mut termux_prefs := pref.new_preferences()
109 termux_prefs.target_os = 'termux'
110 assert comptime_cond_matches_with_pref('termux', &termux_prefs)
111 assert comptime_cond_matches_with_pref('linux || termux', &termux_prefs)
112 assert !comptime_cond_matches_with_pref('android', &termux_prefs)
113 assert !comptime_cond_matches_with_pref('android && !termux', &termux_prefs)
114
115 mut free_prefs := pref.new_preferences()
116 free_prefs.target_os = 'linux'
117 free_prefs.user_defines = ['freestanding']
118 assert comptime_cond_matches_with_pref('freestanding', &free_prefs)
119 assert !comptime_cond_matches_with_pref('freestanding ?', &free_prefs)
120 assert comptime_cond_matches_with_pref('linux', &free_prefs)
121 assert comptime_cond_matches_with_pref('freestanding && linux', &free_prefs)
122}
123
124fn test_comptime_pkgconfig_condition_matches_available_package() {
125 mut prefs := pref.new_preferences()
126 prefs.target_os = os.user_os()
127 assert !comptime_cond_matches_with_pref(r"$pkgconfig('__v2_definitely_missing_pkgconfig_test_package__')",
128 &prefs)
129 if pref.comptime_pkgconfig_value('sqlite3') {
130 assert comptime_cond_matches_with_pref(r"$pkgconfig('sqlite3')", &prefs)
131 }
132}
133
134fn test_pkgconfig_directive_collects_flags_for_active_native_branch() {
135 mut prefs := pref.new_preferences()
136 prefs.target_os = os.user_os()
137 if pref.comptime_pkgconfig_value('sqlite3') {
138 flag := parse_flag_directive_line_with_pref('#pkgconfig sqlite3', '/tmp/source.v', &prefs) or {
139 ''
140 }
141 assert flag.contains('sqlite3')
142 }
143
144 mut cross_prefs := pref.new_preferences()
145 cross_prefs.target_os = 'cross'
146 cross_prefs.output_cross_c = true
147 flag := parse_flag_directive_line_with_pref('#pkgconfig sqlite3', '/tmp/source.v', &cross_prefs) or {
148 ''
149 }
150 assert flag == ''
151}
152
153fn test_comptime_optional_target_mode_flags_require_explicit_define() {
154 mut cross_prefs := pref.new_preferences()
155 cross_prefs.target_os = 'cross'
156 cross_prefs.user_defines = ['cross']
157 assert comptime_cond_matches_with_pref('cross', &cross_prefs)
158 assert !comptime_cond_matches_with_pref('cross ?', &cross_prefs)
159 cross_prefs.explicit_user_defines = ['cross']
160 assert comptime_cond_matches_with_pref('cross ?', &cross_prefs)
161
162 mut free_prefs := pref.new_preferences()
163 free_prefs.target_os = 'linux'
164 free_prefs.user_defines = ['freestanding']
165 assert comptime_cond_matches_with_pref('freestanding', &free_prefs)
166 assert !comptime_cond_matches_with_pref('freestanding ?', &free_prefs)
167 free_prefs.explicit_user_defines = ['freestanding']
168 assert comptime_cond_matches_with_pref('freestanding ?', &free_prefs)
169
170 mut none_prefs := pref.new_preferences()
171 none_prefs.target_os = 'none'
172 none_prefs.user_defines = ['freestanding']
173 assert comptime_cond_matches_with_pref('none', &none_prefs)
174 assert !comptime_cond_matches_with_pref('none ?', &none_prefs)
175 none_prefs.explicit_user_defines = ['none']
176 assert comptime_cond_matches_with_pref('none ?', &none_prefs)
177}
178
179fn test_comptime_flag_blocks_use_or_and_not_precedence() {
180 mut linux_prefs := pref.new_preferences()
181 linux_prefs.target_os = 'linux'
182 assert comptime_cond_matches_with_pref('!windows && linux', &linux_prefs)
183 assert comptime_cond_matches_with_pref('linux || windows && macos', &linux_prefs)
184
185 mut macos_prefs := pref.new_preferences()
186 macos_prefs.target_os = 'macos'
187 assert !comptime_cond_matches_with_pref('!windows && linux', &macos_prefs)
188 assert !comptime_cond_matches_with_pref('linux || windows && macos', &macos_prefs)
189
190 mut windows_prefs := pref.new_preferences()
191 windows_prefs.target_os = 'windows'
192 assert !comptime_cond_matches_with_pref('!windows && linux', &windows_prefs)
193 assert !comptime_cond_matches_with_pref('linux || windows && macos', &windows_prefs)
194}
195
196fn test_parser_level_comptime_flags_match_cross_and_accepted_targets() {
197 assert ast_comptime_flag_matches('cross', [], 'cross')
198 assert ast_comptime_flag_matches('solaris', [], 'solaris')
199 assert ast_comptime_flag_matches('qnx', [], 'qnx')
200 assert ast_comptime_flag_matches('serenity', [], 'serenity')
201 assert ast_comptime_flag_matches('plan9', [], 'plan9')
202 assert ast_comptime_flag_matches('vinix', [], 'vinix')
203 assert ast_comptime_flag_matches('ios', [], 'ios')
204 assert ast_comptime_flag_matches('termux', [], 'termux')
205 assert ast_comptime_flag_matches('none', [], 'none')
206 assert !ast_comptime_flag_matches('linux', [], 'cross')
207 assert !ast_comptime_flag_matches('linux', ['linux'], 'windows')
208 assert !ast_comptime_flag_matches('none', ['none'], 'linux')
209}
210
211fn test_flag_directives_match_all_accepted_target_os_names() {
212 for target in ['android', 'termux', 'ios', 'solaris', 'qnx', 'serenity', 'plan9', 'vinix'] {
213 flag := parse_flag_directive_line('#flag ${target} -D${target.to_upper()}',
214 '/tmp/source.v', target) or { '' }
215 assert flag == '-D${target.to_upper()}'
216 assert comptime_cond_matches(target, target)
217 }
218}
219
220fn test_collect_cflags_from_sources_matches_cross_and_freestanding_blocks() {
221 cross_source := 'module main
222
223$if cross {
224#flag -DCROSS_BLOCK
225}
226$if cross ? {
227#flag -DOPTIONAL_CROSS_BLOCK
228}
229$if linux {
230#flag -DLINUX_BLOCK
231}
232$if linux ? {
233#flag -DOPTIONAL_LINUX_BLOCK
234}
235$if macos {
236#flag -DMACOS_BLOCK
237}
238$if windows {
239#flag -DWINDOWS_BLOCK
240}
241#flag cross -DCROSS_DIRECT
242#flag linux -DLINUX_DIRECT
243#flag macos -DMACOS_DIRECT
244#flag windows -DWINDOWS_DIRECT
245'
246 mut cross_prefs := pref.new_preferences()
247 cross_prefs.target_os = 'cross'
248 cross_prefs.user_defines = ['cross']
249 cross_flags := collect_cflags_for_test_source(cross_source, mut cross_prefs)
250 assert cross_flags.contains('-DCROSS_BLOCK')
251 assert cross_flags.contains('-DCROSS_DIRECT')
252 assert !cross_flags.contains('-DOPTIONAL_CROSS_BLOCK')
253 assert !cross_flags.contains('-DOPTIONAL_LINUX_BLOCK')
254 host_os := normalize_target_os_name(os.user_os())
255 if host_os in ['linux', 'macos', 'windows'] {
256 assert cross_flags.contains(match host_os {
257 'macos' { '-DMACOS_BLOCK' }
258 'windows' { '-DWINDOWS_BLOCK' }
259 else { '-DLINUX_BLOCK' }
260 })
261 assert cross_flags.contains(match host_os {
262 'macos' { '-DMACOS_DIRECT' }
263 'windows' { '-DWINDOWS_DIRECT' }
264 else { '-DLINUX_DIRECT' }
265 })
266 }
267 if host_os != 'linux' {
268 assert !cross_flags.contains('-DLINUX_BLOCK')
269 assert !cross_flags.contains('-DLINUX_DIRECT')
270 }
271 if host_os != 'macos' {
272 assert !cross_flags.contains('-DMACOS_BLOCK')
273 assert !cross_flags.contains('-DMACOS_DIRECT')
274 }
275 if host_os != 'windows' {
276 assert !cross_flags.contains('-DWINDOWS_BLOCK')
277 assert !cross_flags.contains('-DWINDOWS_DIRECT')
278 }
279 mut cross_with_optional_linux_prefs := pref.new_preferences()
280 cross_with_optional_linux_prefs.target_os = 'cross'
281 cross_with_optional_linux_prefs.user_defines = ['cross', 'linux']
282 cross_with_optional_linux_prefs.explicit_user_defines = ['linux']
283 cross_with_optional_linux_flags := collect_cflags_for_test_source(cross_source, mut
284 cross_with_optional_linux_prefs)
285 assert cross_with_optional_linux_flags.contains('-DOPTIONAL_LINUX_BLOCK')
286 assert !cross_with_optional_linux_flags.contains('-DOPTIONAL_CROSS_BLOCK')
287
288 mut cross_explicit_prefs := pref.new_preferences()
289 cross_explicit_prefs.target_os = 'cross'
290 cross_explicit_prefs.user_defines = ['cross']
291 cross_explicit_prefs.explicit_user_defines = ['cross']
292 cross_explicit_flags := collect_cflags_for_test_source(cross_source, mut cross_explicit_prefs)
293 assert cross_explicit_flags.contains('-DOPTIONAL_CROSS_BLOCK')
294
295 free_source := 'module main
296
297$if freestanding {
298#flag -DFREE_BLOCK
299}
300$if freestanding ? {
301#flag -DOPTIONAL_FREE_BLOCK
302}
303$if linux {
304#flag -DLINUX_BLOCK
305}
306#flag freestanding -DFREE_DIRECT
307#flag linux -DLINUX_DIRECT
308'
309 mut free_prefs := pref.new_preferences()
310 free_prefs.target_os = 'linux'
311 free_prefs.user_defines = ['freestanding']
312 free_flags := collect_cflags_for_test_source(free_source, mut free_prefs)
313 assert free_flags.contains('-DFREE_BLOCK')
314 assert !free_flags.contains('-DOPTIONAL_FREE_BLOCK')
315 assert free_flags.contains('-DFREE_DIRECT')
316 assert free_flags.contains('-DLINUX_BLOCK')
317 assert free_flags.contains('-DLINUX_DIRECT')
318
319 mut free_explicit_prefs := pref.new_preferences()
320 free_explicit_prefs.target_os = 'linux'
321 free_explicit_prefs.user_defines = ['freestanding']
322 free_explicit_prefs.explicit_user_defines = ['freestanding']
323 free_explicit_flags := collect_cflags_for_test_source(free_source, mut free_explicit_prefs)
324 assert free_explicit_flags.contains('-DOPTIONAL_FREE_BLOCK')
325}
326
327fn test_collect_cflags_from_sources_reads_flat_file_names() {
328 source := 'module main
329
330#flag -DFLAT_ONLY_FLAG
331'
332 mut prefs := pref.new_preferences()
333 flags := collect_cflags_for_flat_only_test_source(source, mut prefs)
334 assert flags.contains('-DFLAT_ONLY_FLAG')
335}
336
337fn test_collect_cflags_from_sources_keeps_optional_os_flags_custom_only() {
338 source := 'module main
339
340$if linux {
341#flag -DLINUX_BLOCK
342}
343$if linux ? {
344#flag -DOPTIONAL_LINUX_BLOCK
345}
346$if linux ? || windows {
347#flag -DOPTIONAL_LINUX_OR_WINDOWS_BLOCK
348}
349'
350 mut linux_prefs := pref.new_preferences()
351 linux_prefs.target_os = 'linux'
352 linux_flags := collect_cflags_for_test_source(source, mut linux_prefs)
353 assert linux_flags.contains('-DLINUX_BLOCK')
354 assert !linux_flags.contains('-DOPTIONAL_LINUX_BLOCK')
355 assert !linux_flags.contains('-DOPTIONAL_LINUX_OR_WINDOWS_BLOCK')
356
357 mut linux_defined_prefs := pref.new_preferences()
358 linux_defined_prefs.target_os = 'linux'
359 linux_defined_prefs.user_defines = ['linux']
360 linux_defined_prefs.explicit_user_defines = ['linux']
361 linux_defined_flags := collect_cflags_for_test_source(source, mut linux_defined_prefs)
362 assert linux_defined_flags.contains('-DLINUX_BLOCK')
363 assert linux_defined_flags.contains('-DOPTIONAL_LINUX_BLOCK')
364 assert linux_defined_flags.contains('-DOPTIONAL_LINUX_OR_WINDOWS_BLOCK')
365
366 mut windows_prefs := pref.new_preferences()
367 windows_prefs.target_os = 'windows'
368 windows_flags := collect_cflags_for_test_source(source, mut windows_prefs)
369 assert !windows_flags.contains('-DLINUX_BLOCK')
370 assert !windows_flags.contains('-DOPTIONAL_LINUX_BLOCK')
371 assert windows_flags.contains('-DOPTIONAL_LINUX_OR_WINDOWS_BLOCK')
372}
373
374fn test_collect_cflags_from_sources_keeps_optional_none_custom_only() {
375 source := 'module main
376
377$if none {
378#flag -DNONE_BLOCK
379}
380$if none ? {
381#flag -DOPTIONAL_NONE_BLOCK
382}
383'
384 mut none_prefs := pref.new_preferences()
385 none_prefs.target_os = 'none'
386 none_prefs.user_defines = ['freestanding']
387 none_flags := collect_cflags_for_test_source(source, mut none_prefs)
388 assert none_flags.contains('-DNONE_BLOCK')
389 assert !none_flags.contains('-DOPTIONAL_NONE_BLOCK')
390
391 mut none_explicit_prefs := pref.new_preferences()
392 none_explicit_prefs.target_os = 'none'
393 none_explicit_prefs.user_defines = ['freestanding']
394 none_explicit_prefs.explicit_user_defines = ['none']
395 none_explicit_flags := collect_cflags_for_test_source(source, mut none_explicit_prefs)
396 assert none_explicit_flags.contains('-DOPTIONAL_NONE_BLOCK')
397}
398
399fn test_collect_cflags_from_sources_matches_termux_blocks_and_directives() {
400 source := 'module main
401
402$if termux {
403#flag -DTERMUX_BLOCK
404}
405$if linux || termux {
406#flag -DTERMUX_OR_LINUX_BLOCK
407}
408$if android && !termux {
409#flag -DANDROID_OUTSIDE_TERMUX_BLOCK
410}
411#flag termux -DTERMUX_DIRECT
412#flag android -DANDROID_DIRECT
413'
414 mut termux_prefs := pref.new_preferences()
415 termux_prefs.target_os = 'termux'
416 flags := collect_cflags_for_test_source(source, mut termux_prefs)
417 assert flags.contains('-DTERMUX_BLOCK')
418 assert flags.contains('-DTERMUX_OR_LINUX_BLOCK')
419 assert flags.contains('-DTERMUX_DIRECT')
420 assert !flags.contains('-DANDROID_OUTSIDE_TERMUX_BLOCK')
421 assert !flags.contains('-DANDROID_DIRECT')
422}
423
424fn test_freestanding_diagnostics_gate_direct_builtins_by_capability() {
425 for name in ['print', 'println', 'eprint', 'eprintln'] {
426 assert freestanding_test_call_name(name, ['freestanding_hooks']) == name
427 assert freestanding_test_call_name_with_hooks(name, ['freestanding_hooks',
428 'freestanding_output'], ['output']) == ''
429 }
430 assert freestanding_test_call_name('panic', ['freestanding_hooks']) == 'panic'
431 assert freestanding_test_call_name_with_hooks('panic', ['freestanding_hooks',
432 'freestanding_panic'], ['panic']) == ''
433}
434
435fn test_freestanding_diagnostics_leave_runtime_helpers_to_cleanc() {
436 for name in ['_write_buf_to_fd', '_writeln_to_fd', 'flush_stdout', 'flush_stderr'] {
437 assert freestanding_test_call_name(name, ['freestanding_hooks']) == ''
438 }
439
440 assert freestanding_test_call_name_with_hooks('arguments', ['freestanding_hooks',
441 'freestanding_output'], ['output']) == ''
442 assert freestanding_test_call_name_with_hooks('arguments', ['freestanding_hooks',
443 'freestanding_alloc'], ['alloc']) == ''
444 assert freestanding_test_call_name('malloc_noscan',
445 ['freestanding_hooks', 'freestanding_alloc']) == ''
446 assert freestanding_test_call_name_with_hooks('malloc_noscan', [
447 'freestanding_hooks',
448 'freestanding_alloc',
449 ], ['alloc']) == ''
450 assert freestanding_restricted_call_in_expr(ast.Expr(ast.CallExpr{
451 lhs: ast.Expr(ast.Ident{
452 name: 'println'
453 })
454 args: [
455 ast.Expr(ast.BasicLiteral{
456 kind: .number
457 value: '123'
458 }),
459 ]
460 }), FreestandingScanContext{
461 user_defines: ['freestanding_hooks', 'freestanding_output']
462 target_os: 'linux'
463 freestanding_hooks: ['output']
464 }) == ''
465 assert freestanding_restricted_call_in_expr(ast.Expr(ast.CallExpr{
466 lhs: ast.Expr(ast.Ident{
467 name: 'println'
468 })
469 args: [
470 ast.Expr(ast.BasicLiteral{
471 kind: .number
472 value: '123'
473 }),
474 ]
475 }), FreestandingScanContext{
476 user_defines: ['freestanding_hooks', 'freestanding_output', 'freestanding_alloc']
477 target_os: 'linux'
478 freestanding_hooks: ['output', 'alloc']
479 }) == ''
480}
481
482fn test_freestanding_diagnostics_skip_inactive_conditional_functions() {
483 ctx := FreestandingScanContext{
484 user_defines: ['freestanding']
485 target_os: 'linux'
486 }
487 hosted_call := ast.Stmt(ast.ExprStmt{
488 expr: ast.Expr(ast.CallExpr{
489 lhs: ast.Expr(ast.Ident{
490 name: 'println'
491 })
492 })
493 })
494 inactive_windows_fn := ast.Stmt(ast.FnDecl{
495 attributes: [
496 ast.Attribute{
497 comptime_cond: ast.Expr(ast.Ident{
498 name: 'windows'
499 })
500 },
501 ]
502 stmts: [hosted_call]
503 })
504 inactive_not_freestanding_fn := ast.Stmt(ast.FnDecl{
505 attributes: [
506 ast.Attribute{
507 comptime_cond: ast.Expr(ast.PrefixExpr{
508 op: .not
509 expr: ast.Expr(ast.Ident{
510 name: 'freestanding'
511 })
512 })
513 },
514 ]
515 stmts: [hosted_call]
516 })
517 active_fn := ast.Stmt(ast.FnDecl{
518 attributes: [
519 ast.Attribute{
520 comptime_cond: ast.Expr(ast.Ident{
521 name: 'freestanding'
522 })
523 },
524 ]
525 stmts: [hosted_call]
526 })
527 assert freestanding_restricted_call_in_stmt(inactive_windows_fn, ctx) == ''
528 assert freestanding_restricted_call_in_stmt(inactive_not_freestanding_fn, ctx) == ''
529 assert freestanding_restricted_call_in_stmt(active_fn, ctx) == 'println'
530}
531
532fn test_freestanding_diagnostics_leave_array_allocation_to_cleanc() {
533 ctx := FreestandingScanContext{
534 user_defines: ['freestanding']
535 target_os: 'linux'
536 }
537 fixed_array := ast.Expr(ast.ArrayInitExpr{
538 typ: ast.Expr(ast.Type(ast.ArrayFixedType{
539 len: ast.Expr(ast.BasicLiteral{
540 kind: .number
541 value: '3'
542 })
543 elem_type: ast.Expr(ast.Ident{
544 name: 'int'
545 })
546 }))
547 })
548 dynamic_array := ast.Expr(ast.ArrayInitExpr{
549 typ: ast.Expr(ast.Type(ast.ArrayType{
550 elem_type: ast.Expr(ast.Ident{
551 name: 'int'
552 })
553 }))
554 })
555 fixed_literal_array := ast.Expr(ast.ArrayInitExpr{
556 exprs: [
557 ast.Expr(ast.BasicLiteral{
558 kind: .number
559 value: '1'
560 }),
561 ast.Expr(ast.BasicLiteral{
562 kind: .number
563 value: '2'
564 }),
565 ast.Expr(ast.BasicLiteral{
566 kind: .number
567 value: '3'
568 }),
569 ]
570 len: ast.Expr(ast.PostfixExpr{
571 op: .not
572 expr: ast.empty_expr
573 })
574 })
575 assert freestanding_restricted_call_in_expr(fixed_array, ctx) == ''
576 assert freestanding_restricted_call_in_expr(fixed_literal_array, ctx) == ''
577 assert freestanding_restricted_call_in_expr(dynamic_array, ctx) == ''
578}
579
580fn test_collect_cflags_from_sources_uses_or_and_not_precedence() {
581 source := 'module main
582
583$if !windows && linux {
584#flag -DNEGATED_AND_LINUX
585}
586
587$if linux || windows && macos {
588#flag -DOR_AND_LINUX
589}
590'
591 mut linux_prefs := pref.new_preferences()
592 linux_prefs.target_os = 'linux'
593 linux_flags := collect_cflags_for_test_source(source, mut linux_prefs)
594 assert linux_flags.contains('-DNEGATED_AND_LINUX')
595 assert linux_flags.contains('-DOR_AND_LINUX')
596
597 mut macos_prefs := pref.new_preferences()
598 macos_prefs.target_os = 'macos'
599 macos_flags := collect_cflags_for_test_source(source, mut macos_prefs)
600 assert !macos_flags.contains('-DNEGATED_AND_LINUX')
601 assert !macos_flags.contains('-DOR_AND_LINUX')
602
603 mut windows_prefs := pref.new_preferences()
604 windows_prefs.target_os = 'windows'
605 windows_flags := collect_cflags_for_test_source(source, mut windows_prefs)
606 assert !windows_flags.contains('-DNEGATED_AND_LINUX')
607 assert !windows_flags.contains('-DOR_AND_LINUX')
608}
609