Ver Fonte

Merge pull request #3505 from nadako/3504_fix

[cs] fix default arguments in super constructor call (see #3504)
Cauê Waneck há 11 anos atrás
pai
commit
0eca03c055
2 ficheiros alterados com 59 adições e 21 exclusões
  1. 29 21
      gencommon.ml
  2. 30 0
      tests/unit/src/unit/issues/Issue3504.hx

+ 29 - 21
gencommon.ml

@@ -10180,6 +10180,33 @@ struct
 
 	let priority = solve_deps name [ DBefore OverloadingConstructor.priority ]
 
+	let gen_check basic t nullable_var const pos =
+		let is_null t = match t with TType({t_path = ([],"Null")}, _) -> true | _ -> false in
+		let needs_cast t1 t2 = match is_null t1, is_null t2 with
+			| true, false | false, true -> true
+			| _ -> false
+		in
+
+		let const_t = match const with
+			| TString _ -> basic.tstring | TInt _ -> basic.tint | TFloat _ -> basic.tfloat
+			| TNull -> t | TBool _ -> basic.tbool | _ -> assert false
+		in
+		let const = { eexpr = TConst(const); etype = const_t; epos = pos } in
+		let const = if needs_cast t const_t then mk_cast t const else const in
+
+		let arg = mk_local nullable_var pos in
+		let arg = if needs_cast t nullable_var.v_type then mk_cast t arg else arg in
+
+		{
+			eexpr = TIf(
+				{ eexpr = TBinop(Ast.OpEq, mk_local nullable_var pos, null nullable_var.v_type pos); etype = basic.tbool; epos = pos },
+				const,
+				Some(arg)
+			);
+			etype = t;
+			epos = pos;
+		}
+
 	let add_opt gen block pos (var,opt) =
 		match opt with
 			| None | Some TNull -> (var,opt)
@@ -10192,23 +10219,10 @@ struct
 				let orig_name = var.v_name in
 				var.v_name <- nullable_var.v_name;
 				nullable_var.v_name <- orig_name;
-				let const_t = match const with
-					| TString _ -> basic.tstring | TInt _ -> basic.tint | TFloat _ -> basic.tfloat
-					| TNull -> var.v_type | TBool _ -> basic.tbool | _ -> assert false
-				in
 				(* var v = (temp_var == null) ? const : cast temp_var; *)
 				block :=
 				{
-					eexpr = TVar(var, Some(
-					{
-						eexpr = TIf(
-							{ eexpr = TBinop(Ast.OpEq, mk_local nullable_var pos, null nullable_var.v_type pos); etype = basic.tbool; epos = pos },
-							mk_cast var.v_type { eexpr = TConst(const); etype = const_t; epos = pos },
-							Some(mk_cast var.v_type (mk_local nullable_var pos))
-						);
-						etype = var.v_type;
-						epos = pos;
-					}));
+					eexpr = TVar(var, Some(gen_check basic var.v_type nullable_var const pos));
 					etype = basic.tvoid;
 					epos = pos;
 				} :: !block;
@@ -10267,14 +10281,8 @@ struct
 												| None -> raise Not_found
 												| Some o -> o
 											in
-											let e = { e with eexpr = TLocal v2; etype = basic.tnull e.etype } in
-											let const = mk_cast e.etype { e with eexpr = TConst(o); etype = follow v.v_type } in
 											found := true;
-											{ e with eexpr = TIf({
-												eexpr = TBinop(Ast.OpEq, e, null e.etype e.epos);
-												etype = basic.tbool;
-												epos = e.epos
-											}, const, Some e) }
+											gen_check gen.gcon.basic v.v_type v2 o e.epos
 										with | Not_found -> e)
 										| _ -> Type.map_expr replace_args e
 									in

+ 30 - 0
tests/unit/src/unit/issues/Issue3504.hx

@@ -0,0 +1,30 @@
+package unit.issues;
+
+private class A {
+	public var a:Int;
+	public function new(a) this.a = a;
+}
+
+private class B extends A {
+	public function new(a = false) {
+		super(a ? 1 : 0);
+	}
+}
+
+private class C extends A {
+    public function new(a:Null<Bool> = false) {
+        super(a ? 1 : 0);
+    }
+}
+
+class Issue3504 extends Test {
+	function test() {
+		eq(new B().a, 0);
+		eq(new B(false).a, 0);
+		eq(new B(true).a, 1);
+
+		eq(new C().a, 0);
+		eq(new C(false).a, 0);
+		eq(new C(true).a, 1);
+	}
+}