浏览代码

[js] don't use enum names as object fields (closes #9345)

Aleksandr Kuzmenko 5 年之前
父节点
当前提交
7de956f847
共有 3 个文件被更改,包括 26 次插入12 次删除
  1. 9 4
      src/generators/genjs.ml
  2. 2 2
      std/js/Boot.hx
  3. 15 6
      std/js/_std/Type.hx

+ 9 - 4
src/generators/genjs.ml

@@ -1503,8 +1503,11 @@ let generate_enum ctx e =
 	else if has_feature ctx "Type.resolveEnum" then
 	else if has_feature ctx "Type.resolveEnum" then
 		print ctx "$hxClasses[\"%s\"] = " dotp);
 		print ctx "$hxClasses[\"%s\"] = " dotp);
 	spr ctx "{";
 	spr ctx "{";
-	if has_feature ctx "js.Boot.isEnum" then print ctx " __ename__ : %s," (if has_feature ctx "Type.getEnumName" then "\"" ^ dotp ^ "\"" else "true");
-	print ctx " __constructs__ : [%s]" (String.concat "," (List.map (fun s -> Printf.sprintf "\"%s\"" s) e.e_names));
+	if has_feature ctx "js.Boot.isEnum" then print ctx " __ename__:%s," (if has_feature ctx "Type.getEnumName" then "\"" ^ dotp ^ "\"" else "true");
+	if as_objects then
+		print ctx "__constructs__:null"
+	else
+		print ctx "__constructs__:[%s]" (String.concat "," (List.map (fun s -> Printf.sprintf "\"%s\"" s) e.e_names));
 	let bend =
 	let bend =
 		if not as_objects then begin
 		if not as_objects then begin
 			spr ctx " }";
 			spr ctx " }";
@@ -1531,7 +1534,7 @@ let generate_enum ctx e =
 				print ctx "($_=function(%s) { return {_hx_index:%d,%s,__enum__:\"%s\"" sargs f.ef_index sfields dotp;
 				print ctx "($_=function(%s) { return {_hx_index:%d,%s,__enum__:\"%s\"" sargs f.ef_index sfields dotp;
 				if has_enum_feature then
 				if has_enum_feature then
 					spr ctx ",toString:$estr";
 					spr ctx ",toString:$estr";
-				print ctx "}; },$_.__params__ = [%s],$_)" sparams
+				print ctx "}; },$_._hx_name=\"%s\",$_.__params__ = [%s],$_)" f.ef_name sparams
 			end else begin
 			end else begin
 				print ctx "function(%s) { var $x = [\"%s\",%d,%s]; $x.__enum__ = %s;" sargs f.ef_name f.ef_index sargs p;
 				print ctx "function(%s) { var $x = [\"%s\",%d,%s]; $x.__enum__ = %s;" sargs f.ef_name f.ef_index sargs p;
 				if has_enum_feature then
 				if has_enum_feature then
@@ -1540,7 +1543,7 @@ let generate_enum ctx e =
 			end end;
 			end end;
 		| _ ->
 		| _ ->
 			if as_objects then
 			if as_objects then
-				print ctx "{_hx_index:%d,__enum__:\"%s\"%s}" f.ef_index dotp (if has_enum_feature then ",toString:$estr" else "")
+				print ctx "{_hx_name:\"%s\",_hx_index:%d,__enum__:\"%s\"%s}" f.ef_name f.ef_index dotp (if has_enum_feature then ",toString:$estr" else "")
 			else begin
 			else begin
 				print ctx "[\"%s\",%d]" f.ef_name f.ef_index;
 				print ctx "[\"%s\",%d]" f.ef_name f.ef_index;
 				newline ctx;
 				newline ctx;
@@ -1559,6 +1562,8 @@ let generate_enum ctx e =
 		spr ctx "\n}";
 		spr ctx "\n}";
 		ctx.separator <- true;
 		ctx.separator <- true;
 		newline ctx;
 		newline ctx;
