json: decode_array fix

pull/4732/head
Alexander Medvednikov 2020-05-05 14:19:31 +02:00
parent ef6c418eb6
commit ee92060d4d
5 changed files with 14 additions and 8 deletions

View File

@ -735,7 +735,8 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type {
} else if fn_name == 'json.decode' {
expr := call_expr.args[0].expr
if !(expr is ast.Type) {
c.error('json.decode: first argument needs to be a type', call_expr.pos)
typ := typeof(expr)
c.error('json.decode: first argument needs to be a type, got `$typ`', call_expr.pos)
return table.void_type
}
typ := expr as ast.Type

View File

@ -124,7 +124,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string {
if is_js_prim(styp) {
s = '$styp val = ${fn_name}(jsval); '
} else {
s = '\t$styp val; ${fn_name}(jsval, &val); '
s = '\t$styp val = *($styp*) ${fn_name}(jsval).data; '
}
return '
res = __new_array(0, 0, sizeof($styp));

View File

@ -22,7 +22,7 @@ pub fn (mut p Parser) call_expr(is_c, is_js bool, mod string) ast.CallExpr {
}
if fn_name == 'json.decode' {
// Makes name_expr() parse the type (`User` in `json.decode(User, txt)`)`
p.inside_is = true
p.expecting_type = true
p.expr_mod = ''
}
p.check(.lpar)

View File

@ -42,7 +42,7 @@ mut:
inside_match bool // to separate `match A { }` from `Struct{}`
inside_match_case bool // to separate `match_expr { }` from `Struct{}`
is_stmt_ident bool // true while the beginning of a statement is an ident/selector
inside_is bool // `is Type`, expecting type
expecting_type bool // `is Type`, expecting type
}
// for tests
@ -584,8 +584,8 @@ pub fn (mut p Parser) parse_ident(is_c, is_js bool) ast.Ident {
pub fn (mut p Parser) name_expr() ast.Expr {
mut node := ast.Expr{}
if p.inside_is {
p.inside_is = false
if p.expecting_type {
p.expecting_type = false
// get type position before moving to next
type_pos := p.tok.position()
typ := p.parse_type()

View File

@ -62,7 +62,12 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
node = p.if_expr()
}
.lsbr {
node = p.array_init()
if p.expecting_type {
// parse json.decode type (`json.decode([]User, s)`)
node = p.name_expr()
} else {
node = p.array_init()
}
}
.key_none {
p.next()
@ -190,7 +195,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
p.next()
mut right := ast.Expr{}
if op == .key_is {
p.inside_is = true
p.expecting_type = true
}
right = p.expr(precedence)
return ast.InfixExpr{