瀏覽代碼

[4.3.6] Context.reportError should not abort build macros (#11741)

* [macro] flush pass before altering error reporting

* [tests] add test showing Context.reportError vs build macro issue
Rudy Ges 1 年之前
父節點
當前提交
00947ede25

+ 5 - 4
src/typing/macroContext.ml

@@ -94,14 +94,15 @@ let typing_timer ctx need_type f =
 		| Stack stack -> (Stack (List.map located_to_error stack),null_pos)
 		| Stack stack -> (Stack (List.map located_to_error stack),null_pos)
 	in
 	in
 
 
-	ctx.com.located_error <- (fun ?(depth=0) msg ->
-		let (e,p) = located_to_error msg in
-		raise (Error (e,p,depth)));
-
 	if need_type && ctx.pass < PTypeField then begin
 	if need_type && ctx.pass < PTypeField then begin
 		ctx.pass <- PTypeField;
 		ctx.pass <- PTypeField;
 		flush_pass ctx PBuildClass "typing_timer";
 		flush_pass ctx PBuildClass "typing_timer";
 	end;
 	end;
+
+	ctx.com.located_error <- (fun ?(depth=0) msg ->
+		let (e,p) = located_to_error msg in
+		raise (Error (e,p,depth)));
+
 	let exit() =
 	let exit() =
 		t();
 		t();
 		ctx.com.located_error <- old;
 		ctx.com.located_error <- old;

+ 39 - 0
tests/misc/projects/Issue11741/Macro.hx

@@ -0,0 +1,39 @@
+
+import haxe.macro.Expr.Field;
+import haxe.macro.Context;
+
+class Macro {
+    public static macro function buildMain(): Array<Field> {
+        final pos = Context.currentPos();
+        final bf = Context.getBuildFields();
+    
+        final type = Context.getType('Test2');
+    
+        switch (type) {
+            case TInst(ctRef, _):
+                final ct = ctRef.get();
+                
+                try {
+                    final ctor = ct.constructor.get().expr();
+                } catch (e: Dynamic) {
+
+                }
+                
+                Context.warning('This does not show if printStuff() calls error() or reportError()', pos);
+            case _:
+        }
+    
+        return bf;
+    }
+
+    public static macro function buildTest2(): Array<Field> {
+        final pos = Context.currentPos();
+        final bf = Context.getBuildFields();
+        
+        // Use error() or reportError() here -> Main Completion does not work, Eval crashes
+        // Use warning() or info() -> Everything works as expected
+        Context.reportError('Crashes HERE in eval.vm.callMacroApi', pos);
+
+        return bf;
+    }
+}

+ 7 - 0
tests/misc/projects/Issue11741/Main.hx

@@ -0,0 +1,7 @@
+// Should be a warning here, UNLESS Macro.printStuff() calls reportError()/error()
+@:build(Macro.buildMain())
+class Main {
+  static function main() {
+    final x = 5 - ""; // No errors shown for this, completion/hover does not work
+  }
+}

+ 7 - 0
tests/misc/projects/Issue11741/Test2.hx

@@ -0,0 +1,7 @@
+
+@:autoBuild(Macro.buildTest2())
+class Test2 {
+  public function new(a: Int, b: Int) {}
+}
+
+class Test2Ext extends Test2 {}

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

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

+ 18 - 0
tests/misc/projects/Issue11741/compile-fail.hxml.stderr

@@ -0,0 +1,18 @@
+[ERROR] Test2.hx:7: character 1
+
+ 7 | class Test2Ext extends Test2 {}
+   | ^
+   | Crashes HERE in eval.vm.callMacroApi
+
+[WARNING] Main.hx:2: characters 1-8
+
+ 2 | @:build(Macro.buildMain())
+   | ^^^^^^^
+   | This does not show if printStuff() calls error() or reportError()
+
+[ERROR] Main.hx:5: characters 19-21
+
+ 5 |     final x = 5 - ""; // No errors shown for this, completion/hover does not work
+   |                   ^^
+   | String should be Int
+