浏览代码

[js] rework Type.instanceFields for -D js-es=6 (#7825)

Dan Korostelev 6 年之前
父节点
当前提交
77b4377d03
共有 2 个文件被更改,包括 41 次插入28 次删除
  1. 27 25
      src/generators/genjs.ml
  2. 14 3
      std/js/_std/Type.hx

+ 27 - 25
src/generators/genjs.ml

@@ -1176,15 +1176,19 @@ let generate_class_es6 ctx c =
 		ctx.separator <- false
 	| _ -> ());
 
-	List.iter (fun cf ->
-		match cf.cf_kind, cf.cf_expr with
-		| Method _, Some { eexpr = TFunction f; epos = pos } ->
-			check_field_name c cf;
-			newline ctx;
-			gen_function ~keyword:cf.cf_name ctx f pos;
-			ctx.separator <- false
-		| _ -> ()
-	) c.cl_ordered_fields;
+	let nonmethod_fields = 
+		List.filter (fun cf ->
+			match cf.cf_kind, cf.cf_expr with
+			| Method _, Some { eexpr = TFunction f; epos = pos } ->
+				check_field_name c cf;
+				newline ctx;
+				gen_function ~keyword:cf.cf_name ctx f pos;
+				ctx.separator <- false;
+				false
+			| _ ->
+				true
+		) c.cl_ordered_fields
+	in
 	
 	let exposed_static_methods = ref [] in
 	let nonmethod_statics =
@@ -1263,25 +1267,19 @@ let generate_class_es6 ctx c =
 		end
 	| None -> ());
 
-	if has_feature ctx "Type.getInstanceFields" then begin
-		let rec loop c acc =
-			let fields = List.filter (fun cf -> cf.cf_name <> ES6Ctors.ctor_method_name && is_physical_field cf && not (List.memq cf c.cl_overrides)) c.cl_ordered_fields in
-			let acc = acc @ List.map (fun cf -> "\"" ^ cf.cf_name ^ "\"") fields in
-			match c.cl_super with
-			| None -> acc
-			| Some (csup,_) -> loop csup acc
-		in
-		match loop c [] with
-		| [] -> ()
-		| fl ->
-			print ctx "%s.__instanceFields__ = [%s];" p (String.concat "," fl);
-			newline ctx
-	end;
-
 	let has_class = has_feature ctx "js.Boot.getClass" && (c.cl_super <> None || c.cl_ordered_fields <> [] || c.cl_constructor <> None) in
 	let props_to_generate = if has_property_reflection then Codegen.get_properties c.cl_ordered_fields else [] in
+	let fields_to_generate =
+		if has_feature ctx "Type.getInstanceFields" then
+			if c.cl_interface then
+				List.filter is_physical_field c.cl_ordered_fields
+			else
+				List.filter is_physical_var_field nonmethod_fields
+		else
+			[]
+	in
 
-	if has_class || props_to_generate <> [] then begin
+	if has_class || props_to_generate <> [] || fields_to_generate <> [] then begin
 		print ctx "Object.assign(%s.prototype, {" p;
 		let bend = open_block ctx in
 
@@ -1290,6 +1288,10 @@ let generate_class_es6 ctx c =
 			print ctx "__class__: %s" p
 		end;
 
+		if fields_to_generate <> [] then begin
+			List.iter (gen_class_field ctx c) fields_to_generate;
+		end;
+
 		if props_to_generate <> [] then begin
 			newprop ctx;
 			match c.cl_super with

+ 14 - 3
std/js/_std/Type.hx

@@ -159,8 +159,20 @@ enum ValueType {
 
 	#if (js_es >= 6)
 	public static function getInstanceFields( c : Class<Dynamic> ) : Array<String> {
-		var fields:Null<Array<String>> = (cast c).__instanceFields__;
-		return if (fields == null) [] else fields.copy();
+		var result = [];
+		while (c != null) {
+			for (name in js.Object.getOwnPropertyNames((cast c).prototype)) {
+				switch name {
+					case "constructor" | "__class__" | "__properties__":
+						// skip special names
+					case _:
+						if (result.indexOf(name) == -1)
+							result.push(name);
+				}
+			}
+			c = getSuperClass(c);
+		}
+		return result;
 	}
 
 	public static function getClassFields( c : Class<Dynamic> ) : Array<String> {
@@ -310,4 +322,3 @@ enum ValueType {
 	}
 
 }
-