v / vlib / v2 / ssa / build_module_from_flat_test.v
114 lines · 103 sloc · 3.34 KB · ddb021b9866c3b4523b746fa2f4c16a594f8bd89
Raw
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 s180: `build_module_from_flat` (fifth per-kind port
7// inside the s175 seam) must set `b.cur_module` to the same dotted-to-
8// underscore form as the legacy `ast.ModuleStmt` arm in `build_stmt`. The
9// flat path drops the ModuleStmt struct decode entirely and reads the
10// module name straight from `c.name()`.
11module ssa
12
13import v2.ast
14import v2.types
15
16// Fixture: a file with `module foo.bar` (dotted name to exercise the
17// `.replace('.', '_')`). No fns — we test the seam by directly driving
18// `build_stmt`/`build_stmt_from_flat` on the file's top-level stmts list.
19fn make_module_fixture() []ast.File {
20 return [
21 ast.File{
22 name: 'main.v'
23 mod: 'foo.bar'
24 stmts: [
25 ast.Stmt(ast.ModuleStmt{
26 name: 'foo.bar'
27 }),
28 ]
29 },
30 ]
31}
32
33fn test_build_module_from_flat_matches_legacy() {
34 files := make_module_fixture()
35 flat := ast.flatten_files(files)
36 env := types.Environment.new()
37
38 mut mod_legacy := Module.new('mod_legacy')
39 mut b_legacy := Builder.new_with_env(mod_legacy, env)
40 b_legacy.build_stmts(files[0].stmts)
41
42 mut mod_flat := Module.new('mod_flat')
43 mut b_flat := Builder.new_with_env(mod_flat, env)
44 b_flat.build_stmts_from_flat(flat.file_cursor(0).stmts())
45
46 // Both paths must transform 'foo.bar' → 'foo_bar' on b.cur_module.
47 assert b_legacy.cur_module == 'foo_bar'
48 assert b_flat.cur_module == b_legacy.cur_module
49 // And neither path emits any SSA for a ModuleStmt.
50 assert mod_legacy.instrs.len == mod_flat.instrs.len
51 assert mod_legacy.blocks.len == mod_flat.blocks.len
52 assert mod_legacy.values.len == mod_flat.values.len
53}
54
55fn test_module_import_aliases_keep_nested_module_path() {
56 aliases := module_import_aliases_from_imports([
57 ast.ImportStmt{
58 name: 'foo.bar'
59 alias: 'bar'
60 },
61 ast.ImportStmt{
62 name: 'foo.baz'
63 alias: 'qux'
64 is_aliased: true
65 },
66 ])
67 assert aliases['bar'] == 'foo.bar'
68 assert aliases['qux'] == 'foo.baz'
69}
70
71fn test_selective_import_fn_names_keep_nested_module_path() {
72 names := selective_import_fn_names_from_imports([
73 ast.ImportStmt{
74 name: 'foo.bar'
75 alias: 'bar'
76 symbols: [
77 ast.Expr(ast.Ident{
78 name: 'leaf'
79 }),
80 ]
81 },
82 ])
83 assert names['leaf'] == 'foo_bar__leaf'
84}
85
86fn test_selective_import_fn_candidates_try_nested_path_then_leaf_module() {
87 candidates := selective_import_fn_candidates_from_imports([
88 ast.ImportStmt{
89 name: 'foo.bar'
90 alias: 'bar'
91 symbols: [
92 ast.Expr(ast.Ident{
93 name: 'leaf'
94 }),
95 ]
96 },
97 ])
98 assert candidates['leaf'] == ['foo_bar__leaf', 'bar__leaf']
99
100 mut mod_full := Module.new('selective_full')
101 mut b_full := Builder.new_with_env(mod_full, types.Environment.new())
102 b_full.selective_import_fn_candidates = candidates.clone()
103 b_full.fn_index['foo_bar__leaf'] = 0
104 b_full.fn_index['bar__leaf'] = 1
105 resolved_full := b_full.selective_import_fn_name('leaf') or { '' }
106 assert resolved_full == 'foo_bar__leaf'
107
108 mut mod_leaf := Module.new('selective_leaf')
109 mut b_leaf := Builder.new_with_env(mod_leaf, types.Environment.new())
110 b_leaf.selective_import_fn_candidates = candidates.clone()
111 b_leaf.fn_index['bar__leaf'] = 1
112 resolved_leaf := b_leaf.selective_import_fn_name('leaf') or { '' }
113 assert resolved_leaf == 'bar__leaf'
114}
115