Browse Source

move some codegen stuff to typeload to simplify dependency chain

Simon Krajewski 9 năm trước cách đây
mục cha
commit
feecd39377
8 tập tin đã thay đổi với 580 bổ sung578 xóa
  1. 1 1
      Makefile
  2. 0 562
      src/generators/codegen.ml
  3. 1 1
      src/main.ml
  4. 1 1
      src/optimization/filters.ml
  5. 9 0
      src/typing/type.ml
  6. 8 0
      src/typing/typecore.ml
  7. 547 0
      src/typing/typeload.ml
  8. 13 13
      src/typing/typer.ml

+ 1 - 1
Makefile

@@ -139,7 +139,7 @@ src/optimization/analyzerTexprTransformer.$(MODULE_EXT): src/syntax/ast.$(MODULE
 
 src/optimization/analyzerTypes.$(MODULE_EXT): src/syntax/ast.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/typing/common.$(MODULE_EXT) src/optimization/analyzerConfig.$(MODULE_EXT)
 
-src/generators/codegen.$(MODULE_EXT): src/optimization/optimizer.$(MODULE_EXT) src/typing/typeload.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/generators/genxml.$(MODULE_EXT) src/typing/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT)
+src/generators/codegen.$(MODULE_EXT): src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/generators/genxml.$(MODULE_EXT) src/typing/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT)
 
 src/typing/common.$(MODULE_EXT): src/typing/type.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT)
 

+ 0 - 562
src/generators/codegen.ml

@@ -134,447 +134,6 @@ let escape_res_name name allow_dirs =
 		else
 			"-x" ^ (string_of_int (Char.code chr))) name
 
