Browse Source

[macro] add flags to TDAbstract to be able to construct enum abstracts (#11230)

* [macro] add flags to TDAbstract to be able to construct enum abstracts

* Remove remnants of AbExtern

* Printer: handle null from/to arrays
Rudy Ges 2 years ago
parent
commit
17cf98c97d
3 changed files with 51 additions and 7 deletions
  1. 11 2
      src/macro/macroApi.ml
  2. 23 1
      std/haxe/macro/Expr.hx
  3. 17 4
      std/haxe/macro/Printer.hx

+ 11 - 2
src/macro/macroApi.ml

@@ -1623,10 +1623,19 @@ let decode_type_def v =
 		EClass (mk flags fields)
 	| 3, [t] ->
 		ETypedef (mk (if isExtern then [EExtern] else []) (decode_ctype t))
-	| 4, [tthis;tfrom;tto] ->
-		let flags = match opt decode_array tfrom with None -> [] | Some ta -> List.map (fun t -> AbFrom (decode_ctype t)) ta in
+	| 4, [tthis;tflags;tfrom;tto] ->
+		let flags = match opt decode_array tflags with
+			| None -> []
+			| Some ta -> List.map (fun f -> match decode_enum f with
+				| 0, [] -> AbEnum
+				| 1, [ct] -> AbFrom (decode_ctype ct)
+				| 2, [ct] -> AbTo (decode_ctype ct)
+				| _ -> raise Invalid_expr
+		) ta in
+		let flags = match opt decode_array tfrom with None -> flags | Some ta -> List.map (fun t -> AbFrom (decode_ctype t)) ta @ flags in
 		let flags = match opt decode_array tto with None -> flags | Some ta -> (List.map (fun t -> AbTo (decode_ctype t)) ta) @ flags in
 		let flags = match opt decode_ctype tthis with None -> flags | Some t -> (AbOver t) :: flags in
+		let flags = if isExtern then AbExtern :: flags else flags in
 		EAbstract(mk flags fields)
 	| 5, [fk;al] ->
 		let fk = decode_class_field_kind fk in

+ 23 - 1
std/haxe/macro/Expr.hx

@@ -999,7 +999,7 @@ enum TypeDefKind {
 	/**
 		Represents an abstract kind.
 	**/
-	TDAbstract(tthis:Null<ComplexType>, ?from:Array<ComplexType>, ?to:Array<ComplexType>);
+	TDAbstract(tthis:Null<ComplexType>, ?flags:Array<AbstractFlag>, ?from:Array<ComplexType>, ?to:Array<ComplexType>);
 
 	/**
 		Represents a module-level field.
@@ -1007,6 +1007,28 @@ enum TypeDefKind {
 	TDField(kind:FieldType, ?access:Array<Access>); // ignore TypeDefinition.fields
 }
 
+/**
+	Represents an abstract flag.
+**/
+enum AbstractFlag {
+	/**
+		Indicates that this abstract is an `enum abstract`
+	**/
+	AbEnum;
+
+	/**
+		Indicates that this abstract can be assigned from `ct`.
+		This flag can be added several times to add multiple "from" types.
+	**/
+	AbFrom(ct:ComplexType);
+
+	/**
+		Indicates that this abstract can be assigned to `ct`.
+		This flag can be added several times to add multiple "to" types.
+	**/
+	AbTo(ct:ComplexType);
+}
+
 /**
 	This error can be used to handle or produce compilation errors in macros.
 **/

+ 17 - 4
std/haxe/macro/Printer.hx

@@ -382,13 +382,26 @@ class Printer {
 						case _: printComplexType(ct);
 					})
 					+ ";";
-				case TDAbstract(tthis, from, to):
-					"abstract "
+				case TDAbstract(tthis, tflags, from, to):
+					var from = from == null ? [] : from.copy();
+					var to = to == null ? [] : to.copy();
+					var isEnum = false;
+
+					for (flag in tflags) {
+						switch (flag) {
+							case AbEnum: isEnum = true;
+							case AbFrom(ct): from.push(ct);
+							case AbTo(ct): to.push(ct);
+						}
+					}
+
+					(isEnum ? "enum " : "")
+					+ "abstract "
 					+ t.name
 					+ ((t.params != null && t.params.length > 0) ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "")
 					+ (tthis == null ? "" : "(" + printComplexType(tthis) + ")")
-					+ (from == null ? "" : [for (f in from) " from " + printComplexType(f)].join(""))
-					+ (to == null ? "" : [for (t in to) " to " + printComplexType(t)].join(""))
+					+ [for (f in from) " from " + printComplexType(f)].join("")
+					+ [for (f in to) " to " + printComplexType(f)].join("")
 					+ " {\n"
 					+ [
 						for (f in t.fields) {