Macro.hx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package;
  2. #if macro
  3. import haxe.macro.Type;
  4. using haxe.macro.TypeTools;
  5. class Macro {
  6. public static function start() {
  7. haxe.macro.Context.onGenerate(function(types: Array<haxe.macro.Type>) {
  8. // Make sure this actually runs.
  9. Sys.println("On Generate");
  10. for(t in types) {
  11. switch (t) {
  12. case TAbstract(a, _): {
  13. makeMalformedType(a);
  14. }
  15. case TInst(c, _) if(c.get().name == "TestClass"): {
  16. testWithClass(c);
  17. }
  18. case _: {}
  19. }
  20. }
  21. });
  22. }
  23. // General test that ensures crash doesn't occur
  24. static function makeMalformedType(a: Ref<AbstractType>) {
  25. // If passed as it is, this will crash the Haxe compiler.
  26. // https://github.com/HaxeFoundation/haxe/issues/10959
  27. final type = TAbstract(a, []);
  28. // Use TypeTools.resolveTypeParameters
  29. final valid = type.resolveTypeParameters(true, (tp,t,i) -> tp.defaultType ?? tp.t);
  30. haxe.macro.Context.followWithAbstracts(valid);
  31. }
  32. // Test specific aspects of the resolveTypeParameters function
  33. static function testWithClass(c: Ref<ClassType>) {
  34. // Various types to use with tests
  35. final voidType = haxe.macro.Context.getType("Void");
  36. final intType = haxe.macro.Context.getType("Int");
  37. final floatType = haxe.macro.Context.getType("Float");
  38. final stringType = haxe.macro.Context.getType("String");
  39. // Print type before and after using "resolveTypeParameters"
  40. function print(t:Type, other:Null<Type> = null) {
  41. Sys.println("Before: " + t.toString());
  42. // Automatically resolve to the defaultType or `KTypeParameter` for testing purposes.
  43. if(other == null) {
  44. other = t.resolveTypeParameters(true, (tp,t,i) -> tp.defaultType ?? tp.t);
  45. }
  46. Sys.println("After: " + other.toString());
  47. Sys.println("");
  48. }
  49. Sys.println("-- Too Few Params --");
  50. print(TInst(c, []));
  51. print(TInst(c, [voidType]));
  52. Sys.println("-- Too Many Params --");
  53. print(TInst(c, [voidType, intType, floatType, stringType]));
  54. Sys.println("-- Correct Number of Params (3rd is optional) --");
  55. print(TInst(c, [voidType, intType, floatType]));
  56. print(TInst(c, [voidType, intType]));
  57. Sys.println("-- Shouldn't Have Params --");
  58. switch(voidType) {
  59. case TAbstract(absRef, _): {
  60. print(TAbstract(absRef, [intType, floatType]));
  61. }
  62. case _:
  63. }
  64. Sys.println("-- Recursive Test --");
  65. final inner1 = TInst(c, []);
  66. final inner2 = TInst(c, [voidType, intType, floatType, stringType]);
  67. print(TInst(c, [inner1, inner2]));
  68. Sys.println("-- Fill With Specific Type --");
  69. print(inner1, inner1.resolveTypeParameters(true, (_,_,_) -> intType));
  70. print(inner1, inner1.resolveTypeParameters(true, (_,_,_) -> stringType));
  71. print(inner2, inner2.resolveTypeParameters(true, (_,_,_) -> stringType));
  72. Sys.println("-- Recursive Param OFF --");
  73. final recursiveType = TInst(c, [inner1, inner2]);
  74. print(recursiveType, recursiveType.resolveTypeParameters(false, (_,_,_) -> stringType));
  75. Sys.println("-- Index Print --");
  76. recursiveType.resolveTypeParameters(true, function(tp, type, index) {
  77. Sys.println(type.toString() + " - " + index);
  78. return voidType;
  79. });
  80. }
  81. }
  82. #end