Browse Source

Macro generated EVars position fixes (#11163)

* set EVars position from macro reification

* [tests] add test for 11162

* Expose Var.namePos

* Fallback to EVars position for var names when namePos is null_pos

* fix null_pos check
Rudy Ges 2 years ago
parent
commit
88a65c275a

+ 4 - 2
src/macro/macroApi.ml

@@ -560,7 +560,7 @@ and encode_expr e =
 				10, [encode_array (List.map (fun v ->
 					encode_obj [
 						"name",encode_placed_name v.ev_name;
-						"name_pos",encode_pos (pos v.ev_name);
+						"namePos",encode_pos (pos v.ev_name);
 						"isFinal",vbool v.ev_final;
 						"isStatic",vbool v.ev_static;
 						"type",null encode_ctype v.ev_type;
@@ -924,7 +924,9 @@ and decode_expr v =
 				let static = if vstatic == vnull then false else decode_bool vstatic in
 				let vmeta = field v "meta" in
 				let meta = if vmeta == vnull then [] else decode_meta_content vmeta in
-				let name = (decode_placed_name (field v "name_pos") (field v "name"))
+				let name_pos = maybe_decode_pos (field v "namePos") in
+				let name_pos = if name_pos = null_pos then p else name_pos in
+				let name = ((decode_string (field v "name")), name_pos)
 				and t = opt decode_ctype (field v "type")
 				and eo = opt loop (field v "expr") in
 				mk_evar ~final ~static ?t ?eo ~meta name

+ 1 - 0
src/syntax/reification.ml

@@ -293,6 +293,7 @@ let reify in_macro =
 			expr "EVars" [to_array (fun v p ->
 				let fields = [
 					"name", to_string (fst v.ev_name) (snd v.ev_name);
+					"namePos", to_pos (snd v.ev_name);
 					"type", to_opt to_type_hint v.ev_type p;
 					"expr", to_opt to_expr v.ev_expr p;
 					"isFinal",to_bool v.ev_final p;

+ 5 - 0
std/haxe/macro/Expr.hx

@@ -316,6 +316,11 @@ typedef Var = {
 	**/
 	var name:String;
 
+	/**
+		The position of the variable name.
+	**/
+	var ?namePos:Position;
+
 	/**
 		The type-hint of the variable, if available.
 	**/

+ 7 - 0
tests/misc/projects/Issue11162/Macro.macro.hx

@@ -0,0 +1,7 @@
+class Macro {
+  public static function build() {
+	return haxe.macro.Context.getBuildFields().concat((macro class A {
+		function bar() var a = main();
+	}).fields);
+  }
+}

+ 15 - 0
tests/misc/projects/Issue11162/Macro2.macro.hx

@@ -0,0 +1,15 @@
+import haxe.macro.Expr;
+
+class Macro2 {
+	public static function build() {
+		var pos = (macro 0).pos;
+		var e = {expr: EBlock([
+			{expr: EVars([{name: "a", type: null, expr: null}]), pos: pos},
+			{expr: EBinop(OpAssign, {expr: EConst(CIdent("a")), pos: pos}, macro main()), pos: pos}
+		]), pos: pos};
+
+		return haxe.macro.Context.getBuildFields().concat((macro class A {
+			function bar() $e;
+		}).fields);
+	}
+}

+ 4 - 0
tests/misc/projects/Issue11162/Main.hx

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

+ 4 - 0
tests/misc/projects/Issue11162/Main2.hx

@@ -0,0 +1,4 @@
+@:build(Macro2.build())
+class Main {
+	static function main() {}
+}

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

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

+ 6 - 0
tests/misc/projects/Issue11162/compile-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Macro.macro.hx:4: characters 22-23
+
+ 4 |   function bar() var a = main();
+   |                      ^
+   | Variables of type Void are not allowed
+

+ 3 - 0
tests/misc/projects/Issue11162/compile2-fail.hxml

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

+ 6 - 0
tests/misc/projects/Issue11162/compile2-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Macro2.macro.hx:5: characters 20-21
+
+ 5 |   var pos = (macro 0).pos;
+   |                    ^
+   | Variables of type Void are not allowed
+