Skip to content

Commit ff0c25c

Browse files
committed
v3: address gitly review feedback
1 parent 7694803 commit ff0c25c

16 files changed

Lines changed: 566 additions & 81 deletions

vlib/v3/gen/c/array.v

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ fn (mut g FlatGen) gen_slice_expr(node flat.Node, base_id flat.NodeId, base_type
104104
}
105105

106106
fn (mut g FlatGen) gen_array_method_call(node flat.Node, fn_node &flat.Node, arr types.Array) {
107-
c_elem := g.tc.c_type(arr.elem_type)
107+
c_elem := g.value_c_type(arr.elem_type)
108108
base_id := g.a.child(fn_node, 0)
109109
base_node := g.a.nodes[int(base_id)]
110110
is_ptr := if base_node.kind == .ident {
@@ -331,8 +331,8 @@ fn (mut g FlatGen) gen_index_assign(node flat.Node) {
331331
base_type := g.tc.resolve_type(base_id)
332332
clean_base := types.unwrap_pointer(base_type)
333333
if clean_base is types.Map {
334-
c_key := g.tc.c_type(clean_base.key_type)
335-
c_val := g.tc.c_type(clean_base.value_type)
334+
c_key := g.value_c_type(clean_base.key_type)
335+
c_val := g.value_c_type(clean_base.value_type)
336336
is_ptr := base_type is types.Pointer
337337
if is_ptr {
338338
g.write('map__set(')
@@ -374,7 +374,7 @@ fn (mut g FlatGen) gen_index_assign(node flat.Node) {
374374
}
375375
}
376376
if is_array_base {
377-
c_elem := g.tc.c_type(arr_type.elem_type)
377+
c_elem := g.value_c_type(arr_type.elem_type)
378378
g.write('array_set(')
379379
if base_type is types.Pointer {
380380
g.write('*')

vlib/v3/gen/c/cleanc.v

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ pub fn (mut g FlatGen) gen_with_used_options(a &flat.FlatAst, used_fns map[strin
165165
g.collect_gen_info()
166166
g.collect_interface_impls()
167167
g.preseed_struct_fn_ptr_types()
168+
g.preseed_global_fn_ptr_types()
168169
const_code := g.precompute_consts()
169170
orig_sb := g.sb
170171
orig_line_start := g.line_start
@@ -317,14 +318,8 @@ fn (mut g FlatGen) collect_gen_info() {
317318
continue
318319
}
319320
if kind_id == 70 {
320-
mut methods := []string{}
321-
for i in 0 .. node.children_count {
322-
f := g.a.child_node(&node, i)
323-
if node_kind_id(f) == 71 && f.op == .dot {
324-
methods << f.value
325-
}
326-
}
327-
g.interfaces[qualify_name_in_module(cur_module, node.value)] = methods
321+
iface_name := qualify_name_in_module(cur_module, node.value)
322+
g.interfaces[iface_name] = g.tc.interface_abstract_method_names(iface_name)
328323
continue
329324
}
330325
if kind_id == 65 {
@@ -452,6 +447,12 @@ fn (mut g FlatGen) register_fn_decl_param_types(name string, full_name string, p
452447
if name !in g.fn_decl_param_types {
453448
g.fn_decl_param_types[name] = ptypes.clone()
454449
}
450+
if g.tc.cur_module.len > 0 && g.tc.cur_module != 'main' && g.tc.cur_module != 'builtin' {
451+
dotted_name := '${g.tc.cur_module}.${name}'
452+
if dotted_name !in g.fn_decl_param_types {
453+
g.fn_decl_param_types[dotted_name] = ptypes.clone()
454+
}
455+
}
455456
if full_name !in g.fn_decl_param_types {
456457
g.fn_decl_param_types[full_name] = ptypes.clone()
457458
}
@@ -542,6 +543,17 @@ fn (mut g FlatGen) gen_expr_with_expected_type(id flat.NodeId, expected types.Ty
542543
actual = param_type
543544
}
544545
}
546+
if node.kind == .ident {
547+
if _ := fn_type_from(expected) {
548+
call_name := g.call_key(id, node.value)
549+
if call_name in g.tc.fn_param_types || call_name in g.tc.fn_ret_types {
550+
g.write(c_name(call_name))
551+
g.expected_expr_type = old_expected
552+
g.expected_enum = old_expected_enum
553+
return
554+
}
555+
}
556+
}
545557
if expected is types.Array && node.kind == .array_literal {
546558
elem_type := if node.children_count > 0 {
547559
g.tc.resolve_type(g.a.child(&node, 0))
@@ -568,6 +580,11 @@ fn (mut g FlatGen) gen_expr_with_expected_type(id flat.NodeId, expected types.Ty
568580
g.expected_enum = old_expected_enum
569581
return
570582
}
583+
if g.gen_interface_value_expr(id, expected) {
584+
g.expected_expr_type = old_expected
585+
g.expected_enum = old_expected_enum
586+
return
587+
}
571588
if g.gen_sum_value_expr(id, expected) {
572589
g.expected_expr_type = old_expected
573590
g.expected_enum = old_expected_enum
@@ -734,6 +751,13 @@ fn (mut g FlatGen) gen_expr_with_possible_enum_type(id flat.NodeId, expected typ
734751
g.gen_expr(id)
735752
}
736753

754+
fn (g &FlatGen) expected_expr_is_optional_struct() bool {
755+
if g.expected_expr_type is types.Struct {
756+
return g.expected_expr_type.name.starts_with('Optional')
757+
}
758+
return false
759+
}
760+
737761
fn (mut g FlatGen) optional_none_type(id flat.NodeId) types.Type {
738762
if g.expected_expr_type is types.OptionType || g.expected_expr_type is types.ResultType {
739763
return g.expected_expr_type
@@ -1275,7 +1299,7 @@ fn (mut g FlatGen) gen_expr(id flat.NodeId) {
12751299
g.gen_heap_assoc_expr(child)
12761300
} else if node.op == .amp && child.kind == .cast_expr {
12771301
target_type := g.tc.parse_type(child.value)
1278-
ct := g.tc.c_type(target_type)
1302+
ct := g.cast_c_type(target_type)
12791303
cast_arg := g.a.child_node(&child, 0)
12801304
if cast_arg.kind == .nil_literal {
12811305
g.write('(${ct}*)NULL')
@@ -1522,8 +1546,8 @@ fn (mut g FlatGen) gen_expr(id flat.NodeId) {
15221546
if node.value == 'range' {
15231547
g.gen_slice_expr(node, base_id, base_type)
15241548
} else if base_type is types.Map {
1525-
c_key := g.tc.c_type(base_type.key_type)
1526-
c_val := g.tc.c_type(base_type.value_type)
1549+
c_key := g.value_c_type(base_type.key_type)
1550+
c_val := g.value_c_type(base_type.value_type)
15271551
g.write('(*(${c_val}*)map__get(&')
15281552
g.gen_expr(base_id)
15291553
g.write(', &(${c_key}[]){')
@@ -1532,7 +1556,16 @@ fn (mut g FlatGen) gen_expr(id flat.NodeId) {
15321556
} else {
15331557
is_array_index, is_ptr, arr_type := array_index_info(base_type)
15341558
if is_array_index {
1535-
c_elem := g.tc.c_type(arr_type.elem_type)
1559+
index_type := if g.expected_expr_type is types.OptionType
1560+
|| g.expected_expr_type is types.ResultType
1561+
|| g.expected_expr_is_optional_struct() {
1562+
g.expected_expr_type
1563+
} else if node.typ.starts_with('?') || node.typ.starts_with('!') {
1564+
g.tc.parse_type(node.typ)
1565+
} else {
1566+
arr_type.elem_type
1567+
}
1568+
c_elem := g.value_c_type(index_type)
15361569
g.write('(*(${c_elem}*)array_get(')
15371570
if is_ptr {
15381571
g.write('*')
@@ -1587,7 +1620,7 @@ fn (mut g FlatGen) gen_expr(id flat.NodeId) {
15871620
}
15881621
.cast_expr {
15891622
target_type := g.tc.parse_type(node.value)
1590-
mut ct := g.tc.c_type(target_type)
1623+
mut ct := g.cast_c_type(target_type)
15911624
if ct.starts_with('fn_ptr:') {
15921625
ct = g.resolve_fn_ptr_type(ct)
15931626
}
@@ -2179,8 +2212,42 @@ fn (mut g FlatGen) late_compat_decls() {
21792212
g.writeln('static inline Array binary__little_endian_get_u32(u32 v) { (void)v; return (Array){.data = NULL, .offset = 0, .len = 0, .cap = 0, .flags = 0, .element_size = sizeof(u8)}; }')
21802213
g.writeln('static inline Array binary__big_endian_get_u32(u32 v) { (void)v; return (Array){.data = NULL, .offset = 0, .len = 0, .cap = 0, .flags = 0, .element_size = sizeof(u8)}; }')
21812214
g.writeln('static inline Optional rand__int_u64(u64 max) { (void)max; return (Optional){.ok = true, .value = 0}; }')
2215+
g.writeln('typedef struct PGconn { int _dummy; } PGconn;')
2216+
g.writeln('typedef struct PGresult { int _dummy; } PGresult;')
2217+
g.writeln('typedef struct PGnotify { char* relname; int be_pid; char* extra; } PGnotify;')
2218+
g.writeln('static inline PGconn* PQconnectdb(char* conninfo) { (void)conninfo; static PGconn conn; return &conn; }')
2219+
g.writeln('static inline int PQstatus(PGconn* conn) { (void)conn; return 0; }')
2220+
g.writeln('static inline int PQtransactionStatus(PGconn* conn) { (void)conn; return 0; }')
2221+
g.writeln('static inline char* PQerrorMessage(PGconn* conn) { (void)conn; return ""; }')
2222+
g.writeln('static inline PGresult* PQexec(PGconn* conn, char* query) { (void)conn; (void)query; static PGresult res; return &res; }')
2223+
g.writeln('static inline int PQgetisnull(PGresult* res, int row, int col) { (void)res; (void)row; (void)col; return 1; }')
2224+
g.writeln('static inline char* PQgetvalue(PGresult* res, int row, int col) { (void)res; (void)row; (void)col; return ""; }')
2225+
g.writeln('static inline int PQresultStatus(PGresult* res) { (void)res; return 1; }')
2226+
g.writeln('static inline int PQntuples(PGresult* res) { (void)res; return 0; }')
2227+
g.writeln('static inline int PQnfields(PGresult* res) { (void)res; return 0; }')
2228+
g.writeln('static inline char* PQfname(PGresult* res, int col) { (void)res; (void)col; return ""; }')
2229+
g.writeln('static inline PGresult* PQexecParams(PGconn* conn, char* query, int nparams, void* types, void* vals, void* lens, void* formats, int result_format) { (void)conn; (void)query; (void)nparams; (void)types; (void)vals; (void)lens; (void)formats; (void)result_format; static PGresult res; return &res; }')
2230+
g.writeln('static inline int PQputCopyData(PGconn* conn, void* buffer, int nbytes) { (void)conn; (void)buffer; (void)nbytes; return 1; }')
2231+
g.writeln('static inline int PQputCopyEnd(PGconn* conn, char* errmsg) { (void)conn; (void)errmsg; return 1; }')
2232+
g.writeln('static inline int PQgetCopyData(PGconn* conn, char** buffer, int async) { (void)conn; (void)buffer; (void)async; return -1; }')
2233+
g.writeln('static inline PGresult* PQprepare(PGconn* conn, char* name, char* query, int nparams, void* param_types) { (void)conn; (void)name; (void)query; (void)nparams; (void)param_types; static PGresult res; return &res; }')
2234+
g.writeln('static inline PGresult* PQexecPrepared(PGconn* conn, char* name, int nparams, void* vals, void* lens, void* formats, int result_format) { (void)conn; (void)name; (void)nparams; (void)vals; (void)lens; (void)formats; (void)result_format; static PGresult res; return &res; }')
2235+
g.writeln('static inline void PQclear(PGresult* res) { (void)res; }')
2236+
g.writeln('static inline void PQfreemem(void* ptr) { (void)ptr; }')
2237+
g.writeln('static inline void PQfinish(PGconn* conn) { (void)conn; }')
2238+
g.writeln('static inline PGnotify* PQnotifies(PGconn* conn) { (void)conn; return NULL; }')
2239+
g.writeln('static inline int PQconsumeInput(PGconn* conn) { (void)conn; return 1; }')
2240+
g.writeln('static inline int PQsocket(PGconn* conn) { (void)conn; return -1; }')
2241+
g.writeln('static inline char* PQescapeLiteral(PGconn* conn, char* str, size_t len) { (void)conn; (void)len; return str; }')
2242+
g.writeln('static inline void pg__pg_stmt_match_array(Array* types, Array* vals, Array* lens, Array* formats, Array data) { (void)types; (void)vals; (void)lens; (void)formats; (void)data; }')
21822243
g.writeln('typedef void* _fn_ptr_64;')
21832244
g.writeln('static inline Optional_string orm__orm_table_gen(int sql_dialect, orm__Table table, string q, bool defaults, int def_unique_len, Array fields, void* sql_from_v, bool unique) { (void)sql_dialect; (void)table; (void)q; (void)defaults; (void)def_unique_len; (void)fields; (void)sql_from_v; (void)unique; return (Optional_string){.ok = true, .value = v3_empty_string_lit()}; }')
2245+
if 'sqlite.Stmt' !in g.struct_decl_infos {
2246+
g.writeln('typedef struct sqlite__Stmt { void* stmt; void* db; } sqlite__Stmt;')
2247+
}
2248+
if 'sqlite.ConnectionPool' !in g.struct_decl_infos {
2249+
g.writeln('typedef struct sqlite__ConnectionPool { int _dummy; } sqlite__ConnectionPool;')
2250+
}
21842251
g.writeln('static inline int sqlite__bind_array(sqlite__Stmt stmt, int** c, Array data) { (void)stmt; (void)c; (void)data; return 0; }')
21852252
g.writeln('#ifndef orm__type_string')
21862253
g.writeln('#define orm__type_string 9')
@@ -2430,7 +2497,7 @@ fn (mut g FlatGen) late_compat_decls() {
24302497
g.writeln('static inline void blowfish__Blowfish__encrypt(blowfish__Blowfish* bf, Array* dst, Array src) { (void)bf; (void)dst; (void)src; }')
24312498
g.writeln('static inline Optional_blowfish__Blowfish blowfish__new_cipher(Array key) { (void)key; return (Optional_blowfish__Blowfish){.ok = true, .value = (blowfish__Blowfish){}}; }')
24322499
g.writeln('static inline Optional_blowfish__Blowfish blowfish__new_salted_cipher(Array key, Array salt) { (void)key; (void)salt; return (Optional_blowfish__Blowfish){.ok = true, .value = (blowfish__Blowfish){}}; }')
2433-
g.writeln('static inline void mbedtls__SSLListener__init_sni(mbedtls__SSLListener* l, _fn_ptr_3 get_cert_callback) { (void)l; (void)get_cert_callback; }')
2500+
g.writeln('static inline void mbedtls__SSLListener__init_sni(mbedtls__SSLListener* l, void* get_cert_callback) { (void)l; (void)get_cert_callback; }')
24342501
g.writeln('static inline orm__Primitive v3_orm_empty_primitive(void) { return (orm__Primitive){}; }')
24352502
g.writeln('static inline orm__Primitive orm__bool_to_primitive(bool b) { (void)b; return v3_orm_empty_primitive(); }')
24362503
g.writeln('static inline orm__Primitive orm__f32_to_primitive(float b) { (void)b; return v3_orm_empty_primitive(); }')

vlib/v3/gen/c/fn.v

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,7 @@ fn (mut g FlatGen) gen_call(id flat.NodeId, node flat.Node) {
718718
g.gen_default_value_for_type(g.call_default_return_type(id))
719719
return
720720
}
721-
if target_name in ['veb.run_at', 'run_at']
722-
|| g.call_has_selector_name(g.a.child(&node, 0), 'run_at') {
721+
if target_name == 'veb.run_at' {
723722
g.gen_default_value_for_type(g.call_default_return_type(id))
724723
return
725724
}
@@ -1474,7 +1473,8 @@ fn (g &FlatGen) is_missing_middleware_use_call(fn_node flat.Node) bool {
14741473
if fn_node.value in g.tc.fn_param_types || fn_node.value in g.tc.fn_ret_types {
14751474
return false
14761475
}
1477-
return true
1476+
receiver := fn_node.value.all_before_last('.')
1477+
return g.struct_has_middleware_receiver(receiver)
14781478
}
14791479
if fn_node.kind != .selector || fn_node.value != 'use' || fn_node.children_count == 0 {
14801480
return false
@@ -1488,7 +1488,27 @@ fn (g &FlatGen) is_missing_middleware_use_call(fn_node flat.Node) bool {
14881488
if method_name in g.tc.fn_param_types || method_name in g.tc.fn_ret_types {
14891489
return false
14901490
}
1491-
return true
1491+
return g.struct_has_middleware_receiver(clean_type.name())
1492+
}
1493+
1494+
fn (g &FlatGen) struct_has_middleware_receiver(type_name string) bool {
1495+
if is_middleware_type_name(type_name) {
1496+
return true
1497+
}
1498+
fields := g.struct_fields_for_type(type_name) or { return false }
1499+
for field in fields {
1500+
embedded_type_name := g.embedded_field_type_name(field)
1501+
if is_middleware_type_name(embedded_type_name) {
1502+
return true
1503+
}
1504+
}
1505+
return false
1506+
}
1507+
1508+
fn is_middleware_type_name(name string) bool {
1509+
short := if name.contains('.') { name.all_after_last('.') } else { name }
1510+
base := if short.contains('[') { short.all_before('[') } else { short }
1511+
return base == 'Middleware'
14921512
}
14931513

14941514
fn (g &FlatGen) call_default_return_type(id flat.NodeId) types.Type {
@@ -1741,16 +1761,13 @@ fn (mut g FlatGen) param_types_for(name string, fallback string) []types.Type {
17411761
if decl_types.len > 0 {
17421762
return decl_types
17431763
}
1764+
if interface_types := g.interface_method_param_types(name) {
1765+
return interface_types
1766+
}
17441767
for candidate in [name, fallback] {
17451768
if candidate in g.tc.fn_param_types {
17461769
return g.tc.fn_param_types[candidate]
17471770
}
1748-
short_method := short_receiver_method_name(candidate)
1749-
if short_method.len > 0 {
1750-
if short_method in g.tc.fn_param_types {
1751-
return g.tc.fn_param_types[short_method]
1752-
}
1753-
}
17541771
if candidate.starts_with('main.') {
17551772
short_name := candidate.all_after_last('.')
17561773
if short_name in g.tc.fn_param_types {
@@ -1761,17 +1778,36 @@ fn (mut g FlatGen) param_types_for(name string, fallback string) []types.Type {
17611778
return []types.Type{}
17621779
}
17631780

1781+
fn (g &FlatGen) interface_method_param_types(name string) ?[]types.Type {
1782+
if !name.contains('.') {
1783+
return none
1784+
}
1785+
iface_name := name.all_before_last('.')
1786+
if iface_name !in g.interfaces {
1787+
return none
1788+
}
1789+
method := name.all_after_last('.')
1790+
decl_key := g.interface_method_signature_key(iface_name, method) or { return none }
1791+
decl_params := g.tc.fn_param_types[decl_key] or { return none }
1792+
mut params := []types.Type{cap: decl_params.len}
1793+
params << types.Type(types.Pointer{
1794+
base_type: types.Type(types.Interface{
1795+
name: iface_name
1796+
})
1797+
})
1798+
if decl_params.len > 1 {
1799+
for i in 1 .. decl_params.len {
1800+
params << decl_params[i]
1801+
}
1802+
}
1803+
return params
1804+
}
1805+
17641806
fn (mut g FlatGen) param_types_from_decl(name string, fallback string) []types.Type {
17651807
if name.contains('.') {
17661808
if ptypes := g.fn_decl_param_types[name] {
17671809
return ptypes
17681810
}
1769-
short_method := short_receiver_method_name(name)
1770-
if short_method.len > 0 {
1771-
if ptypes := g.fn_decl_param_types[short_method] {
1772-
return ptypes
1773-
}
1774-
}
17751811
} else {
17761812
for candidate in [fallback, name] {
17771813
if ptypes := g.fn_decl_param_types[candidate] {
@@ -1782,17 +1818,6 @@ fn (mut g FlatGen) param_types_from_decl(name string, fallback string) []types.T
17821818
return []types.Type{}
17831819
}
17841820

1785-
fn short_receiver_method_name(name string) string {
1786-
if !name.contains('.') {
1787-
return ''
1788-
}
1789-
receiver := name.all_before_last('.')
1790-
if !receiver.contains('.') {
1791-
return ''
1792-
}
1793-
return '${receiver.all_after_last('.')}.${name.all_after_last('.')}'
1794-
}
1795-
17961821
fn (mut g FlatGen) gen_arg_for_expected_type(arg_id flat.NodeId, expected types.Type) {
17971822
arg_node := g.a.nodes[int(arg_id)]
17981823
mut needs_addr := false

vlib/v3/gen/c/for.v

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ fn (mut g FlatGen) gen_for_in(node flat.Node) {
7777
}
7878
clean_container_type := types.unwrap_pointer(container_type)
7979
if clean_container_type is types.Map {
80-
c_key := g.tc.c_type(clean_container_type.key_type)
81-
c_val := g.tc.c_type(clean_container_type.value_type)
80+
c_key := g.value_c_type(clean_container_type.key_type)
81+
c_val := g.value_c_type(clean_container_type.value_type)
8282
container_str := g.expr_to_string(g.a.child(&node, 2))
8383
iter_var := '__mi_${g.tmp_count}'
8484
g.tmp_count++
@@ -96,7 +96,7 @@ fn (mut g FlatGen) gen_for_in(node flat.Node) {
9696
}
9797
g.tc.cur_scope.insert(val_var_, clean_container_type.value_type)
9898
} else if container_type is types.Array {
99-
c_elem := g.tc.c_type(container_type.elem_type)
99+
c_elem := g.value_c_type(container_type.elem_type)
100100
container_str := g.expr_to_string(g.a.child(&node, 2))
101101
g.writeln('for (int ${idx_var} = 0; ${idx_var} < ${container_str}.len; ${idx_var}++) {')
102102
g.indent++
@@ -110,7 +110,7 @@ fn (mut g FlatGen) gen_for_in(node flat.Node) {
110110
g.tc.cur_scope.insert(elem_var, types.Type(types.u8_))
111111
} else if container_type is types.ArrayFixed {
112112
af := container_type
113-
c_elem := g.tc.c_type(af.elem_type)
113+
c_elem := g.value_c_type(af.elem_type)
114114
arr_len := g.fixed_array_len_value(af)
115115
g.writeln('for (int ${idx_var} = 0; ${idx_var} < ${arr_len}; ${idx_var}++) {')
116116
g.indent++

0 commit comments

Comments
 (0)