mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
gen: implement type_name method for sum type instances (#6802)
This commit is contained in:
parent
2dc9a45e06
commit
50163508f8
@ -1634,8 +1634,11 @@ struct Venus {}
|
|||||||
type World = Moon | Mars | Venus
|
type World = Moon | Mars | Venus
|
||||||
|
|
||||||
sum := World(Moon{})
|
sum := World(Moon{})
|
||||||
|
assert sum.type_name() == 'Moon'
|
||||||
println(sum)
|
println(sum)
|
||||||
```
|
```
|
||||||
|
The built-in method `type_name` returns the name of the currently held
|
||||||
|
type.
|
||||||
|
|
||||||
#### Dynamic casts
|
#### Dynamic casts
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ pub:
|
|||||||
left Expr // `user` in `user.register()`
|
left Expr // `user` in `user.register()`
|
||||||
mod string
|
mod string
|
||||||
pub mut:
|
pub mut:
|
||||||
name string
|
name string // left.name()
|
||||||
is_method bool
|
is_method bool
|
||||||
is_field bool // temp hack, remove ASAP when re-impl CallExpr / Selector (joe)
|
is_field bool // temp hack, remove ASAP when re-impl CallExpr / Selector (joe)
|
||||||
args []CallArg
|
args []CallArg
|
||||||
|
@ -1097,6 +1097,9 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
|||||||
c.error('optional type cannot be called directly', call_expr.left.position())
|
c.error('optional type cannot be called directly', call_expr.left.position())
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
|
if left_type_sym.kind == .sum_type && method_name == 'type_name' {
|
||||||
|
return table.string_type
|
||||||
|
}
|
||||||
// TODO: remove this for actual methods, use only for compiler magic
|
// TODO: remove this for actual methods, use only for compiler magic
|
||||||
// FIXME: Argument count != 1 will break these
|
// FIXME: Argument count != 1 will break these
|
||||||
if left_type_sym.kind == .array &&
|
if left_type_sym.kind == .array &&
|
||||||
@ -4424,6 +4427,9 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
|||||||
if sym.kind == .interface_ {
|
if sym.kind == .interface_ {
|
||||||
c.error('interfaces cannot be used as method receiver', node.receiver_pos)
|
c.error('interfaces cannot be used as method receiver', node.receiver_pos)
|
||||||
}
|
}
|
||||||
|
if sym.kind == .sum_type && node.name == 'type_name' {
|
||||||
|
c.error('method overrides built-in sum type method', node.pos)
|
||||||
|
}
|
||||||
// if sym.has_method(node.name) {
|
// if sym.has_method(node.name) {
|
||||||
// c.warn('duplicate method `$node.name`', node.pos)
|
// c.warn('duplicate method `$node.name`', node.pos)
|
||||||
// }
|
// }
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
vlib/v/checker/tests/incorrect_name_sum_type.vv:1:1: error: sum type `integer` must begin with capital letter
|
vlib/v/checker/tests/incorrect_name_sum_type.vv:1:1: error: sum type `integer` must begin with capital letter
|
||||||
1 | type integer = i8 | i16 | int | i64
|
1 | type integer = i8 | i16 | int | i64
|
||||||
| ~~~~~~~~~~~~
|
| ~~~~~~~~~~~~
|
||||||
|
2 | type Integer = i8 | i16 | int | i64
|
||||||
|
3 |
|
||||||
|
vlib/v/checker/tests/incorrect_name_sum_type.vv:4:1: error: method overrides built-in sum type method
|
||||||
|
2 | type Integer = i8 | i16 | int | i64
|
||||||
|
3 |
|
||||||
|
4 | fn (i Integer) type_name() {
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
5 | }
|
||||||
|
6 |
|
||||||
|
@ -1 +1,6 @@
|
|||||||
type integer = i8 | i16 | int | i64
|
type integer = i8 | i16 | int | i64
|
||||||
|
type Integer = i8 | i16 | int | i64
|
||||||
|
|
||||||
|
fn (i Integer) type_name() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -377,6 +377,12 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
|||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if left_sym.kind == .sum_type && node.name == 'type_name' {
|
||||||
|
g.write('tos3( /* $left_sym.name */ v_typeof_sumtype_${node.receiver_type}( (')
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write(').typ ))')
|
||||||
|
return
|
||||||
|
}
|
||||||
if node.name == 'str' {
|
if node.name == 'str' {
|
||||||
mut styp := g.typ(node.receiver_type)
|
mut styp := g.typ(node.receiver_type)
|
||||||
if node.receiver_type.is_ptr() {
|
if node.receiver_type.is_ptr() {
|
||||||
|
@ -65,6 +65,9 @@ fn test_typeof_on_sumtypes() {
|
|||||||
assert typeof(a) == 'int'
|
assert typeof(a) == 'int'
|
||||||
assert typeof(b) == 'f32'
|
assert typeof(b) == 'f32'
|
||||||
assert typeof(c) == 'FooBar'
|
assert typeof(c) == 'FooBar'
|
||||||
|
assert a.type_name() == 'int'
|
||||||
|
assert b.type_name() == 'f32'
|
||||||
|
assert c.type_name() == 'FooBar'
|
||||||
// typeof should be known at compile-time for all types
|
// typeof should be known at compile-time for all types
|
||||||
assert typeof(a).name == 'MySumType'
|
assert typeof(a).name == 'MySumType'
|
||||||
assert typeof(b).name == 'MySumType'
|
assert typeof(b).name == 'MySumType'
|
||||||
@ -96,6 +99,10 @@ fn test_typeof_on_sumtypes_of_structs() {
|
|||||||
assert typeof(b) == 'BinExpr'
|
assert typeof(b) == 'BinExpr'
|
||||||
assert typeof(c) == 'BoolExpr'
|
assert typeof(c) == 'BoolExpr'
|
||||||
assert typeof(d) == 'UnaryExpr'
|
assert typeof(d) == 'UnaryExpr'
|
||||||
|
assert a.type_name() == 'UnaryExpr'
|
||||||
|
assert b.type_name() == 'BinExpr'
|
||||||
|
assert c.type_name() == 'BoolExpr'
|
||||||
|
assert d.type_name() == 'UnaryExpr'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn myfn(i int) int {
|
fn myfn(i int) int {
|
||||||
|
Loading…
Reference in New Issue
Block a user