Browse Source

Internal dependency cleanup 2023 (#11451)

* factor out field call candidate

* load Std when creating typer instead of randomly when we need it

* slightly split up exceptions.ml

* lose genjs dependency on typeloadCheck

* factor out expr preprocessing

to lose a dependency between EvalDebugSocket and typecore

* split up filters.ml a bit

to lose macroContext -> filters because it brings a lot of other stuff

* separate Typer.create from the rest

to lose the macroContext dependency

* lose some weird dependencies from string formatting

* make Eval an isolated dependency

* bring back catch that breaks tink
Simon Krajewski 1 năm trước cách đây
mục cha
commit
599e0ca4bf
46 tập tin đã thay đổi với 865 bổ sung836 xóa
  1. 1 0
      src/codegen/codegen.ml
  2. 1 1
      src/codegen/overloads.ml
  3. 4 4
      src/compiler/compiler.ml
  4. 1 1
      src/compiler/displayOutput.ml
  5. 6 2
      src/compiler/serverCompilationContext.ml
  6. 2 99
      src/context/common.ml
  7. 4 227
      src/context/display/display.ml
  8. 1 1
      src/context/display/displayEmitter.ml
  9. 224 0
      src/context/display/exprPreprocessing.ml
  10. 98 0
      src/context/formatString.ml
  11. 2 2
      src/context/memory.ml
  12. 3 39
      src/context/typecore.ml
  13. 88 0
      src/core/naming.ml
  14. 12 1
      src/core/socket.ml
  15. 68 0
      src/filters/addFieldInits.ml
  16. 22 0
      src/filters/exceptionFunctions.ml
  17. 2 25
      src/filters/exceptions.ml
  18. 4 208
      src/filters/filters.ml
  19. 15 0
      src/filters/filtersCommon.ml
  20. 63 0
      src/filters/localStatic.ml
  21. 3 3
      src/filters/renameVars.ml
  22. 2 2
      src/generators/genjs.ml
  23. 2 2
      src/generators/genjvm.ml
  24. 2 2
      src/generators/genswf9.ml
  25. 5 0
      src/macro/eval/eval.ml
  26. 0 5
      src/macro/eval/evalContext.ml
  27. 1 1
      src/macro/eval/evalDebugSocket.ml
  28. 0 1
      src/macro/eval/evalExceptions.ml
  29. 2 1
      src/macro/eval/evalMain.ml
  30. 1 1
      src/macro/eval/evalStdLib.ml
  31. 1 1
      src/macro/eval/evalThread.ml
  32. 1 0
      src/macro/eval/evalTypes.ml
  33. 3 1
      src/optimization/inline.ml
  34. 1 0
      src/typing/callUnification.ml
  35. 39 0
      src/typing/fieldCallCandidate.ml
  36. 1 1
      src/typing/functionArguments.ml
  37. 1 0
      src/typing/generic.ml
  38. 8 16
      src/typing/macroContext.ml
  39. 1 1
      src/typing/overloadResolution.ml
  40. 0 11
      src/typing/typeload.ml
  41. 2 20
      src/typing/typeloadCheck.ml
  42. 1 1
      src/typing/typeloadFields.ml
  43. 1 1
      src/typing/typeloadFunction.ml
  44. 3 3
      src/typing/typeloadModule.ml
  45. 9 152
      src/typing/typer.ml
  46. 154 0
      src/typing/typerEntry.ml

+ 1 - 0
src/codegen/codegen.ml

@@ -520,3 +520,4 @@ module ExtClass = struct
 		let e_assign = mk (TBinop(OpAssign,ef1,e)) e.etype p in
 		add_cl_init c e_assign
 end
+	

+ 1 - 1
src/codegen/overloads.ml

@@ -1,6 +1,6 @@
 open Globals
 open Type
-open Typecore
+open FieldCallCandidate
 
 let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
 	let f_transform = match get_vmtype with

+ 4 - 4
src/compiler/compiler.ml

@@ -178,7 +178,7 @@ module Setup = struct
 		let fl = List.map (fun (file,extern) -> NativeLibraryHandler.add_native_lib com file extern) (List.rev native_libs) in
 		(* Native lib pass 2: Initialize *)
 		List.iter (fun f -> f()) fl;
-		Typer.create com macros
+		TyperEntry.create com macros
 
 	let executable_path() =
 		Extc.executable_path()
@@ -424,7 +424,7 @@ with
 		error ctx ("Error: No completion point was found") null_pos
 	| DisplayException.DisplayException dex ->
 		DisplayOutput.handle_display_exception ctx dex
-	| Out_of_memory | EvalExceptions.Sys_exit _ | Hlinterp.Sys_exit _ | DisplayProcessingGlobals.Completion _ as exc ->
+	| Out_of_memory | EvalTypes.Sys_exit _ | Hlinterp.Sys_exit _ | DisplayProcessingGlobals.Completion _ as exc ->
 		(* We don't want these to be caught by the catchall below *)
 		raise exc
 	| e when (try Sys.getenv "OCAMLRUNPARAM" <> "b" with _ -> true) && not Helper.is_debug_run ->
@@ -450,7 +450,7 @@ let catch_completion_and_exit ctx callbacks run =
 			ServerMessage.completion str;
 			ctx.comm.write_err str;
 			0
-		| EvalExceptions.Sys_exit i | Hlinterp.Sys_exit i ->
+		| EvalTypes.Sys_exit i | Hlinterp.Sys_exit i ->
 			if i <> 0 then ctx.has_error <- true;
 			finalize ctx;
 			i
@@ -483,7 +483,7 @@ let compile_ctx callbacks ctx =
 		catch_completion_and_exit ctx callbacks run
 
 let create_context comm cs compilation_step params = {
-	com = Common.create compilation_step cs version params;
+	com = Common.create compilation_step cs version params (DisplayTypes.DisplayMode.create !Parser.display_mode);
 	messages = [];
 	has_next = false;
 	has_error = false;

+ 1 - 1
src/compiler/displayOutput.ml

@@ -344,7 +344,7 @@ let handle_type_path_exception ctx p c is_import pos =
 			| None ->
 				DisplayPath.TypePathHandler.complete_type_path com p
 			| Some (c,cur_package) ->
-				let ctx = Typer.create com None in
+				let ctx = TyperEntry.create com None in
 				DisplayPath.TypePathHandler.complete_type_path_inner ctx p c cur_package is_import
 		end with Error.Fatal_error err ->
 			error_ext ctx err;

+ 6 - 2
src/compiler/serverCompilationContext.ml

@@ -70,5 +70,9 @@ let ensure_macro_setup sctx =
 	end
 
 let cleanup () = match !MacroContext.macro_interp_cache with
-	| Some interp -> EvalContext.GlobalState.cleanup interp
-	| None -> ()
+	| Some interp ->
+		(* curapi holds a reference to the typing context which we don't want to persist. Let's unset it so the
+		   context can be collected. *)		
+		interp.curapi <- Obj.magic ""
+	| None ->
+		()

+ 2 - 99
src/context/common.ml

@@ -798,7 +798,7 @@ let get_config com =
 
 let memory_marker = [|Unix.time()|]
 
-let create compilation_step cs version args =
+let create compilation_step cs version args display_mode =
 	let m = Type.mk_mono() in
 	let rec com = {
 		compilation_step = compilation_step;
@@ -819,7 +819,7 @@ let create compilation_step cs version args =
 		};
 		sys_args = args;
 		debug = false;
-		display = DisplayTypes.DisplayMode.create !Parser.display_mode;
+		display = display_mode;
 		verbose = false;
 		foptimize = true;
 		features = Hashtbl.create 0;
@@ -1326,100 +1326,3 @@ let get_entry_point com =
 		let e = Option.get com.main in (* must be present at this point *)
 		(snd path, c, e)
 	) com.main_class
-
-let format_string com s p process_expr =
-	let e = ref None in
-	let pmin = ref p.pmin in
-	let min = ref (p.pmin + 1) in
-	let add_expr (enext,p) len =
-		min := !min + len;
-		let enext = process_expr enext p in
-		match !e with
-		| None -> e := Some enext
-		| Some prev ->
-			e := Some (EBinop (OpAdd,prev,enext),punion (pos prev) p)
-	in
-	let add enext len =
-		let p = { p with pmin = !min; pmax = !min + len } in
-		add_expr (enext,p) len
-	in
-	let add_sub start pos =
-		let len = pos - start in
-		if len > 0 || !e = None then add (EConst (String (String.sub s start len,SDoubleQuotes))) len
-	in
-	let len = String.length s in
-	let rec parse start pos =
-		if pos = len then add_sub start pos else
-		let c = String.unsafe_get s pos in
-		let pos = pos + 1 in
-		if c = '\'' then begin
-			incr pmin;
-			incr min;
-		end;
-		if c <> '$' || pos = len then parse start pos else
-		match String.unsafe_get s pos with
-		| '$' ->
-			(* double $ *)
-			add_sub start pos;
-			parse (pos + 1) (pos + 1)
-		| '{' ->
-			parse_group start pos '{' '}' "brace"
-		| 'a'..'z' | 'A'..'Z' | '_' ->
-			add_sub start (pos - 1);
-			incr min;
-			let rec loop i =
-				if i = len then i else
-				let c = String.unsafe_get s i in
-				match c with
-				| 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' -> loop (i+1)
-				| _ -> i
-			in
-			let iend = loop (pos + 1) in
-			let len = iend - pos in
-			add (EConst (Ident (String.sub s pos len))) len;
-			parse (pos + len) (pos + len)
-		| _ ->
-			(* keep as-it *)
-			parse start pos
-	and parse_group start pos gopen gclose gname =
-		add_sub start (pos - 1);
-		let rec loop groups i =
-			if i = len then
-				match groups with
-				| [] -> die "" __LOC__
-				| g :: _ -> Error.raise_typing_error ("Unclosed " ^ gname) { p with pmin = !pmin + g + 1; pmax = !pmin + g + 2 }
-			else
-				let c = String.unsafe_get s i in
-				if c = gopen then
-					loop (i :: groups) (i + 1)
-				else if c = gclose then begin
-					let groups = List.tl groups in
-					if groups = [] then i else loop groups (i + 1)
-				end else
-					loop groups (i + 1)
-		in
-		let send = loop [pos] (pos + 1) in
-		let slen = send - pos - 1 in
-		let scode = String.sub s (pos + 1) slen in
-		min := !min + 2;
-		begin
-			let e =
-				let ep = { p with pmin = !pmin + pos + 2; pmax = !pmin + send + 1 } in
-				let error msg pos =
-					if Lexer.string_is_whitespace scode then Error.raise_typing_error "Expression cannot be empty" ep
-					else Error.raise_typing_error msg pos
-				in
-				match ParserEntry.parse_expr_string com.defines scode ep error true with
-					| ParseSuccess(data,_,_) -> data
-					| ParseError(_,(msg,p),_) -> error (Parser.error_msg msg) p
-			in
-			add_expr e slen
-		end;
-		min := !min + 1;
-		parse (send + 1) (send + 1)
-	in
-	parse 0 0;
-	match !e with
-	| None -> die "" __LOC__
-	| Some e -> e
-

+ 4 - 227
src/context/display/display.ml

@@ -30,233 +30,10 @@ module ReferencePosition = struct
 	let reset () = reference_position := ("",null_pos,SKOther)
 end
 
-module ExprPreprocessing = struct
-	let find_before_pos dm e =
-		let display_pos = ref (DisplayPosition.display_position#get) in
-		let was_annotated = ref false in
-		let is_annotated,is_completion = match dm with
-			| DMDefault -> (fun p -> not !was_annotated && encloses_position !display_pos p),true
-			| DMHover -> (fun p -> not !was_annotated && encloses_position_gt !display_pos p),false
-			| _ -> (fun p -> not !was_annotated && encloses_position !display_pos p),false
-		in
-		let annotate e dk =
-			was_annotated := true;
-			(EDisplay(e,dk),pos e)
-		in
-		let annotate_marked e = annotate e DKMarked in
-		let mk_null p = annotate_marked ((EConst(Ident "null")),p) in
-		let loop_el el =
-			let pr = DisplayPosition.display_position#with_pos (pos e) in
-			let rec loop el = match el with
-				| [] -> [mk_null pr]
-				| e :: el ->
-					if (pos e).pmin >= pr.pmax then (mk_null pr) :: e :: el
-					else e :: loop el
-			in
-			(* print_endline (Printf.sprintf "%i-%i: PR" pr.pmin pr.pmax);
-			List.iter (fun e ->
-				print_endline (Printf.sprintf "%i-%i: %s" (pos e).pmin (pos e).pmax (Ast.s_expr e));
-			) el; *)
-			match el with
-			| [] -> [mk_null pr]
-			| e :: el ->
-				if (pos e).pmin >= pr.pmax then (mk_null pr) :: e :: el
-				else loop (e :: el)
-		in
-		let in_pattern = ref false in
-		let loop e =
-			(* print_endline (Printf.sprintf "%i-%i: %s" (pos e).pmin (pos e).pmax (Ast.s_expr e)); *)
-			match fst e with
-			| EFunction(FKNamed((_,p),_),_) when is_annotated p && is_completion ->
-				raise Exit
-			| EVars vl when is_annotated (pos e) && is_completion ->
-				let rec loop2 acc mark vl = match vl with
-					| v :: vl ->
-						if mark then
-							loop2 (v :: acc) mark vl
-						else if is_annotated (snd v.ev_name) then
-							(* If the name is the display position, mark the expression *)
-							loop2 (v :: acc) true vl
-						else begin match v.ev_expr with
-							| None ->
-								(* If there is no expression, we don't have to do anything.
-								   Should the display position be on the type-hint, it will
-								   be picked up while loading the type. *)
-								loop2 (v :: acc) mark vl
-							| Some e ->
-								(* Determine the area between the `|` in `var x| = | e`. This is not really
-								   correct because we don't want completion on the left side of the `=`, but
-								   we cannot determine that correctly without knowing its position.
-								   Note: We know `e` itself isn't the display position because this entire
-								   algorithm is bottom-up and it would be marked already if it was. *)
-								let p0 = match v.ev_type with
-									| Some (_,pt) -> pt
-									| None -> snd v.ev_name
-								in
-								let p = {p0 with pmax = (pos e).pmin} in
-								let e = if is_annotated p then annotate_marked e else e in
-								loop2 ({ v with ev_expr = Some e } :: acc) mark vl
-						end
-					| [] ->
-						List.rev acc,mark
-				in
-				let vl,mark = loop2 [] false vl in
-				let e = EVars (List.rev vl),pos e in
-				if !was_annotated then e else raise Exit
-			| EBinop((OpAssign | OpAssignOp _) as op,e1,e2) when is_annotated (pos e) && is_completion ->
-				(* Special case for assign ops: If the expression is marked, but none of its operands are,
-				   we are "probably" interested in the rhs. Like with EVars, this isn't accurate because we
-				   could be on the left side of the `=`. I don't think there's a reason for requesting
-				   completion there though. *)
-				(EBinop(op,e1,annotate_marked e2)),(pos e)
-			| EBinop(OpOr,e1,(EIf(_,(EConst(Ident "null"),_),None),p1)) when is_annotated (pos e) && is_completion && !in_pattern ->
-				(* This HAS TO come from an attempted `case pattern | guard:` completion (issue #7068). *)
-				let p = { p1 with pmin = (pos e1).pmax; pmax = p1.pmin } in
-				EBinop(OpOr,e1,mk_null p),(pos e)
-			| EIf(_,(EConst(Ident "null"),_),None) when is_completion && !in_pattern ->
-				(* This is fine. *)
-				mk_null (pos e)
-			| EBlock [] when is_annotated (pos e) ->
-				annotate e DKStructure
-			| EBlock [EDisplay((EConst(Ident s),pn),DKMarked),_] when is_completion ->
-				let e = EObjectDecl [(s,pn,NoQuotes),(EConst (Ident "null"),null_pos)],(pos e) in
-				annotate e DKStructure
-			| EBlock el when is_annotated (pos e) && is_completion ->
-				let el = loop_el el in
-				EBlock el,(pos e)
-			| ECall(e1,el) when is_annotated (pos e) && is_completion ->
-				let el = loop_el el in
-				ECall(e1,el),(pos e)
-			| ENew(ptp,el) when is_annotated (pos e) && is_completion ->
-				if is_annotated ptp.pos_full || ptp.pos_full.pmax >= (DisplayPosition.display_position#get).pmax then
-					annotate_marked e
-				else begin
-					let el = loop_el el in
-					ENew(ptp,el),(pos e)
-				end
-			| EArrayDecl el when is_annotated (pos e) && is_completion ->
-				let el = loop_el el in
-				EArrayDecl el,(pos e)
-			| EObjectDecl fl when is_annotated (pos e) && is_completion ->
-				annotate e DKStructure
-			| ESwitch(e1,cases,def) when is_annotated (pos e) ->
-				(* We must be "between" two cases, or at the end of the last case.
-				   Let's find the last case which has a position that is < the display
-				   position and mark it. *)
-				let did_mark = ref false in
-				let mark_case ec p =
-					did_mark := true;
-					let ep = mk_null p in
-					match ec with
-					| Some ec ->
-						let ec = match fst ec with
-							| EBlock el -> (EBlock (el @ [ep]),p)
-							| _ -> (EBlock [ec;ep],p)
-						in
-						Some ec
-					| None ->
-						Some (mk_null p)
-				in
-				let rec loop cases = match cases with
-					| [el,eg,ec,p1] ->
-						let ec = match def with
-						| None when (pos e).pmax > !display_pos.pmin -> (* this is so we don't trigger if we're on the } *)
-							mark_case ec p1 (* no default, must be the last case *)
-						| Some (_,p2) when p1.pmax <= !display_pos.pmin && p2.pmin >= !display_pos.pmax ->
-							mark_case ec p1 (* default is beyond display position, mark *)
-						| _ ->
-							ec (* default contains display position, don't mark *)
-						in
-						[el,eg,ec,p1]
-					| (el1,eg1,ec1,p1) :: (el2,eg2,ec2,p2) :: cases ->
-						if p1.pmax <= !display_pos.pmin && p2.pmin >= !display_pos.pmax then
-							(el1,eg1,mark_case ec1 p1,p1) :: (el2,eg2,ec2,p2) :: cases
-						else
-							(el1,eg1,ec1,p1) :: loop ((el2,eg2,ec2,p2) :: cases)
-					| [] ->
-						[]
-				in
-				let cases = loop cases in
-				let def = if !did_mark then
-					def
-				else match def with
-					| Some(eo,p) when (pos e).pmax > !display_pos.pmin -> Some (mark_case eo p,p)
-					| _ -> def
-				in
-				ESwitch(e1,cases,def),pos e
-			| EDisplay _ ->
-				raise Exit
-			| EMeta((Meta.Markup,_,_),(EConst(String _),p)) when is_annotated p ->
-				annotate_marked e
-			| EConst (String (_,q)) when ((q <> SSingleQuotes) || !Parser.was_auto_triggered) && is_annotated (pos e) && is_completion ->
-				(* TODO: check if this makes any sense *)
-				raise Exit
-			| EConst(Regexp _) when is_annotated (pos e) && is_completion ->
-				raise Exit
-			| EVars vl when is_annotated (pos e) ->
-				(* We only want to mark EVars if we're on a var name. *)
-				if List.exists (fun v -> is_annotated (snd v.ev_name)) vl then
-					annotate_marked e
-				else
-					raise Exit
-			| _ ->
-				if is_annotated (pos e) then
-					annotate_marked e
-				else
-					e
-		in
-		let opt f o =
-			match o with None -> None | Some v -> Some (f v)
-		in
-		let rec map e = match fst e with
-			| ESwitch(e1,cases,def) when is_annotated (pos e) ->
-				let e1 = map e1 in
-				let cases = List.map (fun (el,eg,e,p) ->
-					let old = !in_pattern in
-					in_pattern := true;
-					let el = List.map map el in
-					in_pattern := old;
-					let eg = opt map eg in
-					let e = opt map e in
-					el,eg,e,p
-				) cases in
-				let def = opt (fun (eo,p) -> opt map eo,p) def in
-				loop (ESwitch (e1, cases, def),(pos e))
-			| _ ->
-				loop (Ast.map_expr map e)
-		in
-		try map e with Exit -> e
-
-	let find_display_call e =
-		let found = ref false in
-		let handle_el e el =
-			let call_arg_is_marked () =
-				el = [] || List.exists (fun (e,_) -> match e with EDisplay(_,DKMarked) -> true | _ -> false) el
-			in
-			if not !Parser.was_auto_triggered || call_arg_is_marked () then begin
-			found := true;
-			Parser.mk_display_expr e DKCall
-			end else
-				e
-		in
-		let loop e = match fst e with
-			| ECall(_,el) | ENew(_,el) when not !found && display_position#enclosed_in (pos e) ->
-				handle_el e el
-			| EArray(e1,e2) when not !found && display_position#enclosed_in (pos e2) ->
-				handle_el e [e2]
-			| EDisplay(_,DKCall) ->
-				raise Exit
-			| _ -> e
-		in
-		let rec map e = loop (Ast.map_expr map e) in
-		try map e with Exit -> e
-
-
-	let process_expr com e = match com.display.dms_kind with
-		| DMDefinition | DMTypeDefinition | DMUsage _ | DMImplementation | DMHover | DMDefault -> find_before_pos com.display.dms_kind e
-		| DMSignature -> find_display_call e
-		| _ -> e
-end
+let preprocess_expr com e = match com.display.dms_kind with
+	| DMDefinition | DMTypeDefinition | DMUsage _ | DMImplementation | DMHover | DMDefault -> ExprPreprocessing.find_before_pos com.display.dms_kind e
+	| DMSignature -> ExprPreprocessing.find_display_call e
+	| _ -> e
 
 let get_expected_name with_type = match with_type with
 	| WithType.Value (Some src) | WithType.WithType(_,Some src) ->

+ 1 - 1
src/context/display/displayEmitter.ml

@@ -168,7 +168,7 @@ let check_display_metadata ctx meta =
 		if display_position#enclosed_in p then display_meta ctx.com meta p;
 		List.iter (fun e ->
 			if display_position#enclosed_in (pos e) then begin
-				let e = ExprPreprocessing.process_expr ctx.com e in
+				let e = preprocess_expr ctx.com e in
 				delay ctx PTypeField (fun _ -> ignore(type_expr ctx e WithType.value));
 			end
 		) args

+ 224 - 0
src/context/display/exprPreprocessing.ml

@@ -0,0 +1,224 @@
+open Globals
+open Ast
+open DisplayTypes.DisplayMode
+open DisplayPosition
+
+let find_before_pos dm e =
+	let display_pos = ref (DisplayPosition.display_position#get) in
+	let was_annotated = ref false in
+	let is_annotated,is_completion = match dm with
+		| DMDefault -> (fun p -> not !was_annotated && encloses_position !display_pos p),true
+		| DMHover -> (fun p -> not !was_annotated && encloses_position_gt !display_pos p),false
+		| _ -> (fun p -> not !was_annotated && encloses_position !display_pos p),false
+	in
+	let annotate e dk =
+		was_annotated := true;
+		(EDisplay(e,dk),pos e)
+	in
+	let annotate_marked e = annotate e DKMarked in
+	let mk_null p = annotate_marked ((EConst(Ident "null")),p) in
+	let loop_el el =
+		let pr = DisplayPosition.display_position#with_pos (pos e) in
+		let rec loop el = match el with
+			| [] -> [mk_null pr]
+			| e :: el ->
+				if (pos e).pmin >= pr.pmax then (mk_null pr) :: e :: el
+				else e :: loop el
+		in
+		(* print_endline (Printf.sprintf "%i-%i: PR" pr.pmin pr.pmax);
+		List.iter (fun e ->
+			print_endline (Printf.sprintf "%i-%i: %s" (pos e).pmin (pos e).pmax (Ast.s_expr e));
+		) el; *)
+		match el with
+		| [] -> [mk_null pr]
+		| e :: el ->
+			if (pos e).pmin >= pr.pmax then (mk_null pr) :: e :: el
+			else loop (e :: el)
+	in
+	let in_pattern = ref false in
+	let loop e =
+		(* print_endline (Printf.sprintf "%i-%i: %s" (pos e).pmin (pos e).pmax (Ast.s_expr e)); *)
+		match fst e with
+		| EFunction(FKNamed((_,p),_),_) when is_annotated p && is_completion ->
+			raise Exit
+		| EVars vl when is_annotated (pos e) && is_completion ->
+			let rec loop2 acc mark vl = match vl with
+				| v :: vl ->
+					if mark then
+						loop2 (v :: acc) mark vl
+					else if is_annotated (snd v.ev_name) then
+						(* If the name is the display position, mark the expression *)
+						loop2 (v :: acc) true vl
+					else begin match v.ev_expr with
+						| None ->
+							(* If there is no expression, we don't have to do anything.
+							   Should the display position be on the type-hint, it will
+							   be picked up while loading the type. *)
+							loop2 (v :: acc) mark vl
+						| Some e ->
+							(* Determine the area between the `|` in `var x| = | e`. This is not really
+							   correct because we don't want completion on the left side of the `=`, but
+							   we cannot determine that correctly without knowing its position.
+							   Note: We know `e` itself isn't the display position because this entire
+							   algorithm is bottom-up and it would be marked already if it was. *)
+							let p0 = match v.ev_type with
+								| Some (_,pt) -> pt
+								| None -> snd v.ev_name
+							in
+							let p = {p0 with pmax = (pos e).pmin} in
+							let e = if is_annotated p then annotate_marked e else e in
+							loop2 ({ v with ev_expr = Some e } :: acc) mark vl
+					end
+				| [] ->
+					List.rev acc,mark
+			in
+			let vl,mark = loop2 [] false vl in
+			let e = EVars (List.rev vl),pos e in
+			if !was_annotated then e else raise Exit
+		| EBinop((OpAssign | OpAssignOp _) as op,e1,e2) when is_annotated (pos e) && is_completion ->
+			(* Special case for assign ops: If the expression is marked, but none of its operands are,
+			   we are "probably" interested in the rhs. Like with EVars, this isn't accurate because we
+			   could be on the left side of the `=`. I don't think there's a reason for requesting
+			   completion there though. *)
+			(EBinop(op,e1,annotate_marked e2)),(pos e)
+		| EBinop(OpOr,e1,(EIf(_,(EConst(Ident "null"),_),None),p1)) when is_annotated (pos e) && is_completion && !in_pattern ->
+			(* This HAS TO come from an attempted `case pattern | guard:` completion (issue #7068). *)
+			let p = { p1 with pmin = (pos e1).pmax; pmax = p1.pmin } in
+			EBinop(OpOr,e1,mk_null p),(pos e)
+		| EIf(_,(EConst(Ident "null"),_),None) when is_completion && !in_pattern ->
+			(* This is fine. *)
+			mk_null (pos e)
+		| EBlock [] when is_annotated (pos e) ->
+			annotate e DKStructure
+		| EBlock [EDisplay((EConst(Ident s),pn),DKMarked),_] when is_completion ->
+			let e = EObjectDecl [(s,pn,NoQuotes),(EConst (Ident "null"),null_pos)],(pos e) in
+			annotate e DKStructure
+		| EBlock el when is_annotated (pos e) && is_completion ->
+			let el = loop_el el in
+			EBlock el,(pos e)
+		| ECall(e1,el) when is_annotated (pos e) && is_completion ->
+			let el = loop_el el in
+			ECall(e1,el),(pos e)
+		| ENew(ptp,el) when is_annotated (pos e) && is_completion ->
+			if is_annotated ptp.pos_full || ptp.pos_full.pmax >= (DisplayPosition.display_position#get).pmax then
+				annotate_marked e
+			else begin
+				let el = loop_el el in
+				ENew(ptp,el),(pos e)
+			end
+		| EArrayDecl el when is_annotated (pos e) && is_completion ->
+			let el = loop_el el in
+			EArrayDecl el,(pos e)
+		| EObjectDecl fl when is_annotated (pos e) && is_completion ->
+			annotate e DKStructure
+		| ESwitch(e1,cases,def) when is_annotated (pos e) ->
+			(* We must be "between" two cases, or at the end of the last case.
+			   Let's find the last case which has a position that is < the display
+			   position and mark it. *)
+			let did_mark = ref false in
+			let mark_case ec p =
+				did_mark := true;
+				let ep = mk_null p in
+				match ec with
+				| Some ec ->
+					let ec = match fst ec with
+						| EBlock el -> (EBlock (el @ [ep]),p)
+						| _ -> (EBlock [ec;ep],p)
+					in
+					Some ec
+				| None ->
+					Some (mk_null p)
+			in
+			let rec loop cases = match cases with
+				| [el,eg,ec,p1] ->
+					let ec = match def with
+					| None when (pos e).pmax > !display_pos.pmin -> (* this is so we don't trigger if we're on the } *)
+						mark_case ec p1 (* no default, must be the last case *)
+					| Some (_,p2) when p1.pmax <= !display_pos.pmin && p2.pmin >= !display_pos.pmax ->
+						mark_case ec p1 (* default is beyond display position, mark *)
+					| _ ->
+						ec (* default contains display position, don't mark *)
+					in
+					[el,eg,ec,p1]
+				| (el1,eg1,ec1,p1) :: (el2,eg2,ec2,p2) :: cases ->
+					if p1.pmax <= !display_pos.pmin && p2.pmin >= !display_pos.pmax then
+						(el1,eg1,mark_case ec1 p1,p1) :: (el2,eg2,ec2,p2) :: cases
+					else
+						(el1,eg1,ec1,p1) :: loop ((el2,eg2,ec2,p2) :: cases)
+				| [] ->
+					[]
+			in
+			let cases = loop cases in
+			let def = if !did_mark then
+				def
+			else match def with
+				| Some(eo,p) when (pos e).pmax > !display_pos.pmin -> Some (mark_case eo p,p)
+				| _ -> def
+			in
+			ESwitch(e1,cases,def),pos e
+		| EDisplay _ ->
+			raise Exit
+		| EMeta((Meta.Markup,_,_),(EConst(String _),p)) when is_annotated p ->
+			annotate_marked e
+		| EConst (String (_,q)) when ((q <> SSingleQuotes) || !Parser.was_auto_triggered) && is_annotated (pos e) && is_completion ->
+			(* TODO: check if this makes any sense *)
+			raise Exit
+		| EConst(Regexp _) when is_annotated (pos e) && is_completion ->
+			raise Exit
+		| EVars vl when is_annotated (pos e) ->
+			(* We only want to mark EVars if we're on a var name. *)
+			if List.exists (fun v -> is_annotated (snd v.ev_name)) vl then
+				annotate_marked e
+			else
+				raise Exit
+		| _ ->
+			if is_annotated (pos e) then
+				annotate_marked e
+			else
+				e
+	in
+	let opt f o =
+		match o with None -> None | Some v -> Some (f v)
+	in
+	let rec map e = match fst e with
+		| ESwitch(e1,cases,def) when is_annotated (pos e) ->
+			let e1 = map e1 in
+			let cases = List.map (fun (el,eg,e,p) ->
+				let old = !in_pattern in
+				in_pattern := true;
+				let el = List.map map el in
+				in_pattern := old;
+				let eg = opt map eg in
+				let e = opt map e in
+				el,eg,e,p
+			) cases in
+			let def = opt (fun (eo,p) -> opt map eo,p) def in
+			loop (ESwitch (e1, cases, def),(pos e))
+		| _ ->
+			loop (Ast.map_expr map e)
+	in
+	try map e with Exit -> e
+
+let find_display_call e =
+	let found = ref false in
+	let handle_el e el =
+		let call_arg_is_marked () =
+			el = [] || List.exists (fun (e,_) -> match e with EDisplay(_,DKMarked) -> true | _ -> false) el
+		in
+		if not !Parser.was_auto_triggered || call_arg_is_marked () then begin
+		found := true;
+		Parser.mk_display_expr e DKCall
+		end else
+			e
+	in
+	let loop e = match fst e with
+		| ECall(_,el) | ENew(_,el) when not !found && display_position#enclosed_in (pos e) ->
+			handle_el e el
+		| EArray(e1,e2) when not !found && display_position#enclosed_in (pos e2) ->
+			handle_el e [e2]
+		| EDisplay(_,DKCall) ->
+			raise Exit
+		| _ -> e
+	in
+	let rec map e = loop (Ast.map_expr map e) in
+	try map e with Exit -> e

+ 98 - 0
src/context/formatString.ml

@@ -0,0 +1,98 @@
+open Globals
+open Ast
+
+let format_string defines s p process_expr =
+	let e = ref None in
+	let pmin = ref p.pmin in
+	let min = ref (p.pmin + 1) in
+	let add_expr (enext,p) len =
+		min := !min + len;
+		let enext = process_expr enext p in
+		match !e with
+		| None -> e := Some enext
+		| Some prev ->
+			e := Some (EBinop (OpAdd,prev,enext),punion (pos prev) p)
+	in
+	let add enext len =
+		let p = { p with pmin = !min; pmax = !min + len } in
+		add_expr (enext,p) len
+	in
+	let add_sub start pos =
+		let len = pos - start in
+		if len > 0 || !e = None then add (EConst (String (String.sub s start len,SDoubleQuotes))) len
+	in
+	let len = String.length s in
+	let rec parse start pos =
+		if pos = len then add_sub start pos else
+		let c = String.unsafe_get s pos in
+		let pos = pos + 1 in
+		if c = '\'' then begin
+			incr pmin;
+			incr min;
+		end;
+		if c <> '$' || pos = len then parse start pos else
+		match String.unsafe_get s pos with
+		| '$' ->
+			(* double $ *)
+			add_sub start pos;
+			parse (pos + 1) (pos + 1)
+		| '{' ->
+			parse_group start pos '{' '}' "brace"
+		| 'a'..'z' | 'A'..'Z' | '_' ->
+			add_sub start (pos - 1);
+			incr min;
+			let rec loop i =
+				if i = len then i else
+				let c = String.unsafe_get s i in
+				match c with
+				| 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' -> loop (i+1)
+				| _ -> i
+			in
+			let iend = loop (pos + 1) in
+			let len = iend - pos in
+			add (EConst (Ident (String.sub s pos len))) len;
+			parse (pos + len) (pos + len)
+		| _ ->
+			(* keep as-it *)
+			parse start pos
+	and parse_group start pos gopen gclose gname =
+		add_sub start (pos - 1);
+		let rec loop groups i =
+			if i = len then
+				match groups with
+				| [] -> die "" __LOC__
+				| g :: _ -> Error.raise_typing_error ("Unclosed " ^ gname) { p with pmin = !pmin + g + 1; pmax = !pmin + g + 2 }
+			else
+				let c = String.unsafe_get s i in
+				if c = gopen then
+					loop (i :: groups) (i + 1)
+				else if c = gclose then begin
+					let groups = List.tl groups in
+					if groups = [] then i else loop groups (i + 1)
+				end else
+					loop groups (i + 1)
+		in
+		let send = loop [pos] (pos + 1) in
+		let slen = send - pos - 1 in
+		let scode = String.sub s (pos + 1) slen in
+		min := !min + 2;
+		begin
+			let e =
+				let ep = { p with pmin = !pmin + pos + 2; pmax = !pmin + send + 1 } in
+				let error msg pos =
+					if Lexer.string_is_whitespace scode then Error.raise_typing_error "Expression cannot be empty" ep
+					else Error.raise_typing_error msg pos
+				in
+				match ParserEntry.parse_expr_string defines scode ep error true with
+					| ParseSuccess(data,_,_) -> data
+					| ParseError(_,(msg,p),_) -> error (Parser.error_msg msg) p
+			in
+			add_expr e slen
+		end;
+		min := !min + 1;
+		parse (send + 1) (send + 1)
+	in
+	parse 0 0;
+	match !e with
+	| None -> die "" __LOC__
+	| Some e -> e

+ 2 - 2
src/context/memory.ml

@@ -122,8 +122,8 @@ let get_memory_json (cs : CompilationCache.t) mreq =
 				"nativeLibCache",jint (mem_size cache_mem.(3));
 				"additionalSizes",jarray [
 					jobject ["name",jstring "macro interpreter";"size",jint (mem_size (MacroContext.macro_interp_cache))];
-					jobject ["name",jstring "macro stdlib";"size",jint (mem_size (EvalContext.GlobalState.stdlib))];
-					jobject ["name",jstring "macro macro_lib";"size",jint (mem_size (EvalContext.GlobalState.macro_lib))];
+					(* jobject ["name",jstring "macro stdlib";"size",jint (mem_size (EvalContext.GlobalState.stdlib))];
+					jobject ["name",jstring "macro macro_lib";"size",jint (mem_size (EvalContext.GlobalState.macro_lib))]; *)
 					jobject ["name",jstring "last completion result";"size",jint (mem_size (DisplayException.last_completion_result))];
 					jobject ["name",jstring "Lexer file cache";"size",jint (mem_size (Lexer.all_files))];
 					jobject ["name",jstring "GC heap words";"size",jint (int_of_float size)];

+ 3 - 39
src/context/typecore.ml

@@ -23,6 +23,7 @@ open Common
 open Type
 open Error
 open Resolution
+open FieldCallCandidate
 
 type type_patch = {
 	mutable tp_type : complex_type option;
@@ -98,7 +99,8 @@ type typer_globals = {
 	retain_meta : bool;
 	mutable core_api : typer option;
 	mutable macros : ((unit -> unit) * typer) option;
-	mutable std : module_def;
+	mutable std : tclass;
+	mutable std_types : module_def;
 	type_patches : (path, (string * bool, type_patch) Hashtbl.t * type_patch) Hashtbl.t;
 	mutable module_check_policies : (string list * module_check_policy list * bool) list;
 	mutable global_using : (tclass * pos) list;
@@ -162,24 +164,6 @@ and monomorphs = {
 	mutable perfunction : (tmono * pos) list;
 }
 
-(* This record holds transient information about an (attempted) call on a field. It is created when resolving
-   field calls and is passed to overload filters. *)
-type 'a field_call_candidate = {
-	(* The argument expressions for this call and whether or not the argument is optional on the
-	   target function. *)
-	fc_args  : texpr list;
-	(* The applied return type. *)
-	fc_ret   : Type.t;
-	(* The applied function type. *)
-	fc_type  : Type.t;
-	(* The class field being called. *)
-	fc_field : tclass_field;
-	(* The field monomorphs that were created for this call. *)
-	fc_monos : Type.t list;
-	(* The custom data associated with this call. *)
-	fc_data  : 'a;
-}
-
 type field_host =
 	| FHStatic of tclass
 	| FHInstance of tclass * tparams
@@ -698,26 +682,6 @@ let safe_mono_close ctx m p =
 		Unify_error l ->
 			raise_or_display ctx l p
 
-let make_field_call_candidate args ret monos t cf data = {
-	fc_args  = args;
-	fc_type  = t;
-	fc_field = cf;
-	fc_data  = data;
-	fc_ret   = ret;
-	fc_monos = monos;
-}
-
-let s_field_call_candidate fcc =
-	let pctx = print_context() in
-	let se = s_expr_pretty false "" false (s_type pctx) in
-	let sl_args = List.map se fcc.fc_args in
-	Printer.s_record_fields "" [
-		"fc_args",String.concat ", " sl_args;
-		"fc_type",s_type pctx fcc.fc_type;
-		"fc_field",Printf.sprintf "%s: %s" fcc.fc_field.cf_name (s_type pctx fcc.fc_field.cf_type)
-	]
-
-
 let relative_path ctx file =
 	let slashes path = String.concat "/" (ExtString.String.nsplit path "\\") in
 	let fpath = slashes (Path.get_full_path file) in

+ 88 - 0
src/core/naming.ml

@@ -0,0 +1,88 @@
+open Globals
+open Ast
+open Meta
+open Type
+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 ->
+		()		

+ 12 - 1
src/core/socket.ml

@@ -37,6 +37,17 @@ let read_string socket =
 			let _ = recv socket buf 0 i [] in
 			Bytes.to_string buf
 
+let write_byte this i v =
+	Bytes.set this i (Char.unsafe_chr v)	
+
+let write_i32 this i v =
+	let base = Int32.to_int v in
+	let big = Int32.to_int (Int32.shift_right_logical v 24) in
+	write_byte this i base;
+	write_byte this (i + 1) (base lsr 8);
+	write_byte this (i + 2) (base lsr 16);
+	write_byte this (i + 3) big
+
 let send_string socket s =
 	match socket.socket with
 	| None ->
@@ -45,7 +56,7 @@ let send_string socket s =
 		let b = Bytes.unsafe_of_string s in
 		let l = Bytes.length b in
 		let buf = Bytes.make 4 ' ' in
-		EvalBytes.write_i32 buf 0 (Int32.of_int l);
+		write_i32 buf 0 (Int32.of_int l);
 		ignore(send socket buf 0 4 []);
 		let rec loop length offset =
 			if length <= 0 then

+ 68 - 0
src/filters/addFieldInits.ml

@@ -0,0 +1,68 @@
+open Globals
+open Common
+open Type
+
+
+let add_field_inits cl_path locals com t =
+	let apply c =
+		let ethis = mk (TConst TThis) (TInst (c,extract_param_types c.cl_params)) c.cl_pos in
+		(* TODO: we have to find a variable name which is not used in any of the functions *)
+		let v = alloc_var VGenerated "_g" ethis.etype ethis.epos in
+		let need_this = ref false in
+		let inits,fields = List.fold_left (fun (inits,fields) cf ->
+			match cf.cf_kind,cf.cf_expr with
+			| Var _, Some _ -> (cf :: inits, cf :: fields)
+			| _ -> (inits, cf :: fields)
+		) ([],[]) c.cl_ordered_fields in
+		c.cl_ordered_fields <- (List.rev fields);
+		match inits with
+		| [] -> ()
+		| _ ->
+			let el = List.map (fun cf ->
+				match cf.cf_expr with
+				| None -> die "" __LOC__
+				| Some e ->
+					let lhs = mk (TField({ ethis with epos = cf.cf_pos },FInstance (c,extract_param_types c.cl_params,cf))) cf.cf_type cf.cf_pos in
+					cf.cf_expr <- None;
+					mk (TBinop(OpAssign,lhs,e)) cf.cf_type e.epos
+			) inits in
+			let el = if !need_this then (mk (TVar((v, Some ethis))) ethis.etype ethis.epos) :: el else el in
+			let cf = match c.cl_constructor with
+			| None ->
+				let ct = TFun([],com.basic.tvoid) in
+				let ce = mk (TFunction {
+					tf_args = [];
+					tf_type = com.basic.tvoid;
+					tf_expr = mk (TBlock el) com.basic.tvoid c.cl_pos;
+				}) ct c.cl_pos in
+				let ctor = mk_field "new" ct c.cl_pos null_pos in
+				ctor.cf_kind <- Method MethNormal;
+				{ ctor with cf_expr = Some ce }
+			| Some cf ->
+				match cf.cf_expr with
+				| Some { eexpr = TFunction f } ->
+					let bl = match f.tf_expr with {eexpr = TBlock b } -> b | x -> [x] in
+					let ce = mk (TFunction {f with tf_expr = mk (TBlock (el @ bl)) com.basic.tvoid c.cl_pos }) cf.cf_type cf.cf_pos in
+					{cf with cf_expr = Some ce };
+				| _ ->
+					die "" __LOC__
+			in
+			let config = AnalyzerConfig.get_field_config com c cf in
+			remove_class_field_flag cf CfPostProcessed;
+			Analyzer.Run.run_on_field com config c cf;
+			add_class_field_flag cf CfPostProcessed;
+			(match cf.cf_expr with
+			| Some e ->
+				(* This seems a bit expensive, but hopefully constructor expressions aren't that massive. *)
+				let e = RenameVars.run cl_path locals e in
+				let e = Optimizer.sanitize com e in
+				cf.cf_expr <- Some e
+			| _ ->
+				());
+			c.cl_constructor <- Some cf
+	in
+	match t with
+	| TClassDecl c ->
+		apply c
+	| _ ->
+		()

+ 22 - 0
src/filters/exceptionFunctions.ml

@@ -0,0 +1,22 @@
+open Type
+
+let haxe_exception_type_path = (["haxe"],"Exception")
+let value_exception_type_path = (["haxe"],"ValueException")
+
+(**
+	Check if `cls` is or extends (if `check_parent=true`) `haxe.Exception`
+*)
+	let rec is_haxe_exception_class ?(check_parent=true) cls =
+		cls.cl_path = haxe_exception_type_path
+		|| (check_parent && match cls.cl_super with
+			| None -> false
+			| Some (cls, _) -> is_haxe_exception_class ~check_parent cls
+		)
+	
+	(**
+		Check if `t` is or extends `haxe.Exception`
+	*)
+	let is_haxe_exception ?(check_parent=true) (t:Type.t) =
+		match Abstract.follow_with_abstracts t with
+			| TInst (cls, _) -> is_haxe_exception_class ~check_parent cls
+			| _ -> false

+ 2 - 25
src/filters/exceptions.ml

@@ -4,9 +4,7 @@ open Type
 open Common
 open Typecore
 open Error
-
-let haxe_exception_type_path = (["haxe"],"Exception")
-let value_exception_type_path = (["haxe"],"ValueException")
+open ExceptionFunctions
 
 type context = {
 	typer : typer;
@@ -65,11 +63,7 @@ let haxe_exception_instance_call ctx haxe_exception method_name args p =
 *)
 let std_is ctx e t p =
 	let t = follow t in
-	let std_cls =
-		match Typeload.load_type_raise ctx.typer ([],"Std") "Std" p with
-		| TClassDecl cls -> cls
-		| _ -> raise_typing_error "Std is expected to be a class" p
-	in
+	let std_cls = ctx.typer.g.std in
 	let isOfType_field =
 		try PMap.find "isOfType" std_cls.cl_statics
 		with Not_found -> raise_typing_error ("Std has no field isOfType") p
@@ -122,23 +116,6 @@ let is_haxe_wildcard_catch ctx t =
 	let t = Abstract.follow_with_abstracts t in
 	t == t_dynamic || fast_eq ctx.haxe_exception_type t
 
-(**
-	Check if `cls` is or extends (if `check_parent=true`) `haxe.Exception`
-*)
-let rec is_haxe_exception_class ?(check_parent=true) cls =
-	cls.cl_path = haxe_exception_type_path
-	|| (check_parent && match cls.cl_super with
-		| None -> false
-		| Some (cls, _) -> is_haxe_exception_class ~check_parent cls
-	)
-
-(**
-	Check if `t` is or extends `haxe.Exception`
-*)
-let is_haxe_exception ?(check_parent=true) (t:Type.t) =
-	match Abstract.follow_with_abstracts t with
-		| TInst (cls, _) -> is_haxe_exception_class ~check_parent cls
-		| _ -> false
 
 (**
 	Check if `v` variable is used in `e` expression

+ 4 - 208
src/filters/filters.ml

@@ -25,7 +25,7 @@ open Error
 open Globals
 open FiltersCommon
 
-let get_native_name = TypeloadCheck.get_native_name
+let get_native_name = Naming.get_native_name
 
 (* PASS 1 begin *)
 
@@ -66,66 +66,6 @@ let rec add_final_return e =
 			{ e with eexpr = TFunction f }
 		| _ -> e
 
-module LocalStatic = struct
-	let promote_local_static ctx lut v eo =
-		let name = Printf.sprintf "%s_%s" ctx.curfield.cf_name v.v_name in
-		begin try
-			let cf = PMap.find name ctx.curclass.cl_statics in
-			display_error ctx.com (Printf.sprintf "The expanded name of this local (%s) conflicts with another static field" name) v.v_pos;
-			raise_typing_error ~depth:1 "Conflicting field was found here" cf.cf_name_pos;
-		with Not_found ->
-			let cf = mk_field name ~static:true v.v_type v.v_pos v.v_pos in
-			cf.cf_meta <- v.v_meta;
-			begin match eo with
-			| None ->
-				()
-			| Some e ->
-				let rec loop e = match e.eexpr with
-					| TLocal _ | TFunction _ ->
-						raise_typing_error "Accessing local variables in static initialization is not allowed" e.epos
-					| TConst (TThis | TSuper) ->
-						raise_typing_error "Accessing `this` in static initialization is not allowed" e.epos
-					| TReturn _ | TBreak | TContinue ->
-						raise_typing_error "This kind of control flow in static initialization is not allowed" e.epos
-					| _ ->
-						iter loop e
-				in
-				loop e;
-				cf.cf_expr <- Some e
-			end;
-			TClass.add_field ctx.curclass cf;
-			Hashtbl.add lut v.v_id cf
-		end
-
-	let find_local_static lut v =
-		Hashtbl.find lut v.v_id
-
-	let run ctx e =
-		let local_static_lut = Hashtbl.create 0 in
-		let c = ctx.curclass in
-		let rec run e = match e.eexpr with
-			| TBlock el ->
-				let el = ExtList.List.filter_map (fun e -> match e.eexpr with
-					| TVar(v,eo) when has_var_flag v VStatic ->
-						promote_local_static ctx local_static_lut v eo;
-						None
-					| _ ->
-						Some (run e)
-				) el in
-				{ e with eexpr = TBlock el }
-			| TLocal v when has_var_flag v VStatic ->
-				begin try
-					let cf = find_local_static local_static_lut v in
-					Texpr.Builder.make_static_field c cf e.epos
-				with Not_found ->
-					raise_typing_error (Printf.sprintf "Could not find local static %s (id %i)" v.v_name v.v_id) e.epos
-				end
-			| _ ->
-				Type.map_expr run e
-		in
-		run e
-end
-
 (* -------------------------------------------------------------------------- *)
 (* CHECK LOCAL VARS INIT *)
 
@@ -356,12 +296,6 @@ let check_abstract_as_value e =
 
 (* PASS 2 begin *)
 
-let remove_generic_base t = match t with
-	| TClassDecl c when is_removable_class c ->
-		add_class_flag c CExtern;
-	| _ ->
-		()
-
 (* Removes extern and macro fields, also checks for Void fields *)
 
 let remove_extern_fields com t = match t with
@@ -393,71 +327,6 @@ let check_private_path com t = match t with
 	| _ ->
 		()
 
-(* 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 ->
-		()
-
 (* Adds the __rtti field if required *)
 let add_rtti com t =
 	let rec has_rtti c =
@@ -473,71 +342,6 @@ let add_rtti com t =
 	| _ ->
 		()
 
-(* Adds member field initializations as assignments to the constructor *)
-let add_field_inits cl_path locals com t =
-	let apply c =
-		let ethis = mk (TConst TThis) (TInst (c,extract_param_types c.cl_params)) c.cl_pos in
-		(* TODO: we have to find a variable name which is not used in any of the functions *)
-		let v = alloc_var VGenerated "_g" ethis.etype ethis.epos in
-		let need_this = ref false in
-		let inits,fields = List.fold_left (fun (inits,fields) cf ->
-			match cf.cf_kind,cf.cf_expr with
-			| Var _, Some _ -> (cf :: inits, cf :: fields)
-			| _ -> (inits, cf :: fields)
-		) ([],[]) c.cl_ordered_fields in
-		c.cl_ordered_fields <- (List.rev fields);
-		match inits with
-		| [] -> ()
-		| _ ->
-			let el = List.map (fun cf ->
-				match cf.cf_expr with
-				| None -> die "" __LOC__
-				| Some e ->
-					let lhs = mk (TField({ ethis with epos = cf.cf_pos },FInstance (c,extract_param_types c.cl_params,cf))) cf.cf_type cf.cf_pos in
-					cf.cf_expr <- None;
-					mk (TBinop(OpAssign,lhs,e)) cf.cf_type e.epos
-			) inits in
-			let el = if !need_this then (mk (TVar((v, Some ethis))) ethis.etype ethis.epos) :: el else el in
-			let cf = match c.cl_constructor with
-			| None ->
-				let ct = TFun([],com.basic.tvoid) in
-				let ce = mk (TFunction {
-					tf_args = [];
-					tf_type = com.basic.tvoid;
-					tf_expr = mk (TBlock el) com.basic.tvoid c.cl_pos;
-				}) ct c.cl_pos in
-				let ctor = mk_field "new" ct c.cl_pos null_pos in
-				ctor.cf_kind <- Method MethNormal;
-				{ ctor with cf_expr = Some ce }
-			| Some cf ->
-				match cf.cf_expr with
-				| Some { eexpr = TFunction f } ->
-					let bl = match f.tf_expr with {eexpr = TBlock b } -> b | x -> [x] in
-					let ce = mk (TFunction {f with tf_expr = mk (TBlock (el @ bl)) com.basic.tvoid c.cl_pos }) cf.cf_type cf.cf_pos in
-					{cf with cf_expr = Some ce };
-				| _ ->
-					die "" __LOC__
-			in
-			let config = AnalyzerConfig.get_field_config com c cf in
-			remove_class_field_flag cf CfPostProcessed;
-			Analyzer.Run.run_on_field com config c cf;
-			add_class_field_flag cf CfPostProcessed;
-			(match cf.cf_expr with
-			| Some e ->
-				(* This seems a bit expensive, but hopefully constructor expressions aren't that massive. *)
-				let e = RenameVars.run cl_path locals e in
-				let e = Optimizer.sanitize com e in
-				cf.cf_expr <- Some e
-			| _ ->
-				());
-			c.cl_constructor <- Some cf
-	in
-	match t with
-	| TClassDecl c ->
-		apply c
-	| _ ->
-		()
-
 (* Adds the __meta__ field if required *)
 let add_meta_field com t = match t with
 	| TClassDecl c ->
@@ -667,14 +471,6 @@ let check_reserved_type_paths com t =
 
 (* PASS 3 end *)
 
-let is_cached com t =
-	let m = (t_infos t).mt_module.m_extra in
-	m.m_processed <> 0 && m.m_processed < com.compilation_step
-
-let apply_filters_once ctx filters t =
-	let detail_times = (try int_of_string (Common.defined_value_safe ctx.com ~default:"0" Define.FilterTimes) with _ -> 0) in
-	if not (is_cached ctx.com t) then run_expression_filters ctx detail_times filters t
-
 let iter_expressions fl mt =
 	match mt with
 	| TClassDecl c ->
@@ -715,7 +511,7 @@ let destruction tctx detail_times main locals =
 	with_timer detail_times "type 2" None (fun () ->
 		(* PASS 2: type filters pre-DCE *)
 		List.iter (fun t ->
-			remove_generic_base t;
+			FiltersCommon.remove_generic_base t;
 			remove_extern_fields com t;
 			(* check @:remove metadata before DCE so it is ignored there (issue #2923) *)
 			check_remove_metadata t;
@@ -747,9 +543,9 @@ let destruction tctx detail_times main locals =
 	let type_filters = [
 		Exceptions.patch_constructors tctx; (* TODO: I don't believe this should load_instance anything at this point... *)
 		check_private_path com;
-		apply_native_paths;
+		Naming.apply_native_paths;
 		add_rtti com;
-		(match com.platform with | Java | Cs -> (fun _ -> ()) | _ -> (fun mt -> add_field_inits tctx.curclass.cl_path locals com mt));
+		(match com.platform with | Java | Cs -> (fun _ -> ()) | _ -> (fun mt -> AddFieldInits.add_field_inits tctx.curclass.cl_path locals com mt));
 		(match com.platform with Hl -> (fun _ -> ()) | _ -> add_meta_field com);
 		check_void_field;
 		(match com.platform with | Cpp -> promote_first_interface_to_super | _ -> (fun _ -> ()));

+ 15 - 0
src/filters/filtersCommon.ml

@@ -18,6 +18,7 @@
 *)
 open Globals
 open Type
+open Common
 open Typecore
 
 let rec is_removable_class c =
@@ -36,6 +37,12 @@ let rec is_removable_class c =
 	| _ ->
 		false
 
+let remove_generic_base t = match t with
+	| TClassDecl c when is_removable_class c ->
+		add_class_flag c CExtern;
+	| _ ->
+		()
+
 (**
 	Check if `field` is overridden in subclasses
 *)
@@ -82,3 +89,11 @@ let run_expression_filters ?(ignore_processed_status=false) ctx detail_times fil
 	| TEnumDecl _ -> ()
 	| TTypeDecl _ -> ()
 	| TAbstractDecl _ -> ()
+
+let is_cached com t =
+	let m = (t_infos t).mt_module.m_extra in
+	m.m_processed <> 0 && m.m_processed < com.compilation_step
+
+let apply_filters_once ctx filters t =
+	let detail_times = (try int_of_string (Common.defined_value_safe ctx.com ~default:"0" Define.FilterTimes) with _ -> 0) in
+	if not (is_cached ctx.com t) then run_expression_filters ctx detail_times filters t

+ 63 - 0
src/filters/localStatic.ml

@@ -0,0 +1,63 @@
+open Global
+open Common
+open Type
+open Typecore
+open Error
+
+let promote_local_static ctx lut v eo =
+	let name = Printf.sprintf "%s_%s" ctx.curfield.cf_name v.v_name in
+	begin try
+		let cf = PMap.find name ctx.curclass.cl_statics in
+		display_error ctx.com (Printf.sprintf "The expanded name of this local (%s) conflicts with another static field" name) v.v_pos;
+		raise_typing_error ~depth:1 "Conflicting field was found here" cf.cf_name_pos;
+	with Not_found ->
+		let cf = mk_field name ~static:true v.v_type v.v_pos v.v_pos in
+		cf.cf_meta <- v.v_meta;
+		begin match eo with
+		| None ->
+			()
+		| Some e ->
+			let rec loop e = match e.eexpr with
+				| TLocal _ | TFunction _ ->
+					raise_typing_error "Accessing local variables in static initialization is not allowed" e.epos
+				| TConst (TThis | TSuper) ->
+					raise_typing_error "Accessing `this` in static initialization is not allowed" e.epos
+				| TReturn _ | TBreak | TContinue ->
+					raise_typing_error "This kind of control flow in static initialization is not allowed" e.epos
+				| _ ->
+					iter loop e
+			in
+			loop e;
+			cf.cf_expr <- Some e
+		end;
+		TClass.add_field ctx.curclass cf;
+		Hashtbl.add lut v.v_id cf
+	end
+
+let find_local_static lut v =
+	Hashtbl.find lut v.v_id
+
+let run ctx e =
+	let local_static_lut = Hashtbl.create 0 in
+	let c = ctx.curclass in
+	let rec run e = match e.eexpr with
+		| TBlock el ->
+			let el = ExtList.List.filter_map (fun e -> match e.eexpr with
+				| TVar(v,eo) when has_var_flag v VStatic ->
+					promote_local_static ctx local_static_lut v eo;
+					None
+				| _ ->
+					Some (run e)
+			) el in
+			{ e with eexpr = TBlock el }
+		| TLocal v when has_var_flag v VStatic ->
+			begin try
+				let cf = find_local_static local_static_lut v in
+				Texpr.Builder.make_static_field c cf e.epos
+			with Not_found ->
+				raise_typing_error (Printf.sprintf "Could not find local static %s (id %i)" v.v_name v.v_id) e.epos
+			end
+		| _ ->
+			Type.map_expr run e
+	in
+	run e

+ 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 (TypeloadCheck.get_native_name tinfos.mt_meta) with Not_found -> path_to_name tinfos.mt_path in
+		let native_name = try fst (Naming.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 (TypeloadCheck.get_native_name cf.cf_meta) with Not_found -> cf.cf_name in
+				let native_name = try fst (Naming.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 (TypeloadCheck.get_native_name cf.cf_meta) with Not_found -> prefix ^ cf.cf_name in
+				let name = try fst (Naming.get_native_name cf.cf_meta) with Not_found -> prefix ^ cf.cf_name in
 				reserve_init ri name
 			) fl
 		| _ ->

+ 2 - 2
src/generators/genjs.ml

@@ -154,13 +154,13 @@ let static_field ctx c f =
 
 let module_field m f =
 	try
-		fst (TypeloadCheck.get_native_name f.cf_meta)
+		fst (Naming.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 (TypeloadCheck.get_native_name f.cf_meta)
+		fst (Naming.get_native_name f.cf_meta)
 	with Not_found ->
 		(dot_path mpath) ^ "." ^ f.cf_name
 

+ 2 - 2
src/generators/genjvm.ml

@@ -395,7 +395,7 @@ let is_interface_var_access c cf =
 let follow = Abstract.follow_with_abstracts
 
 class haxe_exception gctx (t : Type.t) =
-	let is_haxe_exception = Exceptions.is_haxe_exception t
+	let is_haxe_exception = ExceptionFunctions.is_haxe_exception t
 	and native_type = jsignature_of_type gctx t in
 object(self)
 	val native_path = (match native_type with TObject(path,_) -> path | _ -> die "" __LOC__)
@@ -2134,7 +2134,7 @@ class texpr_to_jvm
 			self#texpr rvalue_any e1;
 			(* There could be something like `throw throw`, so we should only throw if we aren't terminated (issue #10363) *)
 			if not (jm#is_terminated) then begin
-				if not (Exceptions.is_haxe_exception e1.etype) && not (does_unify e1.etype gctx.t_runtime_exception) then begin
+				if not (ExceptionFunctions.is_haxe_exception e1.etype) && not (does_unify e1.etype gctx.t_runtime_exception) then begin
 					let exc = new haxe_exception gctx e1.etype in
 					if not (List.exists (fun exc' -> exc#is_assignable_to exc') caught_exceptions) then
 						jm#add_thrown_exception exc#get_native_path;

+ 2 - 2
src/generators/genswf9.ml

@@ -1066,7 +1066,7 @@ let rec gen_expr_content ctx retval e =
 		gen_constant ctx c e.etype e.epos
 	| TThrow e ->
 		ctx.infos.icond <- true;
-		if has_feature ctx.com "haxe.CallStack.exceptionStack" && not (Exceptions.is_haxe_exception e.etype) then begin
+		if has_feature ctx.com "haxe.CallStack.exceptionStack" && not (ExceptionFunctions.is_haxe_exception e.etype) then begin
 			getvar ctx (VGlobal (type_path ctx (["flash"],"Boot")));
 			let id = type_path ctx (["flash";"errors"],"Error") in
 			write ctx (HFindPropStrict id);
@@ -1240,7 +1240,7 @@ let rec gen_expr_content ctx retval e =
 					| _ -> Type.iter call_loop e
 				in
 				let has_call = (try call_loop e; false with Exit -> true) in
-				if has_call && has_feature ctx.com "haxe.CallStack.exceptionStack" && not (Exceptions.is_haxe_exception v.v_type) then begin
+				if has_call && has_feature ctx.com "haxe.CallStack.exceptionStack" && not (ExceptionFunctions.is_haxe_exception v.v_type) then begin
 					getvar ctx (gen_local_access ctx v e.epos Read);
 					write ctx (HAsType (type_path ctx (["flash";"errors"],"Error")));
 					let j = jump ctx J3False in

+ 5 - 0
src/macro/eval/eval.ml

@@ -0,0 +1,5 @@
+include EvalEncode
+include EvalDecode
+include EvalValue
+include EvalContext
+include EvalMain

+ 0 - 5
src/macro/eval/evalContext.ml

@@ -302,11 +302,6 @@ module GlobalState = struct
 
 	let stdlib : builtins option ref = ref None
 	let macro_lib : (string,value) Hashtbl.t = Hashtbl.create 0
-
-	let cleanup ctx =
-		(* curapi holds a reference to the typing context which we don't want to persist. Let's unset it so the
-		   context can be collected. *)
-		ctx.curapi <- Obj.magic ""
 end
 
 let get_ctx () = (!GlobalState.get_ctx_ref)()

+ 1 - 1
src/macro/eval/evalDebugSocket.ml

@@ -486,7 +486,7 @@ module ValueCompletion = struct
 		DisplayPosition.display_position#set {p with pmin = offset; pmax = offset};
 		begin try
 			let e = parse_expr ctx text p in
-			let e = Display.ExprPreprocessing.find_before_pos DMDefault e in
+			let e = ExprPreprocessing.find_before_pos DMDefault e in
 			save();
 			let rec loop e = match fst e with
 			| EDisplay(e1,DKDot) ->

+ 0 - 1
src/macro/eval/evalExceptions.ml

@@ -27,7 +27,6 @@ open EvalField
 exception Break
 exception Continue
 exception Return of value
-exception Sys_exit of int
 
 let s_value_kind = function
 	| VNull -> "VNull"

+ 2 - 1
src/macro/eval/evalMain.ml

@@ -145,7 +145,8 @@ let create com api is_macro =
 		Which is printing an error to stderr and exiting with code 2 *)
 	Luv.Error.set_on_unhandled_exception (fun ex ->
 		match ex with
-		| Sys_exit _ -> raise ex
+		| EvalTypes.Sys_exit _ ->
+			raise ex
 		| _ ->
 			let msg = match ex with
 				| Error.Error err ->

+ 1 - 1
src/macro/eval/evalStdLib.ml

@@ -2590,7 +2590,7 @@ module StdSys = struct
 	)
 
 	let exit = vfun1 (fun code ->
-		raise (Sys_exit(decode_int code));
+		raise (EvalTypes.Sys_exit(decode_int code));
 	)
 
 	let getChar = vfun1 (fun echo ->

+ 1 - 1
src/macro/eval/evalThread.ml

@@ -100,7 +100,7 @@ let run ctx f thread =
 		let msg = get_exc_error_message ctx v stack p in
 		prerr_endline msg;
 		close();
-	| Sys_exit i ->
+	| EvalTypes.Sys_exit i ->
 		close();
 		exit i;
 	| exc ->

+ 1 - 0
src/macro/eval/evalTypes.ml

@@ -0,0 +1 @@
+exception Sys_exit of int

+ 3 - 1
src/optimization/inline.ml

@@ -6,6 +6,8 @@ open Common
 open Typecore
 open Error
 
+let maybe_reapply_overload_call_ref = ref (fun _ _ -> assert false)
+
 let mk_untyped_call name p params =
 	{
 		eexpr = TCall({ eexpr = TIdent name; etype = t_dynamic; epos = p }, params);
@@ -627,7 +629,7 @@ class inline_state ctx ethis params cf f p = object(self)
 				else map_type
 			in
 			let e = Type.map_expr_type (map_expr_type map_type) map_type (map_var map_type) e in
-			CallUnification.maybe_reapply_overload_call ctx e
+			(!maybe_reapply_overload_call_ref) ctx e
 		in
 		let e = map_expr_type map_type e in
 		let rec drop_unused_vars e =

+ 1 - 0
src/typing/callUnification.ml

@@ -5,6 +5,7 @@ open Common
 open Typecore
 open Error
 open FieldAccess
+open FieldCallCandidate
 
 let unify_call_args ctx el args r callp inline force_inline in_overload =
 	let call_error err p = raise_error_msg (Call_error err) p in

+ 39 - 0
src/typing/fieldCallCandidate.ml

@@ -0,0 +1,39 @@
+
+open Type
+
+(* This record holds transient information about an (attempted) call on a field. It is created when resolving
+   field calls and is passed to overload filters. *)
+   type 'a field_call_candidate = {
+	(* The argument expressions for this call and whether or not the argument is optional on the
+	   target function. *)
+	fc_args  : texpr list;
+	(* The applied return type. *)
+	fc_ret   : Type.t;
+	(* The applied function type. *)
+	fc_type  : Type.t;
+	(* The class field being called. *)
+	fc_field : tclass_field;
+	(* The field monomorphs that were created for this call. *)
+	fc_monos : Type.t list;
+	(* The custom data associated with this call. *)
+	fc_data  : 'a;
+}
+
+let make_field_call_candidate args ret monos t cf data = {
+	fc_args  = args;
+	fc_type  = t;
+	fc_field = cf;
+	fc_data  = data;
+	fc_ret   = ret;
+	fc_monos = monos;
+}
+
+let s_field_call_candidate fcc =
+	let pctx = print_context() in
+	let se = s_expr_pretty false "" false (s_type pctx) in
+	let sl_args = List.map se fcc.fc_args in
+	Printer.s_record_fields "" [
+		"fc_args",String.concat ", " sl_args;
+		"fc_type",s_type pctx fcc.fc_type;
+		"fc_field",Printf.sprintf "%s: %s" fcc.fc_field.cf_name (s_type pctx fcc.fc_field.cf_type)
+	]

+ 1 - 1
src/typing/functionArguments.ml

@@ -22,7 +22,7 @@ let type_function_arg_value ctx t c do_display =
 		| None -> None
 		| Some e ->
 			let p = pos e in
-			let e = if do_display then Display.ExprPreprocessing.process_expr ctx.com e else e in
+			let e = if do_display then Display.preprocess_expr ctx.com e else e in
 			let e = Optimizer.reduce_expression ctx (type_expr ctx e (WithType.with_type t)) in
 			unify ctx e.etype t p;
 			let rec loop e = match e.eexpr with

+ 1 - 0
src/typing/generic.ml

@@ -5,6 +5,7 @@ open Ast
 open Type
 open Typecore
 open Error
+open FieldCallCandidate
 
 type generic_context = {
 	ctx : typer;

+ 8 - 16
src/typing/macroContext.ml

@@ -26,14 +26,6 @@ open Resolution
 open Error
 open Globals
 
-module Eval = struct
-	include EvalEncode
-	include EvalDecode
-	include EvalValue
-	include EvalContext
-	include EvalMain
-end
-
 module InterpImpl = Eval (* Hlmacro *)
 
 module Interp = struct
@@ -48,7 +40,7 @@ let macro_interp_cache = ref None
 let safe_decode com v expected t p f =
 	try
 		f ()
-	with MacroApi.Invalid_expr | EvalContext.RunTimeException _ ->
+	with MacroApi.Invalid_expr ->
 		let path = [dump_path com;"decoding_error"] in
 		let ch = Path.create_file false ".txt" [] path  in
 		let errors = Interp.handle_decoding_error (output_string ch) v t in
@@ -282,7 +274,7 @@ let make_macro_com_api com mcom p =
 			!macro_enable_cache
 		);
 		format_string = (fun s p ->
-			Common.format_string com s p (fun e p -> (e,p))
+			FormatString.format_string com.defines s p (fun e p -> (e,p))
 		);
 		cast_or_unify = (fun t e p ->
 			Interp.exc_string "unsupported"
@@ -632,7 +624,7 @@ and flush_macro_context mint mctx =
 	(* we should maybe ensure that all filters in Main are applied. Not urgent atm *)
 	let expr_filters = [
 		"handle_abstract_casts",AbstractCast.handle_abstract_casts mctx;
-		"local_statics",Filters.LocalStatic.run mctx;
+		"local_statics",LocalStatic.run mctx;
 		"Exceptions",Exceptions.filter mctx;
 		"captured_vars",CapturedVars.captured_vars mctx.com;
 	] in
@@ -668,14 +660,14 @@ and flush_macro_context mint mctx =
 			()
 	in
 	let type_filters = [
-		Filters.remove_generic_base;
+		FiltersCommon.remove_generic_base;
 		Exceptions.patch_constructors mctx;
-		(fun mt -> Filters.add_field_inits mctx.curclass.cl_path (RenameVars.init mctx.com) mctx.com mt);
+		(fun mt -> AddFieldInits.add_field_inits mctx.curclass.cl_path (RenameVars.init mctx.com) mctx.com mt);
 		minimal_restore;
-		Filters.apply_native_paths
+		Naming.apply_native_paths
 	] in
 	let ready = fun t ->
-		Filters.apply_filters_once mctx expr_filters t;
+		FiltersCommon.apply_filters_once mctx expr_filters t;
 		List.iter (fun f -> f t) type_filters
 	in
 	(try Interp.add_types mint types ready
@@ -996,7 +988,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 						else try
 							let ct = Interp.decode_ctype v in
 							Typeload.load_complex_type ctx false ct;
-						with MacroApi.Invalid_expr | EvalContext.RunTimeException _ ->
+						with MacroApi.Invalid_expr  | EvalContext.RunTimeException _ ->
 							Interp.decode_type v
 						in
 						ctx.ret <- t;

+ 1 - 1
src/typing/overloadResolution.ml

@@ -1,7 +1,7 @@
-open Typecore
 open TType
 open TUnification
 open TFunctions
+open FieldCallCandidate
 
 let unify_cf map_type c cf el =
 	let monos = List.map (fun _ -> mk_mono()) cf.cf_params in

+ 0 - 11
src/typing/typeload.ml

@@ -102,17 +102,6 @@ let find_type_in_module_raise ctx m tname p =
 	with Not_found ->
 		raise_typing_error_ext (make_error (Type_not_found (m.m_path,tname,Not_defined)) p)
 
-(* raises Module_not_found or Type_not_found *)
-let load_type_raise ctx mpath tname p =
-	let m = ctx.g.do_load_module ctx mpath p in
-	find_type_in_module_raise ctx m tname p
-
-(* raises Not_found *)
-let load_type ctx mpath tname p = try
-	load_type_raise ctx mpath tname p
-with Error { err_message = (Module_not_found _ | Type_not_found _); err_pos = p2 } when p = p2 ->
-	raise Not_found
-
 (** since load_type_def and load_instance are used in PASS2, they should not access the structure of a type **)
 
 let find_type_in_current_module_context ctx pack name =

+ 2 - 20
src/typing/typeloadCheck.ml

@@ -130,24 +130,6 @@ let copy_meta meta_src meta_target sl =
 	) meta_src;
 	!meta
 
-(** 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
-	| _ ->
-		raise_typing_error "String expected" mp
-
 let check_native_name_override ctx child base =
 	let error base_pos child_pos =
 		(* TODO construct error *)
@@ -155,9 +137,9 @@ let check_native_name_override ctx child base =
 		display_error ~depth:1 ctx.com (compl_msg "Base field is defined here") base_pos
 	in
 	try
-		let child_name, child_pos = get_native_name child.cf_meta in
+		let child_name, child_pos = Naming.get_native_name child.cf_meta in
 		try
-			let base_name, base_pos = get_native_name base.cf_meta in
+			let base_name, base_pos = Naming.get_native_name base.cf_meta in
 			if base_name <> child_name then
 				error base_pos child_pos
 		with Not_found ->

+ 1 - 1
src/typing/typeloadFields.ml

@@ -706,7 +706,7 @@ let transform_field (ctx,cctx) c f fields p =
 
 let type_var_field ctx t e stat do_display p =
 	if stat then ctx.curfun <- FunStatic else ctx.curfun <- FunMember;
-	let e = if do_display then Display.ExprPreprocessing.process_expr ctx.com e else e in
+	let e = if do_display then Display.preprocess_expr ctx.com e else e in
 	let e = type_expr ctx e (WithType.with_type t) in
 	let e = AbstractCast.cast_or_unify ctx t e p in
 	match t with

+ 1 - 1
src/typing/typeloadFunction.ml

@@ -78,7 +78,7 @@ let type_function ctx (args : function_arguments) ret fmode e do_display p =
 	end else begin
 		let is_display_debug = Meta.has (Meta.Custom ":debug.display") ctx.curfield.cf_meta in
 		if is_display_debug then print_endline ("before processing:\n" ^ (Expr.dump_with_pos e));
-		let e = if !Parser.had_resume then e else Display.ExprPreprocessing.process_expr ctx.com e in
+		let e = if !Parser.had_resume then e else Display.preprocess_expr ctx.com e in
 		if is_display_debug then print_endline ("after processing:\n" ^ (Expr.dump_with_pos e));
 		type_expr ctx e NoValue
 	end in

+ 3 - 3
src/typing/typeloadModule.ml

@@ -707,7 +707,7 @@ let make_curmod ctx m =
 	let rl = new resolution_list ["import";s_type_path m.m_path] in
 	List.iter (fun mt ->
 		rl#add (module_type_resolution mt None null_pos))
-	(List.rev ctx.g.std.m_types);
+	(List.rev ctx.g.std_types.m_types);
 	{
 		curmod = m;
 		import_resolution = rl;
@@ -764,8 +764,8 @@ let type_types_into_module ctx m tdecls p =
 	List.iter (TypeloadCheck.check_module_types ctx m p) types;
 	m.m_types <- m.m_types @ types;
 	(* define the per-module context for the next pass *)
-	if ctx.g.std != null_module then begin
-		add_dependency m ctx.g.std;
+	if ctx.g.std_types != null_module then begin
+		add_dependency m ctx.g.std_types;
 		(* this will ensure both String and (indirectly) Array which are basic types which might be referenced *)
 		ignore(load_instance ctx (make_ptp (mk_type_path (["std"],"String")) null_pos) ParamNormal)
 	end;

+ 9 - 152
src/typing/typer.ml

@@ -750,9 +750,9 @@ and type_vars ctx vl p =
 		mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos
 
 and format_string ctx s p =
-	Common.format_string ctx.com s p (fun enext p ->
+	FormatString.format_string ctx.com.defines s p (fun enext p ->
 		if ctx.in_display && DisplayPosition.display_position#enclosed_in p then
-			Display.ExprPreprocessing.process_expr ctx.com (enext,p)
+			Display.preprocess_expr ctx.com (enext,p)
 		else
 			enext,p
 	)
@@ -2015,160 +2015,18 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 				DisplayEmitter.display_module_type ctx mt p_t;
 			let e_t = type_module_type ctx mt p_t in
 			let e_Std_isOfType =
-				match Typeload.load_type_raise ctx ([],"Std") "Std" p with
-				| TClassDecl c ->
-					let cf =
-						try PMap.find "isOfType" c.cl_statics
-						with Not_found -> die "" __LOC__
-					in
-					Texpr.Builder.make_static_field c cf (mk_zero_range_pos p)
-				| _ -> die "" __LOC__
+				ignore(ctx.g.std.cl_build());
+				let cf = try
+					PMap.find "isOfType" ctx.g.std.cl_statics
+				with Not_found ->
+					die "" __LOC__
+				in
+				Texpr.Builder.make_static_field ctx.g.std cf (mk_zero_range_pos p)
 			in
 			mk (TCall (e_Std_isOfType, [e; e_t])) ctx.com.basic.tbool p
 		| _ ->
 			display_error ctx.com "Unsupported type for `is` operator" p_t;
 			Texpr.Builder.make_bool ctx.com.basic false p
-
-(* ---------------------------------------------------------------------- *)
-(* TYPER INITIALIZATION *)
-
-let create com macros =
-	let ctx = {
-		com = com;
-		t = com.basic;
-		g = {
-			core_api = None;
-			macros = macros;
-			type_patches = Hashtbl.create 0;
-			module_check_policies = [];
-			delayed = [];
-			debug_delayed = [];
-			doinline = com.display.dms_inline && not (Common.defined com Define.NoInline);
-			retain_meta = Common.defined com Define.RetainUntypedMeta;
-			std = null_module;
-			global_using = [];
-			complete = false;
-			type_hints = [];
-			load_only_cached_modules = false;
-			functional_interface_lut = new pmap_lookup;
-			do_macro = MacroContext.type_macro;
-			do_load_macro = MacroContext.load_macro';
-			do_load_module = TypeloadModule.load_module;
-			do_load_type_def = Typeload.load_type_def;
-			get_build_info = InstanceBuilder.get_build_info;
-			do_format_string = format_string;
-			do_load_core_class = Typeload.load_core_class;
-		};
-		m = {
-			curmod = null_module;
-			import_resolution = new resolution_list ["import";"typer"];
-			own_resolution = None;
-			enum_with_type = None;
-			module_using = [];
-			import_statements = [];
-		};
-		is_display_file = false;
-		bypass_accessor = 0;
-		meta = [];
-		with_type_stack = [];
-		call_argument_stack = [];
-		pass = PBuildModule;
-		macro_depth = 0;
-		untyped = false;
-		curfun = FunStatic;
-		in_function = false;
-		in_loop = false;
-		in_display = false;
-		allow_inline = true;
-		allow_transform = true;
-		get_build_infos = (fun() -> None);
-		ret = mk_mono();
-		locals = PMap.empty;
-		type_params = [];
-		curclass = null_class;
-		curfield = null_field;
-		tthis = mk_mono();
-		opened = [];
-		vthis = None;
-		in_call_args = false;
-		in_overload_call_args = false;
-		delayed_display = None;
-		monomorphs = {
-			perfunction = [];
-		};
-		memory_marker = Typecore.memory_marker;
-	} in
-	ctx.g.std <- (try
-		TypeloadModule.load_module ctx ([],"StdTypes") null_pos
-	with
-		Error { err_message = Module_not_found ([],"StdTypes") } ->
-			try
-				let std_path = Sys.getenv "HAXE_STD_PATH" in
-				raise_typing_error ("Standard library not found. Please check your `HAXE_STD_PATH` environment variable (current value: \"" ^ std_path ^ "\")") null_pos
-			with Not_found ->
-				raise_typing_error "Standard library not found. You may need to set your `HAXE_STD_PATH` environment variable" null_pos
-	);
-	(* We always want core types to be available so we add them as default imports (issue #1904 and #3131). *)
-	List.iter (fun mt ->
-		ctx.m.import_resolution#add (module_type_resolution mt None null_pos))
-	(List.rev ctx.g.std.m_types);
-	List.iter (fun t ->
-		match t with
-		| TAbstractDecl a ->
-			(match snd a.a_path with
-			| "Void" -> ctx.t.tvoid <- TAbstract (a,[]);
-			| "Float" -> ctx.t.tfloat <- TAbstract (a,[]);
-			| "Int" -> ctx.t.tint <- TAbstract (a,[])
-			| "Bool" -> ctx.t.tbool <- TAbstract (a,[])
-			| "Dynamic" -> t_dynamic_def := TAbstract(a,extract_param_types a.a_params);
-			| "Null" ->
-				let mk_null t =
-					try
-						if not (is_null ~no_lazy:true t || is_explicit_null t) then TAbstract (a,[t]) else t
-					with Exit ->
-						(* don't force lazy evaluation *)
-						let r = ref (lazy_available t_dynamic) in
-						r := lazy_wait (fun() ->
-							let t = (if not (is_null t) then TAbstract (a,[t]) else t) in
-							r := lazy_available t;
-							t
-						);
-						TLazy r
-				in
-				ctx.t.tnull <- mk_null;
-			| _ -> ())
-		| TEnumDecl _ | TClassDecl _ | TTypeDecl _ ->
-			()
-	) ctx.g.std.m_types;
-	let m = TypeloadModule.load_module ctx ([],"String") null_pos in
-	List.iter (fun mt -> match mt with
-		| TClassDecl c -> ctx.t.tstring <- TInst (c,[])
-		| _ -> ()
-	) m.m_types;
-	let m = TypeloadModule.load_module ctx ([],"Array") null_pos in
-	(try
-		List.iter (fun t -> (
-			match t with
-			| TClassDecl ({cl_path = ([],"Array")} as c) ->
-				ctx.t.tarray <- (fun t -> TInst (c,[t]));
-				raise Exit
-			| _ -> ()
-		)) m.m_types;
-		die "" __LOC__
-	with Exit -> ());
-	let m = TypeloadModule.load_module ctx (["haxe"],"EnumTools") null_pos in
-	(match m.m_types with
-	| [TClassDecl c1;TClassDecl c2] -> ctx.g.global_using <- (c1,c1.cl_pos) :: (c2,c2.cl_pos) :: ctx.g.global_using
-	| [TClassDecl c1] ->
-		let m = TypeloadModule.load_module ctx (["haxe"],"EnumWithType.valueTools") null_pos in
-		(match m.m_types with
-		| [TClassDecl c2 ] -> ctx.g.global_using <- (c1,c1.cl_pos) :: (c2,c2.cl_pos) :: ctx.g.global_using
-		| _ -> die "" __LOC__);
-	| _ -> die "" __LOC__);
-	ignore(TypeloadModule.load_module ctx (["haxe"],"Exception") null_pos);
-	ctx.g.complete <- true;
-	ctx
-
 ;;
 unify_min_ref := unify_min;
 unify_min_for_type_source_ref := unify_min_for_type_source;
@@ -2176,5 +2034,4 @@ make_call_ref := make_call;
 type_call_target_ref := type_call_target;
 type_access_ref := type_access;
 type_block_ref := type_block;
-create_context_ref := create;
 type_expr_ref := (fun ?(mode=MGet) ctx e with_type -> type_expr ~mode ctx e with_type);

+ 154 - 0
src/typing/typerEntry.ml

@@ -0,0 +1,154 @@
+open Globals
+open Common
+open Type
+open Typecore
+open Typer
+open Resolution
+open Error
+
+let create com macros =
+	let ctx = {
+		com = com;
+		t = com.basic;
+		g = {
+			core_api = None;
+			macros = macros;
+			type_patches = Hashtbl.create 0;
+			module_check_policies = [];
+			delayed = [];
+			debug_delayed = [];
+			doinline = com.display.dms_inline && not (Common.defined com Define.NoInline);
+			retain_meta = Common.defined com Define.RetainUntypedMeta;
+			std_types = null_module;
+			std = null_class;
+			global_using = [];
+			complete = false;
+			type_hints = [];
+			load_only_cached_modules = false;
+			functional_interface_lut = new pmap_lookup;
+			do_macro = MacroContext.type_macro;
+			do_load_macro = MacroContext.load_macro';
+			do_load_module = TypeloadModule.load_module;
+			do_load_type_def = Typeload.load_type_def;
+			get_build_info = InstanceBuilder.get_build_info;
+			do_format_string = format_string;
+			do_load_core_class = Typeload.load_core_class;
+		};
+		m = {
+			curmod = null_module;
+			import_resolution = new resolution_list ["import";"typer"];
+			own_resolution = None;
+			enum_with_type = None;
+			module_using = [];
+			import_statements = [];
+		};
+		is_display_file = false;
+		bypass_accessor = 0;
+		meta = [];
+		with_type_stack = [];
+		call_argument_stack = [];
+		pass = PBuildModule;
+		macro_depth = 0;
+		untyped = false;
+		curfun = FunStatic;
+		in_function = false;
+		in_loop = false;
+		in_display = false;
+		allow_inline = true;
+		allow_transform = true;
+		get_build_infos = (fun() -> None);
+		ret = mk_mono();
+		locals = PMap.empty;
+		type_params = [];
+		curclass = null_class;
+		curfield = null_field;
+		tthis = mk_mono();
+		opened = [];
+		vthis = None;
+		in_call_args = false;
+		in_overload_call_args = false;
+		delayed_display = None;
+		monomorphs = {
+			perfunction = [];
+		};
+		memory_marker = Typecore.memory_marker;
+	} in
+	ctx.g.std_types <- (try
+		TypeloadModule.load_module ctx ([],"StdTypes") null_pos
+	with
+		Error { err_message = Module_not_found ([],"StdTypes") } ->
+			try
+				let std_path = Sys.getenv "HAXE_STD_PATH" in
+				raise_typing_error ("Standard library not found. Please check your `HAXE_STD_PATH` environment variable (current value: \"" ^ std_path ^ "\")") null_pos
+			with Not_found ->
+				raise_typing_error "Standard library not found. You may need to set your `HAXE_STD_PATH` environment variable" null_pos
+	);
+	(* We always want core types to be available so we add them as default imports (issue #1904 and #3131). *)
+	List.iter (fun mt ->
+		ctx.m.import_resolution#add (module_type_resolution mt None null_pos))
+	(List.rev ctx.g.std_types.m_types);
+	List.iter (fun t ->
+		match t with
+		| TAbstractDecl a ->
+			(match snd a.a_path with
+			| "Void" -> ctx.t.tvoid <- TAbstract (a,[]);
+			| "Float" -> ctx.t.tfloat <- TAbstract (a,[]);
+			| "Int" -> ctx.t.tint <- TAbstract (a,[])
+			| "Bool" -> ctx.t.tbool <- TAbstract (a,[])
+			| "Dynamic" -> t_dynamic_def := TAbstract(a,extract_param_types a.a_params);
+			| "Null" ->
+				let mk_null t =
+					try
+						if not (is_null ~no_lazy:true t || is_explicit_null t) then TAbstract (a,[t]) else t
+					with Exit ->
+						(* don't force lazy evaluation *)
+						let r = ref (lazy_available t_dynamic) in
+						r := lazy_wait (fun() ->
+							let t = (if not (is_null t) then TAbstract (a,[t]) else t) in
+							r := lazy_available t;
+							t
+						);
+						TLazy r
+				in
+				ctx.t.tnull <- mk_null;
+			| _ -> ())
+		| TEnumDecl _ | TClassDecl _ | TTypeDecl _ ->
+			()
+	) ctx.g.std_types.m_types;
+	let m = TypeloadModule.load_module ctx ([],"String") null_pos in
+	List.iter (fun mt -> match mt with
+		| TClassDecl c -> ctx.t.tstring <- TInst (c,[])
+		| _ -> ()
+	) m.m_types;
+	let m = TypeloadModule.load_module ctx ([],"Std") null_pos in
+	List.iter (fun mt -> match mt with
+		| TClassDecl c -> ctx.g.std <- c;
+		| _ -> ()
+	) m.m_types;	
+	let m = TypeloadModule.load_module ctx ([],"Array") null_pos in
+	(try
+		List.iter (fun t -> (
+			match t with
+			| TClassDecl ({cl_path = ([],"Array")} as c) ->
+				ctx.t.tarray <- (fun t -> TInst (c,[t]));
+				raise Exit
+			| _ -> ()
+		)) m.m_types;
+		die "" __LOC__
+	with Exit -> ());
+	let m = TypeloadModule.load_module ctx (["haxe"],"EnumTools") null_pos in
+	(match m.m_types with
+	| [TClassDecl c1;TClassDecl c2] -> ctx.g.global_using <- (c1,c1.cl_pos) :: (c2,c2.cl_pos) :: ctx.g.global_using
+	| [TClassDecl c1] ->
+		let m = TypeloadModule.load_module ctx (["haxe"],"EnumWithType.valueTools") null_pos in
+		(match m.m_types with
+		| [TClassDecl c2 ] -> ctx.g.global_using <- (c1,c1.cl_pos) :: (c2,c2.cl_pos) :: ctx.g.global_using
+		| _ -> die "" __LOC__);
+	| _ -> die "" __LOC__);
+	ignore(TypeloadModule.load_module ctx (["haxe"],"Exception") null_pos);
+	ctx.g.complete <- true;
+	ctx
+
+;;
+create_context_ref := create;
+Inline.maybe_reapply_overload_call_ref := CallUnification.maybe_reapply_overload_call;