Przeglądaj źródła

[js] add js.Lib.rethrow (closes #4551)

Dan Korostelev 10 lat temu
rodzic
commit
156b2d76d0
4 zmienionych plików z 37 dodań i 0 usunięć
  1. 1 0
      extra/CHANGES.txt
  2. 16 0
      genjs.ml
  3. 9 0
      std/js/Lib.hx
  4. 11 0
      tests/unit/src/unit/issues/Issue4551.hx

+ 1 - 0
extra/CHANGES.txt

@@ -8,6 +8,7 @@
 	all : allowed passing package dot-paths on command line (#4227)
 	js : introduced new jQuery extern (js.jquery.*) for jQuery 1.11.3 / 2.1.4 (#4377)
 	js : introduced new SWFObject extern (js.swfobject.SWFObject) for SWFObject 2.3.20130521 (#4451)
+	js : added js.Lib.rethrow (#4551)
 
 	Bugfixes:
 

+ 16 - 0
genjs.ml

@@ -434,6 +434,8 @@ let rec gen_call ctx e el in_value =
 		else match eelse with
 			| [] -> ()
 			| e :: _ -> gen_value ctx e)
+	| TLocal { v_name = "__rethrow__" }, [] ->
+		spr ctx "throw $hx_rethrow";
 	| TLocal { v_name = "__resources__" }, [] ->
 		spr ctx "[";
 		concat ctx "," (fun (name,data) ->
@@ -673,6 +675,20 @@ and gen_expr ctx e =
 			print ctx "%s.lastException = %s" (ctx.type_accessor (TClassDecl { null_class with cl_path = ["haxe"],"CallStack" })) vname
 		end;
 
+		if (has_feature ctx "js.Lib.rethrow") then begin
+			let has_rethrow (_,e) =
+				let rec loop e = match e.eexpr with 
+				| TCall({eexpr = TLocal {v_name = "__rethrow__"}}, []) -> raise Exit
+				| _ -> Type.iter loop e
+				in
+				try (loop e; false) with Exit -> true
+			in
+			if List.exists has_rethrow catchs then begin
+				newline ctx;
+				print ctx "var $hx_rethrow = %s" vname;
+			end
+		end;
+
 		if (has_feature ctx "js.Boot.HaxeError") then begin
 			newline ctx;
 			print ctx "if (%s instanceof %s) %s = %s.val" vname (ctx.type_accessor (TClassDecl { null_class with cl_path = ["js";"_Boot"],"HaxeError" })) vname vname;

+ 9 - 0
std/js/Lib.hx

@@ -100,4 +100,13 @@ class Lib {
 	@:extern static inline function get_global() : Dynamic {
 		return untyped __define_feature__("js.Lib.global", __js__("$global")); // $global is generated by the compiler
 	}
+
+	/**
+		Re-throw last cathed exception, preserving original stack information.
+
+		Calling this only makes sense inside a catch statement.
+	**/
+	@:extern public static inline function rethrow() {
+		untyped __define_feature__("js.Lib.rethrow", __rethrow__());
+	}
 }

+ 11 - 0
tests/unit/src/unit/issues/Issue4551.hx

@@ -0,0 +1,11 @@
+package unit.issues;
+
+class Issue4551 extends Test {
+    function test() {
+        try {
+            try throw "yay!" catch (e:Dynamic) js.Lib.rethrow();
+        } catch (e:Dynamic) {
+            eq(e, "yay!");
+        }
+    }
+}