Browse Source

[cs] Always encapsulate the rest of a constructor expression inside a block

This solves possible scope issues that may arise from moving all the
init code into the constructor. Closes #6291
Caue Waneck 7 năm trước cách đây
mục cha
commit
29932f8510

+ 7 - 5
src/codegen/gencommon/initFunction.ml

@@ -201,16 +201,18 @@ let handle_class com cl =
 						| TBlock(hd :: tl) ->
 							(match hd.eexpr with
 							| TCall ({ eexpr = TConst TSuper }, _) ->
+								let tl_block = { e with eexpr = TBlock(tl) } in
 								if not (OverloadingConstructor.descends_from_native_or_skipctor cl) then
-									{ e with eexpr = TBlock (vars @ (hd :: (funs @ tl))) }
+									{ e with eexpr = TBlock (vars @ (hd :: (funs @ [tl_block]))) }
 								else
-									{ e with eexpr = TBlock (hd :: (vars @ funs @ tl)) }
+									{ e with eexpr = TBlock (hd :: (vars @ funs @ [tl_block])) }
 							| TBlock _ ->
-								{ e with eexpr = TBlock ((add_fn hd) :: tl) }
+								let tl_block = { e with eexpr = TBlock(tl) } in
+								{ e with eexpr = TBlock ((add_fn hd) :: [tl_block]) }
 							| _ ->
-								{ e with eexpr = TBlock (vars @ funs @ (hd :: tl)) })
+								{ e with eexpr = TBlock (vars @ funs @ [{ e with eexpr = TBlock(hd :: tl) }]) })
 						| _ ->
-							Type.concat { e with eexpr = TBlock (vars @ funs) } e
+							Type.concat { e with eexpr = TBlock (vars @ funs) } { e with eexpr = TBlock([e]) }
 					in
 					let tf_expr = add_fn (mk_block tf.tf_expr) in
 					{ e with eexpr = TFunction { tf with tf_expr = tf_expr } }

+ 35 - 0
tests/unit/src/unit/issues/Issue6291.hx

@@ -0,0 +1,35 @@
+package unit.issues;
+
+class Issue6291 extends Test
+{
+  public function test()
+  {
+    var b = new BadCode();
+    eq(b.d1.get('a'), 1);
+  }
+}
+
+#if (cs || java)
+@:nativeGen @:keep
+#end
+private class BadCode {
+  public var d1:Dictionary= new Dictionary();
+  public var d2:Dictionary= new Dictionary();
+  public var d3:Dictionary= new Dictionary();
+  public var d4:Dictionary= new Dictionary();
+  public var d5:Dictionary;
+
+  public function new() {
+    d5 = new Dictionary();
+  }
+}
+
+@:forward
+private abstract Dictionary(Map<String, Dynamic>)
+{
+  inline public function new()
+  {
+    this = new Map();
+    this.set('a', 1);
+  }
+}