| 1 | import v.ast |
| 2 | import v.pref |
| 3 | import v.parser |
| 4 | |
| 5 | fn test_update_sym_by_idx() { |
| 6 | old_size := 47 |
| 7 | new_size := 100 |
| 8 | b_old_size := 4 * old_size |
| 9 | b_new_size := 4 * new_size |
| 10 | source := 'type T001 = [${old_size}]u32' // u32 is an element type, with a known size, that is not going to change in the future, unlike int |
| 11 | // we will update the `size` & `size_expr` in sym.info for `T001` |
| 12 | mut t := ast.new_table() |
| 13 | parser.parse_text(source, '', mut t, .parse_comments, pref.new_preferences()) |
| 14 | |
| 15 | // retrieve old sym first: |
| 16 | typ := t.type_idxs['[${old_size}]u32']! |
| 17 | old_str := t.type_to_str(typ) |
| 18 | assert old_str == '[${old_size}]u32' |
| 19 | old_sym := t.sym(typ) |
| 20 | old_info := old_sym.info as ast.ArrayFixed |
| 21 | |
| 22 | alias_typ := t.type_idxs['main.T001']! |
| 23 | alias_str := t.type_to_str(alias_typ) |
| 24 | assert alias_str == 'main.T001' |
| 25 | // make sure that the alias type had the correct size before the change (the size is stored in the alias type symbol) |
| 26 | alias_size, _ := t.type_size(alias_typ) |
| 27 | assert alias_size == b_old_size |
| 28 | alias_sym := t.sym(alias_typ) |
| 29 | assert (alias_sym.info as ast.Alias).parent_type == typ |
| 30 | assert alias_sym.size == b_old_size |
| 31 | |
| 32 | // update the existing sym |
| 33 | new_info := ast.ArrayFixed{ |
| 34 | ...old_info |
| 35 | size: new_size |
| 36 | size_expr: ast.empty_expr |
| 37 | } |
| 38 | new_sym := ast.TypeSymbol{ |
| 39 | ...old_sym |
| 40 | info: new_info |
| 41 | } |
| 42 | t.update_sym_by_idx(typ, new_sym) |
| 43 | new_str := t.type_to_str(typ) |
| 44 | assert new_str == '[${new_size}]u32' |
| 45 | |
| 46 | // check again the alias size (it should be indirectly changed as well): |
| 47 | new_alias_sym := t.sym(alias_typ) |
| 48 | assert new_alias_sym.size == -1 |
| 49 | new_alias_size, _ := t.type_size(alias_typ) |
| 50 | assert new_alias_size == b_new_size |
| 51 | assert new_alias_sym.size == b_new_size // make sure that `new_alias_sym` is now updated too (since it is a pointer to a symbol value stored in the table) |
| 52 | } |
| 53 | |
| 54 | fn test_scoped_cname_prefers_escaped_cname_for_generic_scoped_names() { |
| 55 | sym := ast.TypeSymbol{ |
| 56 | cname: 'x__json2__Node_T_x__json2__ValueInfo' |
| 57 | info: ast.Struct{ |
| 58 | scoped_name: 'x.json2.Node[x.json2.ValueInfo]' |
| 59 | } |
| 60 | } |
| 61 | assert sym.scoped_cname() == 'x__json2__Node_T_x__json2__ValueInfo' |
| 62 | } |
| 63 | |
| 64 | fn test_fully_unaliased_type_preserves_nested_c_alias_pointers() { |
| 65 | source := 'type C.WCHAR = u16\ntype C.PWSTR = &C.WCHAR\ntype C.FILE_SHARE_MODE = u32' |
| 66 | mut t := ast.new_table() |
| 67 | parser.parse_text(source, '', mut t, .parse_comments, pref.new_preferences()) |
| 68 | |
| 69 | wchar_typ := t.type_idxs['C.WCHAR']! |
| 70 | pwide_typ := t.type_idxs['C.PWSTR']! |
| 71 | share_mode_typ := t.type_idxs['C.FILE_SHARE_MODE']! |
| 72 | |
| 73 | assert t.fully_unaliased_type(wchar_typ) == ast.u16_type |
| 74 | assert t.fully_unaliased_type(pwide_typ) == ast.u16_type.ref() |
| 75 | assert t.fully_unaliased_type(share_mode_typ) == ast.u32_type |
| 76 | } |
| 77 | |
| 78 | fn test_known_type_names_skips_partial_array_symbols() { |
| 79 | mut t := ast.new_table() |
| 80 | broken_array_idx := t.register_sym(ast.TypeSymbol{ |
| 81 | kind: .array |
| 82 | name: '[]Broken' |
| 83 | cname: 'Array_Broken' |
| 84 | mod: 'main' |
| 85 | is_pub: true |
| 86 | language: .v |
| 87 | }) |
| 88 | broken_array_type := ast.idx_to_type(broken_array_idx) |
| 89 | |
| 90 | assert !t.known_type_idx(broken_array_type) |
| 91 | assert '[]Broken' !in t.known_type_names() |
| 92 | } |
| 93 | |