v / vlib / v2 / gen / cleanc / module_storage_codegen_test.v
275 lines · 230 sloc · 6.06 KB · f3c5760b8838272e4789c38a1be9e03f9ceac351
Raw
1module cleanc
2
3import os
4import v2.parser
5import v2.pref as vpref
6import v2.token
7import v2.transformer
8import v2.types
9
10fn module_storage_csrc_for_test_sources(sources map[string]string) string {
11 tmp_dir := os.join_path(os.temp_dir(), 'v2_module_storage_codegen_${os.getpid()}')
12 os.rmdir_all(tmp_dir) or {}
13 os.mkdir_all(tmp_dir) or { panic('failed to create temp dir') }
14 defer {
15 os.rmdir_all(tmp_dir) or {}
16 }
17 mut paths := []string{}
18 for rel_path, code in sources {
19 tmp_file := os.join_path(tmp_dir, rel_path)
20 os.mkdir_all(os.dir(tmp_file)) or { panic('failed to create temp source dir') }
21 os.write_file(tmp_file, code) or { panic('failed to write temp source') }
22 paths << tmp_file
23 }
24 prefs := &vpref.Preferences{
25 backend: .cleanc
26 no_parallel: true
27 }
28 mut file_set := token.FileSet.new()
29 mut par := parser.Parser.new(prefs)
30 files := par.parse_files(paths, mut file_set)
31 env := types.Environment.new()
32 mut checker := types.Checker.new(prefs, file_set, env)
33 checker.check_files(files)
34 mut trans := transformer.Transformer.new_with_pref(env, prefs)
35 trans.set_file_set(file_set)
36 transformed_files := trans.transform_files(files)
37 mut gen := Gen.new_with_env_and_pref(transformed_files, env, prefs)
38 return gen.gen()
39}
40
41fn test_generate_c_uses_module_prefix_for_qualified_module_storage() {
42 csrc := module_storage_csrc_for_test_sources({
43 'report/report.v': 'module report
44
45pub __global mut errors = 0
46'
47 'main.v': 'module main
48
49import report
50
51fn main() {
52 report.errors += 1
53}
54'
55 })
56 assert csrc.contains('int report__errors'), csrc
57 assert csrc.contains('report__errors'), csrc
58 assert !csrc.contains('\nint errors'), csrc
59}
60
61fn test_generate_c_resolves_module_storage_import_alias() {
62 csrc := module_storage_csrc_for_test_sources({
63 'report/report.v': 'module report
64
65pub __global mut errors = 0
66'
67 'main.v': 'module main
68
69import report as r
70
71fn main() {
72 r.errors += 1
73}
74'
75 })
76 assert csrc.contains('report__errors'), csrc
77 assert !csrc.contains('r__errors'), csrc
78}
79
80fn test_generate_c_keeps_same_short_module_storage_names_distinct() {
81 csrc := module_storage_csrc_for_test_sources({
82 'a/a.v': 'module a
83
84pub __global state = 1
85'
86 'b/b.v': 'module b
87
88pub __global state = 2
89'
90 'main.v': 'module main
91
92import a
93import b
94
95fn main() {
96 _ = a.state + b.state
97}
98'
99 })
100 assert csrc.contains('int a__state = 1;'), csrc
101 assert csrc.contains('int b__state = 2;'), csrc
102 assert !csrc.contains('\nint state ='), csrc
103}
104
105fn test_generate_c_prefixes_module_storage_names_containing_dunders() {
106 csrc := module_storage_csrc_for_test_sources({
107 'a/a.v': 'module a
108
109pub __global mut state__x = 1
110
111pub fn bump() int {
112 state__x += 1
113 return state__x
114}
115 '
116 'b/b.v': 'module b
117
118pub __global mut state__x = 2
119
120pub fn bump() int {
121 state__x += 1
122 return state__x
123}
124 '
125 'main.v': 'module main
126
127import a
128import b
129
130fn main() {
131 _ = a.bump() + b.bump()
132 _ = a.state__x + b.state__x
133}
134'
135 })
136 assert csrc.contains('int a__state__x = 1;'), csrc
137 assert csrc.contains('int b__state__x = 2;'), csrc
138 assert csrc.contains('a__state__x += 1;'), csrc
139 assert csrc.contains('return a__state__x;'), csrc
140 assert csrc.contains('b__state__x += 1;'), csrc
141 assert csrc.contains('return b__state__x;'), csrc
142 assert !csrc.contains('\nint state__x ='), csrc
143 assert !csrc.contains('\n\tstate__x += 1;'), csrc
144 assert !csrc.contains('\n\treturn state__x;'), csrc
145}
146
147fn test_generate_c_keeps_c_global_declaration_unmangled() {
148 csrc := module_storage_csrc_for_test_sources({
149 'main.v': 'module main
150
151@[c_extern]
152__global C.errno int
153
154@[c_extern]
155__global C.stdin voidptr
156
157@[c_extern]
158__global C.stdout voidptr
159
160@[c_extern]
161__global C.stderr voidptr
162
163fn main() {
164 _ = C.errno
165 _ = C.stdin
166 _ = C.stdout
167 _ = C.stderr
168}
169'
170 })
171 assert !csrc.contains('main__C.errno'), csrc
172 assert !csrc.contains('main__errno'), csrc
173 assert !csrc.contains('main__stdin'), csrc
174 assert !csrc.contains('main__stdout'), csrc
175 assert !csrc.contains('main__stderr'), csrc
176 assert csrc.contains('errno'), csrc
177 assert csrc.contains('stdin'), csrc
178 assert csrc.contains('stdout'), csrc
179 assert csrc.contains('stderr'), csrc
180}
181
182fn test_generate_c_keeps_c_extern_global_attributes_unmangled() {
183 csrc := module_storage_csrc_for_test_sources({
184 'main.v': 'module main
185
186@[c_extern; export: "raw_counter"; weak; hidden; markused]
187__global raw_counter int
188
189fn main() {
190 _ = raw_counter
191}
192'
193 })
194 assert csrc.contains('extern int raw_counter;'), csrc
195 assert csrc.contains('raw_counter'), csrc
196 assert !csrc.contains('main__raw_counter'), csrc
197}
198
199fn test_generate_c_keeps_translated_c_v_extern_global_unmangled() {
200 csrc := module_storage_csrc_for_test_sources({
201 'cwrap/runtime.c.v': '@[translated]
202module cwrap
203
204@[c_extern; hidden; markused]
205__global raw_status int
206
207pub fn read_status() int {
208 return raw_status
209}
210'
211 'main.v': 'module main
212
213import cwrap
214
215fn main() {
216 _ = cwrap.read_status()
217 _ = cwrap.raw_status
218}
219'
220 })
221 assert csrc.contains('extern int raw_status;'), csrc
222 assert csrc.contains('return raw_status;'), csrc
223 assert csrc.count('raw_status') >= 3, csrc
224 assert !csrc.contains('cwrap__raw_status'), csrc
225}
226
227fn test_generate_c_keeps_qualified_c_extern_global_alias_unmangled() {
228 csrc := module_storage_csrc_for_test_sources({
229 'cwrap/runtime.c.v': '@[translated]
230module cwrap
231
232@[c_extern; hidden; markused]
233__global raw_status int
234'
235 'main.v': 'module main
236
237import cwrap as cw
238
239fn main() {
240 _ = cw.raw_status
241}
242'
243 })
244 assert csrc.contains('extern int raw_status;'), csrc
245 assert csrc.count('raw_status') >= 2, csrc
246 assert !csrc.contains('cwrap__raw_status'), csrc
247 assert !csrc.contains('cw__raw_status'), csrc
248}
249
250fn test_generate_c_keeps_plain_module_c_extern_global_unmangled() {
251 csrc := module_storage_csrc_for_test_sources({
252 'ext/ext.v': 'module ext
253
254@[c_extern]
255pub __global raw_status int
256
257pub fn read_status() int {
258 return raw_status
259}
260'
261 'main.v': 'module main
262
263import ext
264
265fn main() {
266 _ = ext.raw_status
267 _ = ext.read_status()
268}
269'
270 })
271 assert csrc.contains('extern int raw_status;'), csrc
272 assert csrc.contains('return raw_status;'), csrc
273 assert csrc.contains('(void)(raw_status);'), csrc
274 assert !csrc.contains('ext__raw_status'), csrc
275}
276