mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
js,checker: allow casting JS primitives to V primitives and vice-versa (#12420)
This commit is contained in:
parent
6c244d3065
commit
194b3647e2
@ -5565,6 +5565,18 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
|
||||
node.expr_type = c.expr(node.expr) // type to be casted
|
||||
from_type_sym := c.table.get_type_symbol(node.expr_type)
|
||||
to_type_sym := c.table.get_type_symbol(node.typ) // type to be used as cast
|
||||
|
||||
if (to_type_sym.is_number() && from_type_sym.name == 'JS.Number')
|
||||
|| (to_type_sym.is_number() && from_type_sym.name == 'JS.BigInt')
|
||||
|| (to_type_sym.is_string() && from_type_sym.name == 'JS.String')
|
||||
|| (node.typ.is_bool() && from_type_sym.name == 'JS.Boolean')
|
||||
|| (node.expr_type.is_bool() && to_type_sym.name == 'JS.Boolean')
|
||||
|| (from_type_sym.is_number() && to_type_sym.name == 'JS.Number')
|
||||
|| (from_type_sym.is_number() && to_type_sym.name == 'JS.BigInt')
|
||||
|| (from_type_sym.is_string() && to_type_sym.name == 'JS.String') {
|
||||
return node.typ
|
||||
}
|
||||
|
||||
if to_type_sym.language != .c {
|
||||
c.ensure_type_exists(node.typ, node.pos) or {}
|
||||
}
|
||||
|
@ -3226,8 +3226,39 @@ fn (mut g JsGen) gen_cast_tmp(tmp string, typ_ ast.Type) {
|
||||
fn (mut g JsGen) gen_type_cast_expr(it ast.CastExpr) {
|
||||
is_literal := ((it.expr is ast.IntegerLiteral && it.typ in ast.integer_type_idxs)
|
||||
|| (it.expr is ast.FloatLiteral && it.typ in ast.float_type_idxs))
|
||||
from_type_sym := g.table.get_type_symbol(it.expr_type)
|
||||
to_type_sym := g.table.get_type_symbol(it.typ) // type to be used as cast
|
||||
if it.typ.is_bool() && from_type_sym.name == 'JS.Boolean' {
|
||||
g.write('new bool(')
|
||||
g.expr(it.expr)
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
if it.expr_type.is_bool() && to_type_sym.name == 'JS.Boolean' {
|
||||
g.expr(it.expr)
|
||||
g.write('.\$toJS()')
|
||||
return
|
||||
}
|
||||
if (to_type_sym.is_number() && from_type_sym.name == 'JS.Number')
|
||||
|| (to_type_sym.is_number() && from_type_sym.name == 'JS.BigInt')
|
||||
|| (to_type_sym.is_string() && from_type_sym.name == 'JS.String') {
|
||||
g.write('new ${to_type_sym.kind.str()}(')
|
||||
g.expr(it.expr)
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
|
||||
if (from_type_sym.is_number() && to_type_sym.name == 'JS.Number')
|
||||
|| (from_type_sym.is_number() && to_type_sym.name == 'JS.BigInt')
|
||||
|| (from_type_sym.is_string() && to_type_sym.name == 'JS.String') {
|
||||
g.write('${g.typ(it.typ)}(')
|
||||
g.expr(it.expr)
|
||||
g.write('.\$toJS())')
|
||||
return
|
||||
}
|
||||
|
||||
// Skip cast if type is the same as the parrent caster
|
||||
tsym := g.table.get_final_type_symbol(it.typ)
|
||||
tsym := to_type_sym
|
||||
if tsym.kind == .sum_type {
|
||||
g.expr(it.expr)
|
||||
return
|
||||
|
12
vlib/v/tests/cast_test.js.v
Normal file
12
vlib/v/tests/cast_test.js.v
Normal file
@ -0,0 +1,12 @@
|
||||
fn JS.Math.pow(JS.Number, JS.Number) JS.Number
|
||||
|
||||
fn test_js_prim_cast() {
|
||||
x := JS.Number(f64(42.42))
|
||||
assert f64(x) == 42.42
|
||||
y := JS.BigInt(u64(18446744073709551615))
|
||||
assert u64(y) == u64(18446744073709551615)
|
||||
z := JS.String('hello, world!')
|
||||
assert string(z) == 'hello, world!'
|
||||
w := int(JS.Math.pow(JS.Number(int(2)), JS.Number(int(3))))
|
||||
assert w == 8
|
||||
}
|
Loading…
Reference in New Issue
Block a user