vxx2 / vlib / v3 / tests / struct_default_transform_test.v
88 lines · 80 sloc · 2.26 KB · 6c4d26f1f98c5464b012a375667ab345e462f7e0
Raw
1import os
2import v3.flat
3import v3.parser
4import v3.pref
5import v3.transform
6import v3.types
7
8// parse_and_transform reads parse and transform input for v3 tests.
9fn parse_and_transform(source string) &flat.FlatAst {
10 src := os.join_path(os.temp_dir(), 'v3_struct_default_transform_test.v')
11 os.write_file(src, source) or { panic(err) }
12 prefs := pref.new_preferences()
13 mut p := parser.Parser.new(prefs)
14 mut a := p.parse_file(src)
15 mut tc := types.TypeChecker.new(a)
16 tc.collect(a)
17 tc.annotate_types()
18 transform.transform(mut a, &tc)
19 return a
20}
21
22// transformed_struct_init supports transformed struct init handling for v3 tests.
23fn transformed_struct_init(a &flat.FlatAst, fn_name string) flat.Node {
24 for node in a.nodes {
25 if node.kind != .fn_decl || node.value != fn_name {
26 continue
27 }
28 for i in 0 .. node.children_count {
29 stmt := a.child_node(&node, i)
30 if stmt.kind != .decl_assign || stmt.children_count < 2 {
31 continue
32 }
33 rhs := a.child_node(stmt, 1)
34 if rhs.kind == .struct_init {
35 return *rhs
36 }
37 }
38 }
39 assert false
40 return flat.Node{}
41}
42
43// find_field resolves find field information for v3 tests.
44fn find_field(a &flat.FlatAst, node flat.Node, name string) flat.Node {
45 for i in 0 .. node.children_count {
46 field := a.child_node(&node, i)
47 if field.kind == .field_init && field.value == name {
48 return *field
49 }
50 }
51 assert false
52 return flat.Node{}
53}
54
55// call_name updates call name state for v3 tests.
56fn call_name(a &flat.FlatAst, call flat.Node) string {
57 if call.kind != .call || call.children_count == 0 {
58 return ''
59 }
60 return a.child_node(&call, 0).value
61}
62
63// test_transform_fills_missing_struct_defaults validates this v3 regression case.
64fn test_transform_fills_missing_struct_defaults() {
65 mut a := parse_and_transform("
66struct Person {
67 name string = 'v' + '3'
68 age int = 42
69}
70
71fn main() {
72 person := Person{age: 7}
73}
74")
75 init := transformed_struct_init(a, 'main')
76 assert init.value == 'Person'
77 assert init.children_count == 2
78
79 name_field := find_field(a, init, 'name')
80 name_value := a.child_node(&name_field, 0)
81 assert name_value.kind == .string_literal
82 assert name_value.value == 'v3'
83
84 age_field := find_field(a, init, 'age')
85 age_value := a.child_node(&age_field, 0)
86 assert age_value.kind == .int_literal
87 assert age_value.value == '7'
88}
89