瀏覽代碼

disallow member field initialization of classes without constructors

Simon Krajewski 11 年之前
父節點
當前提交
190865aff9
共有 4 個文件被更改,包括 23 次插入24 次删除
  1. 2 0
      extra/CHANGES.txt
  2. 14 19
      filters.ml
  3. 4 3
      tests/unit/MyClass.hx
  4. 3 2
      tests/unit/TestType.hx

+ 2 - 0
extra/CHANGES.txt

@@ -6,7 +6,9 @@
 	all : fixed invalid cast-to-self generation on some abstracts
 	all : removed @:to Dynamic from UInt to avoid issues in the Map selection algorithm
 	all : fixed various issues with member/static extension macros
+	all : disallowed member field initialization of classes without constructors
 	flash : fixed invalid override involving single-constraint type parameters
+	flash8: fixed various bugs
 	js : disable Std.string optimization of basic type to avoid problems with null values
 
 2014-03-04: 3.1.0

+ 14 - 19
filters.ml

@@ -963,6 +963,13 @@ let add_field_inits ctx t =
 		match inits with
 		| [] -> ()
 		| _ ->
+			let cf_ctor = match c.cl_constructor with
+				| None ->
+					List.iter (fun cf -> display_error ctx "Cannot initialize member fields on classes that do not have a constructor" cf.cf_pos) inits;
+					error "Could not initialize member fields" c.cl_pos;
+				| Some cf ->
+					cf
+			in
 			let el = List.map (fun cf ->
 				match cf.cf_expr with
 				| None -> assert false
@@ -977,25 +984,13 @@ let add_field_inits ctx t =
 						eassign;
 			) inits in
 			let el = if !need_this then (mk (TVar((v, Some ethis))) ethis.etype ethis.epos) :: el else el in
-			match c.cl_constructor with
-			| None ->
-				let ct = TFun([],ctx.com.basic.tvoid) in
-				let ce = mk (TFunction {
-					tf_args = [];
-					tf_type = ctx.com.basic.tvoid;
-					tf_expr = mk (TBlock el) ctx.com.basic.tvoid c.cl_pos;
-				}) ct c.cl_pos in
-				let ctor = mk_field "new" ct c.cl_pos in
-				ctor.cf_kind <- Method MethNormal;
-				c.cl_constructor <- Some { ctor with cf_expr = Some ce };
-			| Some cf ->
-				match cf.cf_expr with
-				| Some { eexpr = TFunction f } ->
-					let bl = match f.tf_expr with {eexpr = TBlock b } -> b | x -> [x] in
-					let ce = mk (TFunction {f with tf_expr = mk (TBlock (el @ bl)) ctx.com.basic.tvoid c.cl_pos }) cf.cf_type cf.cf_pos in
-					c.cl_constructor <- Some {cf with cf_expr = Some ce }
-				| _ ->
-					assert false
+			match cf_ctor.cf_expr with
+			| Some { eexpr = TFunction f } ->
+				let bl = match f.tf_expr with {eexpr = TBlock b } -> b | x -> [x] in
+				let ce = mk (TFunction {f with tf_expr = mk (TBlock (el @ bl)) ctx.com.basic.tvoid c.cl_pos }) cf_ctor.cf_type cf_ctor.cf_pos in
+				c.cl_constructor <- Some {cf_ctor with cf_expr = Some ce }
+			| _ ->
+				assert false
 	in
 	match t with
 	| TClassDecl c ->

+ 4 - 3
tests/unit/MyClass.hx

@@ -135,9 +135,10 @@ class InitChildWithCtor extends InitBase {
 	}
 }
 
-class InitWithoutCtor {
-	public var i = 2;
-}
+// TODO: disallowed (issue #2722)
+//class InitWithoutCtor {
+	//public var i = 2;
+//}
 
 class InitProperties {
 	public var accNull(default, null):Int = 3;

+ 3 - 2
tests/unit/TestType.hx

@@ -393,8 +393,9 @@ class TestType extends Test {
 		eq(c.b, true);
 		eq(c.t, String);
 
-		var c = Type.createInstance(InitWithoutCtor, []);
-		eq(c.i, 2);
+		// TODO: disallowed (issue #2722)
+		//var c = Type.createInstance(InitWithoutCtor, []);
+		//eq(c.i, 2);
 
 		var c = new InitProperties();
 		eq(c.accNull, 3);