+		print ctx "%s.__constructs__ = [%s]" p (String.concat "," (List.map (fun s -> Printf.sprintf "%s%s" p (field s)) e.e_names));
+		newline ctx;
 	end;
 	end;
 	if has_feature ctx "Type.allEnums" then begin
 	if has_feature ctx "Type.allEnums" then begin
 		let ctors_without_args = List.filter (fun s ->
 		let ctors_without_args = List.filter (fun s ->

+ 2 - 2
std/js/Boot.hx

@@ -69,8 +69,8 @@ class Boot {
 					#if !js_enums_as_arrays
 					#if !js_enums_as_arrays
 					__feature__("has_enum", if (o.__enum__) {
 					__feature__("has_enum", if (o.__enum__) {
 						var e = $hxEnums[o.__enum__];
 						var e = $hxEnums[o.__enum__];
-						var n = e.__constructs__[o._hx_index];
-						var con = e[n];
+						var con = e.__constructs__[o._hx_index];
+						var n = con._hx_name;
 						if (con.__params__) {
 						if (con.__params__) {
 							s += "\t";
 							s += "\t";
 							return n + "(" + [for (p in (con.__params__ : Array<String>)) __string_rec(o[p], s)].join(",") + ")";
 							return n + "(" + [for (p in (con.__params__ : Array<String>)) __string_rec(o[p], s)].join(",") + ")";

+ 15 - 6
std/js/_std/Type.hx

@@ -158,7 +158,14 @@ enum ValueType {
 	}
 	}
 
 
 	public static function createEnumIndex<T>(e:Enum<T>, index:Int, ?params:Array<Dynamic>):T {
 	public static function createEnumIndex<T>(e:Enum<T>, index:Int, ?params:Array<Dynamic>):T {
+		#if js_enums_as_arrays
 		var c:String = (untyped e.__constructs__)[index];
 		var c:String = (untyped e.__constructs__)[index];
+		#else
+		var c:String = switch (untyped e.__constructs__)[index] {
+			case null: null;
+			case ctor: ctor._hx_name;
+		}
+		#end
 		if (c == null)
 		if (c == null)
 			throw index + " is not a valid enum constructor index";
 			throw index + " is not a valid enum constructor index";
 		return createEnum(e, c, params);
 		return createEnum(e, c, params);
@@ -220,7 +227,11 @@ enum ValueType {
 	#end
 	#end
 
 
 	public static inline function getEnumConstructs(e:Enum<Dynamic>):Array<String> {
 	public static inline function getEnumConstructs(e:Enum<Dynamic>):Array<String> {
-		return ((cast e).__constructs__ : Array<String>).copy();
+		#if js_enums_as_arrays
+			return ((cast e).__constructs__ : Array<String>).copy();
+		#else
+			return ((cast e).__constructs__ : Array<{_hx_name:String}>).map(c -> c._hx_name);
+		#end
 	}
 	}
 
 
 	@:access(js.Boot)
 	@:access(js.Boot)
@@ -279,8 +290,7 @@ enum ValueType {
 				if (a._hx_index != b._hx_index)
 				if (a._hx_index != b._hx_index)
 					return false;
 					return false;
 				var enm = $hxEnums[e];
 				var enm = $hxEnums[e];
-				var ctorName = enm.__constructs__[a._hx_index];
-				var params:Array<String> = enm[ctorName].__params__;
+				var params:Array<String> = enm.__constructs__[a._hx_index].__params__;
 				for (f in params) {
 				for (f in params) {
 					if (!enumEq(a[f], b[f])) {
 					if (!enumEq(a[f], b[f])) {
 						return false;
 						return false;
@@ -297,7 +307,7 @@ enum ValueType {
 		#if js_enums_as_arrays
 		#if js_enums_as_arrays
 		return untyped e[0];
 		return untyped e[0];
 		#else
 		#else
-		return untyped $hxEnums[e.__enum__].__constructs__[e._hx_index];
+		return untyped $hxEnums[e.__enum__].__constructs__[e._hx_index]._hx_name;
 		#end
 		#end
 	}
 	}
 
 
@@ -309,8 +319,7 @@ enum ValueType {
 	public static function enumParameters(e:EnumValue):Array<Dynamic>
 	public static function enumParameters(e:EnumValue):Array<Dynamic>
 		untyped {
 		untyped {
 			var enm:Enum<Dynamic> = $hxEnums[e.__enum__];
 			var enm:Enum<Dynamic> = $hxEnums[e.__enum__];
-			var ctorName:String = enm.__constructs__[e._hx_index];
-			var params:Array<String> = enm[ctorName].__params__;
+			var params:Array<String> = enm.__constructs__[e._hx_index].__params__;
 			return params != null ? [for (p in params) e[p]] : [];
 			return params != null ? [for (p in params) e[p]] : [];
 		}
 		}
 	#end
 	#end