浏览代码

Merge pull request #3483 from HaxeFoundation/jsrequire_clean

[js/python] don't generate require/import for types that are not directly referenced by non-extern code
Simon Krajewski 11 年之前
父节点
当前提交
8c0300fafa
共有 5 个文件被更改,包括 28 次插入3 次删除
  1. 1 0
      ast.ml
  2. 1 0
      common.ml
  3. 24 1
      dce.ml
  4. 1 1
      genjs.ml
  5. 1 1
      genpy.ml

+ 1 - 0
ast.ml

@@ -124,6 +124,7 @@ module Meta = struct
 		| Public
 		| Public
 		| PublicFields
 		| PublicFields
 		| ReadOnly
 		| ReadOnly
+		| ReallyUsed
 		| RealPath
 		| RealPath
 		| Remove
 		| Remove
 		| Require
 		| Require

+ 1 - 0
common.ml

@@ -433,6 +433,7 @@ module MetaInfo = struct
 		| Protected -> ":protected",("Marks a class field as being protected",[UsedOn TClassField])
 		| Protected -> ":protected",("Marks a class field as being protected",[UsedOn TClassField])
 		| Property -> ":property",("Marks a property field to be compiled as a native C# property",[UsedOn TClassField;Platform Cs])
 		| Property -> ":property",("Marks a property field to be compiled as a native C# property",[UsedOn TClassField;Platform Cs])
 		| ReadOnly -> ":readOnly",("Generates a field with the 'readonly' native keyword",[Platform Cs; UsedOn TClassField])
 		| ReadOnly -> ":readOnly",("Generates a field with the 'readonly' native keyword",[Platform Cs; UsedOn TClassField])
+		| ReallyUsed -> ":reallyUsed",("Marks types that are directly referenced by non-extern code",[Internal])
 		| RealPath -> ":realPath",("Internally used on @:native types to retain original path information",[Internal])
 		| RealPath -> ":realPath",("Internally used on @:native types to retain original path information",[Internal])
 		| Remove -> ":remove",("Causes an interface to be removed from all implementing classes before generation",[UsedOn TClass])
 		| Remove -> ":remove",("Causes an interface to be removed from all implementing classes before generation",[UsedOn TClass])
 		| Require -> ":require",("Allows access to a field only if the specified compiler flag is set",[HasParam "Compiler flag to check";UsedOn TClassField])
 		| Require -> ":require",("Allows access to a field only if the specified compiler flag is set",[HasParam "Compiler flag to check";UsedOn TClassField])

+ 24 - 1
dce.ml

@@ -282,11 +282,23 @@ and field dce c n stat =
 	with Not_found ->
 	with Not_found ->
 		if dce.debug then prerr_endline ("[DCE] Field " ^ n ^ " not found on " ^ (s_type_path c.cl_path)) else ())
 		if dce.debug then prerr_endline ("[DCE] Field " ^ n ^ " not found on " ^ (s_type_path c.cl_path)) else ())
 
 
+and mark_really_used_class c =
+	if not (Meta.has Meta.ReallyUsed c.cl_meta) then
+		c.cl_meta <- (Meta.ReallyUsed,[],c.cl_pos) :: c.cl_meta
+
+and mark_really_used_mt mt =
+	match mt with
+	| TClassDecl c ->
+		mark_really_used_class c
+	| _ ->
+		()
+
 and expr dce e =
 and expr dce e =
 	mark_t dce e.epos e.etype;
 	mark_t dce e.epos e.etype;
 	match e.eexpr with
 	match e.eexpr with
 	| TNew(c,pl,el) ->
 	| TNew(c,pl,el) ->
 		mark_class dce c;
 		mark_class dce c;
+		mark_really_used_class c;
 		field dce c "new" false;
 		field dce c "new" false;
 		List.iter (expr dce) el;
 		List.iter (expr dce) el;
 		List.iter (mark_t dce e.epos) pl;
 		List.iter (mark_t dce e.epos) pl;
@@ -296,9 +308,11 @@ and expr dce e =
 	| TCast(e, Some mt) ->
 	| TCast(e, Some mt) ->
 		check_feature dce "typed_cast";
 		check_feature dce "typed_cast";
 		mark_mt dce mt;
 		mark_mt dce mt;
+		mark_really_used_mt mt;
 		expr dce e;
 		expr dce e;
 	| TTypeExpr mt ->
 	| TTypeExpr mt ->
-		mark_mt dce mt
+		mark_mt dce mt;
+		mark_really_used_mt mt;
 	| TTry(e, vl) ->
 	| TTry(e, vl) ->
 		expr dce e;
 		expr dce e;
 		List.iter (fun (v,e) ->
 		List.iter (fun (v,e) ->
@@ -560,6 +574,15 @@ let run com main full =
 		| _ -> ()
 		| _ -> ()
 	) com.types;
 	) com.types;
 
 
+	(* mark extern classes as really used if they are extended by non-extern ones *)
+	List.iter (function
+		| TClassDecl ({cl_extern = false; cl_super = Some ({cl_extern = true} as csup, _)}) ->
+			mark_really_used_class csup
+		| TClassDecl ({cl_extern = false} as c) when c.cl_implements <> [] ->
+			List.iter (fun (iface,_) -> if (iface.cl_extern) then mark_really_used_class iface) c.cl_implements;
+		| _ -> ()
+	) com.types;
+
 	(* cleanup added fields metadata - compatibility with compilation server *)
 	(* cleanup added fields metadata - compatibility with compilation server *)
 	let rec remove_meta m = function
 	let rec remove_meta m = function
 		| [] -> []
 		| [] -> []

+ 1 - 1
genjs.ml

@@ -1153,7 +1153,7 @@ let generate_type ctx = function
 			()
 			()
 		else if not c.cl_extern then
 		else if not c.cl_extern then
 			generate_class ctx c
 			generate_class ctx c
-		else if Meta.has Meta.JsRequire c.cl_meta then
+		else if (Meta.has Meta.JsRequire c.cl_meta) && (Meta.has Meta.ReallyUsed c.cl_meta) then
 			generate_require ctx c
 			generate_require ctx c
 		else if not ctx.js_flatten && Meta.has Meta.InitPackage c.cl_meta then
 		else if not ctx.js_flatten && Meta.has Meta.InitPackage c.cl_meta then
 			(match c.cl_path with
 			(match c.cl_path with

+ 1 - 1
genpy.ml

@@ -1920,7 +1920,7 @@ module Generator = struct
 	let gen_import ctx c =
 	let gen_import ctx c =
 		gen_pre_code_meta ctx c.cl_meta;
 		gen_pre_code_meta ctx c.cl_meta;
 
 
-		if Meta.has Meta.PythonImport c.cl_meta then begin
+		if (Meta.has Meta.PythonImport c.cl_meta) && (Meta.has Meta.ReallyUsed c.cl_meta) then begin
 			let _, args, mp = Meta.get Meta.PythonImport c.cl_meta in
 			let _, args, mp = Meta.get Meta.PythonImport c.cl_meta in
 
 
 			let class_name = match c.cl_path with
 			let class_name = match c.cl_path with