Simon Krajewski 9 лет назад
Родитель
Сommit
46518add39
3 измененных файлов с 77 добавлено и 1 удалено
  1. 10 1
      optimizer.ml
  2. 49 0
      tests/optimization/src/issues/Issue4690.hx
  3. 18 0
      tests/unit/src/unit/issues/Issue4690.hx

+ 10 - 1
optimizer.ml

@@ -524,6 +524,15 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 			in_local_fun := old_fun;
 			old();
 			{ e with eexpr = TFunction { tf_args = args; tf_expr = expr; tf_type = f.tf_type } }
+		| TCall({eexpr = TConst TSuper; etype = t},el) ->
+			begin match follow t with
+			| TInst({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction tf})} as cf)},_) ->
+				begin match type_inline ctx cf tf ethis el ctx.t.tvoid None po true with
+				| Some e -> map term e
+				| None -> error "Could not inline super constructor call" po
+				end
+			| _ -> error "Cannot inline function containint super" po
+			end
 		| TConst TSuper ->
 			error "Cannot inline function containing super" po
 		| TMeta(m,e1) ->
@@ -1359,7 +1368,7 @@ let inline_constructors ctx e =
 					| [] ->
 						()
 					end
-				| TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction tf})} as cf)} as c,tl,pl) when type_iseq v.v_type e1.etype->
+				| TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction tf})} as cf)} as c,tl,pl) when type_iseq v.v_type e1.etype ->
 					begin match type_inline ctx cf tf (mk (TLocal v) (TInst (c,tl)) e1.epos) pl ctx.t.tvoid None e1.epos true with
 					| Some e ->
 						(* add field inits here because the filter has not run yet (issue #2336) *)

+ 49 - 0
tests/optimization/src/issues/Issue4690.hx

@@ -0,0 +1,49 @@
+package issues;
+
+class Parent {
+	public var x:Int;
+	public var y:String;
+
+	public inline function new(x:Int, y:String) {
+		trace("Parent.new: Before assign");
+		this.x = x;
+		this.y = y;
+		trace("Parent.new: After assign");
+	}
+}
+
+class Child extends Parent {
+
+	public var z:Int;
+
+	public inline function new(x:Int, y:Int, z:Int) {
+		trace("Child.new: Before super");
+		super(x, Std.string(y));
+		trace("Child.new: After super");
+		this.z = z;
+		trace("Child new: After assign");
+	}
+}
+
+class Issue4690 {
+	@:js('
+		console.log("Child.new: Before super");
+		console.log("Parent.new: Before assign");
+		var c_x = 1;
+		var c_y = "" + 2;
+		console.log("Parent.new: After assign");
+		console.log("Child.new: After super");
+		var c_z = 3;
+		console.log("Child new: After assign");
+		console.log(c_x);
+		console.log(c_y);
+		console.log(c_z);
+	')
+	@:analyzer(no_const_propagation)
+	static function test() {
+		var c = new Child(1, 2, 3);
+		trace(c.x);
+		trace(c.y);
+		trace(c.z);
+	}
+}

+ 18 - 0
tests/unit/src/unit/issues/Issue4690.hx

@@ -0,0 +1,18 @@
+package unit.issues;
+
+private class Parent {
+	public var x:Int;
+
+	public inline function new(x:Int) {
+		this.x = x;
+	}
+}
+
+private class Child extends Parent { }
+
+class Issue4690 extends Test {
+	function test() {
+		var x = new Child(12);
+		eq(12, x.x);
+	}
+}