1
0
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:
playX 2021-11-10 12:37:16 +03:00 committed by GitHub
parent 6c244d3065
commit 194b3647e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 1 deletions

View File

@ -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 {}
}

View File

@ -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

View 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
}