Explorar el Código

restored detection of initialized enum abstract fields
(fixes #9918)

Aleksandr Kuzmenko hace 4 años
padre
commit
17b609d4e4

+ 13 - 9
src/typing/typeloadFields.ml

@@ -369,9 +369,18 @@ let build_enum_abstract ctx c a fields p =
 		else if does_unify a.a_this ctx.t.tstring then EAString
 		else EAOther
 	in
+	let set_field field ct e =
+		field.cff_access <- (AInline,null_pos) :: field.cff_access;
+		let e = (ECast(e,None),(pos e)) in
+		field.cff_kind <- FVar(ct,Some e)
+	and field_is_set field =
+		match field.cff_kind with
+		| FVar(Some _, Some ((ECast _),_)) -> List.exists (fun (access,_) -> access = AInline) field.cff_access
+		| _ -> false
+	in
 	List.iter (fun field ->
 		match field.cff_kind with
-		| FVar(ct,eo) when not (List.mem_assoc AStatic field.cff_access) ->
+		| FVar(ct,eo) when not (List.mem_assoc AStatic field.cff_access) && not (field_is_set field) ->
 			let check_visibility_conflict visibility p1 =
 				match visibility with
 				| VUnknown ->
@@ -402,18 +411,13 @@ let build_enum_abstract ctx c a fields p =
 				| Some _ -> ct
 				| None -> Some (TExprToExpr.convert_type (TAbstract(a,List.map snd a.a_params)),null_pos)
 			in
-			let set_field e =
-				field.cff_access <- (AInline,null_pos) :: field.cff_access;
-				let e = (ECast(e,None),(pos e)) in
-				field.cff_kind <- FVar(ct,Some e)
-			in
 			begin match eo with
 				| None ->
 					if not (has_class_flag c CExtern) then begin match mode with
 						| EAString ->
-							set_field (EConst (String (fst field.cff_name,SDoubleQuotes)),null_pos)
+							set_field field ct (EConst (String (fst field.cff_name,SDoubleQuotes)),null_pos)
 						| EAInt i ->
-							set_field (EConst (Int (string_of_int !i)),null_pos);
+							set_field field ct (EConst (Int (string_of_int !i)),null_pos);
 							incr i;
 						| EAOther ->
 							error "Value required" field.cff_pos
@@ -429,7 +433,7 @@ let build_enum_abstract ctx c a fields p =
 							end
 						| _ -> ()
 					end;
-					set_field e
+					set_field field ct e
 			end
 		| _ ->
 			()

+ 11 - 0
tests/server/src/cases/ServerTests.hx

@@ -236,4 +236,15 @@ class ServerTests extends TestCase {
 	// 	var content = sys.io.File.getContent(haxe.io.Path.join([testDir, "out.js"]));
 	// 	Assert.isTrue(content.indexOf("this1.use(v1)") != -1);
 	// }
+
+	function test9918() {
+		vfs.putContent("Issue9918.hx", getTemplate("Issue9918.hx"));
+		var args = ["-main", "Issue9918.hx"];
+		runHaxe(args);
+		assertHasPrint('Issue9918.hx:22: correct ECast count');
+		runHaxe(args);
+		assertHasPrint('Issue9918.hx:22: correct ECast count');
+		runHaxe(args);
+		assertHasPrint('Issue9918.hx:22: correct ECast count');
+	}
 }

+ 48 - 0
tests/server/test/templates/Issue9918.hx

@@ -0,0 +1,48 @@
+#if macro
+import haxe.macro.Context;
+import haxe.macro.Expr;
+import haxe.macro.Type;
+using haxe.macro.Tools;
+#end
+
+enum abstract Days(Int) to Int {
+	var Sun = 0;
+	var Mon;
+	var Tue;
+}
+class Issue9918 {
+	static function main() {
+		Macros.weirdECast(Days);
+	}
+}
+class Macros {
+	macro public static function weirdECast( typePath : Expr ) {
+		var type = Context.getType(typePath.toString());
+		if(ecastCount(type) == 1) {
+			trace('correct ECast count');
+		}
+		Context.error('error', (macro {}).pos);
+		return macro {};
+	}
+#if macro
+	static function ecastCount( type : Type ) {
+		switch (type) {
+		case TAbstract(_.get() => ab, _) if (ab.meta.has(":enum")):
+			for (field in ab.impl.get().statics.get()) {
+				var first = field.meta.get()[0];
+				return strip(first.params[0], 0);
+			}
+		default:
+		}
+		return -1;
+	}
+	static function strip(e, acc) {
+		return switch(e.expr) {
+		case ECast(e, _):
+			strip(e, acc + 1);
+		case _:
+			acc;
+		}
+	}
+#end
+}