Parcourir la source

[cs] fixed cs.Lib.rethrow (closes #9738)

Aleksandr Kuzmenko il y a 5 ans
Parent
commit
8a67dc64e7
4 fichiers modifiés avec 46 ajouts et 17 suppressions
  1. 1 0
      extra/CHANGES.txt
  2. 10 3
      src/context/common.ml
  3. 17 14
      src/filters/exceptions.ml
  4. 18 0
      tests/unit/src/unit/issues/Issue9738.hx

+ 1 - 0
extra/CHANGES.txt

@@ -9,6 +9,7 @@
 	flash : fixed `VerifyError` exception when `Void` end up as an argument type after inlining (#9678)
 	php : fixed runtime error "cannot use temporary expression in write context" for call arguments passed by reference
 	php : support @:native("") for extern classes (#6448)
+	cs : fixed `cs.Lib.rethrow` (#9738)
 	python : support @:native("") for extern classes (#6448)
 	nullsafety: fixed `@:nullSafety(Off)` in closures inside of constructors (#9643)
 	nullsafety: fixed "Type not found NullSafetyMode_Impl_" (#9483)

+ 10 - 3
src/context/common.ml

@@ -92,6 +92,11 @@ type exceptions_config = {
 		For example `throw 123` is compiled to `throw (cast Exception.thrown(123):ec_base_throw)`
 	*)
 	ec_base_throw : path;
+	(*
+		Checks if throwing this expression is a special case for current target
+		and should not be modified.
+	*)
+	ec_special_throw : texpr -> bool;
 }
 
 type var_scope =
@@ -389,6 +394,7 @@ let default_config =
 			ec_native_catches = [];
 			ec_wildcard_catch = (["StdTypes"],"Dynamic");
 			ec_base_throw = (["StdTypes"],"Dynamic");
+			ec_special_throw = fun _ -> false;
 		};
 		pf_scoping = {
 			vs_scope = BlockScope;
@@ -469,7 +475,7 @@ let get_config com =
 			default_config with
 			pf_static = false;
 			pf_uses_utf16 = false;
-			pf_exceptions = {
+			pf_exceptions = { default_config.pf_exceptions with
 				ec_native_throws = [
 					["php"],"Throwable";
 					["haxe"],"Exception";
@@ -516,6 +522,7 @@ let get_config com =
 				];
 				ec_wildcard_catch = (["cs";"system"],"Exception");
 				ec_base_throw = (["cs";"system"],"Exception");
+				ec_special_throw = fun e -> e.eexpr = TIdent "__rethrow__"
 			};
 			pf_scoping = {
 				vs_scope = FunctionScope;
@@ -530,7 +537,7 @@ let get_config com =
 			pf_overload = true;
 			pf_supports_threads = true;
 			pf_this_before_super = false;
-			pf_exceptions = {
+			pf_exceptions = { default_config.pf_exceptions with
 				ec_native_throws = [
 					["java";"lang"],"RuntimeException";
 					["haxe"],"Exception";
@@ -557,7 +564,7 @@ let get_config com =
 			pf_static = false;
 			pf_capture_policy = CPLoopVars;
 			pf_uses_utf16 = false;
-			pf_exceptions = {
+			pf_exceptions = { default_config.pf_exceptions with
 				ec_native_throws = [
 					["python";"Exceptions"],"BaseException";
 				];

+ 17 - 14
src/filters/exceptions.ml

@@ -150,20 +150,23 @@ let rec contains_throw_or_try e =
 	to be thrown.
 *)
 let requires_wrapped_throw cfg e =
-	(*
-		Check if `e` is of `haxe.Exception` type directly (not a descendant),
-		but not a `new haxe.Exception(...)` expression.
-		In this case we delegate the decision to `haxe.Exception.thrown(e)`.
-		Because it could happen to be a wrapper for a wildcard catch.
-	*)
-	let is_stored_haxe_exception() =
-		is_haxe_exception ~check_parent:false e.etype
-		&& match e.eexpr with
-			| TNew(_,_,_) -> false
-			| _ -> true
-	in
-	is_stored_haxe_exception()
-	|| (not (is_native_throw cfg e.etype) && not (is_haxe_exception e.etype))
+	if cfg.ec_special_throw e then
+		false
+	else
+		(*
+			Check if `e` is of `haxe.Exception` type directly (not a descendant),
+			but not a `new haxe.Exception(...)` expression.
+			In this case we delegate the decision to `haxe.Exception.thrown(e)`.
+			Because it could happen to be a wrapper for a wildcard catch.
+		*)
+		let is_stored_haxe_exception() =
+			is_haxe_exception ~check_parent:false e.etype
+			&& match e.eexpr with
+				| TNew(_,_,_) -> false
+				| _ -> true
+		in
+		is_stored_haxe_exception()
+		|| (not (is_native_throw cfg e.etype) && not (is_haxe_exception e.etype))
 
 (**
 	Generate a throw of a native exception.

+ 18 - 0
tests/unit/src/unit/issues/Issue9738.hx

@@ -0,0 +1,18 @@
+package unit.issues;
+
+class Issue9738 extends Test {
+#if cs
+	function test() {
+		try {
+			try {
+				throw new haxe.Exception("Hello");
+			} catch (e) {
+				cs.Lib.rethrow(e);
+			}
+			assert();
+		} catch(e) {
+			noAssert();
+		}
+	}
+#end
+}