Browse Source

[eval] populate all haxe.macro.Error fields (closes #9600)

Aleksandr Kuzmenko 5 years ago
parent
commit
3ef20749a7

+ 2 - 0
src/macro/eval/evalHash.ml

@@ -44,6 +44,8 @@ let key_file = hash "file"
 let key_len = hash "len"
 let key_len = hash "len"
 let key_message = hash "message"
 let key_message = hash "message"
 let key_exception_message = hash "__exceptionMessage"
 let key_exception_message = hash "__exceptionMessage"
+let key_native_exception = hash "__nativeException"
+let key_native_stack = hash "__nativeStack"
 let key_Array = hash "Array"
 let key_Array = hash "Array"
 let key_eval_Vector = hash "eval.Vector"
 let key_eval_Vector = hash "eval.Vector"
 let key_String = hash "String"
 let key_String = hash "String"

+ 10 - 1
src/macro/eval/evalMain.ml

@@ -381,8 +381,17 @@ let compiler_error msg pos =
 	let vi = encode_instance key_haxe_macro_Error in
 	let vi = encode_instance key_haxe_macro_Error in
 	match vi with
 	match vi with
 	| VInstance i ->
 	| VInstance i ->
-		set_instance_field i key_exception_message (EvalString.create_unknown msg);
+		let msg = EvalString.create_unknown msg in
+		set_instance_field i key_exception_message msg;
 		set_instance_field i key_pos (encode_pos pos);
 		set_instance_field i key_pos (encode_pos pos);
+		set_instance_field i key_native_exception msg;
+		let ctx = get_ctx() in
+		let eval = get_eval ctx in
+		(match eval.env with
+		| Some _ ->
+			let stack = EvalStdLib.StdNativeStackTrace.make_stack_value (call_stack eval) in
+			set_instance_field i key_native_stack stack;
+		| None -> ());
 		exc vi
 		exc vi
 	| _ ->
 	| _ ->
 		die "" __LOC__
 		die "" __LOC__

+ 4 - 1
src/macro/eval/evalStdLib.ml

@@ -566,6 +566,9 @@ module StdNativeStackTrace = struct
 		) envs;
 		) envs;
 		encode_array (DynArray.to_list l)
 		encode_array (DynArray.to_list l)
 
 
+	let make_stack_value envs =
+		make_stack (List.map (fun env -> {pfile = rev_hash env.env_info.pfile;pmin = env.env_leave_pmin; pmax = env.env_leave_pmax},env.env_info.kind) envs)
+
 	let getCallStack = vfun0 (fun () ->
 	let getCallStack = vfun0 (fun () ->
 		let ctx = get_ctx() in
 		let ctx = get_ctx() in
 		let envs = call_stack (get_eval ctx) in
 		let envs = call_stack (get_eval ctx) in
@@ -573,7 +576,7 @@ module StdNativeStackTrace = struct
 			| _ :: _ :: envs -> envs (* Skip calls to callStack() and getCallStack() *)
 			| _ :: _ :: envs -> envs (* Skip calls to callStack() and getCallStack() *)
 			| _ -> envs
 			| _ -> envs
 		in
 		in
-		make_stack (List.map (fun env -> {pfile = rev_hash env.env_info.pfile;pmin = env.env_leave_pmin; pmax = env.env_leave_pmax},env.env_info.kind) envs)
+		make_stack_value  envs
 	)
 	)
 
 
 	let getExceptionStack = vfun0 (fun () ->
 	let getExceptionStack = vfun0 (fun () ->

+ 8 - 0
tests/unit/src/unit/issues/Issue9600.hx

@@ -0,0 +1,8 @@
+package unit.issues;
+
+class Issue9600 extends Test {
+	function test() {
+		var error = unit.issues.misc.Issue9600Macro.contextTypeofError();
+		eq('{ b : Bool, a : Int } has extra field b', error);
+	}
+}

+ 12 - 0
tests/unit/src/unit/issues/misc/Issue9600Macro.hx

@@ -0,0 +1,12 @@
+package unit.issues.misc;
+
+class Issue9600Macro {
+	public static macro function contextTypeofError() {
+		try {
+			haxe.macro.Context.typeof(macro ({a: 42, b: true} :{a:Int}));
+			return macro "exception expected";
+		} catch (e:Dynamic) {
+			return macro $v{Std.string(e)};
+		}
+	}
+}