From 7fe62a8b3ea1780252bf2b3830d372b88f116c6f Mon Sep 17 00:00:00 2001 From: playX Date: Sat, 15 Jan 2022 10:55:03 +0300 Subject: [PATCH] js,os: fix `return` in `or` blocks; Properly get path_delimiter and path_separator in JS (#13179) --- vlib/os/os.js.v | 26 ++++++++++++++++---- vlib/v/gen/js/fn.v | 9 +++++++ vlib/v/gen/js/js.v | 59 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/vlib/os/os.js.v b/vlib/os/os.js.v index fff2f90a7a..916083c21e 100644 --- a/vlib/os/os.js.v +++ b/vlib/os/os.js.v @@ -1,17 +1,33 @@ module os $if js_node { - #const $fs = require('fs'); - #const $path = require('path'); - #const tty = require('tty') + #var $fs = require('fs'); + #var $path = require('path'); + #var tty = require('tty') } pub const ( - path_delimiter = '/' - path_separator = '/' + path_delimiter = get_path_delimiter() + path_separator = get_path_separator() args = []string{} ) +fn get_path_delimiter() string { + delimiter := ':' + $if js_node { + #delimiter.str = $path.delimiter + } + return delimiter +} + +fn get_path_separator() string { + separator := '/' + $if js_node { + #separator.str = $path.sep + } + return separator +} + fn init() { $if js_node { #$process.argv.forEach(function(val,index) { os__args.arr[index] = new string(val); }) diff --git a/vlib/v/gen/js/fn.v b/vlib/v/gen/js/fn.v index 4971858e3c..0cb6748691 100644 --- a/vlib/v/gen/js/fn.v +++ b/vlib/v/gen/js/fn.v @@ -692,7 +692,16 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl, typ FnGenType) { } } } + g.inc_indent() + g.writeln('try {') + g.inc_indent() g.stmts(it.stmts) + g.dec_indent() + g.writeln('} catch (e) { ') + g.writeln('\tif (e instanceof ReturnException) { return e.val; } ') + g.writeln('\tthrow e;') + g.writeln('}') + g.dec_indent() g.writeln('}') if is_main { diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 9109910bd2..d62be9c800 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -482,6 +482,7 @@ pub fn (mut g JsGen) init() { g.definitions.writeln('function BreakException() {}') g.definitions.writeln('function ContinueException() {}') + g.definitions.writeln('function ReturnException(val) { this.val = val; }') } pub fn (g JsGen) hashes() string { @@ -1624,13 +1625,18 @@ fn (mut g JsGen) gen_for_c_stmt(it ast.ForCStmt) { g.stmt_no_semi(it.inc) } g.writeln(') {') + g.inc_indent() g.writeln('try { ') + g.inc_indent() g.stmts(it.stmts) + g.dec_indent() g.writeln('} catch (e) {') g.writeln(' if (e instanceof BreakException) { break; }') g.writeln(' else if (e instanceof ContinueException) { continue; }') g.writeln(' else { throw e; } }') + g.dec_indent() g.writeln('}') + g.inside_loop = false } @@ -1648,12 +1654,16 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) { g.expr(it.high) g.writeln('; $i = new int($i + 1)) {') g.inside_loop = false + g.inc_indent() g.writeln('try { ') + g.inc_indent() g.stmts(it.stmts) + g.dec_indent() g.writeln('} catch (e) {') g.writeln(' if (e instanceof BreakException) { break; }') g.writeln(' else if (e instanceof ContinueException) { continue; }') g.writeln(' else { throw e; } }') + g.dec_indent() g.writeln('}') } else if it.kind in [.array, .string] || it.cond_type.has_flag(.variadic) { // `for num in nums {` @@ -1698,12 +1708,16 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) { } } g.writeln(') {') + g.inc_indent() g.writeln('try { ') + g.inc_indent() g.stmts(it.stmts) + g.dec_indent() g.writeln('} catch (e) {') g.writeln(' if (e instanceof BreakException) { break; }') g.writeln(' else if (e instanceof ContinueException) { continue; }') g.writeln(' else { throw e; } }') + g.dec_indent() g.writeln('}') } else if it.kind == .map { // `for key, val in map[string]int {` @@ -1748,8 +1762,11 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) { g.inc_indent() g.writeln('let $val = ${tmp}.map[$tmp2];') g.writeln('let $key = $tmp2;') + g.writeln('try { ') + g.inc_indent() g.stmts(it.stmts) + g.dec_indent() g.writeln('} catch (e) {') g.writeln(' if (e instanceof BreakException) { break; }') g.writeln(' else if (e instanceof ContinueException) { continue; }') @@ -1769,12 +1786,16 @@ fn (mut g JsGen) gen_for_stmt(it ast.ForStmt) { g.expr(it.cond) } g.writeln(') {') + g.inc_indent() g.writeln('try { ') + g.inc_indent() g.stmts(it.stmts) + g.dec_indent() g.writeln('} catch (e) {') g.writeln(' if (e instanceof BreakException) { break; }') g.writeln(' else if (e instanceof ContinueException) { continue; }') g.writeln(' else { throw e; } }') + g.dec_indent() g.writeln('}') } @@ -1823,9 +1844,17 @@ fn (mut g JsGen) gen_return_stmt(it ast.Return) { fn_return_is_optional := g.fn_decl.return_type.has_flag(.optional) if node.exprs.len == 0 { if fn_return_is_optional { - g.writeln('return {state: new int(0)}') + if g.inside_or { + g.writeln('throw new ReturnException({state: new int(0)});') + } else { + g.writeln('return {state: new int(0)}') + } } else { - g.writeln('return;') + if g.inside_or { + g.writeln('throw new ReturnException(undefined);') + } else { + g.writeln('return;') + } } return } @@ -1841,8 +1870,15 @@ fn (mut g JsGen) gen_return_stmt(it ast.Return) { g.writeln('return $test_error_var;') return } - g.write('return ') + if !g.inside_or { + g.write('return ') + } else { + g.write('throw new ReturnException(') + } g.gen_optional_error(it.exprs[0]) + if g.inside_or { + g.writeln(')') + } g.writeln(';') return } @@ -1860,15 +1896,26 @@ fn (mut g JsGen) gen_return_stmt(it ast.Return) { g.gen_array_init_values(it.exprs) } g.writeln('') - g.write('return $tmp;') + if g.inside_or { + g.write('throw new ReturnException($tmp);') + } else { + g.write('return $tmp;') + } return } - g.write('return ') + if !g.inside_or { + g.write('return ') + } else { + g.write('throw new ReturnException(') + } if it.exprs.len == 1 { g.expr(it.exprs[0]) } else { // Multi return g.gen_array_init_values(it.exprs) } + if g.inside_or { + g.writeln(')') + } g.writeln(';') } @@ -2808,11 +2855,13 @@ fn (mut g JsGen) gen_if_expr(node ast.IfExpr) { } } } + g.inc_indent() if needs_tmp_var { g.stmts_with_tmp_var(branch.stmts, tmp) } else { g.stmts(branch.stmts) } + g.dec_indent() } if node.branches.len > 0 { g.writeln('}')