Browse Source

[eval] Don't choke on env_parent = None (#11679)

* [eval] Don't choke on env_parent = None

Note that something wrong might be happening somewhere for this to happen...

* Revert "[eval] Don't choke on env_parent = None"

This reverts commit dbba36c029929ee23a70ad31d3e60c0536395168.

* [eval] Use a different env_kind for build macros

* Add test

* No color

* Simplify repro

* Improve test again..

* Pretty~

* [eval] reword macro calls in eval debugger stack

* [macro] add stack

* [tests] update test (added macro stack to 9389)

* Remove TODO
Rudy Ges 1 year ago
parent
commit
1a66e9bb31

+ 3 - 0
src/macro/eval/evalContext.ml

@@ -44,6 +44,7 @@ type scope = {
 type env_kind =
 type env_kind =
 	| EKLocalFunction of int
 	| EKLocalFunction of int
 	| EKMethod of int * int
 	| EKMethod of int * int
+	| EKMacro of int * int
 	| EKEntrypoint
 	| EKEntrypoint
 
 
 (* Compile-time information for environments. This information is static for all
 (* Compile-time information for environments. This information is static for all
@@ -332,6 +333,8 @@ let kind_name eval kind =
 	let rec loop kind env = match kind with
 	let rec loop kind env = match kind with
 		| EKMethod(i1,i2) ->
 		| EKMethod(i1,i2) ->
 			Printf.sprintf "%s.%s" (rev_hash i1) (rev_hash i2)
 			Printf.sprintf "%s.%s" (rev_hash i1) (rev_hash i2)
+		| EKMacro(i1,i2) ->
+			Printf.sprintf "Macro call: %s.%s" (rev_hash i1) (rev_hash i2)
 		| EKLocalFunction i ->
 		| EKLocalFunction i ->
 			begin match env with
 			begin match env with
 			| None -> Printf.sprintf "localFunction%i" i
 			| None -> Printf.sprintf "localFunction%i" i

+ 1 - 0
src/macro/eval/evalDebugMisc.ml

@@ -146,6 +146,7 @@ let resolve_ident ctx env s =
 					| Some env -> loop env
 					| Some env -> loop env
 				end
 				end
 			| EKMethod _ -> env
 			| EKMethod _ -> env
+			| EKMacro _ -> env
 			| EKEntrypoint ->
 			| EKEntrypoint ->
 				(* This can happen due to threads. Have to check what we can do here... *)
 				(* This can happen due to threads. Have to check what we can do here... *)
 				raise Not_found
 				raise Not_found

+ 1 - 1
src/macro/eval/evalDebugSocket.ml

@@ -171,7 +171,7 @@ let output_call_stack ctx eval p =
 		let line1,col1,line2,col2 = Lexer.get_pos_coords p in
 		let line1,col1,line2,col2 = Lexer.get_pos_coords p in
 		let path = Path.get_real_path p.pfile in
 		let path = Path.get_real_path p.pfile in
 		let artificial,name = match kind with
 		let artificial,name = match kind with
-			| EKMethod _ | EKLocalFunction _ -> false,kind_name eval kind
+			| EKMethod _ | EKLocalFunction _ | EKMacro _ -> false,kind_name eval kind
 			| EKEntrypoint -> true,p.pfile
 			| EKEntrypoint -> true,p.pfile
 		in
 		in
 		let source = if Sys.file_exists path then JString path else JNull in
 		let source = if Sys.file_exists path then JString path else JNull in

+ 15 - 8
src/macro/eval/evalExceptions.ml

@@ -122,6 +122,17 @@ let catch_exceptions ctx ?(final=(fun() -> ())) f p =
 		eval.caught_exception <- vnull;
 		eval.caught_exception <- vnull;
 		Option.may (build_exception_stack ctx) env;
 		Option.may (build_exception_stack ctx) env;
 		eval.env <- env;
 		eval.env <- env;
+
+		(* Careful: We have to get the message before resetting the context because toString() might access it. *)
+		let get_stack ctx =
+			let stack = match eval_stack with
+				| [] -> []
+				| l when p' = null_pos -> l (* If the exception position is null_pos, we're "probably" in a built-in function. *)
+				| _ :: l -> l (* Otherwise, ignore topmost frame position. *)
+			in
+			get_exc_error_stack ctx stack
+		in
+
 		if is v key_haxe_macro_Error then begin
 		if is v key_haxe_macro_Error then begin
 			let v1 = field v key_exception_message in
 			let v1 = field v key_exception_message in
 			let v2 = field v key_pos in
 			let v2 = field v key_pos in
@@ -139,7 +150,9 @@ let catch_exceptions ctx ?(final=(fun() -> ())) f p =
 							end else
 							end else
 								Error.raise_typing_error (Printf.sprintf "Unexpected value where haxe.macro.Error was expected: %s" (s_value 0 v).sstring) null_pos
 								Error.raise_typing_error (Printf.sprintf "Unexpected value where haxe.macro.Error was expected: %s" (s_value 0 v).sstring) null_pos
 						) (EvalArray.to_list sub)
 						) (EvalArray.to_list sub)
