| 1 | // Copyright (c) 2026 Alexander Medvednikov. All rights reserved. |
| 2 | // Use of this source code is governed by an MIT license |
| 3 | // that can be found in the LICENSE file. |
| 4 | // vtest build: macos |
| 5 | // |
| 6 | // Bit-equality pin for s168: `build_all_from_flat` (a thin rehydrate-then-call |
| 7 | // wrapper) must produce the same `Module` state as `build_all`. The wrapper |
| 8 | // rehydrates `flat` into `[]ast.File` via `flat.to_files_range(0, |
| 9 | // flat.files.len)` and delegates to the legacy walker. Behaviour is identical |
| 10 | // by construction provided flatten+rehydrate preserves the bits build_all |
| 11 | // reads (file.mod, file.stmts shape). |
| 12 | module ssa |
| 13 | |
| 14 | import v2.ast |
| 15 | import v2.types |
| 16 | |
| 17 | fn make_build_all_test_files() []ast.File { |
| 18 | return [ |
| 19 | ast.File{ |
| 20 | name: 'main.v' |
| 21 | mod: 'main' |
| 22 | stmts: [ |
| 23 | ast.Stmt(ast.ModuleStmt{ |
| 24 | name: 'main' |
| 25 | }), |
| 26 | ] |
| 27 | }, |
| 28 | ] |
| 29 | } |
| 30 | |
| 31 | // Empty flat — both paths must pre-register the same builtin globals and not |
| 32 | // crash on the empty stmt set. |
| 33 | fn test_build_all_from_flat_empty_flat_matches_legacy() { |
| 34 | flat := ast.FlatAst{} |
| 35 | |
| 36 | env := types.Environment.new() |
| 37 | mut mod_legacy := Module.new('build_all_empty_legacy') |
| 38 | mut b_legacy := Builder.new_with_env(mod_legacy, env) |
| 39 | b_legacy.build_all([]ast.File{}) |
| 40 | |
| 41 | mut mod_flat := Module.new('build_all_empty_flat') |
| 42 | mut b_flat := Builder.new_with_env(mod_flat, env) |
| 43 | b_flat.build_all_from_flat(&flat) |
| 44 | |
| 45 | // Both modules should have the same number of pre-registered builtin |
| 46 | // globals (g_main_argc, g_main_argv, __stdoutp, __stdinp, __stderrp). |
| 47 | assert mod_legacy.globals.len == mod_flat.globals.len |
| 48 | for i in 0 .. mod_legacy.globals.len { |
| 49 | assert mod_legacy.globals[i].name == mod_flat.globals[i].name |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | // Single ModuleStmt file — flatten+rehydrate must preserve the stmt shape so |
| 54 | // that build_all sees the same input both times. |
| 55 | fn test_build_all_from_flat_matches_legacy_for_simple_files() { |
| 56 | files := make_build_all_test_files() |
| 57 | flat := ast.flatten_files(files) |
| 58 | |
| 59 | env := types.Environment.new() |
| 60 | mut mod_legacy := Module.new('build_all_simple_legacy') |
| 61 | mut b_legacy := Builder.new_with_env(mod_legacy, env) |
| 62 | b_legacy.build_all(files) |
| 63 | |
| 64 | mut mod_flat := Module.new('build_all_simple_flat') |
| 65 | mut b_flat := Builder.new_with_env(mod_flat, env) |
| 66 | b_flat.build_all_from_flat(&flat) |
| 67 | |
| 68 | // Globals, values, funcs all materialised the same way on both paths. |
| 69 | assert mod_legacy.globals.len == mod_flat.globals.len |
| 70 | assert mod_legacy.values.len == mod_flat.values.len |
| 71 | assert mod_legacy.funcs.len == mod_flat.funcs.len |
| 72 | // Builder state mirrors module state. |
| 73 | assert b_legacy.cur_module == b_flat.cur_module |
| 74 | } |
| 75 | |