Browse Source

[macro] Print new function syntax (#7484)

* [macro] print new function syntax

* [tests] add new function syntax tests for macro printer
George Corney 7 years ago
parent
commit
0d1f239089
2 changed files with 17 additions and 5 deletions
  1. 8 5
      std/haxe/macro/Printer.hx
  2. 9 0
      tests/unit/src/unit/TestMacro.hx

+ 8 - 5
std/haxe/macro/Printer.hx

@@ -112,11 +112,14 @@ class Printer {
 	public function printComplexType(ct:ComplexType) return switch(ct) {
 		case TPath(tp): printTypePath(tp);
 		case TFunction(args, ret):
-			function printArg(ct) return switch ct {
-				case TFunction(_): "(" + printComplexType(ct) + ")";
-				default: printComplexType(ct);
-			};
-			(args.length>0 ? args.map(printArg).join(" -> ") :"Void") + " -> " + printComplexType(ret);
+			if (args.length == 1 && !(args[0].match(TNamed(_, _)) || args[0].match(TFunction(_, _)))) {
+				// This special case handles an ambigity between the old function syntax and the new
+				// (T) -> T parses as `TFunction([TParent(TPath)], ...`, rather than `TFunction([TPath], ...`
+				// We forgo patenthesis in this case so that (T) -> T doesn't get round-tripped to ((T)) -> T
+				printComplexType(args[0]) + " -> " + printComplexType(ret);
+			} else {
+				'(${args.map(printComplexType).join(", ")})' + " -> " + printComplexType(ret);
+			}
 		case TAnonymous(fields): "{ " + [for (f in fields) printField(f) + "; "].join("") + "}";
 		case TParent(ct): "(" + printComplexType(ct) + ")";
 		case TOptional(ct): "?" + printComplexType(ct);

+ 9 - 0
tests/unit/src/unit/TestMacro.hx

@@ -57,5 +57,14 @@ class TestMacro extends Test {
 		parseAndPrint("@:meta a");
 		parseAndPrint("@:meta(a) b");
 		parseAndPrint("@:meta(a, b) b");
+		// new function syntax
+		parseAndPrint("var a:(x:X, y:Y) -> Z");
+		parseAndPrint("var a:(X, Y) -> Z");
+		parseAndPrint("var a:() -> A");
+		parseAndPrint("var a:() -> (() -> A)");
+		parseAndPrint("var a:(x:(y:Y) -> Z) -> A");
+		// special case with 1 argument
+		parseAndPrint("var a:X -> Y");
+		parseAndPrint("var a:(X) -> Y");
 	}
 }