js: fix -stats compilation of tests, proper alias codegen (#11327)
parent
25bf68e2f1
commit
118c5fdcd8
|
@ -243,3 +243,11 @@ pub fn (mut a array) delete_last() {
|
|||
[unsafe]
|
||||
pub fn (a array) free() {
|
||||
}
|
||||
|
||||
// todo: once (a []byte) will work rewrite this
|
||||
pub fn (a array) bytestr() string {
|
||||
res := ''
|
||||
#a.arr.forEach((item) => res.str += String.fromCharCode(+item))
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -184,8 +184,9 @@ pub fn (mut g JsGen) typ(t ast.Type) string {
|
|||
styp = 'union_sym_type'
|
||||
}
|
||||
.alias {
|
||||
// TODO: Implement aliases
|
||||
styp = 'alias'
|
||||
fsym := g.table.get_final_type_symbol(t)
|
||||
name := g.js_name(fsym.name)
|
||||
styp += '$name'
|
||||
}
|
||||
.enum_ {
|
||||
// NB: We could declare them as TypeScript enums but TS doesn't like
|
||||
|
@ -278,7 +279,7 @@ fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeConfig) {
|
|||
}
|
||||
for method in g.method_fn_decls[c.typ_name] {
|
||||
g.inside_def_typ_decl = true
|
||||
g.gen_method_decl(method)
|
||||
g.gen_method_decl(method, .struct_method)
|
||||
g.inside_def_typ_decl = false
|
||||
g.writeln(',')
|
||||
}
|
||||
|
|
|
@ -284,24 +284,25 @@ pub fn (mut g JsGen) gen_js_main_for_tests() {
|
|||
|
||||
g.writeln('')
|
||||
g.writeln('globalThis.VTEST=1')
|
||||
// g.writeln('let bt = start_testing($all_tfuncs.len, "$g.pref.path")')
|
||||
|
||||
if g.pref.is_stats {
|
||||
g.writeln('let bt = start_testing($all_tfuncs.len, "$g.pref.path")')
|
||||
}
|
||||
for tname in all_tfuncs {
|
||||
tcname := g.js_name(tname)
|
||||
|
||||
if g.pref.is_stats {
|
||||
// g.writeln('bt.testing_step_start("$tcname")')
|
||||
g.writeln('bt.testing_step_start("$tcname")')
|
||||
}
|
||||
|
||||
g.writeln('try { ${tcname}(); } catch (_e) {} ')
|
||||
if g.pref.is_stats {
|
||||
// g.writeln('bt.testing_step_end();')
|
||||
g.writeln('bt.testing_step_end();')
|
||||
}
|
||||
}
|
||||
|
||||
g.writeln('')
|
||||
if g.pref.is_stats {
|
||||
// g.writeln('bt.end_testing();')
|
||||
g.writeln('bt.end_testing();')
|
||||
}
|
||||
g.dec_indent()
|
||||
g.writeln('})();')
|
||||
|
@ -380,7 +381,7 @@ pub fn (mut g JsGen) find_class_methods(stmts []ast.Stmt) {
|
|||
|
||||
pub fn (mut g JsGen) init() {
|
||||
g.definitions.writeln('// Generated by the V compiler\n')
|
||||
g.definitions.writeln('"use strict";')
|
||||
// g.definitions.writeln('"use strict";')
|
||||
g.definitions.writeln('')
|
||||
g.definitions.writeln('var \$global = (new Function("return this"))();')
|
||||
g.definitions.writeln('function \$ref(value) { if (value instanceof \$ref) { return value; } this.val = value; } ')
|
||||
|
@ -699,9 +700,7 @@ fn (mut g JsGen) stmt_no_semi(node ast.Stmt) {
|
|||
g.write_v_source_line_info(node.pos)
|
||||
g.gen_struct_decl(node)
|
||||
}
|
||||
ast.TypeDecl {
|
||||
// skip JS has no typedecl
|
||||
}
|
||||
ast.TypeDecl {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1319,8 +1318,25 @@ fn (mut g JsGen) gen_expr_stmt_no_semi(it ast.ExprStmt) {
|
|||
g.expr(it.expr)
|
||||
}
|
||||
|
||||
enum FnGenType {
|
||||
function
|
||||
struct_method
|
||||
alias_method
|
||||
}
|
||||
|
||||
fn (g &JsGen) fn_gen_type(it &ast.FnDecl) FnGenType {
|
||||
if it.is_method && g.table.get_type_symbol(it.params[0].typ).kind == .alias {
|
||||
return .alias_method
|
||||
} else if it.is_method || it.no_body {
|
||||
return .struct_method
|
||||
} else {
|
||||
return .function
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_fn_decl(it ast.FnDecl) {
|
||||
if it.no_body || it.is_method {
|
||||
res := g.fn_gen_type(it)
|
||||
if res == .struct_method {
|
||||
// Struct methods are handled by class generation code.
|
||||
return
|
||||
}
|
||||
|
@ -1328,7 +1344,7 @@ fn (mut g JsGen) gen_fn_decl(it ast.FnDecl) {
|
|||
g.builtin_fns << it.name
|
||||
}
|
||||
cur_fn_decl := g.fn_decl
|
||||
g.gen_method_decl(it)
|
||||
g.gen_method_decl(it, res)
|
||||
g.fn_decl = cur_fn_decl
|
||||
}
|
||||
|
||||
|
@ -1345,10 +1361,18 @@ fn fn_has_go(node ast.FnDecl) bool {
|
|||
return has_go
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
|
||||
fn (mut g JsGen) gen_method_decl(it ast.FnDecl, typ FnGenType) {
|
||||
unsafe {
|
||||
g.fn_decl = &it
|
||||
}
|
||||
if typ == .alias_method {
|
||||
sym := g.table.get_final_type_symbol(it.params[0].typ.set_nr_muls(0))
|
||||
name := g.js_name(sym.name)
|
||||
if name in js.v_types {
|
||||
g.writeln('builtin.')
|
||||
}
|
||||
g.writeln('${name}.prototype.$it.name = function ')
|
||||
}
|
||||
has_go := fn_has_go(it)
|
||||
is_main := it.name == 'main.main'
|
||||
g.gen_attrs(it.attrs)
|
||||
|
@ -1422,7 +1446,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
|
|||
if is_main {
|
||||
g.write(')();')
|
||||
}
|
||||
if !it.is_anon && !it.is_method {
|
||||
if typ == .struct_method || typ == .alias_method {
|
||||
g.writeln('\n')
|
||||
}
|
||||
g.fn_decl = voidptr(0)
|
||||
|
@ -1661,8 +1685,9 @@ fn (mut g JsGen) gen_struct_decl(node ast.StructDecl) {
|
|||
g.write('$field.name: ${g.to_js_typ_val(field.typ)}')
|
||||
g.writeln(',')
|
||||
}
|
||||
|
||||
for cfn in fns {
|
||||
g.gen_method_decl(cfn)
|
||||
g.gen_method_decl(cfn, .struct_method)
|
||||
g.writeln(',')
|
||||
}
|
||||
// gen toString method
|
||||
|
@ -2435,8 +2460,8 @@ fn (mut g JsGen) gen_deref_ptr(ty ast.Type) {
|
|||
}
|
||||
|
||||
fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
||||
l_sym := g.table.get_type_symbol(it.left_type)
|
||||
r_sym := g.table.get_type_symbol(it.right_type)
|
||||
l_sym := g.table.get_final_type_symbol(it.left_type)
|
||||
r_sym := g.table.get_final_type_symbol(it.right_type)
|
||||
|
||||
is_not := it.op in [.not_in, .not_is, .ne]
|
||||
if is_not {
|
||||
|
@ -2444,10 +2469,15 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
|||
}
|
||||
is_arithmetic := it.op in [token.Kind.plus, .minus, .mul, .div, .mod, .right_shift, .left_shift,
|
||||
.amp, .pipe, .xor]
|
||||
|
||||
if is_arithmetic && ((l_sym.kind == .i64 || l_sym.kind == .u64)
|
||||
|| (r_sym.kind == .i64 || r_sym.kind == .u64)) {
|
||||
// if left or right is i64 or u64 we convert them to bigint to perform operation.
|
||||
greater_typ := g.greater_typ(it.left_type, it.right_type)
|
||||
greater_typ := if l_sym.kind == .i64 || l_sym.kind == .u64 {
|
||||
it.left_type
|
||||
} else {
|
||||
it.right_type
|
||||
} // g.greater_typ(it.left_type, it.right_type)
|
||||
g.write('new ')
|
||||
if g.ns.name != 'builtin' {
|
||||
g.write('builtin.')
|
||||
|
@ -2894,7 +2924,7 @@ 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))
|
||||
// Skip cast if type is the same as the parrent caster
|
||||
tsym := g.table.get_type_symbol(it.typ)
|
||||
tsym := g.table.get_final_type_symbol(it.typ)
|
||||
if it.expr is ast.IntegerLiteral && (tsym.kind == .i64 || tsym.kind == .u64) {
|
||||
g.write('new ')
|
||||
if g.ns.name != 'builtin' {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
module stats_import
|
||||
|
||||
pub fn get_stats_ok() int {
|
||||
res := 0
|
||||
#res.val = +g_test_oks
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn get_stats_fail() int {
|
||||
res := 0
|
||||
#res.val = +g_test_fails
|
||||
|
||||
return res
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
module main
|
||||
|
||||
import stats_import
|
||||
import benchmark
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
// / This file will get compiled as a part of the same module,
|
||||
// / in which a given _test.v file is, when v is given -stats argument
|
||||
|
@ -7,10 +9,12 @@ module main
|
|||
// / main function, so that customizing the look & feel of the results
|
||||
// / is easy, since it is done in normal V code, instead of in embedded C ...
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
|
||||
const inner_indent = ' '
|
||||
|
||||
struct BenchedTests {
|
||||
mut:
|
||||
bench benchmark.Benchmark
|
||||
oks int
|
||||
fails int
|
||||
test_suit_file string
|
||||
|
@ -21,7 +25,10 @@ mut:
|
|||
// ///////////////////////////////////////////////////////////////////
|
||||
// Called at the start of the test program produced by `v -stats file_test.v`
|
||||
pub fn start_testing(total_number_of_tests int, vfilename string) BenchedTests {
|
||||
mut benched_tests_res := BenchedTests{}
|
||||
mut benched_tests_res := BenchedTests{
|
||||
bench: benchmark.new_benchmark()
|
||||
}
|
||||
benched_tests_res.bench.set_total_expected_steps(total_number_of_tests)
|
||||
benched_tests_res.total_number_of_tests = total_number_of_tests
|
||||
benched_tests_res.test_suit_file = vfilename
|
||||
println('running tests in: $benched_tests_res.test_suit_file')
|
||||
|
@ -31,14 +38,15 @@ pub fn start_testing(total_number_of_tests int, vfilename string) BenchedTests {
|
|||
// Called before each test_ function, defined in file_test.v
|
||||
fn (mut b BenchedTests) testing_step_start(stepfunc string) {
|
||||
b.step_func_name = stepfunc.replace('main.', '').replace('__', '.')
|
||||
b.oks = C.g_test_oks
|
||||
b.fails = C.g_test_fails
|
||||
b.oks = stats_import.get_stats_ok()
|
||||
b.fails = stats_import.get_stats_fail()
|
||||
b.bench.step()
|
||||
}
|
||||
|
||||
// Called after each test_ function, defined in file_test.v
|
||||
fn (mut b BenchedTests) testing_step_end() {
|
||||
ok_diff := C.g_test_oks - b.oks
|
||||
fail_diff := C.g_test_fails - b.fails
|
||||
ok_diff := stats_import.get_stats_ok() - b.oks
|
||||
fail_diff := stats_import.get_stats_fail() - b.fails
|
||||
// ////////////////////////////////////////////////////////////////
|
||||
if ok_diff == 0 && fail_diff == 0 {
|
||||
println(inner_indent + ' NO asserts | ' + b.fn_name())
|
||||
|
@ -46,17 +54,19 @@ fn (mut b BenchedTests) testing_step_end() {
|
|||
}
|
||||
// ////////////////////////////////////////////////////////////////
|
||||
if ok_diff > 0 {
|
||||
// b.bench.ok_many(ok_diff)
|
||||
b.bench.ok_many(ok_diff)
|
||||
}
|
||||
if fail_diff > 0 {
|
||||
// b.bench.fail_many(fail_diff)
|
||||
b.bench.fail_many(fail_diff)
|
||||
}
|
||||
// ////////////////////////////////////////////////////////////////
|
||||
if ok_diff > 0 && fail_diff == 0 {
|
||||
println(inner_indent + b.bench.step_message_ok(nasserts(ok_diff)) + b.fn_name())
|
||||
println(inner_indent + nasserts(ok_diff) + b.fn_name())
|
||||
return
|
||||
}
|
||||
if fail_diff > 0 {
|
||||
println(inner_indent + b.bench.step_message_fail(nasserts(fail_diff)) + b.fn_name())
|
||||
println(inner_indent + nasserts(fail_diff) + b.fn_name())
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue