Browse Source

[typer] remove internal @:enum handling on enum abstract ctors

Introduce AEnum instead
Simon Krajewski 2 years ago
parent
commit
894dec6992

+ 2 - 0
src/core/ast.ml

@@ -300,6 +300,7 @@ and access =
 	| AExtern
 	| AAbstract
 	| AOverload
+	| AEnum
 
 and placed_access = access * pos
 
@@ -491,6 +492,7 @@ let s_access = function
 	| AExtern -> "extern"
 	| AAbstract -> "abstract"
 	| AOverload -> "overload"
+	| AEnum -> "enum"
 
 let s_placed_access (a,_) = s_access a
 

+ 3 - 0
src/macro/macroApi.ml

@@ -315,6 +315,8 @@ and encode_access a =
 		| AExtern -> 8
 		| AAbstract -> 9
 		| AOverload -> 10
+		| AEnum -> 11
+
 	in
 	encode_enum ~pos:(Some (pos a)) IAccess tag []
 
@@ -785,6 +787,7 @@ and decode_access v =
 	| 8 -> AExtern
 	| 9 -> AAbstract
 	| 10 -> AOverload
+	| 11 -> AEnum
 	| _ -> raise Invalid_expr
 	in
 	a,p

+ 1 - 0
src/syntax/reification.ml

@@ -188,6 +188,7 @@ let reify in_macro =
 			| AExtern -> "AExtern"
 			| AAbstract -> "AAbstract"
 			| AOverload -> "AOverload"
+			| AEnum -> "AEnum"
 			) in
 			mk_enum "Access" n [] p
 		in

+ 1 - 1
src/typing/typeload.ml

@@ -553,7 +553,7 @@ and load_complex_type' ctx allow_display (t,p) =
 					pub := false;
 				| ADynamic when (match f.cff_kind with FFun _ -> true | _ -> false) -> dyn := true
 				| AFinal -> final := true
-				| AStatic | AOverride | AInline | ADynamic | AMacro | AExtern | AAbstract | AOverload as a -> raise_typing_error ("Invalid access " ^ Ast.s_access a) p
+				| AStatic | AOverride | AInline | ADynamic | AMacro | AExtern | AAbstract | AOverload | AEnum as a -> raise_typing_error ("Invalid access " ^ Ast.s_access a) p
 			) f.cff_access;
 			let t , access = (match f.cff_kind with
 				| FVar(t,e) when !final ->

+ 6 - 5
src/typing/typeloadFields.ml

@@ -270,7 +270,7 @@ let transform_abstract_field com this_t a_t a f =
 	match f.cff_kind with
 	| FProp ((("get" | "never"),_),(("set" | "never"),_),_,_) when not stat ->
 		f
-	| FProp _ when not stat && not (Meta.has Meta.Enum f.cff_meta) ->
+	| FProp _ when not stat && not (List.mem_assoc AEnum f.cff_access) ->
 		raise_typing_error "Member property accessors must be get/set or never" p;
 	| FFun fu when fst f.cff_name = "new" && not stat ->
 		let init p = (EVars [mk_evar ~t:this_t ~meta:([Meta.This,[],null_pos]) ("this",null_pos)],p) in
@@ -436,8 +436,7 @@ let build_enum_abstract ctx c a fields p =
 					visibility
 			in
 			let visibility = loop VUnknown field.cff_access in
-			field.cff_access <- [match visibility with VPublic acc | VPrivate acc -> acc | VUnknown -> (APublic,null_pos)];
-			field.cff_meta <- (Meta.Enum,[],null_pos) :: field.cff_meta;
+			field.cff_access <- (AEnum,null_pos) :: [match visibility with VPublic acc | VPrivate acc -> acc | VUnknown -> (APublic,null_pos)];
 			let ct = match ct with
 				| Some _ -> ct
 				| None -> Some (TExprToExpr.convert_type (TAbstract(a,extract_param_types a.a_params)),null_pos)
@@ -1012,7 +1011,7 @@ let load_variable_type_hint ctx fctx eo p = function
 		lazy_display_type ctx (fun () -> load_type_hint ctx p (Some t))
 
 let create_variable (ctx,cctx,fctx) c f t eo p =
-	let is_abstract_enum_field = Meta.has Meta.Enum f.cff_meta in
+	let is_abstract_enum_field = List.mem_assoc AEnum f.cff_access in
 	if fctx.is_abstract_member && not is_abstract_enum_field then raise_typing_error "Cannot declare member variable in abstract" p;
 	if fctx.is_inline && not fctx.is_static then invalid_modifier ctx.com fctx "inline" "non-static variable" p;
 	if fctx.is_inline && eo = None then missing_expression ctx.com fctx "Inline variable must be initialized" p;
@@ -1588,7 +1587,7 @@ let create_property (ctx,cctx,fctx) c f (get,set,t,eo) p =
 	if (set = AccNever && get = AccNever)  then raise_typing_error (name ^ ": Unsupported property combination") p;
 	cf.cf_kind <- Var { v_read = get; v_write = set };
 	if fctx.is_extern then add_class_field_flag cf CfExtern;
-	if Meta.has Meta.Enum cf.cf_meta then add_class_field_flag cf CfEnum;
+	if List.mem_assoc AEnum f.cff_access then add_class_field_flag cf CfEnum;
 	ctx.curfield <- cf;
 	TypeBinding.bind_var ctx cctx fctx cf eo;
 	cf
@@ -1618,8 +1617,10 @@ let init_field (ctx,cctx,fctx) f =
 		match (fst acc, f.cff_kind) with
 		| APublic, _ | APrivate, _ | AStatic, _ | AFinal, _ | AExtern, _ -> ()
 		| ADynamic, FFun _ | AOverride, FFun _ | AMacro, FFun _ | AInline, FFun _ | AInline, FVar _ | AAbstract, FFun _ | AOverload, FFun _ -> ()
+		| AEnum, (FVar _ | FProp _) -> ()
 		| _, FVar _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for variable " ^ name) (snd acc)
 		| _, FProp _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for property " ^ name) (snd acc)
+		| _, FFun _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for function " ^ name) (snd acc)
 	) f.cff_access;
 	begin match fctx.override with
 		| Some _ ->