-(* -------------------------------------------------------------------------- *)
-(* REMOTING PROXYS *)
-
-let extend_remoting ctx c t p async prot =
-	if c.cl_super <> None then error "Cannot extend several classes" p;
-	(* remove forbidden packages *)
-	let rules = ctx.com.package_rules in
-	ctx.com.package_rules <- PMap.foldi (fun key r acc -> match r with Forbidden -> acc | _ -> PMap.add key r acc) rules PMap.empty;
-	(* parse module *)
-	let path = (t.tpackage,t.tname) in
-	let new_name = (if async then "Async_" else "Remoting_") ^ t.tname in
-	(* check if the proxy already exists *)
-	let t = (try
-		Typeload.load_type_def ctx p { tpackage = fst path; tname = new_name; tparams = []; tsub = None }
-	with
-		Error (Module_not_found _,p2) when p == p2 ->
-	(* build it *)
-	Common.log ctx.com ("Building proxy for " ^ s_type_path path);
-	let file, decls = (try
-		Typeload.parse_module ctx path p
-	with
-		| Not_found -> ctx.com.package_rules <- rules; error ("Could not load proxy module " ^ s_type_path path ^ (if fst path = [] then " (try using absolute path)" else "")) p
-		| e -> ctx.com.package_rules <- rules; raise e) in
-	ctx.com.package_rules <- rules;
-	let base_fields = [
-		{ cff_name = "__cnx"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = []; cff_kind = FVar (Some (CTPath { tpackage = ["haxe";"remoting"]; tname = if async then "AsyncConnection" else "Connection"; tparams = []; tsub = None }),None) };
-		{ cff_name = "new"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun { f_args = ["c",false,None,None]; f_type = None; f_expr = Some (EBinop (OpAssign,(EConst (Ident "__cnx"),p),(EConst (Ident "c"),p)),p); f_params = [] } };
-	] in
-	let tvoid = CTPath { tpackage = []; tname = "Void"; tparams = []; tsub = None } in
-	let build_field is_public acc f =
-		if f.cff_name = "new" then
-			acc
-		else match f.cff_kind with
-		| FFun fd when (is_public || List.mem APublic f.cff_access) && not (List.mem AStatic f.cff_access) ->
-			if List.exists (fun (_,_,t,_) -> t = None) fd.f_args then error ("Field " ^ f.cff_name ^ " type is not complete and cannot be used by RemotingProxy") p;
-			let eargs = [EArrayDecl (List.map (fun (a,_,_,_) -> (EConst (Ident a),p)) fd.f_args),p] in
-			let ftype = (match fd.f_type with Some (CTPath { tpackage = []; tname = "Void" }) -> None | _ -> fd.f_type) in
-			let fargs, eargs = if async then match ftype with
-				| Some tret -> fd.f_args @ ["__callb",true,Some (CTFunction ([tret],tvoid)),None], eargs @ [EConst (Ident "__callb"),p]
-				| _ -> fd.f_args, eargs @ [EConst (Ident "null"),p]
-			else
-				fd.f_args, eargs
-			in
-			let id = (EConst (String f.cff_name), p) in
-			let id = if prot then id else ECall ((EConst (Ident "__unprotect__"),p),[id]),p in
-			let expr = ECall (
-				(EField (
-					(ECall ((EField ((EConst (Ident "__cnx"),p),"resolve"),p),[id]),p),
-					"call")
-				,p),eargs),p
-			in
-			let expr = if async || ftype = None then expr else (EReturn (Some expr),p) in
-			let fd = {
-				f_params = fd.f_params;
-				f_args = fargs;
-				f_type = if async then None else ftype;
-				f_expr = Some (EBlock [expr],p);
-			} in
-			{ cff_name = f.cff_name; cff_pos = f.cff_pos; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun fd } :: acc
-		| _ -> acc
-	in
-	let decls = List.map (fun d ->
-		match d with
-		| EClass c, p when c.d_name = t.tname ->
-			let is_public = List.mem HExtern c.d_flags || List.mem HInterface c.d_flags in
-			let fields = List.rev (List.fold_left (build_field is_public) base_fields c.d_data) in
-			(EClass { c with d_flags = []; d_name = new_name; d_data = fields },p)
-		| _ -> d
-	) decls in
-	let m = Typeload.type_module ctx (t.tpackage,new_name) file decls p in
-	add_dependency ctx.m.curmod m;
-	try
-		List.find (fun tdecl -> snd (t_path tdecl) = new_name) m.m_types
-	with Not_found ->
-		error ("Module " ^ s_type_path path ^ " does not define type " ^ t.tname) p
-	) in
-	match t with
-	| TClassDecl c2 when c2.cl_params = [] -> ignore(c2.cl_build()); c.cl_super <- Some (c2,[]);
-	| _ -> error "Remoting proxy must be a class without parameters" p
-
-(* -------------------------------------------------------------------------- *)
-(* HAXE.RTTI.GENERIC *)
-
-exception Generic_Exception of string * Ast.pos
-
-type generic_context = {
-	ctx : typer;
-	subst : (t * t) list;
-	name : string;
-	p : pos;
-	mutable mg : module_def option;
-}
-
-let make_generic ctx ps pt p =
-	let rec loop l1 l2 =
-		match l1, l2 with
-		| [] , [] -> []
-		| (x,TLazy f) :: l1, _ -> loop ((x,(!f)()) :: l1) l2
-		| (_,t1) :: l1 , t2 :: l2 -> (t1,t2) :: loop l1 l2
-		| _ -> assert false
-	in
-	let name =
-		String.concat "_" (List.map2 (fun (s,_) t ->
-			let s_type_path_underscore (p,s) = match p with [] -> s | _ -> String.concat "_" p ^ "_" ^ s in
-			let rec loop top t = match follow t with
-				| TInst(c,tl) -> (s_type_path_underscore c.cl_path) ^ (loop_tl tl)
-				| TEnum(en,tl) -> (s_type_path_underscore en.e_path) ^ (loop_tl tl)
-				| TAbstract(a,tl) -> (s_type_path_underscore a.a_path) ^ (loop_tl tl)
-				| _ when not top -> "_" (* allow unknown/incompatible types as type parameters to retain old behavior *)
-				| TMono _ -> raise (Generic_Exception (("Could not determine type for parameter " ^ s), p))
-				| TDynamic _ -> "Dynamic"
-				| t -> raise (Generic_Exception (("Type parameter must be a class or enum instance (found " ^ (s_type (print_context()) t) ^ ")"), p))
-			and loop_tl tl = match tl with
-				| [] -> ""
-				| tl -> "_" ^ String.concat "_" (List.map (loop false) tl)
-			in
-			loop true t
-		) ps pt)
-	in
-	{
-		ctx = ctx;
-		subst = loop ps pt;
-		name = name;
-		p = p;
-		mg = None;
-	}
-
-let rec generic_substitute_type gctx t =
-	match t with
-	| TInst ({ cl_kind = KGeneric } as c2,tl2) ->
-		(* maybe loop, or generate cascading generics *)
-		let _, _, f = gctx.ctx.g.do_build_instance gctx.ctx (TClassDecl c2) gctx.p in
-		let t = f (List.map (generic_substitute_type gctx) tl2) in
-		(match follow t,gctx.mg with TInst(c,_), Some m -> add_dependency m c.cl_module | _ -> ());
-		t
-	| _ ->
-		try
-			generic_substitute_type gctx (List.assq t gctx.subst)
-		with Not_found ->
-			Type.map (generic_substitute_type gctx) t
-
-let generic_substitute_expr gctx e =
-	let vars = Hashtbl.create 0 in
-	let build_var v =
-		try
-			Hashtbl.find vars v.v_id
-		with Not_found ->
-			let v2 = alloc_var v.v_name (generic_substitute_type gctx v.v_type) in
-			v2.v_meta <- v.v_meta;
-			Hashtbl.add vars v.v_id v2;
-			v2
-	in
-	let rec build_expr e =
-		match e.eexpr with
-		| TField(e1, FInstance({cl_kind = KGeneric} as c,tl,cf)) ->
-			let _, _, f = gctx.ctx.g.do_build_instance gctx.ctx (TClassDecl c) gctx.p in
-			let t = f (List.map (generic_substitute_type gctx) tl) in
-			let fa = try
-				quick_field t cf.cf_name
-			with Not_found ->
-				error (Printf.sprintf "Type %s has no field %s (possible typing order issue)" (s_type (print_context()) t) cf.cf_name) e.epos
-			in
-			build_expr {e with eexpr = TField(e1,fa)}
-		| TTypeExpr (TClassDecl ({cl_kind = KTypeParameter _;} as c)) when Meta.has Meta.Const c.cl_meta ->
-			let rec loop subst = match subst with
-				| (t1,t2) :: subst ->
-					begin match follow t1 with
-						| TInst(c2,_) when c == c2 -> t2
-						| _ -> loop subst
-					end
-				| [] -> raise Not_found
-			in
-			begin try
-				let t = loop gctx.subst in
-				begin match follow t with
-					| TInst({cl_kind = KExpr e},_) -> type_expr gctx.ctx e Value
-					| _ -> error "Only Const type parameters can be used as value" e.epos
-				end
-			with Not_found ->
-				e
-			end
-		| _ ->
-			map_expr_type build_expr (generic_substitute_type gctx) build_var e
-	in
-	build_expr e
-
-let has_ctor_constraint c = match c.cl_kind with
-	| KTypeParameter tl ->
-		List.exists (fun t -> match follow t with
-			| TAnon a when PMap.mem "new" a.a_fields -> true
-			| TAbstract({a_path=["haxe"],"Constructible"},_) -> true
-			| _ -> false
-		) tl;
-	| _ -> false
-
-let get_short_name =
-	let i = ref (-1) in
-	(fun () ->
-		incr i;
-		Printf.sprintf "Hx___short___hx_type_%i" !i
-	)
-
-let rec build_generic ctx c p tl =
-	let pack = fst c.cl_path in
-	let recurse = ref false in
-	let rec check_recursive t =
-		match follow t with
-		| TInst (c2,tl) ->
-			(match c2.cl_kind with
-			| KTypeParameter tl ->
-				if not (Typeload.is_generic_parameter ctx c2) && has_ctor_constraint c2 then
-					error "Type parameters with a constructor cannot be used non-generically" p;
-				recurse := true
-			| _ -> ());
-			List.iter check_recursive tl;
-		| _ ->
-			()
-	in
-	List.iter check_recursive tl;
-	if !recurse then begin
-		TInst (c,tl) (* build a normal instance *)
-	end else begin
-	let gctx = make_generic ctx c.cl_params tl p in
-	let name = (snd c.cl_path) ^ "_" ^ gctx.name in
-	try
-		Typeload.load_instance ctx { tpackage = pack; tname = name; tparams = []; tsub = None } p false
-	with Error(Module_not_found path,_) when path = (pack,name) ->
-		let m = (try Hashtbl.find ctx.g.modules (Hashtbl.find ctx.g.types_module c.cl_path) with Not_found -> assert false) in
-		let ctx = { ctx with m = { ctx.m with module_types = m.m_types @ ctx.m.module_types } } in
-		ignore(c.cl_build()); (* make sure the super class is already setup *)
-		let mg = {
-			m_id = alloc_mid();
-			m_path = (pack,name);
-			m_types = [];
-			m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake;
-		} in
-		gctx.mg <- Some mg;
-		let cg = mk_class mg (pack,name) c.cl_pos in
-		mg.m_types <- [TClassDecl cg];
-		Hashtbl.add ctx.g.modules mg.m_path mg;
-		add_dependency mg m;
-		add_dependency ctx.m.curmod mg;
-		(* ensure that type parameters are set in dependencies *)
-		let dep_stack = ref [] in
-		let rec loop t =
-			if not (List.memq t !dep_stack) then begin
-			dep_stack := t :: !dep_stack;
-			match t with
-			| TInst (c,tl) -> add_dep c.cl_module tl
-			| TEnum (e,tl) -> add_dep e.e_module tl
-			| TType (t,tl) -> add_dep t.t_module tl
-			| TAbstract (a,tl) -> add_dep a.a_module tl
-			| TMono r ->
-				(match !r with
-				| None -> ()
-				| Some t -> loop t)
-			| TLazy f ->
-				loop ((!f)());
-			| TDynamic t2 ->
-				if t == t2 then () else loop t2
-			| TAnon a ->
-				PMap.iter (fun _ f -> loop f.cf_type) a.a_fields
-			| TFun (args,ret) ->
-				List.iter (fun (_,_,t) -> loop t) args;
-				loop ret
-			end
-		and add_dep m tl =
-			add_dependency mg m;
-			List.iter loop tl
-		in
-		List.iter loop tl;
-		let build_field cf_old =
-			(* We have to clone the type parameters (issue #4672). We cannot substitute the constraints immediately because
-		       we need the full substitution list first. *)
-			let param_subst,params = List.fold_left (fun (subst,params) (s,t) -> match follow t with
-				| TInst(c,tl) as t ->
-					let t2 = TInst({c with cl_pos = c.cl_pos;},tl) in
-					(t,t2) :: subst,(s,t2) :: params
-				| _ -> assert false
-			) ([],[]) cf_old.cf_params in
-			let gctx = {gctx with subst = param_subst @ gctx.subst} in
-			let cf_new = {cf_old with cf_pos = cf_old.cf_pos} in (* copy *)
-			(* Type parameter constraints are substituted here. *)
-			cf_new.cf_params <- List.rev_map (fun (s,t) -> match follow t with
-				| TInst({cl_kind = KTypeParameter tl1} as c,_) ->
-					let tl1 = List.map (generic_substitute_type gctx) tl1 in
-					c.cl_kind <- KTypeParameter tl1;
-					s,t
-				| _ -> assert false
-			) params;
-			let f () =
-				let t = generic_substitute_type gctx cf_old.cf_type in
-				ignore (follow t);
-				begin try (match cf_old.cf_expr with
-					| None ->
-						begin match cf_old.cf_kind with
-							| Method _ when not c.cl_interface && not c.cl_extern ->
-								display_error ctx (Printf.sprintf "Field %s has no expression (possible typing order issue)" cf_new.cf_name) cf_new.cf_pos;
-								display_error ctx (Printf.sprintf "While building %s" (s_type_path cg.cl_path)) p;
-							| _ ->
-								()
-						end
-					| Some e ->
-						cf_new.cf_expr <- Some (generic_substitute_expr gctx e)
-				) with Unify_error l ->
-					error (error_msg (Unify l)) cf_new.cf_pos
-				end;
-				t
-			in
-			let r = exc_protect ctx (fun r ->
-				let t = mk_mono() in
-				r := (fun() -> t);
-				unify_raise ctx (f()) t p;
-				t
-			) "build_generic" in
-			delay ctx PForce (fun() -> ignore ((!r)()));
-			cf_new.cf_type <- TLazy r;
-			cf_new
-		in
-		if c.cl_init <> None || c.cl_dynamic <> None then error "This class can't be generic" p;
-		List.iter (fun cf -> match cf.cf_kind with
-			| Method MethMacro when not ctx.in_macro -> ()
-			| _ -> error "A generic class can't have static fields" cf.cf_pos
-		) c.cl_ordered_statics;
-		cg.cl_super <- (match c.cl_super with
-			| None -> None
-			| Some (cs,pl) ->
-				let find_class subst =
-					let rec loop subst = match subst with
-						| (TInst(c,[]),t) :: subst when c == cs -> t
-						| _ :: subst -> loop subst
-						| [] -> raise Not_found
-					in
-					try
-						if pl <> [] then raise Not_found;
-						let t = loop subst in
-						(* extended type parameter: concrete type must have a constructor, but generic base class must not have one *)
-						begin match follow t,c.cl_constructor with
-							| TInst(cs,_),None ->
-								ignore(cs.cl_build());
-								begin match cs.cl_constructor with
-									| None -> error ("Cannot use " ^ (s_type_path cs.cl_path) ^ " as type parameter because it is extended and has no constructor") p
-									| _ -> ()
-								end;
-							| _,Some cf -> error "Generics extending type parameters cannot have constructors" cf.cf_pos
-							| _ -> ()
-						end;
-						t
-					with Not_found ->
-						apply_params c.cl_params tl (TInst(cs,pl))
-				in
-				let ts = follow (find_class gctx.subst) in
-				let cs,pl = Typeload.Inheritance.check_extends ctx c ts p in
-				match cs.cl_kind with
-				| KGeneric ->
-					(match build_generic ctx cs p pl with
-					| TInst (cs,pl) -> Some (cs,pl)
-					| _ -> assert false)
-				| _ -> Some(cs,pl)
-		);
-		Typeload.add_constructor ctx cg false p;
-		cg.cl_kind <- KGenericInstance (c,tl);
-		cg.cl_meta <- (Meta.NoDoc,[],p) :: cg.cl_meta;
-		if has_meta Meta.Keep c.cl_meta then cg.cl_meta <- (Meta.Keep,[],p) :: cg.cl_meta;
-		cg.cl_interface <- c.cl_interface;
-		cg.cl_constructor <- (match cg.cl_constructor, c.cl_constructor, c.cl_super with
-			| _, Some cf, _ -> Some (build_field cf)
-			| Some ctor, _, _ -> Some ctor
-			| None, None, None -> None
-			| _ -> error "Please define a constructor for this class in order to use it as generic" c.cl_pos
-		);
-		cg.cl_implements <- List.map (fun (i,tl) ->
-			(match follow (generic_substitute_type gctx (TInst (i, List.map (generic_substitute_type gctx) tl))) with
-			| TInst (i,tl) -> i, tl
-			| _ -> assert false)
-		) c.cl_implements;
-		cg.cl_ordered_fields <- List.map (fun f ->
-			let f = build_field f in
-			cg.cl_fields <- PMap.add f.cf_name f cg.cl_fields;
-			f
-		) c.cl_ordered_fields;
-		cg.cl_overrides <- List.map (fun f ->
-			try PMap.find f.cf_name cg.cl_fields with Not_found -> assert false
-		) c.cl_overrides;
-		(* In rare cases the class name can become too long, so let's shorten it (issue #3090). *)
-		if String.length (snd cg.cl_path) > 254 then begin
-			let n = get_short_name () in
-			cg.cl_meta <- (Meta.Native,[EConst(String (n)),p],p) :: cg.cl_meta;
-		end;
-		TInst (cg,[])
-	end
-
-(* -------------------------------------------------------------------------- *)
-(* HAXE.XML.PROXY *)
-
-let extend_xml_proxy ctx c t file p =
-	let t = Typeload.load_complex_type ctx p t in
-	let file = (try Common.find_file ctx.com file with Not_found -> file) in
-	add_dependency c.cl_module (create_fake_module ctx file);
-	let used = ref PMap.empty in
-	let print_results() =
-		PMap.iter (fun id used ->
-			if not used then ctx.com.warning (id ^ " is not used") p;
-		) (!used)
-	in
-	let check_used = Common.defined ctx.com Define.CheckXmlProxy in
-	if check_used then ctx.g.hook_generate <- print_results :: ctx.g.hook_generate;
-	try
-		let rec loop = function
-			| Xml.Element (_,attrs,childs) ->
-				(try
-					let id = List.assoc "id" attrs in
-					if PMap.mem id c.cl_fields then error ("Duplicate id " ^ id) p;
-					let t = if not check_used then t else begin
-						used := PMap.add id false (!used);
-						let ft() = used := PMap.add id true (!used); t in
-						TLazy (ref ft)
-					end in
-					let f = {
-						cf_name = id;
-						cf_type = t;
-						cf_public = true;
-						cf_pos = p;
-						cf_doc = None;
-						cf_meta = no_meta;
-						cf_kind = Var { v_read = AccResolve; v_write = AccNo };
-						cf_params = [];
-						cf_expr = None;
-						cf_overloads = [];
-					} in
-					c.cl_fields <- PMap.add id f c.cl_fields;
-				with
-					Not_found -> ());
-				List.iter loop childs;
-			| Xml.PCData _ -> ()
-		in
-		loop (Xml.parse_file file)
-	with
-		| Xml.Error e -> error ("XML error " ^ Xml.error e) p
-		| Xml.File_not_found f -> error ("XML File not found : " ^ f) p
-
 (* -------------------------------------------------------------------------- *)
 (* BUILD META DATA OBJECT *)
 
@@ -617,127 +176,6 @@ let build_metadata com t =
 		let meta_obj = (try ("obj", make_meta_field (List.assoc "" meta)) :: meta_obj with Not_found -> meta_obj) in
 		Some (mk (TObjectDecl meta_obj) t_dynamic p)
 
-(* -------------------------------------------------------------------------- *)
-(* MACRO TYPE *)
-
-let get_macro_path ctx e args p =
-	let rec loop e =
-		match fst e with
-		| EField (e,f) -> f :: loop e
-		| EConst (Ident i) -> [i]
-		| _ -> error "Invalid macro call" p
-	in
-	let path = match e with
-		| (EConst(Ident i)),_ ->
-			let path = try
-				if not (PMap.mem i ctx.curclass.cl_statics) then raise Not_found;
-				ctx.curclass.cl_path
-			with Not_found -> try
-				(t_infos (fst (PMap.find i ctx.m.module_globals))).mt_path
-			with Not_found ->
-				error "Invalid macro call" p
-			in
-			i :: (snd path) :: (fst path)
-		| _ ->
-			loop e
-	in
-	(match path with
-	| meth :: cl :: path -> (List.rev path,cl), meth, args
-	| _ -> error "Invalid macro call" p)
-
-let build_macro_type ctx pl p =
-	let path, field, args = (match pl with
-		| [TInst ({ cl_kind = KExpr (ECall (e,args),_) },_)]
-		| [TInst ({ cl_kind = KExpr (EArrayDecl [ECall (e,args),_],_) },_)] ->
-			get_macro_path ctx e args p
-		| _ ->
-			error "MacroType requires a single expression call parameter" p
-	) in
-	let old = ctx.ret in
-	let t = (match ctx.g.do_macro ctx MMacroType path field args p with
-		| None -> mk_mono()
-		| Some _ -> ctx.ret
-	) in
-	ctx.ret <- old;
-	t
-
-let build_macro_build ctx c pl cfl p =
-	let path, field, args = match Meta.get Meta.GenericBuild c.cl_meta with
-		| _,[ECall(e,args),_],_ -> get_macro_path ctx e args p
-		| _ -> error "genericBuild requires a single expression call parameter" p
-	in
-	let old = ctx.ret,ctx.g.get_build_infos in
-	ctx.g.get_build_infos <- (fun() -> Some (TClassDecl c, pl, cfl));
-	let t = (match ctx.g.do_macro ctx MMacroType path field args p with
-		| None -> mk_mono()
-		| Some _ -> ctx.ret
-	) in
-	ctx.ret <- fst old;
-	ctx.g.get_build_infos <- snd old;
-	t
-
-(* -------------------------------------------------------------------------- *)
-(* API EVENTS *)
-
-let build_instance ctx mtype p =
-	match mtype with
-	| TClassDecl c ->
-		if ctx.pass > PBuildClass then ignore(c.cl_build());
-		let build f s =
-			let r = exc_protect ctx (fun r ->
-				let t = mk_mono() in
-				r := (fun() -> t);
-				let tf = (f()) in
-				unify_raise ctx tf t p;
-				link_dynamic t tf;
-				t
-			) s in
-			delay ctx PForce (fun() -> ignore ((!r)()));
-			TLazy r
-		in
-		let ft = (fun pl ->
-			match c.cl_kind with
-			| KGeneric ->
-				build (fun () -> build_generic ctx c p pl) "build_generic"
-			| KMacroType ->
-				build (fun () -> build_macro_type ctx pl p) "macro_type"
-			| KGenericBuild cfl ->
-				build (fun () -> build_macro_build ctx c pl cfl p) "generic_build"
-			| _ ->
-				TInst (c,pl)
-		) in
-		c.cl_params , c.cl_path , ft
-	| TEnumDecl e ->
-		e.e_params , e.e_path , (fun t -> TEnum (e,t))
-	| TTypeDecl t ->
-		t.t_params , t.t_path , (fun tl -> TType(t,tl))
-	| TAbstractDecl a ->
-		a.a_params, a.a_path, (fun tl -> TAbstract(a,tl))
-
-let on_inherit ctx c p (is_extends,tp) =
-	if not is_extends then
-		true
-	else match tp with
-	| { tpackage = ["haxe";"remoting"]; tname = "Proxy"; tparams = [TPType(CTPath t)] } ->
-		extend_remoting ctx c t p false true;
-		false
-	| { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(CTPath t)] } ->
-		extend_remoting ctx c t p true true;
-		false
-	| { tpackage = ["haxe";"xml"]; tname = "Proxy"; tparams = [TPExpr(EConst (String file),p);TPType t] } ->
-		extend_xml_proxy ctx c t file p;
-		true
-	| _ ->
-		true
-
-let push_this ctx e = match e.eexpr with
-	| TConst ((TInt _ | TFloat _ | TString _ | TBool _) as ct) ->
-		(EConst (tconst_to_const ct),e.epos),fun () -> ()
-	| _ ->
-		ctx.this_stack <- e :: ctx.this_stack;
-		let er = EMeta((Meta.This,[],e.epos), (EConst(Ident "this"),e.epos)),e.epos in
-		er,fun () -> ctx.this_stack <- List.tl ctx.this_stack
-
 (* -------------------------------------------------------------------------- *)
 (* ABSTRACT CASTS *)
 

+ 1 - 1
src/main.ml

@@ -1654,7 +1654,7 @@ with
 		message ctx msg p;
 		List.iter (message ctx "Called from") l;
 		error ctx "Aborted" Ast.null_pos;
-	| Codegen.Generic_Exception(m,p) ->
+	| Typeload.Generic_Exception(m,p) ->
 		error ctx m p
 	| Arg.Bad msg ->
 		error ctx ("Error: " ^ msg) Ast.null_pos

+ 1 - 1
src/optimization/filters.ml

@@ -668,7 +668,7 @@ let rec is_removable_class c =
 			| _ -> false) ||
 		List.exists (fun (_,t) -> match follow t with
 			| TInst(c,_) ->
-				Codegen.has_ctor_constraint c || Meta.has Meta.Const c.cl_meta
+				has_ctor_constraint c || Meta.has Meta.Const c.cl_meta
 			| _ ->
 				false
 		) c.cl_params)

