diff --git a/vlib/json/json_primitives.v b/vlib/json/json_primitives.v index eab1f0a185..517d2583c0 100644 --- a/vlib/json/json_primitives.v +++ b/vlib/json/json_primitives.v @@ -12,7 +12,7 @@ struct C.cJSON { valuestring byteptr } -pub fn decode() ?voidptr { +pub fn decode(typ voidptr, s string) ?voidptr { // compiler implementation return 0 } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 4c7c7bba41..c4df4dd01e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -607,12 +607,10 @@ pub fn (mut c Checker) call_method(call_expr mut ast.CallExpr) table.Type { mut scope := c.file.scope.innermost(call_expr.pos.pos) scope.update_var_type('it', array_info.elem_type) } - mut arg_type := left_type for arg in call_expr.args { arg_type = c.expr(arg.expr) } - call_expr.return_type = left_type call_expr.receiver_type = left_type if method_name == 'map' && call_expr.args.len == 1 { @@ -687,17 +685,13 @@ pub fn (mut c Checker) call_method(call_expr mut ast.CallExpr) table.Type { return table.string_type } // call struct field fn type - // TODO: can we use SelectorExpr for all? this dosent really belong here + // TODO: can we use SelectorExpr for all? if field := c.table.struct_find_field(left_type_sym, method_name) { field_type_sym := c.table.get_type_symbol(field.typ) if field_type_sym.kind == .function { call_expr.is_method = false info := field_type_sym.info as table.FnType call_expr.return_type = info.func.return_type - // TODO: check args (do it once for all of the above) - for i, arg in call_expr.args { - arg_typ := c.expr(arg.expr) - } return info.func.return_type } } @@ -722,6 +716,13 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type { // } if fn_name == 'json.encode' { } + if fn_name == 'json.decode' { + ident := call_expr.args[0].expr as ast.Ident + // sym := c.table.find_type(ident.name) + idx := c.table.find_type_idx(ident.name) + println('js.decode t=$ident.name') + return table.Type(idx) + } // look for function in format `mod.fn` or `fn` (main/builtin) mut f := table.Fn{} mut found := false @@ -1720,6 +1721,10 @@ pub fn (mut c Checker) ident(ident mut ast.Ident) table.Type { if ident.is_c { return table.int_type } + if c.table.known_type(ident.name) { + // e.g. `User` in `json.decode(User, '...')` + return table.void_type + } if ident.name != '_' { c.error('undefined: `$ident.name`', ident.pos) } diff --git a/vlib/v/gen/json.v b/vlib/v/gen/json.v index eab7ccdbfb..6e19efcafc 100644 --- a/vlib/v/gen/json.v +++ b/vlib/v/gen/json.v @@ -25,54 +25,25 @@ fn (mut g Gen) gen_json_for_type(typ table.Type) { if sym.name in ['int', 'string', 'bool'] { return } - // println('gen_json_for_type( $typ.name )') - // Register decoder fn - /* - mut dec_fn := Fn{ - mod: p.mod - typ: 'Option_$typ.name' - name: js_dec_name(t) - } - if p.table.known_fn(dec_fn.name) { - // Already registered? Skip. - return - } - + // println('gen_json_for_type($typ.name)') // decode_TYPE funcs receive an actual cJSON* object to decode // cJSON_Parse(str) call is added by the compiler - arg := Var{ - typ: 'cJSON*' - } - dec_fn.args << arg - p.table.register_fn(dec_fn) - // Register encoder fn - mut enc_fn := Fn{ - mod: p.mod - typ: 'cJSON*' - name: js_enc_name(t) - } - // encode_TYPE funcs receive an object to encode - enc_arg := Var{ - typ: t - } - enc_fn.args << enc_arg - p.table.register_fn(enc_fn) // Code gen decoder - dec += ' -//$t $dec_fn.name (cJSON* root) { -Option ${dec_fn.name}(cJSON* root, $t* res) { -// $t res; + dec_fn_name := js_dec_name(sym.name) + dec.writeln(' +Option ${dec_fn_name}(cJSON* root, $styp* res) { +// $styp res; if (!root) { const char *error_ptr = cJSON_GetErrorPtr(); if (error_ptr != NULL) { - fprintf(stderr, "Error in decode() for $t error_ptr=: %%s\\n", error_ptr); + fprintf(stderr, "Error in decode() for $styp error_ptr=: %%s\\n", error_ptr); // printf("\\nbad js=%%s\\n", js.str); return v_error(tos2(error_ptr)); } } -' - */ +') // Code gen encoder + // encode_TYPE funcs receive an object to encode enc_fn_name := js_enc_name(sym.name) enc.writeln(' cJSON* ${enc_fn_name}($styp val) { @@ -111,7 +82,7 @@ cJSON* ${enc_fn_name}($styp val) { // p.cgen.fns << '$dec return opt_ok(res); \n}' dec.writeln('return opt_ok(res, sizeof(*res)); \n}') enc.writeln('\treturn o;\n}') - // g.definitions.writeln(dec.str()) + g.definitions.writeln(dec.str()) g.gowrappers.writeln(enc.str()) }