+ 6 - 0
std/haxe/macro/Expr.hx

@@ -894,6 +894,11 @@ enum Access {
 		Overload access modifier.
 	**/
 	AOverload;
+
+	/**
+		Enum access modifier.
+	**/
+	AEnum;
 }
 
 /**
@@ -1000,6 +1005,7 @@ enum TypeDefKind {
 		Represents a module-level field.
 	**/
 	TDField(kind:FieldType, ?access:Array<Access>); // ignore TypeDefinition.fields
+
 }
 
 /**

+ 32 - 23
std/haxe/macro/Printer.hx

@@ -137,7 +137,7 @@ class Printer {
 				(wrapArgumentsInParentheses ? '($argStr)' : argStr) + " -> " + (switch ret {
 					// wrap return type in parentheses if it's also a function
 					case TFunction(_): '(${printComplexType(ret)})';
-					default: (printComplexType(ret): String);
+					default: (printComplexType(ret) : String);
 				});
 			case TAnonymous(fields): "{ " + [for (f in fields) printField(f) + "; "].join("") + "}";
 			case TParent(ct): "(" + printComplexType(ct) + ")";
@@ -166,10 +166,11 @@ class Printer {
 			case AExtern: "extern";
 			case AAbstract: "abstract";
 			case AOverload: "overload";
+			case AEnum: "enum";
 		}
 
 	public function printField(field:Field) {
-		inline function orderAccess(access: Array<Access>) {
+		inline function orderAccess(access:Array<Access>) {
 			// final should always be printed last
 			// (does not modify input array)
 			return access.has(AFinal) ? access.filter(a -> !a.match(AFinal)).concat([AFinal]) : access;
@@ -186,11 +187,14 @@ class Printer {
 			+ (field.meta != null && field.meta.length > 0 ? field.meta.map(printMetadata).join('\n$tabs') + '\n$tabs' : "")
 			+ (field.access != null && field.access.length > 0 ? orderAccess(field.access).map(printAccess).join(" ") + " " : "")
 			+ switch (field.kind) {
-				case FVar(t, eo): ((field.access != null && field.access.has(AFinal)) ? '' : 'var ') + '${field.name}' + opt(t, printComplexType, " : ") + opt(eo, printExpr, " = ");
+				case FVar(t,
+					eo): ((field.access != null && field.access.has(AFinal)) ? '' : 'var ')
+						+ '${field.name}'
+						+ opt(t, printComplexType, " : ")
+						+ opt(eo, printExpr, " = ");
 				case FProp(get, set, t, eo): 'var ${field.name}($get, $set)' + opt(t, printComplexType, " : ") + opt(eo, printExpr, " = ");
 				case FFun(func): 'function ${field.name}' + printFunction(func);
-			}
-	}
+			}}
 
 	public function printTypeParamDecl(tpd:TypeParamDecl)
 		return (tpd.meta != null && tpd.meta.length > 0 ? tpd.meta.map(printMetadata).join(" ") + " " : "")
@@ -204,7 +208,7 @@ class Printer {
 
 	public function printFunction(func:Function, ?kind:FunctionKind) {
 		var skipParentheses = switch func.args {
-			case [{ type:null }]: kind == FArrow;
+			case [{type: null}]: kind == FArrow;
 			case _: false;
 		}
 		return (func.params == null ? "" : func.params.length > 0 ? "<" + func.params.map(printTypeParamDecl).join(", ") + ">" : "")
@@ -219,7 +223,7 @@ class Printer {
 	public function printVar(v:Var) {
 		var s = v.name + opt(v.type, printComplexType, ":") + opt(v.expr, printExpr, " = ");
 		return switch v.meta {
-			case null|[]: s;
+			case null | []: s;
 			case meta: meta.map(printMetadata).join(" ") + " " + s;
 		}
 	}
@@ -249,7 +253,7 @@ class Printer {
 			case ENew(tp, el): 'new ${printTypePath(tp)}(${printExprs(el, ", ")})';
 			case EUnop(op, true, e1): printExpr(e1) + printUnop(op);
 			case EUnop(op, false, e1): printUnop(op) + printExpr(e1);
-			case EFunction(FNamed(no,inlined), func): (inlined ? 'inline ' : '') + 'function $no' + printFunction(func);
+			case EFunction(FNamed(no, inlined), func): (inlined ? 'inline ' : '') + 'function $no' + printFunction(func);
 			case EFunction(kind, func): (kind != FArrow ? "function" : "") + printFunction(func, kind);
 			case EVars([]): "var ";
 			case EVars(vl): ((vl[0].isStatic) ? "static " : "") + ((vl[0].isFinal) ? "final " : "var ") + vl.map(printVar).join(", ");
@@ -277,7 +281,9 @@ class Printer {
 				tabs = old;
 				s + '\n$tabs}';
 			case ETry(e1, cl):
-				'try ${printExpr(e1)}' + cl.map(function(c) return ' catch(${c.name}${c.type == null ? '' : (':' + printComplexType(c.type))}) ${printExpr(c.expr)}').join("");
+				'try ${printExpr(e1)}' + cl.map(function(c) return
+					' catch(${c.name}${c.type == null ? '' : (':' + printComplexType(c.type))}) ${printExpr(c.expr)}')
+					.join("");
 			case EReturn(eo): "return" + opt(eo, printExpr, " ");
 			case EBreak: "break";
 			case EContinue: "continue";
@@ -289,7 +295,7 @@ class Printer {
 			case EDisplay(e1, _): '#DISPLAY(${printExpr(e1)})';
 			case ETernary(econd, eif, eelse): '${printExpr(econd)} ? ${printExpr(eif)} : ${printExpr(eelse)}';
 			case ECheckType(e1, ct): '(${printExpr(e1)} : ${printComplexType(ct)})';
-			case EMeta({ name:":implicitReturn" }, { expr:EReturn(e1) }): printExpr(e1);
+			case EMeta({name: ":implicitReturn"}, {expr: EReturn(e1)}): printExpr(e1);
 			case EMeta(meta, e1): printMetadata(meta) + " " + printExpr(e1);
 		}
 
@@ -340,8 +346,7 @@ class Printer {
 								case FProp(_, _, _, _): throw "FProp is invalid for TDEnum.";
 								case FFun(func): field.name + printFunction(func);
 							})
-							+ ";"].join("\n")
-					+ "\n}";
+							+ ";"].join("\n") + "\n}";
 				case TDStructure:
 					"typedef "
 					+ t.name
@@ -351,8 +356,7 @@ class Printer {
 						for (f in t.fields) {
 							tabs + printField(f) + ";";
 						}
-					].join("\n")
-					+ "\n}";
+					].join("\n") + "\n}";
 				case TDClass(superClass, interfaces, isInterface, isFinal, isAbstract):
 					(isFinal ? "final " : "")
 						+ (isAbstract ? "abstract " : "")
@@ -369,8 +373,7 @@ class Printer {
 							for (f in t.fields) {
 								tabs + printFieldWithDelimiter(f);
 							}
-						].join("\n")
-						+ "\n}";
+						].join("\n") + "\n}";
 				case TDAlias(ct):
 					"typedef "
 					+ t.name
@@ -394,15 +397,21 @@ class Printer {
 						for (f in t.fields) {
 							tabs + printFieldWithDelimiter(f);
 						}
-					].join("\n")
-					+ "\n}";
+					].join("\n") + "\n}";
 				case TDField(kind, access):
 					tabs = old;
-					(access != null && access.length > 0 ? access.map(printAccess).join(" ") + " " : "")
-					+ switch (kind) {
-						case FVar(type, eo): ((access != null && access.has(AFinal)) ? '' : 'var ') + '${t.name}' + opt(type, printComplexType, " : ") + opt(eo, printExpr, " = ") + ";";
-						case FProp(get, set, type, eo): 'var ${t.name}($get, $set)' + opt(type, printComplexType, " : ") + opt(eo, printExpr, " = ") + ";";
-						case FFun(func): 'function ${t.name}' + printFunction(func) + switch func.expr { case {expr: EBlock(_)}: ""; case _: ";"; };
+					(access != null && access.length > 0 ? access.map(printAccess).join(" ") + " " : "") + switch (kind) {
+						case FVar(type,
+							eo): ((access != null && access.has(AFinal)) ? '' : 'var ') + '${t.name}' + opt(type, printComplexType, " : ")
+								+ opt(eo, printExpr, " = ") + ";";
+						case FProp(get, set, type, eo): 'var ${t.name}($get, $set)'
+							+ opt(type, printComplexType, " : ")
+							+ opt(eo, printExpr, " = ")
+							+ ";";
+						case FFun(func): 'function ${t.name}' + printFunction(func) + switch func.expr {
+								case {expr: EBlock(_)}: "";
+								case _: ";";
+							};
 					}
 			} tabs = old;