|
@@ -67,12 +67,22 @@ let keep_whole_enum dce en =
|
|
|
Meta.has Meta.Keep en.e_meta
|
|
|
|| not (dce.full || is_std_file dce en.e_module.m_extra.m_file || has_meta Meta.Dce en.e_meta)
|
|
|
|
|
|
-(* check if a field is kept *)
|
|
|
-let keep_field dce cf =
|
|
|
+(*
|
|
|
+ Check if a field is kept.
|
|
|
+ `keep_field` is checked to determine the DCE entry points, i.e. all fields that have `@:keep` or kept for other reasons.
|
|
|
+ And then it is used at the end to check which fields can be filtered from their classes.
|
|
|
+*)
|
|
|
+let rec keep_field dce cf c =
|
|
|
Meta.has Meta.Keep cf.cf_meta
|
|
|
|| Meta.has Meta.Used cf.cf_meta
|
|
|
|| cf.cf_name = "__init__"
|
|
|
|| is_extern_field cf
|
|
|
+ || (
|
|
|
+ cf.cf_name = "new"
|
|
|
+ && match c.cl_super with (* parent class kept constructor *)
|
|
|
+ | Some ({ cl_constructor = Some ctor } as csup, _) -> keep_field dce ctor csup
|
|
|
+ | _ -> false
|
|
|
+ )
|
|
|
|
|
|
(* marking *)
|
|
|
|
|
@@ -117,7 +127,11 @@ and mark_field dce c cf stat =
|
|
|
| None -> add cf
|
|
|
| Some (c,_) -> mark_field dce c cf stat
|
|
|
end else
|
|
|
- add cf
|
|
|
+ add cf;
|
|
|
+ if not stat then
|
|
|
+ match c.cl_constructor with
|
|
|
+ | None -> ()
|
|
|
+ | Some ctor -> mark_field dce c ctor false
|
|
|
end
|
|
|
|
|
|
let rec update_marked_class_fields dce c =
|
|
@@ -662,7 +676,7 @@ let run com main full =
|
|
|
| TClassDecl c ->
|
|
|
let keep_class = keep_whole_class dce c && (not c.cl_extern || c.cl_interface) in
|
|
|
let loop stat cf =
|
|
|
- if keep_class || keep_field dce cf then mark_field dce c cf stat
|
|
|
+ if keep_class || keep_field dce cf c then mark_field dce c cf stat
|
|
|
in
|
|
|
List.iter (loop true) c.cl_ordered_statics;
|
|
|
List.iter (loop false) c.cl_ordered_fields;
|
|
@@ -747,7 +761,7 @@ let run com main full =
|
|
|
(* add :keep so subsequent filter calls do not process class fields again *)
|
|
|
c.cl_meta <- (Meta.Keep,[],c.cl_pos) :: c.cl_meta;
|
|
|
c.cl_ordered_statics <- List.filter (fun cf ->
|
|
|
- let b = keep_field dce cf in
|
|
|
+ let b = keep_field dce cf c in
|
|
|
if not b then begin
|
|
|
if dce.debug then print_endline ("[DCE] Removed field " ^ (s_type_path c.cl_path) ^ "." ^ (cf.cf_name));
|
|
|
check_property cf true;
|
|
@@ -756,7 +770,7 @@ let run com main full =
|
|
|
b
|
|
|
) c.cl_ordered_statics;
|
|
|
c.cl_ordered_fields <- List.filter (fun cf ->
|
|
|
- let b = keep_field dce cf in
|
|
|
+ let b = keep_field dce cf c in
|
|
|
if not b then begin
|
|
|
if dce.debug then print_endline ("[DCE] Removed field " ^ (s_type_path c.cl_path) ^ "." ^ (cf.cf_name));
|
|
|
check_property cf false;
|
|
@@ -764,7 +778,7 @@ let run com main full =
|
|
|
end;
|
|
|
b
|
|
|
) c.cl_ordered_fields;
|
|
|
- (match c.cl_constructor with Some cf when not (keep_field dce cf) -> c.cl_constructor <- None | _ -> ());
|
|
|
+ (match c.cl_constructor with Some cf when not (keep_field dce cf c) -> c.cl_constructor <- None | _ -> ());
|
|
|
let inef cf = not (is_extern_field cf) in
|
|
|
let has_non_extern_fields = List.exists inef c.cl_ordered_fields || List.exists inef c.cl_ordered_statics in
|
|
|
(* we keep a class if it was used or has a used field *)
|