Browse Source

move more things around (#11854)

Simon Krajewski 7 months ago
parent
commit
a3a23cce9c

+ 0 - 345
src/codegen/codegen.ml

@@ -19,7 +19,6 @@
 
 open Ast
 open Type
-open Common
 open Globals
 open Extlib_leftovers
 
@@ -48,152 +47,6 @@ let get_properties fields =
 			| _ -> acc
 	) [] fields
 
-let add_property_field com c =
-	let p = c.cl_pos in
-	let props = get_properties (c.cl_ordered_statics @ c.cl_ordered_fields) in
-	match props with
-	| [] -> ()
-	| _ ->
-		let fields,values = List.fold_left (fun (fields,values) (n,v) ->
-			let cf = mk_field n com.basic.tstring p null_pos in
-			PMap.add n cf fields,((n,null_pos,NoQuotes),Texpr.Builder.make_string com.basic v p) :: values
-		) (PMap.empty,[]) props in
-		let t = mk_anon ~fields (ref Closed) in
-		let e = mk (TObjectDecl values) t p in
-		let cf = mk_field ~static:true "__properties__" t p null_pos in
-		cf.cf_expr <- Some e;
-		c.cl_statics <- PMap.add cf.cf_name cf c.cl_statics;
-		c.cl_ordered_statics <- cf :: c.cl_ordered_statics
-
-(* -------------------------------------------------------------------------- *)
-(* FIX OVERRIDES *)
-
-(*
-	on some platforms which doesn't support type parameters, we must have the
-	exact same type for overridden/implemented function as the original one
-*)
-
-let rec find_field com c f =
-	try
-		(match c.cl_super with
-		| None ->
-			raise Not_found
-		| Some ( {cl_path = (["cpp"],"FastIterator")}, _ ) ->
-			raise Not_found (* This is a strongly typed 'extern' and the usual rules don't apply *)
-		| Some (c,_) ->
-			find_field com c f)
-	with Not_found -> try
-		if com.platform = Cpp || com.platform = Hl then (* uses delegation for interfaces *)
-			raise Not_found;
-		let rec loop = function
-			| [] ->
-				raise Not_found
-			| (c,_) :: l ->
-				try
-					find_field com c f
-				with
-					Not_found -> loop l
-		in
-		loop c.cl_implements
-	with Not_found ->
-		let f = PMap.find f.cf_name c.cl_fields in
-		(match f.cf_kind with Var { v_read = AccRequire _ } -> raise Not_found | _ -> ());
-		f
-
-let fix_override com c f fd =
-	let f2 = (try Some (find_field com c f) with Not_found -> None) in
-	match f2,fd with
-		| Some (f2), Some(fd) ->
-			let targs, tret = (match follow f2.cf_type with TFun (args,ret) -> args, ret | _ -> die "" __LOC__) in
-			let changed_args = ref [] in
-			let prefix = "_tmp_" in
-			let nargs = List.map2 (fun ((v,ct) as cur) (_,_,t2) ->
-				try
-					type_eq EqStrict (monomorphs c.cl_params (monomorphs f.cf_params v.v_type)) t2;
-					(* Flash generates type parameters with a single constraint as that constraint type, so we
-					   have to detect this case and change the variable (issue #2712). *)
-					begin match follow v.v_type with
-						| TInst({cl_kind = KTypeParameter ttp} as cp,_) when com.platform = Flash ->
-							begin match get_constraints ttp with
-							| [tc] ->
-								if List.exists (fun tp -> tp.ttp_name = (snd cp.cl_path)) c.cl_params then raise (Unify_error [])
-							| _ ->
-								()
-							end
-						| _ ->
-							()
-					end;
-					cur
-				with Unify_error _ ->
-					let v2 = alloc_var VGenerated (prefix ^ v.v_name) t2 v.v_pos in
-					changed_args := (v,v2) :: !changed_args;
-					v2,ct
-			) fd.tf_args targs in
-			let fd2 = {
-				tf_args = nargs;
-				tf_type = tret;
-				tf_expr = (match List.rev !changed_args with
-					| [] -> fd.tf_expr
-					| args ->
-						let e = fd.tf_expr in
-						let el = (match e.eexpr with TBlock el -> el | _ -> [e]) in
-						let p = (match el with [] -> e.epos | e :: _ -> e.epos) in
-						let el_v = List.map (fun (v,v2) ->
-							mk (TVar (v,Some (mk (TCast (mk (TLocal v2) v2.v_type p,None)) v.v_type p))) com.basic.tvoid p
-						) args in
-						{ e with eexpr = TBlock (el_v @ el) }
-				);
-			} in
-			let targs = List.map (fun(v,c) -> (v.v_name, Option.is_some c, v.v_type)) nargs in
-			let fde = (match f.cf_expr with None -> die "" __LOC__ | Some e -> e) in
-			f.cf_expr <- Some { fde with eexpr = TFunction fd2 };
-			f.cf_type <- TFun(targs,tret);
-		| Some(f2), None when (has_class_flag c CInterface) ->
-			let targs, tret = (match follow f2.cf_type with TFun (args,ret) -> args, ret | _ -> die "" __LOC__) in
-			f.cf_type <- TFun(targs,tret)
-		| _ ->
-			()
-
-let fix_overrides com t =
-	match t with
-	| TClassDecl c ->
-		(* overrides can be removed from interfaces *)
-		if (has_class_flag c CInterface) then
-			c.cl_ordered_fields <- List.filter (fun f ->
-				try
-					if find_field com c f == f then raise Not_found;
-					c.cl_fields <- PMap.remove f.cf_name c.cl_fields;
-					false;
-				with Not_found ->
-					true
-			) c.cl_ordered_fields;
-		List.iter (fun f ->
-			match f.cf_expr, f.cf_kind with
-			| Some { eexpr = TFunction fd }, Method (MethNormal | MethInline) ->
-				fix_override com c f (Some fd)
-			| None, Method (MethNormal | MethInline) when (has_class_flag c CInterface) ->
-				fix_override com c f None
-			| _ ->
-				()
-		) c.cl_ordered_fields
-	| _ ->
-		()
-
-(*
-	PHP does not allow abstract classes extending other abstract classes to override any fields, so these duplicates
-	must be removed from the child interface
-*)
-let fix_abstract_inheritance com t =
-	match t with
-	| TClassDecl c when (has_class_flag c CInterface) ->
-		c.cl_ordered_fields <- List.filter (fun f ->
-			let b = try (find_field com c f) == f
-			with Not_found -> false in
-			if not b then c.cl_fields <- PMap.remove f.cf_name c.cl_fields;
-			b;
-		) c.cl_ordered_fields
-	| _ -> ()
-
 (* -------------------------------------------------------------------------- *)
 (* MISC FEATURES *)
 
@@ -216,204 +69,6 @@ let bytes_serialize data =
 	let tbl = Array.init (String.length b64) (fun i -> String.get b64 i) in
 	Bytes.unsafe_to_string (Base64.str_encode ~tbl data)
 
-module Dump = struct
-	(*
-		Make a dump of the full typed AST of all types
-	*)
-	let create_dumpfile acc l =
-		let ch = Path.create_file false ".dump" acc l in
-		let buf = Buffer.create 0 in
-		buf, (fun () ->
-			output_string ch (Buffer.contents buf);
-			close_out ch)
-
-	let create_dumpfile_from_path com path =
-		let buf,close = create_dumpfile [] ((dump_path com) :: (platform_name_macro com) :: fst path @ [snd path]) in
-		buf,close
-
-	let dump_types com pretty =
-		let s_type = s_type (Type.print_context()) in
-		let s_expr,s_type_param = if not pretty then
-			(Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t"),(Printer.s_type_param "")
-		else
-			(Type.s_expr_pretty false "\t" true),(s_type_param s_type)
-		in
-		let params tl = match tl with
-			| [] -> ""
-			| l -> Printf.sprintf "<%s>" (String.concat ", " (List.map s_type_param l))
-		in
-		List.iter (fun mt ->
-			let path = Type.t_path mt in
-			let buf,close = create_dumpfile_from_path com path in
-			let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
-			let s_metas ml tabs =
-				let args el =
-					match el with
-					| [] -> ""
-					| el -> Printf.sprintf "(%s)" (String.concat ", " (List.map (fun e -> Ast.Printer.s_expr e) el)) in
-				match ml with
-				| [] -> ""
-				| ml -> String.concat " " (List.map (fun me -> match me with (m,el,_) -> "@" ^ Meta.to_string m ^ args el) ml) ^ "\n" ^ tabs in
-			(match mt with
-			| Type.TClassDecl c ->
-				let s_cf_expr f =
-					match f.cf_expr with
-					| None -> ""
-					| Some e -> Printf.sprintf "%s" (s_expr s_type e) in
-				let is_inline_var v : bool = v = Var { v_read = AccInline; v_write = AccNever } in
-				let rec print_field stat f =
-					print "\n\t%s%s%s%s%s %s%s"
-						(s_metas f.cf_meta "\t")
-						(if (has_class_field_flag f CfPublic && not ((has_class_flag c CExtern) || (has_class_flag c CInterface))) then "public " else "")
-						(if stat then "static " else "")
-						(match f.cf_kind with
-							| Var v when (is_inline_var f.cf_kind) -> "inline "
-							| Var v -> ""
-							| Method m ->
-								match m with
-								| MethNormal -> ""
-								| MethDynamic -> "dynamic "
-								| MethInline -> "inline "
-								| MethMacro -> "macro ")
-						(match f.cf_kind with Var v -> "var" | Method m -> "function")
-						(f.cf_name ^ match f.cf_kind with
-							| Var { v_read = AccNormal; v_write = AccNormal } -> ""
-							| Var v when (is_inline_var f.cf_kind) -> ""
-							| Var v -> "(" ^ s_access true v.v_read ^ "," ^ s_access false v.v_write ^ ")"
-							| _ -> "")
-						(params f.cf_params);
-					(match f.cf_kind with
-						| Var v -> print ":%s%s;" (s_type f.cf_type)
-							(match f.cf_expr with
-							| None -> ""
-							| Some e -> " = " ^ (s_cf_expr f));
-						| Method m -> if ((has_class_flag c CExtern) || (has_class_flag c CInterface)) then (
-							match f.cf_type with
-							| TFun(al,t) -> print "(%s):%s;" (String.concat ", " (
-								List.map (fun (n,o,t) -> n ^ ":" ^ (s_type t)) al))
-								(s_type t)
-							| _ -> ()
-						) else print "%s" (s_cf_expr f));
-					print "\n";
-					List.iter (fun f -> print_field stat f) f.cf_overloads
-				in
-				print "%s%s%s%s %s%s" (s_metas c.cl_meta "") (if c.cl_private then "private " else "") (if (has_class_flag c CExtern) then "extern " else "") (if (has_class_flag c CInterface) then "interface" else "class") (s_type_path path) (params c.cl_params);
-				(match c.cl_super with None -> () | Some (c,pl) -> print " extends %s" (s_type (TInst (c,pl))));
-				List.iter (fun (c,pl) -> print " implements %s" (s_type (TInst (c,pl)))) c.cl_implements;
-				(match c.cl_array_access with None -> () | Some t -> print " implements ArrayAccess<%s>" (s_type t));
-				print " {\n";
-				(match c.cl_constructor with
-				| None -> ()
-				| Some f -> print_field false f);
-				List.iter (print_field false) c.cl_ordered_fields;
-				List.iter (print_field true) c.cl_ordered_statics;
-				(match TClass.get_cl_init c with
-				| None -> ()
-				| Some e ->
-					print "\n\tstatic function __init__() ";
-					print "%s" (s_expr s_type e);
-					print "\n");
-				print "}";
-			| Type.TEnumDecl e ->
-				print "%s%s%senum %s%s {\n" (s_metas e.e_meta "") (if e.e_private then "private " else "") (if has_enum_flag e EnExtern then "extern " else "") (s_type_path path) (params e.e_params);
-				List.iter (fun n ->
-					let f = PMap.find n e.e_constrs in
-					print "\t%s%s;\n" f.ef_name (
-						match f.ef_type with
-						| TFun (al,t) -> Printf.sprintf "(%s)" (String.concat ", "
-							(List.map (fun (n,o,t) -> (if o then "?" else "") ^ n ^ ":" ^ (s_type t)) al))
-						| _ -> "")
-				) e.e_names;
-				print "}"
-			| Type.TTypeDecl t ->
-				print "%s%stypedef %s%s = %s" (s_metas t.t_meta "") (if t.t_private then "private " else "") (s_type_path path) (params t.t_params) (s_type t.t_type);
-			| Type.TAbstractDecl a ->
-				print "%s%sabstract %s%s%s%s {}" (s_metas a.a_meta "") (if a.a_private then "private " else "") (s_type_path path) (params a.a_params)
-				(String.concat " " (List.map (fun t -> " from " ^ s_type t) a.a_from))
-				(String.concat " " (List.map (fun t -> " to " ^ s_type t) a.a_to));
-			);
-			close();
-		) com.types
-
-	let dump_record com =
-		List.iter (fun mt ->
-			let buf,close = create_dumpfile_from_path com (t_path mt) in
-			let s = match mt with
-				| TClassDecl c -> Printer.s_tclass "" c
-				| TEnumDecl en -> Printer.s_tenum "" en
-				| TTypeDecl t -> Printer.s_tdef "" t
-				| TAbstractDecl a -> Printer.s_tabstract "" a
-			in
-			Buffer.add_string buf s;
-			close();
-		) com.types
-
-	let dump_position com =
-		List.iter (fun mt ->
-			match mt with
-				| TClassDecl c ->
-					let buf,close = create_dumpfile_from_path com (t_path mt) in
-					Printf.bprintf buf "%s\n" (s_type_path c.cl_path);
-					let field cf =
-						Printf.bprintf buf "\t%s\n" cf.cf_name;
-						begin match cf.cf_expr with
-						| None -> ()
-						| Some e ->
-							Printf.bprintf buf "%s\n" (Texpr.dump_with_pos "\t" e);
-						end
-					in
-					Option.may field c.cl_constructor;
-					List.iter field c.cl_ordered_statics;
-					List.iter field c.cl_ordered_fields;
-					close();
-				| _ ->
-					()
-		) com.types
-
-	let dump_types com =
-		match Common.defined_value_safe com Define.Dump with
-			| "pretty" -> dump_types com true
-			| "record" -> dump_record com
-			| "position" -> dump_position com
-			| _ -> dump_types com false
-
-	let dump_dependencies ?(target_override=None) com =
-		let target_name = match target_override with
-			| None -> platform_name_macro com
-			| Some s -> s
-		in
-		let dump_dependencies_path = [dump_path com;target_name;"dependencies"] in
-		let buf,close = create_dumpfile [] dump_dependencies_path in
-		let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
-		let dep = Hashtbl.create 0 in
-		List.iter (fun m ->
-			print "%s:\n" (Path.UniqueKey.lazy_path m.m_extra.m_file);
-			PMap.iter (fun _ mdep ->
-				let (ctx,m2) = match mdep.md_kind with
-					| MMacro when not com.is_macro_context ->
-						("[macro] ", (Option.get (com.get_macros())).module_lut#find mdep.md_path)
-					| _ ->
-						("", com.module_lut#find mdep.md_path)
-				in
-				let file = Path.UniqueKey.lazy_path m2.m_extra.m_file in
-				print "\t%s%s\n" ctx file;
-				let l = try Hashtbl.find dep file with Not_found -> [] in
-				Hashtbl.replace dep file (m :: l)
-			) m.m_extra.m_deps;
-		) com.Common.modules;
-		close();
-		let dump_dependants_path = [dump_path com;target_name;"dependants"] in
-		let buf,close = create_dumpfile [] dump_dependants_path in
-		let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
-		Hashtbl.iter (fun n ml ->
-			print "%s:\n" n;
-			List.iter (fun m ->
-				print "\t%s\n" (Path.UniqueKey.lazy_path m.m_extra.m_file);
-			) ml;
-		) dep;
-		close()
-end
-
 (*
 	Build a default safe-cast expression :
 	{ var $t = <e>; if( Std.is($t,<t>) ) $t else throw "Class cast error"; }

+ 199 - 0
src/codegen/dump.ml

@@ -0,0 +1,199 @@
+open Globals
+open Common
+open Type
+
+(*
+	Make a dump of the full typed AST of all types
+*)
+let create_dumpfile acc l =
+	let ch = Path.create_file false ".dump" acc l in
+	let buf = Buffer.create 0 in
+	buf, (fun () ->
+		output_string ch (Buffer.contents buf);
+		close_out ch)
+
+let create_dumpfile_from_path com path =
+	let buf,close = create_dumpfile [] ((dump_path com) :: (platform_name_macro com) :: fst path @ [snd path]) in
+	buf,close
+
+let dump_types com pretty =
+	let s_type = s_type (Type.print_context()) in
+	let s_expr,s_type_param = if not pretty then
+		(Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t"),(Printer.s_type_param "")
+	else
+		(Type.s_expr_pretty false "\t" true),(s_type_param s_type)
+	in
+	let params tl = match tl with
+		| [] -> ""
+		| l -> Printf.sprintf "<%s>" (String.concat ", " (List.map s_type_param l))
+	in
+	List.iter (fun mt ->
+		let path = Type.t_path mt in
+		let buf,close = create_dumpfile_from_path com path in
+		let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
+		let s_metas ml tabs =
+			let args el =
+				match el with
+				| [] -> ""
+				| el -> Printf.sprintf "(%s)" (String.concat ", " (List.map (fun e -> Ast.Printer.s_expr e) el)) in
+			match ml with
+			| [] -> ""
+			| ml -> String.concat " " (List.map (fun me -> match me with (m,el,_) -> "@" ^ Meta.to_string m ^ args el) ml) ^ "\n" ^ tabs in
+		(match mt with
+		| Type.TClassDecl c ->
+			let s_cf_expr f =
+				match f.cf_expr with
+				| None -> ""
+				| Some e -> Printf.sprintf "%s" (s_expr s_type e) in
+			let is_inline_var v : bool = v = Var { v_read = AccInline; v_write = AccNever } in
+			let rec print_field stat f =
+				print "\n\t%s%s%s%s%s %s%s"
+					(s_metas f.cf_meta "\t")
+					(if (has_class_field_flag f CfPublic && not ((has_class_flag c CExtern) || (has_class_flag c CInterface))) then "public " else "")
+					(if stat then "static " else "")
+					(match f.cf_kind with
+						| Var v when (is_inline_var f.cf_kind) -> "inline "
+						| Var v -> ""
+						| Method m ->
+							match m with
+							| MethNormal -> ""
+							| MethDynamic -> "dynamic "
+							| MethInline -> "inline "
+							| MethMacro -> "macro ")
+					(match f.cf_kind with Var v -> "var" | Method m -> "function")
+					(f.cf_name ^ match f.cf_kind with
+						| Var { v_read = AccNormal; v_write = AccNormal } -> ""
+						| Var v when (is_inline_var f.cf_kind) -> ""
+						| Var v -> "(" ^ s_access true v.v_read ^ "," ^ s_access false v.v_write ^ ")"
+						| _ -> "")
+					(params f.cf_params);
+				(match f.cf_kind with
+					| Var v -> print ":%s%s;" (s_type f.cf_type)
+						(match f.cf_expr with
+						| None -> ""
+						| Some e -> " = " ^ (s_cf_expr f));
+					| Method m -> if ((has_class_flag c CExtern) || (has_class_flag c CInterface)) then (
+						match f.cf_type with
+						| TFun(al,t) -> print "(%s):%s;" (String.concat ", " (
+							List.map (fun (n,o,t) -> n ^ ":" ^ (s_type t)) al))
+							(s_type t)
+						| _ -> ()
+					) else print "%s" (s_cf_expr f));
+				print "\n";
+				List.iter (fun f -> print_field stat f) f.cf_overloads
+			in
+			print "%s%s%s%s %s%s" (s_metas c.cl_meta "") (if c.cl_private then "private " else "") (if (has_class_flag c CExtern) then "extern " else "") (if (has_class_flag c CInterface) then "interface" else "class") (s_type_path path) (params c.cl_params);
+			(match c.cl_super with None -> () | Some (c,pl) -> print " extends %s" (s_type (TInst (c,pl))));
+			List.iter (fun (c,pl) -> print " implements %s" (s_type (TInst (c,pl)))) c.cl_implements;
+			(match c.cl_array_access with None -> () | Some t -> print " implements ArrayAccess<%s>" (s_type t));
+			print " {\n";
+			(match c.cl_constructor with
+			| None -> ()
+			| Some f -> print_field false f);
+			List.iter (print_field false) c.cl_ordered_fields;
+			List.iter (print_field true) c.cl_ordered_statics;
+			(match TClass.get_cl_init c with
+			| None -> ()
+			| Some e ->
+				print "\n\tstatic function __init__() ";
+				print "%s" (s_expr s_type e);
+				print "\n");
+			print "}";
+		| Type.TEnumDecl e ->
+			print "%s%s%senum %s%s {\n" (s_metas e.e_meta "") (if e.e_private then "private " else "") (if has_enum_flag e EnExtern then "extern " else "") (s_type_path path) (params e.e_params);
+			List.iter (fun n ->
+				let f = PMap.find n e.e_constrs in
+				print "\t%s%s;\n" f.ef_name (
+					match f.ef_type with
+					| TFun (al,t) -> Printf.sprintf "(%s)" (String.concat ", "
+						(List.map (fun (n,o,t) -> (if o then "?" else "") ^ n ^ ":" ^ (s_type t)) al))
+					| _ -> "")
+			) e.e_names;
+			print "}"
+		| Type.TTypeDecl t ->
+			print "%s%stypedef %s%s = %s" (s_metas t.t_meta "") (if t.t_private then "private " else "") (s_type_path path) (params t.t_params) (s_type t.t_type);
+		| Type.TAbstractDecl a ->
+			print "%s%sabstract %s%s%s%s {}" (s_metas a.a_meta "") (if a.a_private then "private " else "") (s_type_path path) (params a.a_params)
+			(String.concat " " (List.map (fun t -> " from " ^ s_type t) a.a_from))
+			(String.concat " " (List.map (fun t -> " to " ^ s_type t) a.a_to));
+		);
+		close();
+	) com.types
+
+let dump_record com =
+	List.iter (fun mt ->
+		let buf,close = create_dumpfile_from_path com (t_path mt) in
+		let s = match mt with
+			| TClassDecl c -> Printer.s_tclass "" c
+			| TEnumDecl en -> Printer.s_tenum "" en
+			| TTypeDecl t -> Printer.s_tdef "" t
+			| TAbstractDecl a -> Printer.s_tabstract "" a
+		in
+		Buffer.add_string buf s;
+		close();
+	) com.types
+
+let dump_position com =
+	List.iter (fun mt ->
+		match mt with
+			| TClassDecl c ->
+				let buf,close = create_dumpfile_from_path com (t_path mt) in
+				Printf.bprintf buf "%s\n" (s_type_path c.cl_path);
+				let field cf =
+					Printf.bprintf buf "\t%s\n" cf.cf_name;
+					begin match cf.cf_expr with
+					| None -> ()
+					| Some e ->
+						Printf.bprintf buf "%s\n" (Texpr.dump_with_pos "\t" e);
+					end
+				in
+				Option.may field c.cl_constructor;
+				List.iter field c.cl_ordered_statics;
+				List.iter field c.cl_ordered_fields;
+				close();
+			| _ ->
+				()
+	) com.types
+
+let dump_types com =
+	match Common.defined_value_safe com Define.Dump with
+		| "pretty" -> dump_types com true
+		| "record" -> dump_record com
+		| "position" -> dump_position com
+		| _ -> dump_types com false
+
+let dump_dependencies ?(target_override=None) com =
+	let target_name = match target_override with
+		| None -> platform_name_macro com
+		| Some s -> s
+	in
+	let dump_dependencies_path = [dump_path com;target_name;"dependencies"] in
+	let buf,close = create_dumpfile [] dump_dependencies_path in
+	let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
+	let dep = Hashtbl.create 0 in
+	List.iter (fun m ->
+		print "%s:\n" (Path.UniqueKey.lazy_path m.m_extra.m_file);
+		PMap.iter (fun _ mdep ->
+			let (ctx,m2) = match mdep.md_kind with
+				| MMacro when not com.is_macro_context ->
+					("[macro] ", (Option.get (com.get_macros())).module_lut#find mdep.md_path)
+				| _ ->
+					("", com.module_lut#find mdep.md_path)
+			in
+			let file = Path.UniqueKey.lazy_path m2.m_extra.m_file in
+			print "\t%s%s\n" ctx file;
+			let l = try Hashtbl.find dep file with Not_found -> [] in
+			Hashtbl.replace dep file (m :: l)
+		) m.m_extra.m_deps;
+	) com.Common.modules;
+	close();
+	let dump_dependants_path = [dump_path com;target_name;"dependants"] in
+	let buf,close = create_dumpfile [] dump_dependants_path in
+	let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in
+	Hashtbl.iter (fun n ml ->
+		print "%s:\n" n;
+		List.iter (fun m ->
+			print "\t%s\n" (Path.UniqueKey.lazy_path m.m_extra.m_file);
+		) ml;
+	) dep;
+	close()

+ 132 - 0
src/codegen/fixOverrides.ml

@@ -0,0 +1,132 @@
+open Globals
+open Common
+open Type
+
+(* -------------------------------------------------------------------------- *)
+(* FIX OVERRIDES *)
+
+(*
+	on some platforms which doesn't support type parameters, we must have the
+	exact same type for overridden/implemented function as the original one
+*)
+
+let rec find_field com c f =
+	try
+		(match c.cl_super with
+		| None ->
+			raise Not_found
+		| Some ( {cl_path = (["cpp"],"FastIterator")}, _ ) ->
+			raise Not_found (* This is a strongly typed 'extern' and the usual rules don't apply *)
+		| Some (c,_) ->
+			find_field com c f)
+	with Not_found -> try
+		if com.platform = Cpp || com.platform = Hl then (* uses delegation for interfaces *)
+			raise Not_found;
+		let rec loop = function
+			| [] ->
+				raise Not_found
+			| (c,_) :: l ->
+				try
+					find_field com c f
+				with
+					Not_found -> loop l
+		in
+		loop c.cl_implements
+	with Not_found ->
+		let f = PMap.find f.cf_name c.cl_fields in
+		(match f.cf_kind with Var { v_read = AccRequire _ } -> raise Not_found | _ -> ());
+		f
+
+let fix_override com c f fd =
+	let f2 = (try Some (find_field com c f) with Not_found -> None) in
+	match f2,fd with
+		| Some (f2), Some(fd) ->
+			let targs, tret = (match follow f2.cf_type with TFun (args,ret) -> args, ret | _ -> die "" __LOC__) in
+			let changed_args = ref [] in
+			let prefix = "_tmp_" in
+			let nargs = List.map2 (fun ((v,ct) as cur) (_,_,t2) ->
+				try
+					type_eq EqStrict (monomorphs c.cl_params (monomorphs f.cf_params v.v_type)) t2;
+					(* Flash generates type parameters with a single constraint as that constraint type, so we
+					   have to detect this case and change the variable (issue #2712). *)
+					begin match follow v.v_type with
+						| TInst({cl_kind = KTypeParameter ttp} as cp,_) when com.platform = Flash ->
+							begin match get_constraints ttp with
+							| [tc] ->
+								if List.exists (fun tp -> tp.ttp_name = (snd cp.cl_path)) c.cl_params then raise (Unify_error [])
+							| _ ->
+								()
+							end
+						| _ ->
+							()
+					end;
+					cur
+				with Unify_error _ ->
+					let v2 = alloc_var VGenerated (prefix ^ v.v_name) t2 v.v_pos in
+					changed_args := (v,v2) :: !changed_args;
+					v2,ct
+			) fd.tf_args targs in
+			let fd2 = {
+				tf_args = nargs;
+				tf_type = tret;
+				tf_expr = (match List.rev !changed_args with
+					| [] -> fd.tf_expr
+					| args ->
+						let e = fd.tf_expr in
+						let el = (match e.eexpr with TBlock el -> el | _ -> [e]) in
+						let p = (match el with [] -> e.epos | e :: _ -> e.epos) in
+						let el_v = List.map (fun (v,v2) ->
+							mk (TVar (v,Some (mk (TCast (mk (TLocal v2) v2.v_type p,None)) v.v_type p))) com.basic.tvoid p
+						) args in
+						{ e with eexpr = TBlock (el_v @ el) }
+				);
+			} in
+			let targs = List.map (fun(v,c) -> (v.v_name, Option.is_some c, v.v_type)) nargs in
+			let fde = (match f.cf_expr with None -> die "" __LOC__ | Some e -> e) in
+			f.cf_expr <- Some { fde with eexpr = TFunction fd2 };
+			f.cf_type <- TFun(targs,tret);
+		| Some(f2), None when (has_class_flag c CInterface) ->
+			let targs, tret = (match follow f2.cf_type with TFun (args,ret) -> args, ret | _ -> die "" __LOC__) in
+			f.cf_type <- TFun(targs,tret)
+		| _ ->
+			()
+
+let fix_overrides com t =
+	match t with
+	| TClassDecl c ->
+		(* overrides can be removed from interfaces *)
+		if (has_class_flag c CInterface) then
+			c.cl_ordered_fields <- List.filter (fun f ->
+				try
+					if find_field com c f == f then raise Not_found;
+					c.cl_fields <- PMap.remove f.cf_name c.cl_fields;
+					false;
+				with Not_found ->
+					true
+			) c.cl_ordered_fields;
+		List.iter (fun f ->
+			match f.cf_expr, f.cf_kind with
+			| Some { eexpr = TFunction fd }, Method (MethNormal | MethInline) ->
+				fix_override com c f (Some fd)
+			| None, Method (MethNormal | MethInline) when (has_class_flag c CInterface) ->
+				fix_override com c f None
+			| _ ->
+				()
+		) c.cl_ordered_fields
+	| _ ->
+		()
+
+(*
+	PHP does not allow abstract classes extending other abstract classes to override any fields, so these duplicates
+	must be removed from the child interface
+*)
+let fix_abstract_inheritance com t =
+	match t with
+	| TClassDecl c when (has_class_flag c CInterface) ->
+		c.cl_ordered_fields <- List.filter (fun f ->
+			let b = try (find_field com c f) == f
+			with Not_found -> false in
+			if not b then c.cl_fields <- PMap.remove f.cf_name c.cl_fields;
+			b;
+		) c.cl_ordered_fields
+	| _ -> ()

+ 5 - 5
src/compiler/generate.ml

@@ -135,14 +135,14 @@ let delete_file f = try Sys.remove f with _ -> ()
 let maybe_generate_dump ctx tctx =
 	let com = tctx.Typecore.com in
 	if Common.defined com Define.Dump then begin
-		Codegen.Dump.dump_types com;
-		Option.may Codegen.Dump.dump_types (com.get_macros())
+		Dump.dump_types com;
+		Option.may Dump.dump_types (com.get_macros())
 	end;
 	if Common.defined com Define.DumpDependencies then begin
-		Codegen.Dump.dump_dependencies com;
+		Dump.dump_dependencies com;
 		if not com.is_macro_context then match tctx.Typecore.g.Typecore.macros with
 			| None -> ()
-			| Some(_,ctx) -> Codegen.Dump.dump_dependencies ~target_override:(Some "macro") ctx.Typecore.com
+			| Some(_,ctx) -> Dump.dump_dependencies ~target_override:(Some "macro") ctx.Typecore.com
 	end
 
 let generate ctx tctx ext actx =
@@ -150,7 +150,7 @@ let generate ctx tctx ext actx =
 	(* check file extension. In case of wrong commandline, we don't want
 		to accidentaly delete a source file. *)
 	if Path.file_extension com.file = ext then delete_file com.file;
-	if com.platform = Flash || com.platform = Cpp || com.platform = Hl then List.iter (Codegen.fix_overrides com) com.types;
+	if com.platform = Flash || com.platform = Cpp || com.platform = Hl then List.iter (FixOverrides.fix_overrides com) com.types;
 	begin match com.platform with
 		| Neko | Hl | Eval when actx.interp -> ()
 		| Cpp when Common.defined com Define.Cppia -> ()

+ 0 - 84
src/core/naming.ml

@@ -4,90 +4,6 @@ open Type
 open Common
 open Error
 
-(** retrieve string from @:native metadata or raise Not_found *)
-let get_native_name meta =
-	let rec get_native meta = match meta with
-		| [] -> raise Not_found
-		| (Meta.Native,[v],p as meta) :: _ ->
-			meta
-		| _ :: meta ->
-			get_native meta
-	in
-	let (_,e,mp) = get_native meta in
-	match e with
-	| [Ast.EConst (Ast.String(name,_)),p] ->
-		name,p
-	| [] ->
-		raise Not_found
-	| _ ->
-		Error.raise_typing_error "String expected" mp
-
-(* Rewrites class or enum paths if @:native metadata is set *)
-let apply_native_paths t =
-	let get_real_name meta name =
-		let name',p = get_native_name meta in
-		(Meta.RealPath,[Ast.EConst (Ast.String (name,SDoubleQuotes)), p], p), name'
-	in
-	let get_real_path meta path =
-		let name,p = get_native_name meta in
-		(Meta.RealPath,[Ast.EConst (Ast.String (s_type_path path,SDoubleQuotes)), p], p), parse_path name
-	in
-	try
-		(match t with
-		| TClassDecl c ->
-			let did_change = ref false in
-			let field cf = try
-				let meta,name = get_real_name cf.cf_meta cf.cf_name in
-				cf.cf_name <- name;
-				cf.cf_meta <- meta :: cf.cf_meta;
-				List.iter (fun cf -> cf.cf_name <- name) cf.cf_overloads;
-				did_change := true
-			with Not_found ->
-				()
-			in
-			let fields cfs old_map =
-				did_change := false;
-				List.iter field cfs;
-				if !did_change then
-					List.fold_left (fun map f -> PMap.add f.cf_name f map) PMap.empty cfs
-				else
-					old_map
-			in
-			c.cl_fields <- fields c.cl_ordered_fields c.cl_fields;
-			c.cl_statics <- fields c.cl_ordered_statics c.cl_statics;
-			let meta,path = get_real_path c.cl_meta c.cl_path in
-			c.cl_meta <- meta :: c.cl_meta;
-			c.cl_path <- path;
-		| TEnumDecl e ->
-			let did_change = ref false in
-			let field _ ef = try
-				let meta,name = get_real_name ef.ef_meta ef.ef_name in
-				ef.ef_name <- name;
-				ef.ef_meta <- meta :: ef.ef_meta;
-				did_change := true;
-			with Not_found ->
-				()
-			in
-			PMap.iter field e.e_constrs;
-			if !did_change then begin
-				let names = ref [] in
-				e.e_constrs <- PMap.fold
-					(fun ef map ->
-						names := ef.ef_name :: !names;
-						PMap.add ef.ef_name ef map
-					)
-					e.e_constrs PMap.empty;
-				e.e_names <- !names;
-			end;
-			let meta,path = get_real_path e.e_meta e.e_path in
-			e.e_meta <- meta :: e.e_meta;
-			e.e_path <- path;
-		| _ ->
-			())
-	with Not_found ->
-		()
-
-
 let display_identifier_error com ?prepend_msg msg p =
 	let prepend = match prepend_msg with Some s -> s ^ " " | _ -> "" in
 	Common.display_error com (prepend ^ msg) p

+ 86 - 0
src/core/native.ml

@@ -0,0 +1,86 @@
+open Globals
+open Ast
+open Type
+
+(** retrieve string from @:native metadata or raise Not_found *)
+let get_native_name meta =
+	let rec get_native meta = match meta with
+		| [] -> raise Not_found
+		| (Meta.Native,[v],p as meta) :: _ ->
+			meta
+		| _ :: meta ->
+			get_native meta
+	in
+	let (_,e,mp) = get_native meta in
+	match e with
+	| [Ast.EConst (Ast.String(name,_)),p] ->
+		name,p
+	| [] ->
+		raise Not_found
+	| _ ->
+		Error.raise_typing_error "String expected" mp
+
+(* Rewrites class or enum paths if @:native metadata is set *)
+let apply_native_paths t =
+	let get_real_name meta name =
+		let name',p = get_native_name meta in
+		(Meta.RealPath,[Ast.EConst (Ast.String (name,SDoubleQuotes)), p], p), name'
+	in
+	let get_real_path meta path =
+		let name,p = get_native_name meta in
+		(Meta.RealPath,[Ast.EConst (Ast.String (s_type_path path,SDoubleQuotes)), p], p), parse_path name
+	in
+	try
+		(match t with
+		| TClassDecl c ->
+			let did_change = ref false in
+			let field cf = try
+				let meta,name = get_real_name cf.cf_meta cf.cf_name in
+				cf.cf_name <- name;
+				cf.cf_meta <- meta :: cf.cf_meta;
+				List.iter (fun cf -> cf.cf_name <- name) cf.cf_overloads;
+				did_change := true
+			with Not_found ->
+				()
+			in
+			let fields cfs old_map =
+				did_change := false;
+				List.iter field cfs;
+				if !did_change then
+					List.fold_left (fun map f -> PMap.add f.cf_name f map) PMap.empty cfs
+				else
+					old_map
+			in
+			c.cl_fields <- fields c.cl_ordered_fields c.cl_fields;
+			c.cl_statics <- fields c.cl_ordered_statics c.cl_statics;
+			let meta,path = get_real_path c.cl_meta c.cl_path in
+			c.cl_meta <- meta :: c.cl_meta;
+			c.cl_path <- path;
+		| TEnumDecl e ->
+			let did_change = ref false in
+			let field _ ef = try
+				let meta,name = get_real_name ef.ef_meta ef.ef_name in
+				ef.ef_name <- name;
+				ef.ef_meta <- meta :: ef.ef_meta;
+				did_change := true;
+			with Not_found ->
+				()
+			in
+			PMap.iter field e.e_constrs;
+			if !did_change then begin
+				let names = ref [] in
+				e.e_constrs <- PMap.fold
+					(fun ef map ->
+						names := ef.ef_name :: !names;
+						PMap.add ef.ef_name ef map
+					)
+					e.e_constrs PMap.empty;
+				e.e_names <- !names;
+			end;
+			let meta,path = get_real_path e.e_meta e.e_path in
+			e.e_meta <- meta :: e.e_meta;
+			e.e_path <- path;
+		| _ ->
+			())
+	with Not_found ->
+		()

+ 2 - 2
src/filters/filters.ml

@@ -25,7 +25,7 @@ open Error
 open Globals
 open FiltersCommon
 
-let get_native_name = Naming.get_native_name
+let get_native_name = Native.get_native_name
 
 (* PASS 1 begin *)
 
@@ -497,7 +497,7 @@ let destruction tctx ectx detail_times main locals =
 	let type_filters = [
 		(fun tctx -> Exceptions.patch_constructors tctx ectx); (* TODO: I don't believe this should load_instance anything at this point... *)
 		(fun _ -> check_private_path com);
-		(fun _ -> Naming.apply_native_paths);
+		(fun _ -> Native.apply_native_paths);
 		(fun _ -> add_rtti com);
 		(match com.platform with | Jvm -> (fun _ _ -> ()) | _ -> (fun tctx mt -> AddFieldInits.add_field_inits tctx.c.curclass.cl_path locals com mt));
 		(match com.platform with Hl -> (fun _ _ -> ()) | _ -> (fun _ -> add_meta_field com));

+ 3 - 3
src/filters/renameVars.ml

@@ -28,17 +28,17 @@ let reserve_init ri name =
 let reserve_all_types ri com path_to_name =
 	List.iter (fun mt ->
 		let tinfos = t_infos mt in
-		let native_name = try fst (Naming.get_native_name tinfos.mt_meta) with Not_found -> path_to_name tinfos.mt_path in
+		let native_name = try fst (Native.get_native_name tinfos.mt_meta) with Not_found -> path_to_name tinfos.mt_path in
 		match mt with
 		| TClassDecl c when native_name = "" ->
 			List.iter (fun cf ->
-				let native_name = try fst (Naming.get_native_name cf.cf_meta) with Not_found -> cf.cf_name in
+				let native_name = try fst (Native.get_native_name cf.cf_meta) with Not_found -> cf.cf_name in
 				reserve_init ri native_name
 			) c.cl_ordered_statics
 		| TClassDecl { cl_kind = KModuleFields m; cl_ordered_statics = fl } ->
 			let prefix = Path.flat_path m.m_path ^ "_" in
 			List.iter (fun cf ->
-				let name = try fst (Naming.get_native_name cf.cf_meta) with Not_found -> prefix ^ cf.cf_name in
+				let name = try fst (Native.get_native_name cf.cf_meta) with Not_found -> prefix ^ cf.cf_name in
 				reserve_init ri name
 			) fl
 		| _ ->

+ 2 - 4
src/generators/genjs.ml

@@ -137,13 +137,13 @@ let static_field ctx c f =
 
 let module_field m f =
 	try
-		fst (Naming.get_native_name f.cf_meta)
+		fst (Native.get_native_name f.cf_meta)
 	with Not_found ->
 		Path.flat_path m.m_path ^ "_" ^ f.cf_name
 
 let module_field_expose_path mpath f =
 	try
-		fst (Naming.get_native_name f.cf_meta)
+		fst (Native.get_native_name f.cf_meta)
 	with Not_found ->
 		(dot_path mpath) ^ "." ^ f.cf_name
 
@@ -276,8 +276,6 @@ let gen_constant ctx p = function
 	| TThis -> spr ctx (this ctx)
 	| TSuper -> assert (ctx.es_version >= 6); spr ctx "super"
 
-let print_deprecation_message = DeprecationCheck.warn_deprecation
-
 let is_code_injection_function e =
 	match e.eexpr with
 	| TIdent "__js__"

+ 1 - 1
src/typing/macroContext.ml

@@ -643,7 +643,7 @@ and flush_macro_context mint mctx =
 			| TEnumDecl e -> has_enum_flag e EnExtern
 			| _ -> false
 		in
-		if apply_native then Naming.apply_native_paths t
+		if apply_native then Native.apply_native_paths t
 	in
 	let type_filters = [
 		FiltersCommon.remove_generic_base;

+ 2 - 2
src/typing/typeloadCheck.ml

@@ -128,9 +128,9 @@ let check_native_name_override ctx child base =
 		]) child_pos);
 	in
 	try
-		let child_name, child_pos = Naming.get_native_name child.cf_meta in
+		let child_name, child_pos = Native.get_native_name child.cf_meta in
 		try
-			let base_name, base_pos = Naming.get_native_name base.cf_meta in
+			let base_name, base_pos = Native.get_native_name base.cf_meta in
 			if base_name <> child_name then
 				error base_pos child_pos
 		with Not_found ->