+ 9 - 0
src/typing/type.ml

@@ -706,6 +706,15 @@ let tconst_to_const = function
 	| TThis -> Ident "this"
 	| TSuper -> Ident "super"
 
+let has_ctor_constraint c = match c.cl_kind with
+	| KTypeParameter tl ->
+		List.exists (fun t -> match follow t with
+			| TAnon a when PMap.mem "new" a.a_fields -> true
+			| TAbstract({a_path=["haxe"],"Constructible"},_) -> true
+			| _ -> false
+		) tl;
+	| _ -> false
+
 (* ======= Field utility ======= *)
 
 let field_name f =

+ 8 - 0
src/typing/typecore.ml

@@ -425,6 +425,14 @@ let create_fake_module ctx file =
 	Hashtbl.replace ctx.g.modules mdep.m_path mdep;
 	mdep
 
+let push_this ctx e = match e.eexpr with
+	| TConst ((TInt _ | TFloat _ | TString _ | TBool _) as ct) ->
+		(Ast.EConst (tconst_to_const ct),e.epos),fun () -> ()
+	| _ ->
+		ctx.this_stack <- e :: ctx.this_stack;
+		let er = Ast.EMeta((Ast.Meta.This,[],e.epos), (Ast.EConst(Ast.Ident "this"),e.epos)),e.epos in
+		er,fun () -> ctx.this_stack <- List.tl ctx.this_stack
+
 (* -------------- debug functions to activate when debugging typer passes ------------------------------- *)
 (*/*
 

+ 547 - 0
src/typing/typeload.ml

@@ -3508,3 +3508,550 @@ let load_module ctx m p =
 
 ;;
 type_function_params_rec := type_function_params
+
+(* former codegen.ml stuff starting here *)
+
+(* -------------------------------------------------------------------------- *)
+(* REMOTING PROXYS *)
+
+let extend_remoting ctx c t p async prot =
+	if c.cl_super <> None then error "Cannot extend several classes" p;
+	(* remove forbidden packages *)
+	let rules = ctx.com.package_rules in
+	ctx.com.package_rules <- PMap.foldi (fun key r acc -> match r with Forbidden -> acc | _ -> PMap.add key r acc) rules PMap.empty;
+	(* parse module *)
+	let path = (t.tpackage,t.tname) in
+	let new_name = (if async then "Async_" else "Remoting_") ^ t.tname in
+	(* check if the proxy already exists *)
+	let t = (try
+		load_type_def ctx p { tpackage = fst path; tname = new_name; tparams = []; tsub = None }
+	with
+		Error (Module_not_found _,p2) when p == p2 ->
+	(* build it *)
+	Common.log ctx.com ("Building proxy for " ^ s_type_path path);
+	let file, decls = (try
+		parse_module ctx path p
+	with
+		| Not_found -> ctx.com.package_rules <- rules; error ("Could not load proxy module " ^ s_type_path path ^ (if fst path = [] then " (try using absolute path)" else "")) p
+		| e -> ctx.com.package_rules <- rules; raise e) in
+	ctx.com.package_rules <- rules;
+	let base_fields = [
+		{ cff_name = "__cnx"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = []; cff_kind = FVar (Some (CTPath { tpackage = ["haxe";"remoting"]; tname = if async then "AsyncConnection" else "Connection"; tparams = []; tsub = None }),None) };
+		{ cff_name = "new"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun { f_args = ["c",false,None,None]; f_type = None; f_expr = Some (EBinop (OpAssign,(EConst (Ident "__cnx"),p),(EConst (Ident "c"),p)),p); f_params = [] } };
+	] in
+	let tvoid = CTPath { tpackage = []; tname = "Void"; tparams = []; tsub = None } in
+	let build_field is_public acc f =
+		if f.cff_name = "new" then
+			acc
+		else match f.cff_kind with
+		| FFun fd when (is_public || List.mem APublic f.cff_access) && not (List.mem AStatic f.cff_access) ->
+			if List.exists (fun (_,_,t,_) -> t = None) fd.f_args then error ("Field " ^ f.cff_name ^ " type is not complete and cannot be used by RemotingProxy") p;
+			let eargs = [EArrayDecl (List.map (fun (a,_,_,_) -> (EConst (Ident a),p)) fd.f_args),p] in
+			let ftype = (match fd.f_type with Some (CTPath { tpackage = []; tname = "Void" }) -> None | _ -> fd.f_type) in
+			let fargs, eargs = if async then match ftype with
+				| Some tret -> fd.f_args @ ["__callb",true,Some (CTFunction ([tret],tvoid)),None], eargs @ [EConst (Ident "__callb"),p]
+				| _ -> fd.f_args, eargs @ [EConst (Ident "null"),p]
+			else
+				fd.f_args, eargs
+			in
+			let id = (EConst (String f.cff_name), p) in
+			let id = if prot then id else ECall ((EConst (Ident "__unprotect__"),p),[id]),p in
+			let expr = ECall (
+				(EField (
+					(ECall ((EField ((EConst (Ident "__cnx"),p),"resolve"),p),[id]),p),
+					"call")
+				,p),eargs),p
+			in
+			let expr = if async || ftype = None then expr else (EReturn (Some expr),p) in
+			let fd = {
+				f_params = fd.f_params;
+				f_args = fargs;
+				f_type = if async then None else ftype;
+				f_expr = Some (EBlock [expr],p);
+			} in
+			{ cff_name = f.cff_name; cff_pos = f.cff_pos; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun fd } :: acc
+		| _ -> acc
+	in
+	let decls = List.map (fun d ->
+		match d with
+		| EClass c, p when c.d_name = t.tname ->
+			let is_public = List.mem HExtern c.d_flags || List.mem HInterface c.d_flags in
+			let fields = List.rev (List.fold_left (build_field is_public) base_fields c.d_data) in
+			(EClass { c with d_flags = []; d_name = new_name; d_data = fields },p)
+		| _ -> d
+	) decls in
+	let m = type_module ctx (t.tpackage,new_name) file decls p in
+	add_dependency ctx.m.curmod m;
+	try
+		List.find (fun tdecl -> snd (t_path tdecl) = new_name) m.m_types
+	with Not_found ->
+		error ("Module " ^ s_type_path path ^ " does not define type " ^ t.tname) p
+	) in
+	match t with
+	| TClassDecl c2 when c2.cl_params = [] -> ignore(c2.cl_build()); c.cl_super <- Some (c2,[]);
+	| _ -> error "Remoting proxy must be a class without parameters" p
+
+(* -------------------------------------------------------------------------- *)
+(* HAXE.RTTI.GENERIC *)
+
+exception Generic_Exception of string * Ast.pos
+
+type generic_context = {
+	ctx : typer;
+	subst : (t * t) list;
+	name : string;
+	p : pos;
+	mutable mg : module_def option;
+}
+
+let make_generic ctx ps pt p =
+	let rec loop l1 l2 =
+		match l1, l2 with
+		| [] , [] -> []
+		| (x,TLazy f) :: l1, _ -> loop ((x,(!f)()) :: l1) l2
+		| (_,t1) :: l1 , t2 :: l2 -> (t1,t2) :: loop l1 l2
+		| _ -> assert false
+	in
+	let name =
+		String.concat "_" (List.map2 (fun (s,_) t ->
+			let s_type_path_underscore (p,s) = match p with [] -> s | _ -> String.concat "_" p ^ "_" ^ s in
+			let rec loop top t = match follow t with
+				| TInst(c,tl) -> (s_type_path_underscore c.cl_path) ^ (loop_tl tl)
+				| TEnum(en,tl) -> (s_type_path_underscore en.e_path) ^ (loop_tl tl)
+				| TAbstract(a,tl) -> (s_type_path_underscore a.a_path) ^ (loop_tl tl)
+				| _ when not top -> "_" (* allow unknown/incompatible types as type parameters to retain old behavior *)
+				| TMono _ -> raise (Generic_Exception (("Could not determine type for parameter " ^ s), p))
+				| TDynamic _ -> "Dynamic"
+				| t -> raise (Generic_Exception (("Type parameter must be a class or enum instance (found " ^ (s_type (print_context()) t) ^ ")"), p))
+			and loop_tl tl = match tl with
+				| [] -> ""
+				| tl -> "_" ^ String.concat "_" (List.map (loop false) tl)
+			in
+			loop true t
+		) ps pt)
+	in
+	{
+		ctx = ctx;
+		subst = loop ps pt;
+		name = name;
+		p = p;
+		mg = None;
+	}
+
+let rec generic_substitute_type gctx t =
+	match t with
+	| TInst ({ cl_kind = KGeneric } as c2,tl2) ->
+		(* maybe loop, or generate cascading generics *)
+		let _, _, f = gctx.ctx.g.do_build_instance gctx.ctx (TClassDecl c2) gctx.p in
+		let t = f (List.map (generic_substitute_type gctx) tl2) in
+		(match follow t,gctx.mg with TInst(c,_), Some m -> add_dependency m c.cl_module | _ -> ());
+		t
+	| _ ->
+		try
+			generic_substitute_type gctx (List.assq t gctx.subst)
+		with Not_found ->
+			Type.map (generic_substitute_type gctx) t
+
+let generic_substitute_expr gctx e =
+	let vars = Hashtbl.create 0 in
+	let build_var v =
+		try
+			Hashtbl.find vars v.v_id
+		with Not_found ->
+			let v2 = alloc_var v.v_name (generic_substitute_type gctx v.v_type) in
+			v2.v_meta <- v.v_meta;
+			Hashtbl.add vars v.v_id v2;
+			v2
+	in
+	let rec build_expr e =
+		match e.eexpr with
+		| TField(e1, FInstance({cl_kind = KGeneric} as c,tl,cf)) ->
+			let _, _, f = gctx.ctx.g.do_build_instance gctx.ctx (TClassDecl c) gctx.p in
+			let t = f (List.map (generic_substitute_type gctx) tl) in
+			let fa = try
+				quick_field t cf.cf_name
+			with Not_found ->
+				error (Printf.sprintf "Type %s has no field %s (possible typing order issue)" (s_type (print_context()) t) cf.cf_name) e.epos
+			in
+			build_expr {e with eexpr = TField(e1,fa)}
+		| TTypeExpr (TClassDecl ({cl_kind = KTypeParameter _;} as c)) when Meta.has Meta.Const c.cl_meta ->
+			let rec loop subst = match subst with
+				| (t1,t2) :: subst ->
+					begin match follow t1 with
+						| TInst(c2,_) when c == c2 -> t2
+						| _ -> loop subst
+					end
+				| [] -> raise Not_found
+			in
+			begin try
+				let t = loop gctx.subst in
+				begin match follow t with
+					| TInst({cl_kind = KExpr e},_) -> type_expr gctx.ctx e Value
+					| _ -> error "Only Const type parameters can be used as value" e.epos
+				end
+			with Not_found ->
+				e
+			end
+		| _ ->
+			map_expr_type build_expr (generic_substitute_type gctx) build_var e
+	in
+	build_expr e
+
+let get_short_name =
+	let i = ref (-1) in
+	(fun () ->
+		incr i;
+		Printf.sprintf "Hx___short___hx_type_%i" !i
+	)
+
+let rec build_generic ctx c p tl =
+	let pack = fst c.cl_path in
+	let recurse = ref false in
+	let rec check_recursive t =
+		match follow t with
+		| TInst (c2,tl) ->
+			(match c2.cl_kind with
+			| KTypeParameter tl ->
+				if not (is_generic_parameter ctx c2) && has_ctor_constraint c2 then
+					error "Type parameters with a constructor cannot be used non-generically" p;
+				recurse := true
+			| _ -> ());
+			List.iter check_recursive tl;
+		| _ ->
+			()
+	in
+	List.iter check_recursive tl;
+	if !recurse then begin
+		TInst (c,tl) (* build a normal instance *)
+	end else begin
+	let gctx = make_generic ctx c.cl_params tl p in
+	let name = (snd c.cl_path) ^ "_" ^ gctx.name in
+	try
+		load_instance ctx { tpackage = pack; tname = name; tparams = []; tsub = None } p false
+	with Error(Module_not_found path,_) when path = (pack,name) ->
+		let m = (try Hashtbl.find ctx.g.modules (Hashtbl.find ctx.g.types_module c.cl_path) with Not_found -> assert false) in
+		let ctx = { ctx with m = { ctx.m with module_types = m.m_types @ ctx.m.module_types } } in
+		ignore(c.cl_build()); (* make sure the super class is already setup *)
+		let mg = {
+			m_id = alloc_mid();
+			m_path = (pack,name);
+			m_types = [];
+			m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake;
+		} in
+		gctx.mg <- Some mg;
+		let cg = mk_class mg (pack,name) c.cl_pos in
+		mg.m_types <- [TClassDecl cg];
+		Hashtbl.add ctx.g.modules mg.m_path mg;
+		add_dependency mg m;
+		add_dependency ctx.m.curmod mg;
+		(* ensure that type parameters are set in dependencies *)
+		let dep_stack = ref [] in
+		let rec loop t =
+			if not (List.memq t !dep_stack) then begin
+			dep_stack := t :: !dep_stack;
+			match t with
+			| TInst (c,tl) -> add_dep c.cl_module tl
+			| TEnum (e,tl) -> add_dep e.e_module tl
+			| TType (t,tl) -> add_dep t.t_module tl
+			| TAbstract (a,tl) -> add_dep a.a_module tl
+			| TMono r ->
+				(match !r with
+				| None -> ()
+				| Some t -> loop t)
+			| TLazy f ->
+				loop ((!f)());
+			| TDynamic t2 ->
+				if t == t2 then () else loop t2
+			| TAnon a ->
+				PMap.iter (fun _ f -> loop f.cf_type) a.a_fields
+			| TFun (args,ret) ->
+				List.iter (fun (_,_,t) -> loop t) args;
+				loop ret
+			end
+		and add_dep m tl =
+			add_dependency mg m;
+			List.iter loop tl
+		in
+		List.iter loop tl;
+		let build_field cf_old =
+			(* We have to clone the type parameters (issue #4672). We cannot substitute the constraints immediately because
+		       we need the full substitution list first. *)
+			let param_subst,params = List.fold_left (fun (subst,params) (s,t) -> match follow t with
+				| TInst(c,tl) as t ->
+					let t2 = TInst({c with cl_pos = c.cl_pos;},tl) in
+					(t,t2) :: subst,(s,t2) :: params
+				| _ -> assert false
+			) ([],[]) cf_old.cf_params in
+			let gctx = {gctx with subst = param_subst @ gctx.subst} in
+			let cf_new = {cf_old with cf_pos = cf_old.cf_pos} in (* copy *)
+			(* Type parameter constraints are substituted here. *)
+			cf_new.cf_params <- List.rev_map (fun (s,t) -> match follow t with
+				| TInst({cl_kind = KTypeParameter tl1} as c,_) ->
+					let tl1 = List.map (generic_substitute_type gctx) tl1 in
+					c.cl_kind <- KTypeParameter tl1;
+					s,t
+				| _ -> assert false
+			) params;
+			let f () =
+				let t = generic_substitute_type gctx cf_old.cf_type in
+				ignore (follow t);
+				begin try (match cf_old.cf_expr with
+					| None ->
+						begin match cf_old.cf_kind with
+							| Method _ when not c.cl_interface && not c.cl_extern ->
+								display_error ctx (Printf.sprintf "Field %s has no expression (possible typing order issue)" cf_new.cf_name) cf_new.cf_pos;
+								display_error ctx (Printf.sprintf "While building %s" (s_type_path cg.cl_path)) p;
+							| _ ->
+								()
+						end
+					| Some e ->
+						cf_new.cf_expr <- Some (generic_substitute_expr gctx e)
+				) with Unify_error l ->
+					error (error_msg (Unify l)) cf_new.cf_pos
+				end;
+				t
+			in
+			let r = exc_protect ctx (fun r ->
+				let t = mk_mono() in
+				r := (fun() -> t);
+				unify_raise ctx (f()) t p;
+				t
+			) "build_generic" in
+			delay ctx PForce (fun() -> ignore ((!r)()));
+			cf_new.cf_type <- TLazy r;
+			cf_new
+		in
+		if c.cl_init <> None || c.cl_dynamic <> None then error "This class can't be generic" p;
+		List.iter (fun cf -> match cf.cf_kind with
+			| Method MethMacro when not ctx.in_macro -> ()
+			| _ -> error "A generic class can't have static fields" cf.cf_pos
+		) c.cl_ordered_statics;
+		cg.cl_super <- (match c.cl_super with
+			| None -> None
+			| Some (cs,pl) ->
+				let find_class subst =
+					let rec loop subst = match subst with
+						| (TInst(c,[]),t) :: subst when c == cs -> t
+						| _ :: subst -> loop subst
+						| [] -> raise Not_found
+					in
+					try
+						if pl <> [] then raise Not_found;
+						let t = loop subst in
+						(* extended type parameter: concrete type must have a constructor, but generic base class must not have one *)
+						begin match follow t,c.cl_constructor with
+							| TInst(cs,_),None ->
+								ignore(cs.cl_build());
+								begin match cs.cl_constructor with
+									| None -> error ("Cannot use " ^ (s_type_path cs.cl_path) ^ " as type parameter because it is extended and has no constructor") p
+									| _ -> ()
+								end;
+							| _,Some cf -> error "Generics extending type parameters cannot have constructors" cf.cf_pos
+							| _ -> ()
+						end;
+						t
+					with Not_found ->
+						apply_params c.cl_params tl (TInst(cs,pl))
+				in
+				let ts = follow (find_class gctx.subst) in
+				let cs,pl = Inheritance.check_extends ctx c ts p in
+				match cs.cl_kind with
+				| KGeneric ->
+					(match build_generic ctx cs p pl with
+					| TInst (cs,pl) -> Some (cs,pl)
+					| _ -> assert false)
+				| _ -> Some(cs,pl)
+		);
+		add_constructor ctx cg false p;
+		cg.cl_kind <- KGenericInstance (c,tl);
+		cg.cl_meta <- (Meta.NoDoc,[],p) :: cg.cl_meta;
+		if has_meta Meta.Keep c.cl_meta then cg.cl_meta <- (Meta.Keep,[],p) :: cg.cl_meta;
+		cg.cl_interface <- c.cl_interface;
+		cg.cl_constructor <- (match cg.cl_constructor, c.cl_constructor, c.cl_super with
+			| _, Some cf, _ -> Some (build_field cf)
+			| Some ctor, _, _ -> Some ctor
+			| None, None, None -> None
+			| _ -> error "Please define a constructor for this class in order to use it as generic" c.cl_pos
+		);
+		cg.cl_implements <- List.map (fun (i,tl) ->
+			(match follow (generic_substitute_type gctx (TInst (i, List.map (generic_substitute_type gctx) tl))) with
+			| TInst (i,tl) -> i, tl
+			| _ -> assert false)
+		) c.cl_implements;
+		cg.cl_ordered_fields <- List.map (fun f ->
+			let f = build_field f in
+			cg.cl_fields <- PMap.add f.cf_name f cg.cl_fields;
+			f
+		) c.cl_ordered_fields;
+		cg.cl_overrides <- List.map (fun f ->
+			try PMap.find f.cf_name cg.cl_fields with Not_found -> assert false
+		) c.cl_overrides;
+		(* In rare cases the class name can become too long, so let's shorten it (issue #3090). *)
+		if String.length (snd cg.cl_path) > 254 then begin
+			let n = get_short_name () in
+			cg.cl_meta <- (Meta.Native,[EConst(String (n)),p],p) :: cg.cl_meta;
+		end;
+		TInst (cg,[])
+	end
+
+(* -------------------------------------------------------------------------- *)
+(* HAXE.XML.PROXY *)
+
+let extend_xml_proxy ctx c t file p =
+	let t = load_complex_type ctx p t in
+	let file = (try Common.find_file ctx.com file with Not_found -> file) in
+	add_dependency c.cl_module (create_fake_module ctx file);
+	let used = ref PMap.empty in
+	let print_results() =
+		PMap.iter (fun id used ->
+			if not used then ctx.com.warning (id ^ " is not used") p;
+		) (!used)
+	in
+	let check_used = Common.defined ctx.com Define.CheckXmlProxy in
+	if check_used then ctx.g.hook_generate <- print_results :: ctx.g.hook_generate;
+	try
+		let rec loop = function
+			| Xml.Element (_,attrs,childs) ->
+				(try
+					let id = List.assoc "id" attrs in
+					if PMap.mem id c.cl_fields then error ("Duplicate id " ^ id) p;
+					let t = if not check_used then t else begin
+						used := PMap.add id false (!used);
+						let ft() = used := PMap.add id true (!used); t in
+						TLazy (ref ft)
+					end in
+					let f = {
+						cf_name = id;
+						cf_type = t;
+						cf_public = true;
+						cf_pos = p;
+						cf_doc = None;
+						cf_meta = no_meta;
+						cf_kind = Var { v_read = AccResolve; v_write = AccNo };
+						cf_params = [];
+						cf_expr = None;
+						cf_overloads = [];
+					} in
+					c.cl_fields <- PMap.add id f c.cl_fields;
+				with
+					Not_found -> ());
+				List.iter loop childs;
+			| Xml.PCData _ -> ()
+		in
+		loop (Xml.parse_file file)
+	with
+		| Xml.Error e -> error ("XML error " ^ Xml.error e) p
+		| Xml.File_not_found f -> error ("XML File not found : " ^ f) p
+
+(* -------------------------------------------------------------------------- *)
+(* MACRO TYPE *)
+
+let get_macro_path ctx e args p =
+	let rec loop e =
+		match fst e with
+		| EField (e,f) -> f :: loop e
+		| EConst (Ident i) -> [i]
+		| _ -> error "Invalid macro call" p
+	in
+	let path = match e with
+		| (EConst(Ident i)),_ ->
+			let path = try
+				if not (PMap.mem i ctx.curclass.cl_statics) then raise Not_found;
+				ctx.curclass.cl_path
+			with Not_found -> try
+				(t_infos (fst (PMap.find i ctx.m.module_globals))).mt_path
+			with Not_found ->
+				error "Invalid macro call" p
+			in
+			i :: (snd path) :: (fst path)
+		| _ ->
+			loop e
+	in
+	(match path with
+	| meth :: cl :: path -> (List.rev path,cl), meth, args
+	| _ -> error "Invalid macro call" p)
+
+let build_macro_type ctx pl p =
+	let path, field, args = (match pl with
+		| [TInst ({ cl_kind = KExpr (ECall (e,args),_) },_)]
+		| [TInst ({ cl_kind = KExpr (EArrayDecl [ECall (e,args),_],_) },_)] ->
+			get_macro_path ctx e args p
+		| _ ->
+			error "MacroType requires a single expression call parameter" p
+	) in
+	let old = ctx.ret in
+	let t = (match ctx.g.do_macro ctx MMacroType path field args p with
+		| None -> mk_mono()
+		| Some _ -> ctx.ret
+	) in
+	ctx.ret <- old;
+	t
+
+let build_macro_build ctx c pl cfl p =
+	let path, field, args = match Meta.get Meta.GenericBuild c.cl_meta with
+		| _,[ECall(e,args),_],_ -> get_macro_path ctx e args p
+		| _ -> error "genericBuild requires a single expression call parameter" p
+	in
+	let old = ctx.ret,ctx.g.get_build_infos in
+	ctx.g.get_build_infos <- (fun() -> Some (TClassDecl c, pl, cfl));
+	let t = (match ctx.g.do_macro ctx MMacroType path field args p with
+		| None -> mk_mono()
+		| Some _ -> ctx.ret
+	) in
+	ctx.ret <- fst old;
+	ctx.g.get_build_infos <- snd old;
+	t
+
+(* -------------------------------------------------------------------------- *)
+(* API EVENTS *)
+
+let build_instance ctx mtype p =
+	match mtype with
+	| TClassDecl c ->
+		if ctx.pass > PBuildClass then ignore(c.cl_build());
+		let build f s =
+			let r = exc_protect ctx (fun r ->
+				let t = mk_mono() in
+				r := (fun() -> t);
+				let tf = (f()) in
+				unify_raise ctx tf t p;
+				link_dynamic t tf;
+				t
+			) s in
+			delay ctx PForce (fun() -> ignore ((!r)()));
+			TLazy r
+		in
+		let ft = (fun pl ->
+			match c.cl_kind with
+			| KGeneric ->
+				build (fun () -> build_generic ctx c p pl) "build_generic"
+			| KMacroType ->
+				build (fun () -> build_macro_type ctx pl p) "macro_type"
+			| KGenericBuild cfl ->
+				build (fun () -> build_macro_build ctx c pl cfl p) "generic_build"
+			| _ ->
+				TInst (c,pl)
+		) in
+		c.cl_params , c.cl_path , ft
+	| TEnumDecl e ->
+		e.e_params , e.e_path , (fun t -> TEnum (e,t))
+	| TTypeDecl t ->
+		t.t_params , t.t_path , (fun tl -> TType(t,tl))
+	| TAbstractDecl a ->
+		a.a_params, a.a_path, (fun tl -> TAbstract(a,tl))
+
+let on_inherit ctx c p (is_extends,tp) =
+	if not is_extends then
+		true
+	else match tp with
+	| { tpackage = ["haxe";"remoting"]; tname = "Proxy"; tparams = [TPType(CTPath t)] } ->
+		extend_remoting ctx c t p false true;
+		false
+	| { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(CTPath t)] } ->
+		extend_remoting ctx c t p true true;
+		false
+	| { tpackage = ["haxe";"xml"]; tname = "Proxy"; tparams = [TPExpr(EConst (String file),p);TPType t] } ->
+		extend_xml_proxy ctx c t file p;
+		true
+	| _ ->
+		true

+ 13 - 13
src/typing/typer.ml

@@ -845,7 +845,7 @@ let fast_enum_field e ef p =
 let rec type_module_type ctx t tparams p =
 	match t with
 	| TClassDecl {cl_kind = KGenericBuild _} ->
-		let _,_,f = Codegen.build_instance ctx t p in
+		let _,_,f = Typeload.build_instance ctx t p in
 		let t = f (match tparams with None -> [] | Some tl -> tl) in
 		let mt = try
 			module_type_of_type t
@@ -1848,8 +1848,8 @@ let unify_int ctx e k =
 	end;
 	let el = match using_param with None -> el | Some e -> e :: el in
 	(try
-		let gctx = Codegen.make_generic ctx cf.cf_params monos p in
-		let name = cf.cf_name ^ "_" ^ gctx.Codegen.name in
+		let gctx = Typeload.make_generic ctx cf.cf_params monos p in
+		let name = cf.cf_name ^ "_" ^ gctx.Typeload.name in
 		let unify_existing_field tcf pcf = try
 			unify_raise ctx tcf t p
 		with Error(Unify _,_) as err ->
@@ -1890,7 +1890,7 @@ let unify_int ctx e k =
 				| None ->
 					display_error ctx "Recursive @:generic function" p; None;
 				| Some e ->
-					let e = Codegen.generic_substitute_expr gctx e in
+					let e = Typeload.generic_substitute_expr gctx e in
 					check e;
 					Some e
 			);
@@ -1907,7 +1907,7 @@ let unify_int ctx e k =
 		let fa = if stat then FStatic (c,cf2) else FInstance (c,tl,cf2) in
 		let e = mk (TField(e,fa)) cf2.cf_type p in
 		make_call ctx e el ret p
-	with Codegen.Generic_Exception (msg,p) ->
+	with Typeload.Generic_Exception (msg,p) ->
 		error msg p)
 
 let call_to_string ctx e =
@@ -3106,10 +3106,10 @@ and type_new ctx t el with_type p =
 		ctx.call_argument_stack <- List.tl ctx.call_argument_stack;
 		(* Try to properly build @:generic classes here (issue #2016) *)
 		begin match t with
-			| TInst({cl_kind = KGeneric } as c,tl) -> follow (Codegen.build_generic ctx c p tl)
+			| TInst({cl_kind = KGeneric } as c,tl) -> follow (Typeload.build_generic ctx c p tl)
 			| _ -> t
 		end
-	with Codegen.Generic_Exception _ ->
+	with Typeload.Generic_Exception _ ->
 		(* Try to infer generic parameters from the argument list (issue #2044) *)
 		match Typeload.resolve_typedef (Typeload.load_type_def ctx p t) with
 		| TClassDecl ({cl_constructor = Some cf} as c) ->
@@ -3117,11 +3117,11 @@ and type_new ctx t el with_type p =
 			let ct, f = get_constructor ctx c monos p in
 			ignore (unify_constructor_call c monos f ct);
 			begin try
-				let t = Codegen.build_generic ctx c p monos in
+				let t = Typeload.build_generic ctx c p monos in
 				let map = apply_params c.cl_params monos in
 				check_constraints ctx (s_type_path c.cl_path) c.cl_params monos map true p;
 				t
-			with Codegen.Generic_Exception _ as exc ->
+			with Typeload.Generic_Exception _ as exc ->
 				(* If we have an expected type, just use that (issue #3804) *)
 				begin match with_type with
 					| WithType t ->
@@ -4135,7 +4135,7 @@ and build_call ctx acc el (with_type:with_type) p =
 		begin match ef.cf_kind with
 		| Method MethMacro ->
 			let ethis = type_module_type ctx (TClassDecl cl) None p in
-			let eparam,f = Codegen.push_this ctx eparam in
+			let eparam,f = push_this ctx eparam in
 			let e = build_call ctx (AKMacro (ethis,ef)) (eparam :: el) with_type p in
 			f();
 			e
@@ -4176,7 +4176,7 @@ and build_call ctx acc el (with_type:with_type) p =
 			| TInst (c,_) ->
 				let rec loop c =
 					if PMap.mem cf.cf_name c.cl_fields then
-						let eparam,f = Codegen.push_this ctx ethis in
+						let eparam,f = push_this ctx ethis in
 						ethis_f := f;
 						let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name (eparam :: el) p with
 							| None -> (fun() -> type_expr ctx (EConst (Ident "null"),p) Value)
@@ -5136,12 +5136,12 @@ let rec create com =
 			get_build_infos = (fun() -> None);
 			std = null_module;
 			global_using = [];
-			do_inherit = Codegen.on_inherit;
+			do_inherit = Typeload.on_inherit;
 			do_create = create;
 			do_macro = type_macro;
 			do_load_module = Typeload.load_module;
 			do_optimize = Optimizer.reduce_expression;
-			do_build_instance = Codegen.build_instance;
+			do_build_instance = Typeload.build_instance;
 		};
 		m = {
 			curmod = null_module;