Quellcode durchsuchen

TAnonymous mapping in TypeTools.map (closes #9147)

Aleksandr Kuzmenko vor 5 Jahren
Ursprung
Commit
e83a43889e

+ 7 - 0
src/macro/macroApi.ml

@@ -1971,6 +1971,13 @@ let macro_api ccom get_api =
 			let stop = Timer.timer full_id in
 			vfun0 (fun() -> stop(); vnull)
 		);
+		"map_anon_ref", vfun2 (fun a_ref fn ->
+			let a = decode_ref a_ref
+			and fn = prepare_callback fn 1 in
+			match map (fun t -> decode_type (fn [encode_type t])) (TAnon a) with
+			| TAnon a -> encode_ref a encode_tanon (fun() -> "<anonymous>")
+			| _ -> assert false
+		)
 	]
 
 

+ 1 - 1
std/haxe/macro/TypeTools.hx

@@ -307,7 +307,7 @@ class TypeTools {
 					t: f(arg.t)
 				}), f(ret));
 			case TAnonymous(an):
-				t; // TODO: Ref?
+				TAnonymous(Context.load("map_anon_ref", 2)(an, f));
 			case TDynamic(t2):
 				t == t2 ? t : TDynamic(f(t2));
 			case TLazy(ft):

+ 12 - 0
tests/unit/src/unit/issues/Issue9147.hx

@@ -0,0 +1,12 @@
+package unit.issues;
+
+import unit.Test;
+
+class Issue9147 extends Test {
+	public function test() {
+		var result = unit.issues.misc.Issue9147Macro.typeAndReplaceTypes((null:{a:Bool,b:Int}), 'String');
+		aeq(['Bool', 'Int'], result.foundTypes);
+		eq('{a:String,b:String}', result.mappedAnon);
+	}
+
+}

+ 28 - 0
tests/unit/src/unit/issues/misc/Issue9147Macro.hx

@@ -0,0 +1,28 @@
+package unit.issues.misc;
+
+import haxe.macro.Type;
+import haxe.macro.Expr;
+import haxe.macro.Context;
+
+using haxe.macro.TypeTools;
+
+class Issue9147Macro {
+	macro public static function typeAndReplaceTypes(anon:Expr, replacement:String):Expr {
+		var t = Context.typeExpr(anon).t;
+		var inMapper = [];
+		function mapper(t:Type):Type {
+			inMapper.push(t.toString());
+			return Context.getType(replacement);
+		}
+		var result = [];
+		switch TypeTools.map(t, mapper) {
+			case TAnonymous(a):
+				for(f in a.get().fields) {
+					result.push('${f.name}:${f.type.toString()}');
+				}
+			case _:
+		}
+		inMapper.sort(Reflect.compare);
+		return macro { foundTypes:$v{inMapper}, mappedAnon:$v{'{' + result.join(',') + '}'}}
+	}
+}