-				| _ -> []
+				| _ ->
+					let stack = get_stack ctx in
+					List.map (fun p -> (Error.Custom "Called from here", p)) (List.rev stack)
 			in
 			in
 			reset_ctx();
 			reset_ctx();
 			final();
 			final();
@@ -168,13 +181,7 @@ let catch_exceptions ctx ?(final=(fun() -> ())) f p =
 				| v ->
 				| v ->
 					Error.raise_typing_error (Printf.sprintf "Invalid exception value where string was expected: %s" (s_value 0 v).sstring) null_pos
 					Error.raise_typing_error (Printf.sprintf "Invalid exception value where string was expected: %s" (s_value 0 v).sstring) null_pos
 		end else begin
 		end else begin
-			(* Careful: We have to get the message before resetting the context because toString() might access it. *)
-			let stack = match eval_stack with
-				| [] -> []
-				| l when p' = null_pos -> l (* If the exception position is null_pos, we're "probably" in a built-in function. *)
-				| _ :: l -> l (* Otherwise, ignore topmost frame position. *)
-			in
-			let stack = get_exc_error_stack ctx stack in
+			let stack = get_stack ctx in
 			reset_ctx();
 			reset_ctx();
 			final();
 			final();
 			let p = if p' = null_pos then p else p' in
 			let p = if p' = null_pos then p else p' in

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

@@ -179,7 +179,7 @@ let call_path ctx path f vl api =
 			let vtype = get_static_prototype_as_value ctx (path_hash path) api.pos in
 			let vtype = get_static_prototype_as_value ctx (path_hash path) api.pos in
 			let vfield = field vtype (hash f) in
 			let vfield = field vtype (hash f) in
 			let p = api.pos in
 			let p = api.pos in
-			let info = create_env_info true p.pfile (ctx.file_keys#get p.pfile) EKEntrypoint (Hashtbl.create 0) 0 0 in
+			let info = create_env_info true p.pfile (ctx.file_keys#get p.pfile) (EKMacro (path_hash path, hash f)) (Hashtbl.create 0) 0 0 in
 			let env = push_environment ctx info in
 			let env = push_environment ctx info in
 			env.env_leave_pmin <- p.pmin;
 			env.env_leave_pmin <- p.pmin;
 			env.env_leave_pmax <- p.pmax;
 			env.env_leave_pmax <- p.pmax;

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

@@ -19,6 +19,8 @@ let make_stack envs =
 		| EKMethod(st,sf) ->
 		| EKMethod(st,sf) ->
 			let local_function = encode_enum_value key_haxe_StackItem 3 [|create_unknown (rev_hash st); create_unknown (rev_hash sf)|] None in
 			let local_function = encode_enum_value key_haxe_StackItem 3 [|create_unknown (rev_hash st); create_unknown (rev_hash sf)|] None in
 			DynArray.add l (file_pos local_function);
 			DynArray.add l (file_pos local_function);
+		| EKMacro(st,sf) ->
+			()
 		| EKEntrypoint ->
 		| EKEntrypoint ->
 			()
 			()
 	) envs;
 	) envs;

+ 2 - 0
tests/misc/projects/Issue11679/Bar.hx

@@ -0,0 +1,2 @@
+@:build(Macro.build())
+class Bar {}

+ 14 - 0
tests/misc/projects/Issue11679/Macro.macro.hx

@@ -0,0 +1,14 @@
+import haxe.macro.Context;
+
+function build() {
+	switch (Context.getLocalClass().get().name) {
+		case "Foo":
+			switch Context.getType("Bar") {
+				case TInst(cls,_): cls.get();
+				case _:
+			}
+		case "Bar":
+			throw "Ohno";
+	}
+	return null;
+}

+ 6 - 0
tests/misc/projects/Issue11679/Main.hx

@@ -0,0 +1,6 @@
+class Main {
+	static function main() {}
+}
+
+@:build(Macro.build())
+class Foo {}

+ 3 - 0
tests/misc/projects/Issue11679/compile-fail.hxml

@@ -0,0 +1,3 @@
+-main Main
+-D message.no-color
+-D message.reporting=pretty

+ 24 - 0
tests/misc/projects/Issue11679/compile-fail.hxml.stderr

@@ -0,0 +1,24 @@
+[ERROR] Macro.macro.hx:11: characters 4-9
+
+ 11 |    throw "Ohno";
+    |    ^^^^^
+    | Uncaught exception Ohno
+
+     ->  Bar.hx:1: characters 1-8
+
+     1 | @:build(Macro.build())
+       | ^^^^^^^
+       | Called from here
+
+     ->  Macro.macro.hx:7: characters 24-33
+
+     7 |     case TInst(cls,_): cls.get();
+       |                        ^^^^^^^^^
+       | Called from here
+
+     ->  Main.hx:5: characters 1-8
+
+     5 | @:build(Macro.build())
+       | ^^^^^^^
+       | Called from here
+

+ 2 - 1
tests/misc/projects/Issue9389/compile-fail.hxml.stderr

@@ -1 +1,2 @@
-Main.hx:3: characters 5-8 : boop
+Main.hx:3: characters 5-8 : boop
+Main.hx:3: characters 3-9 : Called from here