v / vlib / v2 / builder / flat_streaming_test.v
157 lines · 133 sloc · 4.29 KB · 3dd96de45339a469cb83ffacc0e50b017468e032
Raw
1// Copyright (c) 2020-2024 Joe Conigliaro. 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
5module builder
6
7import os
8import v2.ast
9import v2.parser
10import v2.pref
11import v2.token
12
13// Phase 2 regression: Parser.parse_files_to_flat must produce a FlatAst whose
14// canonical signature is identical to ast.flatten_files(Parser.parse_files()).
15// This guards the streaming path while downstream consumers are migrated.
16
17fn write_tmp_file(name string, src string) string {
18 path := '/tmp/v2_flat_stream_${os.getpid()}_${name}.v'
19 os.write_file(path, src) or { panic('write_file: ${err}') }
20 return path
21}
22
23fn assert_streaming_matches(srcs map[string]string) {
24 mut paths := []string{cap: srcs.len}
25 for name, src in srcs {
26 paths << write_tmp_file(name, src)
27 }
28 defer {
29 for p in paths {
30 os.rm(p) or {}
31 }
32 }
33
34 prefs := &pref.Preferences{}
35
36 mut fs_batch := token.FileSet.new()
37 mut p_batch := parser.Parser.new(prefs)
38 legacy_files := p_batch.parse_files(paths, mut fs_batch)
39 flat_batch := ast.flatten_files(legacy_files)
40
41 mut fs_stream := token.FileSet.new()
42 mut p_stream := parser.Parser.new(prefs)
43 flat_stream := p_stream.parse_files_to_flat(paths, mut fs_stream)
44
45 sig_batch := flat_batch.signature()
46 sig_stream := flat_stream.signature()
47 if sig_batch != sig_stream {
48 mut diff_at := 0
49 for diff_at < sig_batch.len && diff_at < sig_stream.len
50 && sig_batch[diff_at] == sig_stream[diff_at] {
51 diff_at++
52 }
53 from := if diff_at > 80 { diff_at - 80 } else { 0 }
54 end_b := if diff_at + 200 < sig_batch.len { diff_at + 200 } else { sig_batch.len }
55 end_s := if diff_at + 200 < sig_stream.len { diff_at + 200 } else { sig_stream.len }
56 eprintln('signature mismatch at offset ${diff_at}')
57 eprintln('batch: ${sig_batch[from..end_b]}')
58 eprintln('stream: ${sig_stream[from..end_s]}')
59 }
60 assert sig_batch == sig_stream, 'streaming flat AST diverges from batch flatten'
61}
62
63fn test_streaming_single_file() {
64 assert_streaming_matches({
65 'single': 'module main
66
67fn add(a int, b int) int {
68 return a + b
69}
70'
71 })
72}
73
74fn test_streaming_multi_file_order() {
75 // Two files should produce node ids in parse order regardless of whether
76 // the conversion is batched or streamed. Strings interned by file 0 must
77 // be reused by file 1 in both cases.
78 a := 'module main
79
80pub const greeting = "hello"
81
82fn say() string {
83 return greeting
84}
85'
86 b := 'module main
87
88pub struct Point { x int y int }
89
90fn (p Point) sum() int { return p.x + p.y }
91'
92 assert_streaming_matches({
93 'a': a
94 'b': b
95 })
96}
97
98fn test_streaming_real_source_file() {
99 path := os.real_path('vlib/v2/ast/ast.v')
100 if !os.exists(path) {
101 return
102 }
103 prefs := &pref.Preferences{}
104
105 mut fs_batch := token.FileSet.new()
106 mut p_batch := parser.Parser.new(prefs)
107 legacy := p_batch.parse_files([path], mut fs_batch)
108 flat_batch := ast.flatten_files(legacy)
109
110 mut fs_stream := token.FileSet.new()
111 mut p_stream := parser.Parser.new(prefs)
112 flat_stream := p_stream.parse_files_to_flat([path], mut fs_stream)
113
114 assert flat_batch.signature() == flat_stream.signature(), 'real-source streaming mismatch'
115}
116
117fn test_default_flat_parallel_transform_keeps_user_files() {
118 path := write_tmp_file('parallel_transform_main', 'module main
119
120fn main() {
121 println("flat parallel ok")
122}
123')
124 out_path := '/tmp/v2_flat_parallel_transform_${os.getpid()}.out'
125 defer {
126 os.rm(path) or {}
127 os.rm(out_path) or {}
128 }
129 cmd := '${os.quoted_path(@VEXE)} -v2 -nocache -o ${os.quoted_path(out_path)} ${os.quoted_path(path)} 2>&1'
130 res := os.execute(cmd)
131 assert res.exit_code == 0, res.output
132 run_res := os.execute(os.quoted_path(out_path))
133 assert run_res.exit_code == 0, run_res.output
134 assert run_res.output.trim_space() == 'flat parallel ok', run_res.output
135}
136
137fn test_default_parallel_transform_monomorphizes_generic_calls_for_native_backend() {
138 path := write_tmp_file('parallel_transform_generic_main', 'module main
139
140fn id[T](x T) T {
141 return x
142}
143
144fn main() {
145 _ = id(41)
146}
147')
148 out_path := '/tmp/v2_parallel_generic_transform_${os.getpid()}.out'
149 defer {
150 os.rm(path) or {}
151 os.rm(out_path) or {}
152 }
153 cmd := '${os.quoted_path(@VEXE)} -v2 -nocache -backend arm64 -gc none -o ${os.quoted_path(out_path)} ${os.quoted_path(path)} 2>&1'
154 res := os.execute(cmd)
155 assert !res.output.contains('_id_T_int'), res.output
156 assert res.exit_code == 0, res.output
157}
158