ast: improve Expr.str() for `sizeof(Type)` and `__offsetof(StructName, fieldname)`, for more informative asserts/dumps
							parent
							
								
									3b6045865b
								
							
						
					
					
						commit
						e70bde54dc
					
				| 
						 | 
					@ -248,7 +248,7 @@ pub fn (x Expr) str() string {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		AsCast {
 | 
							AsCast {
 | 
				
			||||||
			return '$x.expr.str() as Type($x.typ)'
 | 
								return '$x.expr.str() as ${global_table.type_to_str(x.typ)}'
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		AtExpr {
 | 
							AtExpr {
 | 
				
			||||||
			return '$x.val'
 | 
								return '$x.val'
 | 
				
			||||||
| 
						 | 
					@ -299,6 +299,9 @@ pub fn (x Expr) str() string {
 | 
				
			||||||
		FloatLiteral, IntegerLiteral {
 | 
							FloatLiteral, IntegerLiteral {
 | 
				
			||||||
			return x.val
 | 
								return x.val
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							GoExpr {
 | 
				
			||||||
 | 
								return 'go $x.call_expr'
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		Ident {
 | 
							Ident {
 | 
				
			||||||
			return x.name
 | 
								return x.name
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -354,12 +357,12 @@ pub fn (x Expr) str() string {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		SizeOf {
 | 
							SizeOf {
 | 
				
			||||||
			if x.is_type {
 | 
								if x.is_type {
 | 
				
			||||||
				return 'sizeof(Type($x.typ))'
 | 
									return 'sizeof(${global_table.type_to_str(x.typ)})'
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return 'sizeof($x.expr)'
 | 
								return 'sizeof($x.expr)'
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		OffsetOf {
 | 
							OffsetOf {
 | 
				
			||||||
			return '__offsetof($x.struct_type, $x.field)'
 | 
								return '__offsetof(${global_table.type_to_str(x.struct_type)}, $x.field)'
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		StringInterLiteral {
 | 
							StringInterLiteral {
 | 
				
			||||||
			mut res := strings.new_builder(50)
 | 
								mut res := strings.new_builder(50)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,9 +159,19 @@ pub fn new_table() &Table {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	t.register_builtin_type_symbols()
 | 
						t.register_builtin_type_symbols()
 | 
				
			||||||
	t.is_fmt = true
 | 
						t.is_fmt = true
 | 
				
			||||||
 | 
						set_global_table(t)
 | 
				
			||||||
	return t
 | 
						return t
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const global_table = &Table(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn set_global_table(t &Table) {
 | 
				
			||||||
 | 
						unsafe {
 | 
				
			||||||
 | 
							mut pg := &ast.global_table
 | 
				
			||||||
 | 
							*pg = t
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// used to compare fn's & for naming anon fn's
 | 
					// used to compare fn's & for naming anon fn's
 | 
				
			||||||
pub fn (t &Table) fn_type_signature(f &Fn) string {
 | 
					pub fn (t &Table) fn_type_signature(f &Fn) string {
 | 
				
			||||||
	mut sig := ''
 | 
						mut sig := ''
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,18 @@ fn testsuite_begin() {
 | 
				
			||||||
fn test_returning_options() {
 | 
					fn test_returning_options() {
 | 
				
			||||||
	res := vexecute('vlib/v/tests/testdata/tests_returning_options_failing_test.v')
 | 
						res := vexecute('vlib/v/tests/testdata/tests_returning_options_failing_test.v')
 | 
				
			||||||
	assert res.exit_code == 1
 | 
						assert res.exit_code == 1
 | 
				
			||||||
	dump(res)
 | 
						// dump(res)
 | 
				
			||||||
	assert res.output.contains('tests_returning_options_failing_test.v:13: fn test_example failed propagation with error: failing test with return, err: oh no')
 | 
						assert res.output.contains('tests_returning_options_failing_test.v:13: fn test_example failed propagation with error: failing test with return, err: oh no')
 | 
				
			||||||
	assert res.output.contains('tests_returning_options_failing_test.v:19: fn test_example_2 failed propagation with error: oh no')
 | 
						assert res.output.contains('tests_returning_options_failing_test.v:19: fn test_example_2 failed propagation with error: oh no')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_sizeof_in_assert() {
 | 
				
			||||||
 | 
						res := vexecute('vlib/v/tests/testdata/sizeof_used_in_assert_test.v')
 | 
				
			||||||
 | 
						assert res.exit_code == 1
 | 
				
			||||||
 | 
						// dump(res)
 | 
				
			||||||
 | 
						assert res.output.contains('sizeof_used_in_assert_test.v:11: fn test_assert_offsetof')
 | 
				
			||||||
 | 
						assert res.output.contains('assert __offsetof(main.Abc, y) == 1')
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						assert res.output.contains('sizeof_used_in_assert_test.v:15: fn test_assert_sizeof')
 | 
				
			||||||
 | 
						assert res.output.contains('assert sizeof(main.Abc) == sizeof(main.Xyz)')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					struct Abc {
 | 
				
			||||||
 | 
						x [20]int
 | 
				
			||||||
 | 
						y [30]int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Xyz {
 | 
				
			||||||
 | 
						x int = 5
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_assert_offsetof() {
 | 
				
			||||||
 | 
						assert __offsetof(Abc, y) == 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_assert_sizeof() {
 | 
				
			||||||
 | 
						assert sizeof(Abc) == sizeof(Xyz)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue