parser: warn about old use of `typeof` (#7923)

pull/7952/head
Nick Treleaven 2021-01-07 19:32:02 +00:00 committed by GitHub
parent a2add15558
commit cbefe6c32f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 93 additions and 92 deletions

View File

@ -9,14 +9,14 @@ fn test_clone() {
xx := byte(35)
assert xx.str() == '35'
assert xx.ascii_str() == '#'
println(typeof(`A`))
assert typeof(`A`) == 'rune'
println(typeof(`A`).name)
assert typeof(`A`).name == 'rune'
x := rune(`A`)
assert x.str() == 'A'
assert typeof(x) == 'rune'
assert typeof(x).name == 'rune'
//
y := `Z`
assert typeof(y) == 'rune'
assert typeof(y).name == 'rune'
assert y.str() == 'Z'
// assert b[1].str() == '1' TODO
}

View File

@ -5,34 +5,34 @@ fn test_float_decl() {
x2 := -2e16
x3 := 1e-15
x4 := -9e-4
assert typeof(x1) == 'f64'
assert typeof(x2) == 'f64'
assert typeof(x3) == 'f64'
assert typeof(x4) == 'f64'
assert typeof(x1).name == 'f64'
assert typeof(x2).name == 'f64'
assert typeof(x3).name == 'f64'
assert typeof(x4).name == 'f64'
x5 := 4e108
x6 := -7e99
x7 := 3e-205
x8 := -6e-147
assert typeof(x5) == 'f64'
assert typeof(x6) == 'f64'
assert typeof(x7) == 'f64'
assert typeof(x8) == 'f64'
assert typeof(x5).name == 'f64'
assert typeof(x6).name == 'f64'
assert typeof(x7).name == 'f64'
assert typeof(x8).name == 'f64'
x9 := 312874834.77
x10 := -22399994.06
x11 := 0.0000000019
x12 := -0.00000000008
assert typeof(x9) == 'f64'
assert typeof(x10) == 'f64'
assert typeof(x11) == 'f64'
assert typeof(x12) == 'f64'
assert typeof(x9).name == 'f64'
assert typeof(x10).name == 'f64'
assert typeof(x11).name == 'f64'
assert typeof(x12).name == 'f64'
x13 := 34234234809890890898903213154353453453253253243432413232228908902183918392183902432432438980380123021983901392183921389083913890389089031.0
x14 := -39999999999999999999222212128182813294989082302832183928343325325233253242312331324392839238239829389038097438248932789371837218372837293.8
x15 := 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002
x16 := -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
assert typeof(x13) == 'f64'
assert typeof(x14) == 'f64'
assert typeof(x15) == 'f64'
assert typeof(x16) == 'f64'
assert typeof(x13).name == 'f64'
assert typeof(x14).name == 'f64'
assert typeof(x15).name == 'f64'
assert typeof(x16).name == 'f64'
}
fn test_f32_equal_operator() {

View File

@ -177,13 +177,13 @@ fn test_int_decl() {
x3 := -88955
x4 := 2000000000
x5 := -1999999999
assert typeof(x1) == 'int'
assert typeof(x2) == 'int'
assert typeof(x3) == 'int'
assert typeof(x4) == 'int'
assert typeof(x5) == 'int'
assert typeof(x1).name == 'int'
assert typeof(x2).name == 'int'
assert typeof(x3).name == 'int'
assert typeof(x4).name == 'int'
assert typeof(x5).name == 'int'
x7 := u64(-321314588900011)
assert typeof(x7) == 'u64'
assert typeof(x7).name == 'u64'
}
fn test_int_to_hex() {

View File

@ -536,8 +536,8 @@ fn test_bytes_to_string() {
fn test_charptr() {
foo := charptr('VLANG'.str)
println(typeof(foo))
assert typeof(foo) == 'charptr'
println(typeof(foo).name)
assert typeof(foo).name == 'charptr'
assert unsafe { foo.vstring() } == 'VLANG'
assert unsafe { foo.vstring_with_len(3) } == 'VLA'
}

View File

@ -1217,11 +1217,11 @@ pub fn (stmt Stmt) check_c_expr() ? {
if stmt.expr.is_expr() {
return
}
return error('unsupported statement (`${typeof(stmt.expr)}`)')
return error('unsupported statement (`$stmt.expr.type_name()`)')
}
else {}
}
return error('unsupported statement (`${typeof(stmt)}`)')
return error('unsupported statement (`$stmt.type_name()`)')
}
// CTempVar is used in cgen only, to hold nodes for temporary variables

View File

@ -288,7 +288,7 @@ pub fn (x Expr) str() string {
}
else {}
}
return '[unhandled expr type ${typeof(x)}]'
return '[unhandled expr type $x.type_name()]'
}
pub fn (a CallArg) str() string {
@ -352,7 +352,7 @@ pub fn (node Stmt) str() string {
return 'struct $node.name { $node.fields.len fields }'
}
else {
return '[unhandled stmt str type: ${typeof(node)} ]'
return '[unhandled stmt str type: $node.type_name() ]'
}
}
}

View File

@ -1086,11 +1086,11 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
return '', pos
}
else {
c.error('unexpected expression `${typeof(expr)}`', expr.position())
c.error('unexpected expression `$expr.type_name()`', expr.position())
}
}
if explicit_lock_needed {
c.error('`$to_lock` is `shared` and needs explicit lock for `${typeof(expr)}`',
c.error('`$to_lock` is `shared` and needs explicit lock for `$expr.type_name()`',
pos)
to_lock = ''
}
@ -1547,7 +1547,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
} else if fn_name == 'json.decode' && call_expr.args.len > 0 {
expr := call_expr.args[0].expr
if expr !is ast.Type {
typ := typeof(expr)
typ := expr.type_name()
c.error('json.decode: first argument needs to be a type, got `$typ`', call_expr.pos)
return table.void_type
}
@ -4428,7 +4428,7 @@ fn (mut c Checker) comp_if_branch(cond ast.Expr, pos token.Position) bool {
!different
}
} else {
c.error('invalid `\$if` condition: ${typeof(cond.left)}', cond.pos)
c.error('invalid `\$if` condition: $cond.left.type_name()', cond.pos)
}
}
else {

View File

@ -3,5 +3,5 @@ vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv:12:12:
11 | // the next line should produce at least a warning, or even an error, without an explicit cast:
12 | z := isym == table.string_type
| ~~
13 | println(typeof(isym))
14 | println(typeof(table.string_type))
13 | println(typeof(isym).name)
14 | println(typeof(table.string_type).name)

View File

@ -10,8 +10,8 @@ fn main() {
x := ityp == table.string_type
// the next line should produce at least a warning, or even an error, without an explicit cast:
z := isym == table.string_type
println(typeof(isym))
println(typeof(table.string_type))
println(typeof(isym).name)
println(typeof(table.string_type).name)
println(x)
println(z)
}

View File

@ -255,7 +255,7 @@ pub fn (mut f Fmt) stmt_str(node ast.Stmt) string {
pub fn (mut f Fmt) stmt(node ast.Stmt) {
if f.is_debug {
eprintln('stmt: ${node.position():-42} | node: ${typeof(node):-20}')
eprintln('stmt: ${node.position():-42} | node: ${node.type_name():-20}')
}
match node {
ast.AssignStmt {
@ -854,7 +854,7 @@ pub fn (mut f Fmt) prefix_expr_cast_expr(fexpr ast.Expr) {
pub fn (mut f Fmt) expr(node ast.Expr) {
if f.is_debug {
eprintln('expr: ${node.position():-42} | node: ${typeof(node):-20} | $node.str()')
eprintln('expr: ${node.position():-42} | node: ${node.type_name():-20} | $node.str()')
}
match mut node {
ast.CTempVar {

View File

@ -823,7 +823,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) {
}
if stmt_pos.pos == 0 {
print('autofree: first stmt pos = 0. ')
println(typeof(stmt))
println(stmt.type_name())
return
}
}
@ -1550,7 +1550,7 @@ fn (mut g Gen) gen_assert_single_expr(e ast.Expr, t table.Type) {
g.gen_expr_to_string(e, t)
}
}
g.write(' /* typeof: ' + typeof(e) + ' type: ' + t.str() + ' */ ')
g.write(' /* typeof: ' + e.type_name() + ' type: ' + t.str() + ' */ ')
}
fn (mut g Gen) write_fn_ptr_decl(func &table.FnType, ptr_name string) {
@ -5049,14 +5049,6 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table.
g.write('}')
}
fn (mut g Gen) type_of_call_expr(node ast.Expr) string {
match node {
ast.CallExpr { return g.typ(node.return_type) }
else { return typeof(node) }
}
return ''
}
// `a in [1,2,3]` => `a == 1 || a == 2 || a == 3`
fn (mut g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) {
is_str := right.elem_type == table.string_type

View File

@ -622,7 +622,7 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
g.mov_var_to_reg(fn_arg_registers[i], var_offset)
}
else {
verror('unhandled call_fn (name=$name) node: ' + typeof(expr))
verror('unhandled call_fn (name=$name) node: ' + expr.type_name())
}
}
}
@ -671,7 +671,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
}
ast.StructDecl {}
else {
println('x64.stmt(): bad node: ' + typeof(node))
println('x64.stmt(): bad node: ' + node.type_name())
}
}
}
@ -704,7 +704,7 @@ fn (mut g Gen) expr(node ast.Expr) {
ast.StringLiteral {}
ast.StructInit {}
else {
println(term.red('x64.expr(): unhandled node: ' + typeof(node)))
println(term.red('x64.expr(): unhandled node: ' + node.type_name()))
}
}
}
@ -775,7 +775,8 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
}
}
else {
g.error_with_pos('x64 assign_stmt unhandled expr: ' + typeof(right), right.position())
g.error_with_pos('x64 assign_stmt unhandled expr: ' + right.type_name(),
right.position())
}
}
// }

View File

@ -187,6 +187,10 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
p.check(.lpar)
expr := p.expr(0)
p.check(.rpar)
if p.tok.kind != .dot && p.tok.line_nr == p.prev_tok.line_nr {
p.warn_with_pos('use e.g. `typeof(expr).name` or `sum_type_instance.type_name()` instead',
spos)
}
node = ast.TypeOf{
expr: expr
pos: spos.extend(p.tok.position())

View File

@ -1,27 +1,27 @@
fn test_fixed_array_lit_init() {
a1 := ['1', '2', '3']!!
assert typeof(a1) == '[3]string'
assert typeof(a1).name == '[3]string'
assert '$a1' == "['1', '2', '3']"
a2 := ['a', 'b']!!
assert typeof(a2) == '[2]string'
assert typeof(a2).name == '[2]string'
assert '$a2' == "['a', 'b']"
c1 := [1, 2, 3]!!
assert typeof(c1) == '[3]int'
assert typeof(c1).name == '[3]int'
assert '$c1' == '[1, 2, 3]'
c2 := [i16(1), 2, 3]!!
assert typeof(c2) == '[3]i16'
assert typeof(c2).name == '[3]i16'
assert '$c2' == '[1, 2, 3]'
mut c3 := [i64(1), 2, 3]!!
assert typeof(c3) == '[3]i64'
assert typeof(c3).name == '[3]i64'
assert '$c3' == '[1, 2, 3]'
mut c4 := [u64(1), 2, 3]!!
assert typeof(c4) == '[3]u64'
assert typeof(c4).name == '[3]u64'
assert '$c4' == '[1, 2, 3]'
mut d1 := [1.1, 2.2, 3.3]!!
assert typeof(d1) == '[3]f64'
assert typeof(d1).name == '[3]f64'
assert '$d1' == '[1.1, 2.2, 3.3]'
mut d2 := [f32(1.1), 2.2, 3.3]!!
assert typeof(d2) == '[3]f32'
assert typeof(d2).name == '[3]f32'
assert '$d2' == '[1.1, 2.2, 3.3]'
}

View File

@ -9,12 +9,12 @@ fn new_tensor<T>(data BuildData) Tensor {
fn test_generic_function_returning_type_starting_with_t() {
ft := new_tensor<f64>(x:123)
println(ft)
assert typeof(ft) == 'Tensor'
assert typeof(ft).name == 'Tensor'
assert '$ft' == 'Tensor{\n x: 123\n}'
//
it := new_tensor<int>(x:456)
println(it)
assert typeof(it) == 'Tensor'
assert typeof(it).name == 'Tensor'
assert '$it' == 'Tensor{\n x: 456\n}'
}

View File

@ -4,7 +4,7 @@ import genericmodule
fn test_generic_function_from_another_module() {
v1 := genericmodule.take<int>(true, 10, 20)
assert typeof(v1) == 'int'
assert typeof(v1).name == 'int'
assert v1 == 10
v2 := genericmodule.take<int>(false, 10, 20)
assert v2 == 20
@ -12,7 +12,7 @@ fn test_generic_function_from_another_module() {
fn test_generic_type_inference_from_another_module() {
v1 := genericmodule.take(true, 10, 20)
assert typeof(v1) == 'int'
assert typeof(v1).name == 'int'
assert v1 == 10
v2 := genericmodule.take(false, 10, 20)
assert v2 == 20
@ -20,7 +20,7 @@ fn test_generic_type_inference_from_another_module() {
fn test_inference_with_strings() {
v1 := genericmodule.take(true, 'abc', 'def')
assert typeof(v1) == 'string'
assert typeof(v1).name == 'string'
assert v1 == 'abc'
v2 := genericmodule.take(false, 'abc', 'def')
assert v2 == 'def'
@ -28,7 +28,7 @@ fn test_inference_with_strings() {
fn test_inference_with_f64() {
v1 := genericmodule.take(true, f64(123), 345)
assert typeof(v1) == 'f64'
assert typeof(v1).name == 'f64'
assert v1 == 123
v2 := genericmodule.take(false, f64(123), 345)
assert v2 == 345

View File

@ -260,10 +260,10 @@ fn test_generic_struct() {
assert b.permission.name == 'superuser'
println('b.model.name: $b.model.name')
println('b.permission.name: $b.permission.name')
assert typeof(a.model) == 'User'
assert typeof(b.model) == 'Group'
println('typeof(a.model): ' + typeof(a.model))
println('typeof(b.model): ' + typeof(b.model))
assert typeof(a.model).name == 'User'
assert typeof(b.model).name == 'Group'
println('typeof(a.model): ' + typeof(a.model).name)
println('typeof(b.model): ' + typeof(b.model).name)
// mut x := new_repo<User>(DB{})
// x.model.name = 'joe2'
// println(x.model.name)

View File

@ -23,7 +23,7 @@ fn (c &Cat) speak(s string) {
}
fn (c Cat) name_detailed(pet_name string) string {
return '$pet_name the ${typeof(c)}, breed:$c.breed'
return '$pet_name the ${typeof(c).name}, breed:$c.breed'
}
fn (mut c Cat) set_breed(new string) {
@ -46,7 +46,7 @@ fn (d Dog) name() string {
}
fn (d Dog) name_detailed(pet_name string) string {
return '$pet_name the ${typeof(d)}, breed:$d.breed'
return '$pet_name the ${typeof(d).name}, breed:$d.breed'
}
fn (mut d Dog) set_breed(new string) {
@ -71,7 +71,7 @@ fn perform_speak(a Animal) {
println(a.breed)
}
println(a.name())
println('Got animal of type: ${typeof(a)}') // TODO: get implementation type (if possible)
println('Got animal of type: ${typeof(a).name}') // TODO: get implementation type (if possible)
assert a is Dog || a is Cat
}
@ -84,7 +84,7 @@ fn perform_speak_on_ptr(a &Animal) {
assert name == 'Dog'
}
println(a.name())
println('Got animal of type: ${typeof(a)}') // TODO: get implementation type (if possible)
println('Got animal of type: ${typeof(a).name}') // TODO: get implementation type (if possible)
assert a is Dog || a is Cat
}

View File

@ -152,7 +152,7 @@ struct B1 {
fn f(s Sum) string {
match s {
A1 { return typeof(s) }
A1 { return typeof(s).name }
B1 { return '' }
}
return ''
@ -167,7 +167,7 @@ fn test_sum_type_name() {
fn f_else(s Sum) string {
match s {
A1 { return typeof(s) }
A1 { return typeof(s).name }
else { return '' }
}
}

View File

@ -165,7 +165,7 @@ fn test_as_cast() {
fn test_typeof() {
x := Expr(IfExpr{})
assert typeof(x) == 'IfExpr'
assert x.type_name() == 'IfExpr'
}
type Food = Milk | Eggs
@ -409,7 +409,7 @@ fn (c CommonType) str() string {
match c {
string {
d := c.int()
e := d
_ := d
return c
}
int {
@ -525,7 +525,7 @@ fn handle(e Expr) string {
assert is_literal
assert !(e !is IntegerLiteral)
if e is IntegerLiteral {
assert typeof(e.val) == 'string'
assert typeof(e.val).name == 'string'
}
match e {
IntegerLiteral {

View File

@ -1,6 +1,6 @@
// _likely_(expr) should be compilable, and it should return the expr
fn test_likely_type() {
assert typeof(_likely_(false)) == 'bool'
assert typeof(_likely_(false)).name == 'bool'
assert _likely_(false) == false
assert _likely_(true) == true
}
@ -26,7 +26,7 @@ fn test_likely_returns_the_value_of_its_bool_argument() {
// _unlikely_ is the same as _likely_ from the V point of view:
fn test_unlikely_type() {
assert typeof(_unlikely_(false)) == 'bool'
assert typeof(_unlikely_(false)).name == 'bool'
assert _unlikely_(false) == false
assert _unlikely_(true) == true
}

View File

@ -4,13 +4,13 @@ fn test_anyfloat() {
c := f32(6.75) / 3.0
d := 16.5 / f32(2)
assert a == 51.515
assert typeof(a) == 'f64'
assert typeof(a).name == 'f64'
assert b == f64(15.3)
assert typeof(b) == 'f64'
assert typeof(b).name == 'f64'
assert c == 2.25
assert typeof(c) == 'f32'
assert typeof(c).name == 'f32'
assert d == 8.25
assert typeof(d) == 'f32'
assert typeof(d).name == 'f32'
}
fn g(x f32) f32 {
@ -92,9 +92,9 @@ fn test_rune() {
assert x == 67
c := b + a
assert c == rune(70)
assert typeof(c) == 'rune'
assert typeof(c).name == 'rune'
d := i64(12)
e := b + d
assert e == i64(79)
assert typeof(e) == 'i64'
assert typeof(e).name == 'i64'
}

View File

@ -54,7 +54,7 @@ pub fn (ms MySumType) str() string {
int { return ms.str() }
f32 { return ms.str() }
// FooBar { return it.x.str() }
else { return 'unknown: ' + typeof(ms) }
else { return ms.type_name() }
}
}
@ -74,6 +74,10 @@ fn test_typeof_on_sumtypes() {
assert typeof(a).name == 'MySumType'
assert typeof(b).name == 'MySumType'
assert typeof(c).name == 'MySumType'
assert a.str() == '32'
assert b.str() == '123.'
assert c.str() == 'FooBar'
}
//