浏览代码

Merge branch 'development' into out_of_curiosity

# Conflicts:
#	src/codegen/gencommon/castDetect.ml
#	src/codegen/gencommon/closuresToClass.ml
#	src/codegen/gencommon/dynamicFieldAccess.ml
#	src/codegen/gencommon/enumToClass.ml
#	src/codegen/gencommon/gencommon.ml
#	src/codegen/gencommon/overloadingConstructor.ml
#	src/codegen/gencommon/realTypeParams.ml
#	src/codegen/gencommon/renameTypeParameters.ml
#	src/filters/filters.ml
#	src/generators/gencs.ml
#	src/generators/genjava.ml
Simon Krajewski 1 年之前
父节点
当前提交
2a6e013d6f
共有 100 个文件被更改,包括 2538 次插入1688 次删除
  1. 113 0
      src-json/define.json
  2. 20 15
      src/codegen/codegen.ml
  3. 4 7
      src/codegen/overloads.ml
  4. 1 1
      src/compiler/args.ml
  5. 4 4
      src/compiler/compiler.ml
  6. 1 1
      src/compiler/displayOutput.ml
  7. 3 3
      src/compiler/displayProcessing.ml
  8. 31 18
      src/compiler/messageReporting.ml
  9. 12 2
      src/compiler/server.ml
  10. 6 2
      src/compiler/serverCompilationContext.ml
  11. 7 4
      src/context/abstractCast.ml
  12. 54 167
      src/context/common.ml
  13. 6 3
      src/context/display/deprecationCheck.ml
  14. 4 227
      src/context/display/display.ml
  15. 1 1
      src/context/display/displayEmitter.ml
  16. 6 5
      src/context/display/displayFields.ml
  17. 1 1
      src/context/display/displayJson.ml
  18. 1 1
      src/context/display/displayTexpr.ml
  19. 2 4
      src/context/display/displayToplevel.ml
  20. 224 0
      src/context/display/exprPreprocessing.ml
  21. 11 0
      src/context/feature.ml
  22. 98 0
      src/context/formatString.ml
  23. 113 0
      src/context/lookup.ml
  24. 2 2
      src/context/memory.ml
  25. 14 48
      src/context/typecore.ml
  26. 13 0
      src/core/ast.ml
  27. 6 8
      src/core/display/completionItem.ml
  28. 1 1
      src/core/displayTypes.ml
  29. 8 2
      src/core/globals.ml
  30. 5 9
      src/core/json/genjson.ml
  31. 86 0
      src/core/naming.ml
  32. 12 1
      src/core/socket.ml
  33. 117 21
      src/core/tFunctions.ml
  34. 88 14
      src/core/tOther.ml
  35. 49 27
      src/core/tPrinting.ml
  36. 37 16
      src/core/tType.ml
  37. 19 18
      src/core/tUnification.ml
  38. 4 5
      src/core/texpr.ml
  39. 68 0
      src/filters/addFieldInits.ml
  40. 22 0
      src/filters/exceptionFunctions.ml
  41. 2 25
      src/filters/exceptions.ml
  42. 5 209
      src/filters/filters.ml
  43. 17 5
      src/filters/filtersCommon.ml
  44. 62 0
      src/filters/localStatic.ml
  45. 3 3
      src/filters/renameVars.ml
  46. 23 3
      src/generators/gencpp.ml
  47. 41 7
      src/generators/genhl.ml
  48. 11 144
      src/generators/genjs.ml
  49. 17 15
      src/generators/genjvm.ml
  50. 40 5
      src/generators/genlua.ml
  51. 1 2
      src/generators/genpy.ml
  52. 1 3
      src/generators/genswf.ml
  53. 4 4
      src/generators/genswf9.ml
  54. 16 2
      src/generators/hl2c.ml
  55. 13 0
      src/generators/hlcode.ml
  56. 6 6
      src/generators/hlinterp.ml
  57. 11 0
      src/generators/hlopt.ml
  58. 158 0
      src/generators/jsSourcemap.ml
  59. 5 0
      src/macro/eval/eval.ml
  60. 0 5
      src/macro/eval/evalContext.ml
  61. 1 1
      src/macro/eval/evalDebugSocket.ml
  62. 0 1
      src/macro/eval/evalExceptions.ml
  63. 2 1
      src/macro/eval/evalLuv.ml
  64. 2 1
      src/macro/eval/evalMain.ml
  65. 1 1
      src/macro/eval/evalStdLib.ml
  66. 1 1
      src/macro/eval/evalThread.ml
  67. 1 0
      src/macro/eval/evalTypes.ml
  68. 10 38
      src/macro/macroApi.ml
  69. 2 2
      src/optimization/analyzer.ml
  70. 26 23
      src/optimization/dce.ml
  71. 6 4
      src/optimization/inline.ml
  72. 18 2
      src/syntax/grammar.mly
  73. 26 10
      src/typing/callUnification.ml
  74. 39 0
      src/typing/fieldCallCandidate.ml
  75. 2 2
      src/typing/fields.ml
  76. 4 4
      src/typing/finalization.ml
  77. 1 1
      src/typing/forLoop.ml
  78. 1 1
      src/typing/functionArguments.ml
  79. 22 23
      src/typing/generic.ml
  80. 9 17
      src/typing/macroContext.ml
  81. 6 2
      src/typing/matcher/exprToPattern.ml
  82. 6 2
      src/typing/operators.ml
  83. 1 1
      src/typing/overloadResolution.ml
  84. 36 16
      src/typing/tanon_identification.ml
  85. 76 96
      src/typing/typeload.ml
  86. 23 56
      src/typing/typeloadCheck.ml
  87. 10 14
      src/typing/typeloadFields.ml
  88. 4 4
      src/typing/typeloadFunction.ml
  89. 15 31
      src/typing/typeloadModule.ml
  90. 26 172
      src/typing/typer.ml
  91. 3 4
      src/typing/typerBase.ml
  92. 3 3
      src/typing/typerDisplay.ml
  93. 167 0
      src/typing/typerEntry.ml
  94. 3 0
      std/hl/Api.hx
  95. 4 21
      std/hl/CArray.hx
  96. 1 1
      std/js/Object.hx
  97. 43 1
      std/js/html/Navigator.hx
  98. 74 0
      std/js/html/WakeLock.hx
  99. 151 53
      std/js/lib/Object.hx
  100. 2 2
      std/js/lib/Proxy.hx

+ 113 - 0
src-json/define.json

@@ -275,6 +275,114 @@
 		"doc": "Include additional information for hxcpp-debugger.",
 		"doc": "Include additional information for hxcpp-debugger.",
 		"platforms": ["cpp"]
 		"platforms": ["cpp"]
 	},
 	},
+	{
+		"name": "HxcppGcMoving",
+		"define": "HXCPP-GC-MOVING",
+		"doc": "Allow garbage collector to move memory to reduce fragmentation",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppGcSummary",
+		"define": "HXCPP-GC-SUMMARY",
+		"doc": "Print small profiling summary at end of program",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppGcDynamicSize",
+		"define": "HXCPP-GC-DYNAMIC-SIZE",
+		"doc": "Monitor GC times and expand memory working space if required",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppGcBigBlocks",
+		"define": "HXCPP-GC-BIG-BLOCKS",
+		"doc": "Allow working memory greater than 1 Gig",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppGcDebugLevel",
+		"define": "HXCPP-GC-DEBUG-LEVEL",
+		"doc": "Number 1-4 indicating additional debugging in GC",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppDebugLink",
+		"define": "HXCPP-DEBUG-LINK",
+		"doc": "Add symbols to final binary, even in release mode.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppStackTrace",
+		"define": "HXCPP-STACK-TRACE",
+		"doc": "Have valid function-level stack traces, even in release mode.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppStackLine",
+		"define": "HXCPP-STACK-LINE",
+		"doc": "Include line information in stack traces, even in release mode.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppCheckPointer",
+		"define": "HXCPP-CHECK-POINTER",
+		"doc": "Add null-pointer checks, even in release mode.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppProfiler",
+		"define": "HXCPP-PROFILER",
+		"doc": "Add profiler support",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppTelemetry",
+		"define": "HXCPP-TELEMETRY",
+		"doc": "Add telemetry support",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppCpp11",
+		"define": "HXCPP-CPP11",
+		"doc": "Use C++11 features and link libraries",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppVerbose",
+		"define": "HXCPP-VERBOSE",
+		"doc": "Print extra output from build tool.",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppTimes",
+		"define": "HXCPP-TIMES",
+		"doc": "Show some basic profiling information",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppM32",
+		"define": "HXCPP-M32",
+		"doc": "Force 32-bit compile for current desktop",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppM64",
+		"define": "HXCPP-M64",
+		"doc": "Force 64-bit compile for current desktop",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppArm64",
+		"define": "HXCPP-ARM64",
+		"doc": "Compile arm-based devices for 64 bits",
+		"platforms": ["cpp"]
+	},
+	{
+		"name": "HxcppLinuxArm64",
+		"define": "HXCPP-LINUX-ARM64",
+		"doc": "Run on a linux ARM64 device",
+		"platforms": ["cpp"]
+	},
 	{
 	{
 		"name": "HxcppSmartStings",
 		"name": "HxcppSmartStings",
 		"define": "hxcpp-smart-strings",
 		"define": "hxcpp-smart-strings",
@@ -681,6 +789,11 @@
 		"define": "message.no-color",
 		"define": "message.no-color",
 		"doc": "Disable ANSI color codes in message reporting."
 		"doc": "Disable ANSI color codes in message reporting."
 	},
 	},
+	{
+		"name": "MessageAbsolutePositions",
+		"define": "message.absolute-positions",
+		"doc": "Use absolute character positions instead of line/columns for message reporting."
+	},
 	{
 	{
 		"name": "MessageLogFile",
 		"name": "MessageLogFile",
 		"define": "message.log-file",
 		"define": "message.log-file",

+ 20 - 15
src/codegen/codegen.ml

@@ -122,8 +122,13 @@ let fix_override com c f fd =
 					(* Flash generates type parameters with a single constraint as that constraint type, so we
 					(* Flash generates type parameters with a single constraint as that constraint type, so we
 					   have to detect this case and change the variable (issue #2712). *)
 					   have to detect this case and change the variable (issue #2712). *)
 					begin match follow v.v_type with
 					begin match follow v.v_type with
-						| TInst({cl_kind = KTypeParameter [tc]} as cp,_) when com.platform = Flash ->
-							if List.exists (fun tp -> tp.ttp_name = (snd cp.cl_path)) c.cl_params then raise (Unify_error [])
+						| TInst({cl_kind = KTypeParameter ttp} as cp,_) when com.platform = Flash ->
+							begin match get_constraints ttp with
+							| [tc] ->
+								if List.exists (fun tp -> tp.ttp_name = (snd cp.cl_path)) c.cl_params then raise (Unify_error [])
+							| _ ->
+								()
+							end
 						| _ ->
 						| _ ->
 							()
 							()
 					end;
 					end;
@@ -235,11 +240,16 @@ module Dump = struct
 		let buf,close = create_dumpfile [] ((dump_path com) :: (platform_name_macro com) :: fst path @ [snd path]) in
 		let buf,close = create_dumpfile [] ((dump_path com) :: (platform_name_macro com) :: fst path @ [snd path]) in
 		buf,close
 		buf,close
 
 
-	let dump_types com s_expr =
+	let dump_types com pretty =
 		let s_type = s_type (Type.print_context()) in
 		let s_type = s_type (Type.print_context()) in
+		let s_expr,s_type_param = if not pretty then
+			(Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t"),(Printer.s_type_param "")
+		else
+			(Type.s_expr_pretty false "\t" true),(s_type_param s_type)
+		in
 		let params tl = match tl with
 		let params tl = match tl with
 			| [] -> ""
 			| [] -> ""
-			| l -> Printf.sprintf "<%s>" (String.concat ", " (List.map Printer.s_type_param l))
+			| l -> Printf.sprintf "<%s>" (String.concat ", " (List.map s_type_param l))
 		in
 		in
 		List.iter (fun mt ->
 		List.iter (fun mt ->
 			let path = Type.t_path mt in
 			let path = Type.t_path mt in
@@ -371,10 +381,10 @@ module Dump = struct
 
 
 	let dump_types com =
 	let dump_types com =
 		match Common.defined_value_safe com Define.Dump with
 		match Common.defined_value_safe com Define.Dump with
-			| "pretty" -> dump_types com (Type.s_expr_pretty false "\t" true)
+			| "pretty" -> dump_types com true
 			| "record" -> dump_record com
 			| "record" -> dump_record com
 			| "position" -> dump_position com
 			| "position" -> dump_position com
-			| _ -> dump_types com (Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t")
+			| _ -> dump_types com false 
 
 
 	let dump_dependencies ?(target_override=None) com =
 	let dump_dependencies ?(target_override=None) com =
 		let target_name = match target_override with
 		let target_name = match target_override with
@@ -388,7 +398,7 @@ module Dump = struct
 		List.iter (fun m ->
 		List.iter (fun m ->
 			print "%s:\n" (Path.UniqueKey.lazy_path m.m_extra.m_file);
 			print "%s:\n" (Path.UniqueKey.lazy_path m.m_extra.m_file);
 			PMap.iter (fun _ (sign,mpath) ->
 			PMap.iter (fun _ (sign,mpath) ->
-				let m2 = (com.cs#get_context sign)#find_module mpath in
+				let m2 = com.module_lut#find mpath in
 				let file = Path.UniqueKey.lazy_path m2.m_extra.m_file in
 				let file = Path.UniqueKey.lazy_path m2.m_extra.m_file in
 				print "\t%s\n" file;
 				print "\t%s\n" file;
 				let l = try Hashtbl.find dep file with Not_found -> [] in
 				let l = try Hashtbl.find dep file with Not_found -> [] in
@@ -414,16 +424,10 @@ end
 *)
 *)
 let default_cast ?(vtmp="$t") com e texpr t p =
 let default_cast ?(vtmp="$t") com e texpr t p =
 	let api = com.basic in
 	let api = com.basic in
-	let mk_texpr = function
-		| TClassDecl c -> mk_anon (ref (ClassStatics c))
-		| TEnumDecl e -> mk_anon (ref (EnumStatics e))
-		| TAbstractDecl a -> mk_anon (ref (AbstractStatics a))
-		| TTypeDecl _ -> die "" __LOC__
-	in
 	let vtmp = alloc_var VGenerated vtmp e.etype e.epos in
 	let vtmp = alloc_var VGenerated vtmp e.etype e.epos in
 	let var = mk (TVar (vtmp,Some e)) api.tvoid p in
 	let var = mk (TVar (vtmp,Some e)) api.tvoid p in
 	let vexpr = mk (TLocal vtmp) e.etype p in
 	let vexpr = mk (TLocal vtmp) e.etype p in
-	let texpr = mk (TTypeExpr texpr) (mk_texpr texpr) p in
+	let texpr = Texpr.Builder.make_typeexpr texpr p in
 	let std = (try List.find (fun t -> t_path t = ([],"Std")) com.types with Not_found -> die "" __LOC__) in
 	let std = (try List.find (fun t -> t_path t = ([],"Std")) com.types with Not_found -> die "" __LOC__) in
 	let fis = (try
 	let fis = (try
 			let c = (match std with TClassDecl c -> c | _ -> die "" __LOC__) in
 			let c = (match std with TClassDecl c -> c | _ -> die "" __LOC__) in
@@ -431,7 +435,7 @@ let default_cast ?(vtmp="$t") com e texpr t p =
 		with Not_found ->
 		with Not_found ->
 			die "" __LOC__
 			die "" __LOC__
 	) in
 	) in
-	let std = mk (TTypeExpr std) (mk_texpr std) p in
+	let std = Texpr.Builder.make_typeexpr std p in
 	let is = mk (TField (std,fis)) (tfun [t_dynamic;t_dynamic] api.tbool) p in
 	let is = mk (TField (std,fis)) (tfun [t_dynamic;t_dynamic] api.tbool) p in
 	let is = mk (TCall (is,[vexpr;texpr])) api.tbool p in
 	let is = mk (TCall (is,[vexpr;texpr])) api.tbool p in
 	let enull = Texpr.Builder.make_null vexpr.etype p in
 	let enull = Texpr.Builder.make_null vexpr.etype p in
@@ -515,3 +519,4 @@ module ExtClass = struct
 		let e_assign = mk (TBinop(OpAssign,ef1,e)) e.etype p in
 		let e_assign = mk (TBinop(OpAssign,ef1,e)) e.etype p in
 		add_cl_init c e_assign
 		add_cl_init c e_assign
 end
 end
+	

+ 4 - 7
src/codegen/overloads.ml

@@ -1,6 +1,6 @@
 open Globals
 open Globals
 open Type
 open Type
-open Typecore
+open FieldCallCandidate
 
 
 let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
 let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
 	let f_transform = match get_vmtype with
 	let f_transform = match get_vmtype with
@@ -13,13 +13,10 @@ let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
 			| [],[] ->
 			| [],[] ->
 				true
 				true
 			| tp1 :: params1,tp2 :: params2 ->
 			| tp1 :: params1,tp2 :: params2 ->
-				let constraints_equal t1 t2 = match follow t1,follow t2 with
-					| TInst({cl_kind = KTypeParameter tl1},_),TInst({cl_kind = KTypeParameter tl2},_) ->
-						Ast.safe_for_all2 f_eq tl1 tl2
-					| _ ->
-						false
+				let constraints_equal ttp1 ttp2 = 
+					Ast.safe_for_all2 f_eq (get_constraints ttp2) (get_constraints ttp2)
 				in
 				in
-				tp1.ttp_name = tp2.ttp_name && constraints_equal tp1.ttp_type tp2.ttp_type && loop params1 params2
+				tp1.ttp_name = tp2.ttp_name && constraints_equal tp1 tp2 && loop params1 params2
 			| [],_
 			| [],_
 			| _,[] ->
 			| _,[] ->
 				false
 				false

+ 1 - 1
src/compiler/args.ml

@@ -42,7 +42,7 @@ let process_args arg_spec =
 
 
 let parse_args com =
 let parse_args com =
 	let usage = Printf.sprintf
 	let usage = Printf.sprintf
-		"Haxe Compiler %s - (C)2005-2023 Haxe Foundation\nUsage: haxe%s <target> [options] [hxml files and dot paths...]\n"
+		"Haxe Compiler %s - (C)2005-2024 Haxe Foundation\nUsage: haxe%s <target> [options] [hxml files and dot paths...]\n"
 		s_version_full (if Sys.os_type = "Win32" then ".exe" else "")
 		s_version_full (if Sys.os_type = "Win32" then ".exe" else "")
 	in
 	in
 	let actx = {
 	let actx = {

+ 4 - 4
src/compiler/compiler.ml

@@ -172,7 +172,7 @@ module Setup = struct
 		let fl = List.map (fun (file,extern) -> NativeLibraryHandler.add_native_lib com file extern) (List.rev native_libs) in
 		let fl = List.map (fun (file,extern) -> NativeLibraryHandler.add_native_lib com file extern) (List.rev native_libs) in
 		(* Native lib pass 2: Initialize *)
 		(* Native lib pass 2: Initialize *)
 		List.iter (fun f -> f()) fl;
 		List.iter (fun f -> f()) fl;
-		Typer.create com macros
+		TyperEntry.create com macros
 
 
 	let executable_path() =
 	let executable_path() =
 		Extc.executable_path()
 		Extc.executable_path()
@@ -418,7 +418,7 @@ with
 		error ctx ("Error: No completion point was found") null_pos
 		error ctx ("Error: No completion point was found") null_pos
 	| DisplayException.DisplayException dex ->
 	| DisplayException.DisplayException dex ->
 		DisplayOutput.handle_display_exception ctx 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 *)
 		(* We don't want these to be caught by the catchall below *)
 		raise exc
 		raise exc
 	| e when (try Sys.getenv "OCAMLRUNPARAM" <> "b" with _ -> true) && not Helper.is_debug_run ->
 	| e when (try Sys.getenv "OCAMLRUNPARAM" <> "b" with _ -> true) && not Helper.is_debug_run ->
@@ -443,7 +443,7 @@ let catch_completion_and_exit ctx callbacks run =
 			ServerMessage.completion str;
 			ServerMessage.completion str;
 			ctx.comm.write_err str;
 			ctx.comm.write_err str;
 			0
 			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;
 			if i <> 0 then ctx.has_error <- true;
 			finalize ctx;
 			finalize ctx;
 			i
 			i
@@ -476,7 +476,7 @@ let compile_ctx callbacks ctx =
 		catch_completion_and_exit ctx callbacks run
 		catch_completion_and_exit ctx callbacks run
 
 
 let create_context comm cs compilation_step params = {
 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 = [];
 	messages = [];
 	has_next = false;
 	has_next = false;
 	has_error = 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 ->
 			| None ->
 				DisplayPath.TypePathHandler.complete_type_path com p
 				DisplayPath.TypePathHandler.complete_type_path com p
 			| Some (c,cur_package) ->
 			| 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
 				DisplayPath.TypePathHandler.complete_type_path_inner ctx p c cur_package is_import
 		end with Error.Fatal_error err ->
 		end with Error.Fatal_error err ->
 			error_ext ctx err;
 			error_ext ctx err;

+ 3 - 3
src/compiler/displayProcessing.ml

@@ -48,7 +48,7 @@ let handle_display_argument_old com file_pos actx =
 			| "diagnostics" ->
 			| "diagnostics" ->
 				com.report_mode <- RMLegacyDiagnostics [file_unique];
 				com.report_mode <- RMLegacyDiagnostics [file_unique];
 				let dm = create DMNone in
 				let dm = create DMNone in
-				{dm with dms_display_file_policy = DFPAlso; dms_per_file = true; dms_populate_cache = !ServerConfig.populate_cache_from_display}
+				{dm with dms_display_file_policy = DFPOnly; dms_per_file = true; dms_populate_cache = !ServerConfig.populate_cache_from_display}
 			| "statistics" ->
 			| "statistics" ->
 				com.report_mode <- RMStatistics;
 				com.report_mode <- RMStatistics;
 				let dm = create DMNone in
 				let dm = create DMNone in
@@ -200,11 +200,11 @@ let load_display_module_in_macro tctx display_file_dot_path clear = match displa
 				begin try
 				begin try
 					let m = mctx.com.module_lut#find cpath in
 					let m = mctx.com.module_lut#find cpath in
 					mctx.com.module_lut#remove cpath;
 					mctx.com.module_lut#remove cpath;
-					mctx.com.type_to_module#remove cpath;
+					mctx.com.module_lut#get_type_lut#remove cpath;
 					List.iter (fun mt ->
 					List.iter (fun mt ->
 						let ti = Type.t_infos mt in
 						let ti = Type.t_infos mt in
 						mctx.com.module_lut#remove ti.mt_path;
 						mctx.com.module_lut#remove ti.mt_path;
-						mctx.com.type_to_module#remove ti.mt_path;
+						mctx.com.module_lut#get_type_lut#remove ti.mt_path;
 					) m.m_types
 					) m.m_types
 				with Not_found ->
 				with Not_found ->
 					()
 					()

+ 31 - 18
src/compiler/messageReporting.ml

@@ -65,13 +65,15 @@ let resolve_file ctx f =
 let error_printer file line = Printf.sprintf "%s:%d:" file line
 let error_printer file line = Printf.sprintf "%s:%d:" file line
 
 
 type error_context = {
 type error_context = {
+	absolute_positions : bool;
 	mutable last_positions : pos IntMap.t;
 	mutable last_positions : pos IntMap.t;
 	mutable max_lines : int IntMap.t;
 	mutable max_lines : int IntMap.t;
 	mutable gutter : int IntMap.t;
 	mutable gutter : int IntMap.t;
 	mutable previous : (pos * MessageSeverity.t * int) option;
 	mutable previous : (pos * MessageSeverity.t * int) option;
 }
 }
 
 
-let create_error_context () = {
+let create_error_context absolute_positions = {
+	absolute_positions = absolute_positions;
 	last_positions = IntMap.empty;
 	last_positions = IntMap.empty;
 	max_lines = IntMap.empty;
 	max_lines = IntMap.empty;
 	gutter = IntMap.empty;
 	gutter = IntMap.empty;
@@ -97,7 +99,10 @@ let compiler_pretty_message_string com ectx cm =
 				let f = Common.find_file com f in
 				let f = Common.find_file com f in
 				let l1, p1, l2, p2 = Lexer.get_pos_coords cm.cm_pos in
 				let l1, p1, l2, p2 = Lexer.get_pos_coords cm.cm_pos in
 				let lines = resolve_source f l1 p1 l2 p2 in
 				let lines = resolve_source f l1 p1 l2 p2 in
-				let epos = Lexer.get_error_pos error_printer cm.cm_pos in
+				let epos =
+					if ectx.absolute_positions then TPrinting.Printer.s_pos cm.cm_pos
+					else Lexer.get_error_pos error_printer cm.cm_pos
+				in
 				(l1, p1, l2, p2, epos, lines)
 				(l1, p1, l2, p2, epos, lines)
 			end with Not_found | Sys_error _ ->
 			end with Not_found | Sys_error _ ->
 				(1, 1, 1, 1, cm.cm_pos.pfile, [])
 				(1, 1, 1, 1, cm.cm_pos.pfile, [])
@@ -243,7 +248,7 @@ let compiler_pretty_message_string com ectx cm =
 		)
 		)
 	end
 	end
 
 
-let compiler_message_string cm =
+let compiler_message_string ectx cm =
 	let str = match cm.cm_severity with
 	let str = match cm.cm_severity with
 		| MessageSeverity.Warning -> "Warning : " ^ cm.cm_message
 		| MessageSeverity.Warning -> "Warning : " ^ cm.cm_message
 		| Information | Error | Hint -> cm.cm_message
 		| Information | Error | Hint -> cm.cm_message
@@ -252,7 +257,10 @@ let compiler_message_string cm =
 	if cm.cm_pos = null_pos then
 	if cm.cm_pos = null_pos then
 		Some str
 		Some str
 	else begin
 	else begin
-		let epos = Lexer.get_error_pos error_printer cm.cm_pos in
+		let epos =
+			if ectx.absolute_positions then TPrinting.Printer.s_pos cm.cm_pos
+			else Lexer.get_error_pos error_printer cm.cm_pos
+		in
 		let str =
 		let str =
 			let lines =
 			let lines =
 				match (ExtString.String.nsplit str "\n") with
 				match (ExtString.String.nsplit str "\n") with
@@ -264,7 +272,7 @@ let compiler_message_string cm =
 		Some (Printf.sprintf "%s : %s" epos str)
 		Some (Printf.sprintf "%s : %s" epos str)
 	end
 	end
 
 
-let compiler_indented_message_string cm =
+let compiler_indented_message_string ectx cm =
 	match cm.cm_message with
 	match cm.cm_message with
 	(* Filter some messages that don't add much when using this message renderer *)
 	(* Filter some messages that don't add much when using this message renderer *)
 	| "End of overload failure reasons" -> None
 	| "End of overload failure reasons" -> None
@@ -278,7 +286,10 @@ let compiler_indented_message_string cm =
 		if cm.cm_pos = null_pos then
 		if cm.cm_pos = null_pos then
 			Some str
 			Some str
 		else begin
 		else begin
-			let epos = Lexer.get_error_pos error_printer cm.cm_pos in
+			let epos =
+				if ectx.absolute_positions then TPrinting.Printer.s_pos cm.cm_pos
+				else Lexer.get_error_pos error_printer cm.cm_pos
+			in
 			let lines =
 			let lines =
 				match (ExtString.String.nsplit str "\n") with
 				match (ExtString.String.nsplit str "\n") with
 				| first :: rest -> (cm.cm_depth, first) :: List.map (fun msg -> (cm.cm_depth+1, msg)) rest
 				| first :: rest -> (cm.cm_depth, first) :: List.map (fun msg -> (cm.cm_depth+1, msg)) rest
@@ -299,10 +310,10 @@ let get_max_line max_lines messages =
 
 
 exception ConfigError of string
 exception ConfigError of string
 
 
-let get_formatter com ectx def default =
+let get_formatter com def default =
 	let format_mode = Define.defined_value_safe ~default com.defines def in
 	let format_mode = Define.defined_value_safe ~default com.defines def in
 	match format_mode with
 	match format_mode with
-		| "pretty" -> compiler_pretty_message_string com ectx
+		| "pretty" -> compiler_pretty_message_string com
 		| "indent" -> compiler_indented_message_string
 		| "indent" -> compiler_indented_message_string
 		| "classic" -> compiler_message_string
 		| "classic" -> compiler_message_string
 		| m -> begin
 		| m -> begin
@@ -318,11 +329,12 @@ let print_error (err : Error.error) =
 	!ret
 	!ret
 
 
 let format_messages com messages =
 let format_messages com messages =
-	let ectx = create_error_context () in
+	let absolute_positions = Define.defined com.defines Define.MessageAbsolutePositions in
+	let ectx = create_error_context absolute_positions in
 	ectx.max_lines <- get_max_line ectx.max_lines messages;
 	ectx.max_lines <- get_max_line ectx.max_lines messages;
-	let message_formatter = get_formatter com ectx Define.MessageReporting "classic" in
+	let message_formatter = get_formatter com Define.MessageReporting "classic" in
 	let lines = List.rev (
 	let lines = List.rev (
-		List.fold_left (fun lines cm -> match (message_formatter cm) with
+		List.fold_left (fun lines cm -> match (message_formatter ectx cm) with
 			| None -> lines
 			| None -> lines
 			| Some str -> str :: lines
 			| Some str -> str :: lines
 		) [] messages
 		) [] messages
@@ -330,18 +342,19 @@ let format_messages com messages =
 	ExtLib.String.join "\n" lines
 	ExtLib.String.join "\n" lines
 
 
 let display_messages ctx on_message = begin
 let display_messages ctx on_message = begin
-	let ectx = create_error_context () in
+	let absolute_positions = Define.defined ctx.com.defines Define.MessageAbsolutePositions in
+	let ectx = create_error_context absolute_positions in
 	ectx.max_lines <- get_max_line ectx.max_lines ctx.messages;
 	ectx.max_lines <- get_max_line ectx.max_lines ctx.messages;
 
 
-	let get_formatter _ _ def default =
-		try get_formatter ctx.com ectx def default
+	let get_formatter _ def default =
+		try get_formatter ctx.com def default
 		with | ConfigError s ->
 		with | ConfigError s ->
 			error ctx s null_pos;
 			error ctx s null_pos;
 			compiler_message_string
 			compiler_message_string
 	in
 	in
 
 
-	let message_formatter = get_formatter ctx.com ectx Define.MessageReporting "classic" in
-	let log_formatter = get_formatter ctx.com ectx Define.MessageLogFormat "indent" in
+	let message_formatter = get_formatter ctx.com Define.MessageReporting "classic" in
+	let log_formatter = get_formatter ctx.com Define.MessageLogFormat "indent" in
 
 
 	let log_messages = ref (Define.defined ctx.com.defines Define.MessageLogFile) in
 	let log_messages = ref (Define.defined ctx.com.defines Define.MessageLogFile) in
 	let log_message = ref None in
 	let log_message = ref None in
@@ -358,7 +371,7 @@ let display_messages ctx on_message = begin
 			in
 			in
 
 
 			log_message := (Some (fun msg ->
 			log_message := (Some (fun msg ->
-				match (log_formatter msg) with
+				match (log_formatter ectx msg) with
 					| None -> ()
 					| None -> ()
 					| Some str -> Rbuffer.add_string buf (str ^ "\n")));
 					| Some str -> Rbuffer.add_string buf (str ^ "\n")));
 
 
@@ -378,7 +391,7 @@ let display_messages ctx on_message = begin
 	List.iter (fun cm ->
 	List.iter (fun cm ->
 		if !log_messages then (Option.get !log_message) cm;
 		if !log_messages then (Option.get !log_message) cm;
 
 
-		match (message_formatter cm) with
+		match (message_formatter ectx cm) with
 			| None -> ()
 			| None -> ()
 			| Some str -> on_message cm.cm_severity str
 			| Some str -> on_message cm.cm_severity str
 	) (List.rev ctx.messages);
 	) (List.rev ctx.messages);

+ 12 - 2
src/compiler/server.ml

@@ -395,6 +395,16 @@ let check_module sctx ctx m p =
 	end;
 	end;
 	state
 	state
 
 
+let handle_cache_bound_objects com cbol =
+	DynArray.iter (function
+		| Resource(name,data) ->
+			Hashtbl.replace com.resources name data
+		| IncludeFile(file,position) ->
+			com.include_files <- (file,position) :: com.include_files
+		| Warning(w,msg,p) ->
+			com.warning w [] msg p
+	) cbol
+
 (* Adds module [m] and all its dependencies (recursively) from the cache to the current compilation
 (* Adds module [m] and all its dependencies (recursively) from the cache to the current compilation
    context. *)
    context. *)
 let add_modules sctx ctx m p =
 let add_modules sctx ctx m p =
@@ -404,7 +414,7 @@ let add_modules sctx ctx m p =
 			(match m0.m_extra.m_kind, m.m_extra.m_kind with
 			(match m0.m_extra.m_kind, m.m_extra.m_kind with
 			| MCode, MMacro | MMacro, MCode ->
 			| MCode, MMacro | MMacro, MCode ->
 				(* this was just a dependency to check : do not add to the context *)
 				(* this was just a dependency to check : do not add to the context *)
-				PMap.iter (Hashtbl.replace com.resources) m.m_extra.m_binded_res;
+				handle_cache_bound_objects com m.m_extra.m_cache_bound_objects;
 			| _ ->
 			| _ ->
 				m.m_extra.m_added <- ctx.com.compilation_step;
 				m.m_extra.m_added <- ctx.com.compilation_step;
 				ServerMessage.reusing com tabs m;
 				ServerMessage.reusing com tabs m;
@@ -412,7 +422,7 @@ let add_modules sctx ctx m p =
 					(t_infos t).mt_restore()
 					(t_infos t).mt_restore()
 				) m.m_types;
 				) m.m_types;
 				TypeloadModule.ModuleLevel.add_module ctx m p;
 				TypeloadModule.ModuleLevel.add_module ctx m p;
-				PMap.iter (Hashtbl.replace com.resources) m.m_extra.m_binded_res;
+				handle_cache_bound_objects com m.m_extra.m_cache_bound_objects;
 				PMap.iter (fun _ (sign,mpath) ->
 				PMap.iter (fun _ (sign,mpath) ->
 					let m2 = (com.cs#get_context sign)#find_module mpath in
 					let m2 = (com.cs#get_context sign)#find_module mpath in
 					add_modules (tabs ^ "  ") m0 m2
 					add_modules (tabs ^ "  ") m0 m2

+ 6 - 2
src/compiler/serverCompilationContext.ml

@@ -70,5 +70,9 @@ let ensure_macro_setup sctx =
 	end
 	end
 
 
 let cleanup () = match !MacroContext.macro_interp_cache with
 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 ->
+		()

+ 7 - 4
src/context/abstractCast.ml

@@ -88,7 +88,9 @@ and do_check_cast ctx uctx tleft eright p =
 					end
 					end
 				| TInst(c,tl), TFun _ when has_class_flag c CFunctionalInterface ->
 				| TInst(c,tl), TFun _ when has_class_flag c CFunctionalInterface ->
 					let cf = ctx.g.functional_interface_lut#find c.cl_path in
 					let cf = ctx.g.functional_interface_lut#find c.cl_path in
-					unify_raise_custom uctx eright.etype (apply_params c.cl_params tl cf.cf_type) p;
+					let map = apply_params c.cl_params tl in
+					let monos = Monomorph.spawn_constrained_monos map cf.cf_params in
+					unify_raise_custom uctx eright.etype (map (apply_params cf.cf_params monos cf.cf_type)) p;
 					eright
 					eright
 				| _ ->
 				| _ ->
 					raise Not_found
 					raise Not_found
@@ -119,10 +121,11 @@ let prepare_array_access_field ctx a pl cf p =
 	let monos = List.map (fun _ -> spawn_monomorph ctx p) cf.cf_params in
 	let monos = List.map (fun _ -> spawn_monomorph ctx p) cf.cf_params in
 	let map t = apply_params a.a_params pl (apply_params cf.cf_params monos t) in
 	let map t = apply_params a.a_params pl (apply_params cf.cf_params monos t) in
 	let check_constraints () =
 	let check_constraints () =
-		List.iter2 (fun m tp -> match follow tp.ttp_type with
-			| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
+		List.iter2 (fun m ttp -> match get_constraints ttp with
+			| [] ->
+				()
+			| constr ->
 				List.iter (fun tc -> match follow m with TMono _ -> raise (Unify_error []) | _ -> Type.unify m (map tc) ) constr
 				List.iter (fun tc -> match follow m with TMono _ -> raise (Unify_error []) | _ -> Type.unify m (map tc) ) constr
-			| _ -> ()
 		) monos cf.cf_params;
 		) monos cf.cf_params;
 	in
 	in
 	let get_ta() =
 	let get_ta() =

+ 54 - 167
src/context/common.ml

@@ -20,6 +20,7 @@ open Extlib_leftovers
 open Ast
 open Ast
 open Type
 open Type
 open Globals
 open Globals
+open Lookup
 open Define
 open Define
 open NativeLibraries
 open NativeLibraries
 open Warning
 open Warning
@@ -293,66 +294,44 @@ type report_mode =
 	| RMDiagnostics of (Path.UniqueKey.t list)
 	| RMDiagnostics of (Path.UniqueKey.t list)
 	| RMStatistics
 	| RMStatistics
 
 
-class virtual ['key,'value] lookup = object(self)
-	method virtual add : 'key -> 'value -> unit
-	method virtual remove : 'key -> unit
-	method virtual find : 'key -> 'value
-	method virtual iter : ('key -> 'value -> unit) -> unit
-	method virtual fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc
-	method virtual mem : 'key -> bool
-	method virtual clear : unit
-end
-
-class ['key,'value] pmap_lookup = object(self)
-	inherit ['key,'value] lookup
-	val mutable lut : ('key,'value) PMap.t = PMap.empty
-
-	method add (key : 'key) (value : 'value) =
-		lut <- PMap.add key value lut
-
-	method remove (key : 'key) =
-		lut <- PMap.remove key lut
-
-	method find (key : 'key) : 'value =
-		PMap.find key lut
-
-	method iter (f : 'key -> 'value -> unit) =
-		PMap.iter f lut
-
-	method fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc = fun f acc ->
-		PMap.foldi f lut acc
+class module_lut = object(self)
+	inherit [path,module_def] hashtbl_lookup as super
 
 
-	method mem (key : 'key) =
-		PMap.mem key lut
+	val type_lut : (path,path) lookup = new hashtbl_lookup
 
 
-	method clear =
-		lut <- PMap.empty
-end
-
-class ['key,'value] hashtbl_lookup = object(self)
-	inherit ['key,'value] lookup
-	val lut : ('key,'value) Hashtbl.t = Hashtbl.create 0
-
-	method add (key : 'key) (value : 'value) =
-		Hashtbl.replace lut key value
-
-	method remove (key : 'key) =
-		Hashtbl.remove lut key
+	method add_module_type (m : module_def) (mt : module_type) =
+		let t = t_infos mt in
+		try
+			let path2 = type_lut#find t.mt_path in
+			let p = t.mt_pos in
+			if m.m_path <> path2 && String.lowercase_ascii (s_type_path path2) = String.lowercase_ascii (s_type_path m.m_path) then Error.raise_typing_error ("Module " ^ s_type_path path2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p;
+			let m2 = self#find path2 in
+			let hex1 = Digest.to_hex m.m_extra.m_sign in
+			let hex2 = Digest.to_hex m2.m_extra.m_sign in
+			let s = if hex1 = hex2 then hex1 else Printf.sprintf "was %s, is %s" hex2 hex1 in
+			Error.raise_typing_error (Printf.sprintf "Type name %s is redefined from module %s (%s)" (s_type_path t.mt_path)  (s_type_path path2) s) p
+		with Not_found ->
+			type_lut#add t.mt_path m.m_path
 
 
-	method find (key : 'key) : 'value =
-		Hashtbl.find lut key
+	method! add (path : path) (m : module_def) =
+		super#add path m;
+		List.iter (fun mt -> self#add_module_type m mt) m.m_types
 
 
-	method iter (f : 'key -> 'value -> unit) =
-		Hashtbl.iter f lut
+	method! remove (path : path) =
+		try
+			List.iter (fun mt -> type_lut#remove (t_path mt)) (self#find path).m_types;
+			super#remove path;
+		with Not_found ->
+			()
 
 
-	method fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc = fun f acc ->
-		Hashtbl.fold f lut acc
+	method find_by_type (path : path) =
+		self#find (type_lut#find path)
 
 
-	method mem (key : 'key) =
-		Hashtbl.mem lut key
+	method! clear =
+		super#clear;
+		type_lut#clear
 
 
-	method clear =
-		Hashtbl.clear lut
+	method get_type_lut = type_lut
 end
 end
 
 
 type context = {
 type context = {
@@ -408,9 +387,8 @@ type context = {
 	cached_macros : (path * string,(((string * bool * t) list * t * tclass * Type.tclass_field) * module_def)) lookup;
 	cached_macros : (path * string,(((string * bool * t) list * t * tclass * Type.tclass_field) * module_def)) lookup;
 	stored_typed_exprs : (int, texpr) lookup;
 	stored_typed_exprs : (int, texpr) lookup;
 	overload_cache : ((path * string),(Type.t * tclass_field) list) lookup;
 	overload_cache : ((path * string),(Type.t * tclass_field) list) lookup;
-	module_lut : (path,module_def) lookup;
+	module_lut : module_lut;
 	module_nonexistent_lut : (path,bool) lookup;
 	module_nonexistent_lut : (path,bool) lookup;
-	type_to_module : (path,path) lookup;
 	mutable has_error : bool;
 	mutable has_error : bool;
 	pass_debug_messages : string DynArray.t;
 	pass_debug_messages : string DynArray.t;
 	(* output *)
 	(* output *)
@@ -443,6 +421,10 @@ let ignore_error com =
 	if b then com.has_error <- true;
 	if b then com.has_error <- true;
 	b
 	b
 
 
+let module_warning com m w options msg p =
+	DynArray.add m.m_extra.m_cache_bound_objects (Warning(w,msg,p));
+	com.warning w options msg p
+
 (* Defines *)
 (* Defines *)
 
 
 module Define = Define
 module Define = Define
@@ -761,8 +743,7 @@ let get_config com =
 
 
 let memory_marker = [|Unix.time()|]
 let memory_marker = [|Unix.time()|]
 
 
-let create compilation_step cs version args =
-	let m = Type.mk_mono() in
+let create compilation_step cs version args display_mode =
 	let rec com = {
 	let rec com = {
 		compilation_step = compilation_step;
 		compilation_step = compilation_step;
 		cs = cs;
 		cs = cs;
@@ -782,7 +763,7 @@ let create compilation_step cs version args =
 		};
 		};
 		sys_args = args;
 		sys_args = args;
 		debug = false;
 		debug = false;
-		display = DisplayTypes.DisplayMode.create !Parser.display_mode;
+		display = display_mode;
 		verbose = false;
 		verbose = false;
 		foptimize = true;
 		foptimize = true;
 		features = Hashtbl.create 0;
 		features = Hashtbl.create 0;
@@ -800,9 +781,8 @@ let create compilation_step cs version args =
 		callbacks = new compiler_callbacks;
 		callbacks = new compiler_callbacks;
 		global_metadata = [];
 		global_metadata = [];
 		modules = [];
 		modules = [];
-		module_lut = new hashtbl_lookup;
+		module_lut = new module_lut;
 		module_nonexistent_lut = new hashtbl_lookup;
 		module_nonexistent_lut = new hashtbl_lookup;
-		type_to_module = new hashtbl_lookup;
 		main = None;
 		main = None;
 		flash_version = 10.;
 		flash_version = 10.;
 		resources = Hashtbl.create 0;
 		resources = Hashtbl.create 0;
@@ -830,12 +810,12 @@ let create compilation_step cs version args =
 		filter_messages = (fun _ -> ());
 		filter_messages = (fun _ -> ());
 		pass_debug_messages = DynArray.create();
 		pass_debug_messages = DynArray.create();
 		basic = {
 		basic = {
-			tvoid = m;
-			tint = m;
-			tfloat = m;
-			tbool = m;
+			tvoid = mk_mono();
+			tint = mk_mono();
+			tfloat = mk_mono();
+			tbool = mk_mono();
+			tstring = mk_mono();
 			tnull = (fun _ -> die "Could use locate abstract Null<T> (was it redefined?)" __LOC__);
 			tnull = (fun _ -> die "Could use locate abstract Null<T> (was it redefined?)" __LOC__);
-			tstring = m;
 			tarray = (fun _ -> die "Could not locate class Array<T> (was it redefined?)" __LOC__);
 			tarray = (fun _ -> die "Could not locate class Array<T> (was it redefined?)" __LOC__);
 		};
 		};
 		file_lookup_cache = new hashtbl_lookup;
 		file_lookup_cache = new hashtbl_lookup;
@@ -871,7 +851,12 @@ let clone com is_macro_context =
 	let t = com.basic in
 	let t = com.basic in
 	{ com with
 	{ com with
 		cache = None;
 		cache = None;
-		basic = { t with tvoid = t.tvoid };
+		basic = { t with
+			tint = mk_mono();
+			tfloat = mk_mono();
+			tbool = mk_mono();
+			tstring = mk_mono();
+		};
 		main_class = None;
 		main_class = None;
 		features = Hashtbl.create 0;
 		features = Hashtbl.create 0;
 		callbacks = new compiler_callbacks;
 		callbacks = new compiler_callbacks;
@@ -891,8 +876,7 @@ let clone com is_macro_context =
 		parser_cache = new hashtbl_lookup;
 		parser_cache = new hashtbl_lookup;
 		module_to_file = new hashtbl_lookup;
 		module_to_file = new hashtbl_lookup;
 		overload_cache = new hashtbl_lookup;
 		overload_cache = new hashtbl_lookup;
-		module_lut = new hashtbl_lookup;
-		type_to_module = new hashtbl_lookup;
+		module_lut = new module_lut;
 	}
 	}
 
 
 let file_time file = Extc.filetime file
 let file_time file = Extc.filetime file
@@ -1106,7 +1090,7 @@ let cache_directory ctx class_path dir f_dir =
 	in
 	in
 	Option.may (Array.iter prepare_file) dir_listing
 	Option.may (Array.iter prepare_file) dir_listing
 
 
-let find_file ctx f =
+let find_file ctx ?(class_path=ctx.class_path) f =
 	try
 	try
 		match ctx.file_lookup_cache#find f with
 		match ctx.file_lookup_cache#find f with
 		| None -> raise Exit
 		| None -> raise Exit
@@ -1141,7 +1125,7 @@ let find_file ctx f =
 						loop (had_empty || p = "") l
 						loop (had_empty || p = "") l
 				end
 				end
 		in
 		in
-		let r = try Some (loop false ctx.class_path) with Not_found -> None in
+		let r = try Some (loop false class_path) with Not_found -> None in
 		ctx.file_lookup_cache#add f r;
 		ctx.file_lookup_cache#add f r;
 		match r with
 		match r with
 		| None -> raise Not_found
 		| None -> raise Not_found
@@ -1297,100 +1281,3 @@ let get_entry_point com =
 		let e = Option.get com.main in (* must be present at this point *)
 		let e = Option.get com.main in (* must be present at this point *)
 		(snd path, c, e)
 		(snd path, c, e)
 	) com.main_class
 	) 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
-

+ 6 - 3
src/context/display/deprecationCheck.ml

@@ -7,12 +7,14 @@ type deprecation_context = {
 	com        : Common.context;
 	com        : Common.context;
 	class_meta : metadata_entry list;
 	class_meta : metadata_entry list;
 	field_meta : metadata_entry list;
 	field_meta : metadata_entry list;
+	curmod     : module_def;
 }
 }
 
 
 let create_context com = {
 let create_context com = {
 	com = com;
 	com = com;
 	class_meta = [];
 	class_meta = [];
 	field_meta = [];
 	field_meta = [];
+	curmod = null_module;
 }
 }
 
 
 let warned_positions = Hashtbl.create 0
 let warned_positions = Hashtbl.create 0
@@ -23,7 +25,7 @@ let warn_deprecation dctx s p_usage =
 		Hashtbl.add warned_positions (pkey p_usage) (s,p_usage);
 		Hashtbl.add warned_positions (pkey p_usage) (s,p_usage);
 		if not (is_diagnostics dctx.com) then begin
 		if not (is_diagnostics dctx.com) then begin
 			let options = Warning.from_meta (dctx.class_meta @ dctx.field_meta) in
 			let options = Warning.from_meta (dctx.class_meta @ dctx.field_meta) in
-			dctx.com.warning WDeprecated options s p_usage;
+			module_warning dctx.com dctx.curmod WDeprecated options s p_usage;
 		end
 		end
 	end
 	end
 
 
@@ -103,7 +105,7 @@ let run com =
 	let dctx = create_context com in
 	let dctx = create_context com in
 	List.iter (fun t -> match t with
 	List.iter (fun t -> match t with
 		| TClassDecl c when not (Meta.has Meta.Deprecated c.cl_meta) ->
 		| TClassDecl c when not (Meta.has Meta.Deprecated c.cl_meta) ->
-			let dctx = {dctx with class_meta = c.cl_meta} in
+			let dctx = {dctx with class_meta = c.cl_meta; curmod = c.cl_module} in
 			(match c.cl_constructor with None -> () | Some cf -> run_on_field dctx cf);
 			(match c.cl_constructor with None -> () | Some cf -> run_on_field dctx cf);
 			(match c.cl_init with None -> () | Some e -> run_on_expr dctx e);
 			(match c.cl_init with None -> () | Some e -> run_on_expr dctx e);
 			List.iter (run_on_field dctx) c.cl_ordered_statics;
 			List.iter (run_on_field dctx) c.cl_ordered_statics;
@@ -112,11 +114,12 @@ let run com =
 			()
 			()
 	) com.types
 	) com.types
 
 
-let check_is com cl_meta cf_meta name meta p =
+let check_is com m cl_meta cf_meta name meta p =
 	let dctx = {
 	let dctx = {
 		com = com;
 		com = com;
 		class_meta = cl_meta;
 		class_meta = cl_meta;
 		field_meta = cf_meta;
 		field_meta = cf_meta;
+		curmod = m;
 	} in
 	} in
 	if is_next dctx.com && name = "is" && not (Meta.has Meta.Deprecated meta) then
 	if is_next dctx.com && name = "is" && not (Meta.has Meta.Deprecated meta) then
 		warn_deprecation dctx "Using \"is\" as an identifier is deprecated" p
 		warn_deprecation dctx "Using \"is\" as an identifier is deprecated" p

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

@@ -30,233 +30,10 @@ module ReferencePosition = struct
 	let reset () = reference_position := ("",null_pos,SKOther)
 	let reset () = reference_position := ("",null_pos,SKOther)
 end
 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
 let get_expected_name with_type = match with_type with
 	| WithType.Value (Some src) | WithType.WithType(_,Some src) ->
 	| 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;
 		if display_position#enclosed_in p then display_meta ctx.com meta p;
 		List.iter (fun e ->
 		List.iter (fun e ->
 			if display_position#enclosed_in (pos e) then begin
 			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));
 				delay ctx PTypeField (fun _ -> ignore(type_expr ctx e WithType.value));
 			end
 			end
 		) args
 		) args

+ 6 - 5
src/context/display/displayFields.ml

@@ -56,10 +56,11 @@ let collect_static_extensions ctx items e p =
 		| TFun((_,_,t) :: args, ret) ->
 		| TFun((_,_,t) :: args, ret) ->
 			begin try
 			begin try
 				let e = TyperBase.unify_static_extension ctx {e with etype = dup e.etype} t p in
 				let e = TyperBase.unify_static_extension ctx {e with etype = dup e.etype} t p in
-				List.iter2 (fun m tp -> match follow tp.ttp_type with
-					| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
+				List.iter2 (fun m ttp -> match get_constraints ttp with
+					| [] ->
+						()
+					| constr ->
 						List.iter (fun tc -> unify_raise m (map tc) e.epos) constr
 						List.iter (fun tc -> unify_raise m (map tc) e.epos) constr
-					| _ -> ()
 				) monos f.cf_params;
 				) monos f.cf_params;
 				if not (can_access ctx c f true) || follow e.etype == t_dynamic && follow t != t_dynamic then
 				if not (can_access ctx c f true) || follow e.etype == t_dynamic && follow t != t_dynamic then
 					acc
 					acc
@@ -157,9 +158,9 @@ let collect ctx e_ast e dk with_type p =
 				List.fold_left fold_constraints items l
 				List.fold_left fold_constraints items l
 			in
 			in
 			fold_constraints items (Monomorph.classify_down_constraints m)
 			fold_constraints items (Monomorph.classify_down_constraints m)
-		| TInst ({cl_kind = KTypeParameter tl},_) ->
+		| TInst ({cl_kind = KTypeParameter ttp},_) ->
 			(* Type parameters can access the fields of their constraints *)
 			(* Type parameters can access the fields of their constraints *)
-			List.fold_left (fun acc t -> loop acc t) items tl
+			List.fold_left (fun acc t -> loop acc t) items (get_constraints ttp)
 		| TInst(c0,tl) ->
 		| TInst(c0,tl) ->
 			(* For classes, browse the hierarchy *)
 			(* For classes, browse the hierarchy *)
 			let fields = TClass.get_all_fields c0 tl in
 			let fields = TClass.get_all_fields c0 tl in

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

@@ -378,7 +378,7 @@ let handler =
 			let file = hctx.jsonrpc#get_string_param "file" in
 			let file = hctx.jsonrpc#get_string_param "file" in
 			let fkey = hctx.com.file_keys#get file in
 			let fkey = hctx.com.file_keys#get file in
 			let cs = hctx.display#get_cs in
 			let cs = hctx.display#get_cs in
-			cs#taint_modules fkey "server/invalidate";
+			cs#taint_modules fkey ServerInvalidate;
 			cs#remove_files fkey;
 			cs#remove_files fkey;
 			hctx.send_result jnull
 			hctx.send_result jnull
 		);
 		);

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

@@ -178,7 +178,7 @@ let check_display_file ctx cs =
 			let fkey = DisplayPosition.display_position#get_file_key in
 			let fkey = DisplayPosition.display_position#get_file_key in
 			(* force parsing again : if the completion point have been changed *)
 			(* force parsing again : if the completion point have been changed *)
 			cs#remove_files fkey;
 			cs#remove_files fkey;
-			cs#taint_modules fkey "check_display_file";
+			cs#taint_modules fkey CheckDisplayFile;
 		end
 		end
 	| None ->
 	| None ->
 		()
 		()

+ 2 - 4
src/context/display/displayToplevel.ml

@@ -449,10 +449,8 @@ let collect ctx tk with_type sort =
 	end;
 	end;
 
 
 	(* type params *)
 	(* type params *)
-	List.iter (fun tp -> match follow tp.ttp_type with
-		| TInst(c,_) ->
-			add (make_ci_type_param c (tpair tp.ttp_type)) (Some (snd c.cl_path))
-		| _ -> die "" __LOC__
+	List.iter (fun tp ->
+		add (make_ci_type_param tp.ttp_class (tpair tp.ttp_type)) (Some (snd tp.ttp_class.cl_path))
 	) ctx.type_params;
 	) ctx.type_params;
 
 
 	(* module types *)
 	(* module types *)

+ 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

+ 11 - 0
src/context/feature.ml

@@ -0,0 +1,11 @@
+open Ast
+open Type
+open Error
+
+let rec check_if_feature = function
+	| [] -> []
+	| (Meta.IfFeature,el,_) :: _ -> List.map (fun (e,p) -> match e with EConst (String(s,_)) -> s | _ -> raise_typing_error "String expected" p) el
+	| _ :: l -> check_if_feature l
+
+let set_feature m cf_ref s =
+	m.m_extra.m_if_feature <- (s, cf_ref) :: m.m_extra.m_if_feature

+ 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

+ 113 - 0
src/context/lookup.ml

@@ -0,0 +1,113 @@
+
+class virtual ['key,'value] lookup = object(self)
+	method virtual add : 'key -> 'value -> unit
+	method virtual remove : 'key -> unit
+	method virtual find : 'key -> 'value
+	method virtual iter : ('key -> 'value -> unit) -> unit
+	method virtual fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc
+	method virtual mem : 'key -> bool
+	method virtual clear : unit
+
+	method virtual start_group : int
+	method virtual commit_group : int -> int
+	method virtual discard_group : int -> int
+end
+
+class ['key,'value] pmap_lookup = object(self)
+	inherit ['key,'value] lookup
+	val mutable lut : ('key,'value) PMap.t = PMap.empty
+
+	val mutable group_id : int ref = ref 0
+	val mutable groups : (int,'key list) PMap.t = PMap.empty
+
+	method add (key : 'key) (value : 'value) =
+		groups <- PMap.map (fun modules -> key :: modules) groups;
+		lut <- PMap.add key value lut
+
+	method remove (key : 'key) =
+		lut <- PMap.remove key lut
+
+	method find (key : 'key) : 'value =
+		PMap.find key lut
+
+	method iter (f : 'key -> 'value -> unit) =
+		PMap.iter f lut
+
+	method fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc = fun f acc ->
+		PMap.foldi f lut acc
+
+	method mem (key : 'key) =
+		PMap.mem key lut
+
+	method clear =
+		lut <- PMap.empty
+
+	method start_group =
+		incr group_id;
+		let i = !group_id in
+		groups <- PMap.add i [] groups;
+		i
+
+	method commit_group i =
+		let group = PMap.find i groups in
+		let n = List.length group in
+		groups <- PMap.remove i groups;
+		n
+
+	method discard_group i =
+		let group = PMap.find i groups in
+		let n = List.length group in
+		List.iter (fun mpath -> self#remove mpath) group;
+		groups <- PMap.remove i groups;
+		n
+end
+
+class ['key,'value] hashtbl_lookup = object(self)
+	inherit ['key,'value] lookup
+	val lut : ('key,'value) Hashtbl.t = Hashtbl.create 0
+
+	val mutable group_id : int ref = ref 0
+	val mutable groups : (int,'key list) Hashtbl.t = Hashtbl.create 0
+
+	method add (key : 'key) (value : 'value) =
+		Hashtbl.iter (fun i modules -> Hashtbl.replace groups i (key :: modules)) groups;
+		Hashtbl.replace lut key value
+
+	method remove (key : 'key) =
+		Hashtbl.remove lut key
+
+	method find (key : 'key) : 'value =
+		Hashtbl.find lut key
+
+	method iter (f : 'key -> 'value -> unit) =
+		Hashtbl.iter f lut
+
+	method fold : 'acc . ('key -> 'value -> 'acc -> 'acc) -> 'acc -> 'acc = fun f acc ->
+		Hashtbl.fold f lut acc
+
+	method mem (key : 'key) =
+		Hashtbl.mem lut key
+
+	method clear =
+		Hashtbl.clear lut
+
+	method start_group =
+		incr group_id;
+		let i = !group_id in
+		Hashtbl.replace groups i [];
+		i
+
+	method commit_group i =
+		let group = Hashtbl.find groups i in
+		let n = List.length group in
+		Hashtbl.remove groups i;
+		n
+
+	method discard_group i =
+		let group = Hashtbl.find groups i in
+		let n = List.length group in
+		List.iter (fun mpath -> self#remove mpath) group;
+		Hashtbl.remove groups i;
+		n
+end
+

+ 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));
 				"nativeLibCache",jint (mem_size cache_mem.(3));
 				"additionalSizes",jarray [
 				"additionalSizes",jarray [
 					jobject ["name",jstring "macro interpreter";"size",jint (mem_size (MacroContext.macro_interp_cache))];
 					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 "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 "Lexer file cache";"size",jint (mem_size (Lexer.all_files))];
 					jobject ["name",jstring "GC heap words";"size",jint (int_of_float size)];
 					jobject ["name",jstring "GC heap words";"size",jint (int_of_float size)];

+ 14 - 48
src/context/typecore.ml

@@ -20,9 +20,11 @@
 open Globals
 open Globals
 open Ast
 open Ast
 open Common
 open Common
+open Lookup
 open Type
 open Type
 open Error
 open Error
 open Resolution
 open Resolution
+open FieldCallCandidate
 
 
 type type_patch = {
 type type_patch = {
 	mutable tp_type : complex_type option;
 	mutable tp_type : complex_type option;
@@ -98,7 +100,8 @@ type typer_globals = {
 	retain_meta : bool;
 	retain_meta : bool;
 	mutable core_api : typer option;
 	mutable core_api : typer option;
 	mutable macros : ((unit -> unit) * 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;
 	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 module_check_policies : (string list * module_check_policy list * bool) list;
 	mutable global_using : (tclass * pos) list;
 	mutable global_using : (tclass * pos) list;
@@ -162,24 +165,6 @@ and monomorphs = {
 	mutable perfunction : (tmono * pos) list;
 	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 =
 type field_host =
 	| FHStatic of tclass
 	| FHStatic of tclass
 	| FHInstance of tclass * tparams
 	| FHInstance of tclass * tparams
@@ -256,7 +241,11 @@ let pass_name = function
 
 
 let warning ?(depth=0) ctx w msg p =
 let warning ?(depth=0) ctx w msg p =
 	let options = (Warning.from_meta ctx.curclass.cl_meta) @ (Warning.from_meta ctx.curfield.cf_meta) in
 	let options = (Warning.from_meta ctx.curclass.cl_meta) @ (Warning.from_meta ctx.curfield.cf_meta) in
-	ctx.com.warning ~depth w options msg p
+	match Warning.get_mode w options with
+	| WMEnable ->
+		module_warning ctx.com ctx.m.curmod w options msg p
+	| WMDisable ->
+		()
 
 
 let make_call ctx e el t p = (!make_call_ref) ctx e el t p
 let make_call ctx e el t p = (!make_call_ref) ctx e el t p
 
 
@@ -273,12 +262,8 @@ let spawn_monomorph' ctx p =
 let spawn_monomorph ctx p =
 let spawn_monomorph ctx p =
 	TMono (spawn_monomorph' ctx p)
 	TMono (spawn_monomorph' ctx p)
 
 
-let make_static_this c p =
-	let ta = mk_anon ~fields:c.cl_statics (ref (ClassStatics c)) in
-	mk (TTypeExpr (TClassDecl c)) ta p
-
 let make_static_field_access c cf t p =
 let make_static_field_access c cf t p =
-	let ethis = make_static_this c p in
+	let ethis = Texpr.Builder.make_static_this c p in
 	mk (TField (ethis,(FStatic (c,cf)))) t p
 	mk (TField (ethis,(FStatic (c,cf)))) t p
 
 
 let make_static_call ctx c cf map args t p =
 let make_static_call ctx c cf map args t p =
@@ -495,7 +480,7 @@ let create_fake_module ctx file =
 			m_path = (["$DEP"],file);
 			m_path = (["$DEP"],file);
 			m_types = [];
 			m_types = [];
 			m_statics = None;
 			m_statics = None;
-			m_extra = module_extra file (Define.get_signature ctx.com.defines) (file_time file) MFake [];
+			m_extra = module_extra file (Define.get_signature ctx.com.defines) (file_time file) MFake ctx.com.compilation_step [];
 		} in
 		} in
 		Hashtbl.add fake_modules key mdep;
 		Hashtbl.add fake_modules key mdep;
 		mdep
 		mdep
@@ -616,8 +601,8 @@ let can_access ctx c cf stat =
 	loop c
 	loop c
 	(* access is also allowed of we access a type parameter which is constrained to our (base) class *)
 	(* access is also allowed of we access a type parameter which is constrained to our (base) class *)
 	|| (match c.cl_kind with
 	|| (match c.cl_kind with
-		| KTypeParameter tl ->
-			List.exists (fun t -> match follow t with TInst(c,_) -> loop c | _ -> false) tl
+		| KTypeParameter ttp ->
+			List.exists (fun t -> match follow t with TInst(c,_) -> loop c | _ -> false) (get_constraints ttp)
 		| _ -> false)
 		| _ -> false)
 	|| (Meta.has Meta.PrivateAccess ctx.meta)
 	|| (Meta.has Meta.PrivateAccess ctx.meta)
 
 
@@ -698,26 +683,6 @@ let safe_mono_close ctx m p =
 		Unify_error l ->
 		Unify_error l ->
 			raise_or_display ctx l p
 			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 relative_path ctx file =
 	let slashes path = String.concat "/" (ExtString.String.nsplit path "\\") in
 	let slashes path = String.concat "/" (ExtString.String.nsplit path "\\") in
 	let fpath = slashes (Path.get_full_path file) in
 	let fpath = slashes (Path.get_full_path file) in
@@ -790,6 +755,7 @@ let create_deprecation_context ctx = {
 	(DeprecationCheck.create_context ctx.com) with
 	(DeprecationCheck.create_context ctx.com) with
 	class_meta = ctx.curclass.cl_meta;
 	class_meta = ctx.curclass.cl_meta;
 	field_meta = ctx.curfield.cf_meta;
 	field_meta = ctx.curfield.cf_meta;
+	curmod = ctx.m.curmod;
 }
 }
 
 
 (* -------------- debug functions to activate when debugging typer passes ------------------------------- *)
 (* -------------- debug functions to activate when debugging typer passes ------------------------------- *)

+ 13 - 0
src/core/ast.ml

@@ -863,6 +863,19 @@ let iter_expr loop (e,p) =
 		opt f.f_expr
 		opt f.f_expr
 	| EVars vl -> List.iter (fun v -> opt v.ev_expr) vl
 	| EVars vl -> List.iter (fun v -> opt v.ev_expr) vl
 
 
+let exists check e =
+	let rec loop (e,p) =
+		if check e then
+			raise Exit
+		else
+			iter_expr loop (e,p)
+	in
+	try
+		loop e;
+		false
+	with Exit ->
+		true
+
 let s_object_key_name name =  function
 let s_object_key_name name =  function
 	| DoubleQuotes -> "\"" ^ StringHelper.s_escape name ^ "\""
 	| DoubleQuotes -> "\"" ^ StringHelper.s_escape name ^ "\""
 	| NoQuotes -> name
 	| NoQuotes -> name

+ 6 - 8
src/core/display/completionItem.ml

@@ -223,16 +223,14 @@ module CompletionModuleType = struct
 		in
 		in
 		let is_extern,is_final,is_abstract,kind,ctor = ctor_info mt in
 		let is_extern,is_final,is_abstract,kind,ctor = ctor_info mt in
 		let infos = t_infos mt in
 		let infos = t_infos mt in
-		let convert_type_param tp = match follow tp.ttp_type with
-			| TInst(c,_) -> {
-				tp_name = tp.ttp_name,null_pos;
+		let convert_type_param ttp =
+			{
+				tp_name = ttp.ttp_name,null_pos;
 				tp_params = [];
 				tp_params = [];
 				tp_constraints = None; (* TODO? *)
 				tp_constraints = None; (* TODO? *)
 				tp_default = None; (* TODO? *)
 				tp_default = None; (* TODO? *)
-				tp_meta = c.cl_meta
+				tp_meta = ttp.ttp_class.cl_meta
 			}
 			}
-			| _ ->
-				die "" __LOC__
 		in
 		in
 		{
 		{
 			pack = fst infos.mt_path;
 			pack = fst infos.mt_path;
@@ -784,11 +782,11 @@ let to_json ctx index item =
 		| ITExpression e -> "Expression",generate_texpr ctx e
 		| ITExpression e -> "Expression",generate_texpr ctx e
 		| ITTypeParameter c ->
 		| ITTypeParameter c ->
 			begin match c.cl_kind with
 			begin match c.cl_kind with
-			| KTypeParameter tl ->
+			| KTypeParameter ttp ->
 				"TypeParameter",jobject [
 				"TypeParameter",jobject [
 					"name",jstring (snd c.cl_path);
 					"name",jstring (snd c.cl_path);
 					"meta",generate_metadata ctx c.cl_meta;
 					"meta",generate_metadata ctx c.cl_meta;
-					"constraints",jlist (generate_type ctx) tl;
+					"constraints",jlist (generate_type ctx) (get_constraints ttp);
 				]
 				]
 			| _ -> die "" __LOC__
 			| _ -> die "" __LOC__
 			end
 			end

+ 1 - 1
src/core/displayTypes.ml

@@ -352,4 +352,4 @@ type display_exception_kind =
 	| DisplayPositions of pos list
 	| DisplayPositions of pos list
 	| DisplayFields of fields_result
 	| DisplayFields of fields_result
 	| DisplayPackage of string list
 	| DisplayPackage of string list
-	| DisplayNoResult
+	| DisplayNoResult

+ 8 - 2
src/core/globals.ml

@@ -167,8 +167,14 @@ let die ?p msg ml_loc =
 	in
 	in
 	let ver = s_version_full
 	let ver = s_version_full
 	and os_type = if Sys.unix then "unix" else "windows" in
 	and os_type = if Sys.unix then "unix" else "windows" in
-	Printf.eprintf "%s\nHaxe: %s; OS type: %s;\n%s\n%s" msg ver os_type ml_loc backtrace;
-	assert false
+	let s = Printf.sprintf "%s\nHaxe: %s; OS type: %s;\n%s\n%s" msg ver os_type ml_loc backtrace in
+	failwith s
+
+let dump_callstack () =
+	print_endline (Printexc.raw_backtrace_to_string (Printexc.get_callstack 200))
+
+let dump_backtrace () =
+	print_endline (Printexc.raw_backtrace_to_string (Printexc.get_raw_backtrace ()))
 
 
 module MessageSeverity = struct
 module MessageSeverity = struct
 	type t =
 	type t =

+ 5 - 9
src/core/json/genjson.ml

@@ -276,15 +276,11 @@ and generate_type_path_with_params ctx mpath tpath tl meta =
 
 
 (* type parameter *)
 (* type parameter *)
 
 
-and generate_type_parameter ctx tp =
-	let generate_constraints () = match follow tp.ttp_type with
-		| TInst({cl_kind = KTypeParameter tl},_) -> generate_types ctx tl
-		| _ -> die "" __LOC__
-	in
+and generate_type_parameter ctx ttp =
 	jobject [
 	jobject [
-		"name",jstring tp.ttp_name;
-		"constraints",generate_constraints ();
-		"defaultType",jopt (generate_type ctx) tp.ttp_default;
+		"name",jstring ttp.ttp_name;
+		"constraints",generate_types ctx (get_constraints ttp);
+		"defaultType",jopt (generate_type ctx) ttp.ttp_default;
 	]
 	]
 
 
 (* texpr *)
 (* texpr *)
@@ -602,7 +598,7 @@ let generate_class ctx c =
 	let generate_class_kind ck =
 	let generate_class_kind ck =
 		let ctor,args = match ck with
 		let ctor,args = match ck with
 		| KNormal -> "KNormal",None
 		| KNormal -> "KNormal",None
-		| KTypeParameter tl -> "KTypeParameter",Some (generate_types ctx tl)
+		| KTypeParameter ttp -> "KTypeParameter",Some (generate_types ctx (get_constraints ttp))
 		| KExpr e -> "KExpr",Some (generate_expr ctx e)
 		| KExpr e -> "KExpr",Some (generate_expr ctx e)
 		| KGeneric -> "KGeneric",None
 		| KGeneric -> "KGeneric",None
 		| KGenericInstance(c,tl) -> "KGenericInstance",Some (generate_type_path_with_params ctx c.cl_module.m_path c.cl_path tl c.cl_meta)
 		| KGenericInstance(c,tl) -> "KGenericInstance",Some (generate_type_path_with_params ctx c.cl_module.m_path c.cl_path tl c.cl_meta)

+ 86 - 0
src/core/naming.ml

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

+ 12 - 1
src/core/socket.ml

@@ -37,6 +37,17 @@ let read_string socket =
 			let _ = recv socket buf 0 i [] in
 			let _ = recv socket buf 0 i [] in
 			Bytes.to_string buf
 			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 =
 let send_string socket s =
 	match socket.socket with
 	match socket.socket with
 	| None ->
 	| None ->
@@ -45,7 +56,7 @@ let send_string socket s =
 		let b = Bytes.unsafe_of_string s in
 		let b = Bytes.unsafe_of_string s in
 		let l = Bytes.length b in
 		let l = Bytes.length b in
 		let buf = Bytes.make 4 ' ' 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 []);
 		ignore(send socket buf 0 4 []);
 		let rec loop length offset =
 		let rec loop length offset =
 			if length <= 0 then
 			if length <= 0 then

+ 117 - 21
src/core/tFunctions.ml

@@ -150,7 +150,7 @@ let mk_typedef m path pos name_pos t =
 		t_restore = (fun () -> ());
 		t_restore = (fun () -> ());
 	}
 	}
 
 
-let module_extra file sign time kind policy =
+let module_extra file sign time kind added policy =
 	{
 	{
 		m_file = Path.UniqueKey.create_lazy file;
 		m_file = Path.UniqueKey.create_lazy file;
 		m_sign = sign;
 		m_sign = sign;
@@ -160,13 +160,13 @@ let module_extra file sign time kind policy =
 			m_import_positions = PMap.empty;
 			m_import_positions = PMap.empty;
 		};
 		};
 		m_cache_state = MSGood;
 		m_cache_state = MSGood;
-		m_added = 0;
+		m_added = added;
 		m_checked = 0;
 		m_checked = 0;
 		m_time = time;
 		m_time = time;
 		m_processed = 0;
 		m_processed = 0;
 		m_deps = PMap.empty;
 		m_deps = PMap.empty;
 		m_kind = kind;
 		m_kind = kind;
-		m_binded_res = PMap.empty;
+		m_cache_bound_objects = DynArray.create ();
 		m_if_feature = [];
 		m_if_feature = [];
 		m_features = Hashtbl.create 0;
 		m_features = Hashtbl.create 0;
 		m_check_policy = policy;
 		m_check_policy = policy;
@@ -198,20 +198,63 @@ let mk_field name ?(public = true) ?(static = false) t p name_pos = {
 	);
 	);
 }
 }
 
 
+let find_field c name kind =
+	match kind with
+	| CfrConstructor ->
+		begin match c.cl_constructor with Some cf -> cf | None -> raise Not_found end
+	| CfrStatic ->
+		PMap.find name c.cl_statics
+	| CfrMember ->
+		PMap.find name c.cl_fields
+
 let null_module = {
 let null_module = {
-		m_id = alloc_mid();
-		m_path = [] , "";
-		m_types = [];
-		m_statics = None;
-		m_extra = module_extra "" "" 0. MFake [];
-	}
+	m_id = alloc_mid();
+	m_path = [] , "";
+	m_types = [];
+	m_statics = None;
+	m_extra = module_extra "" (Digest.string "") 0. MFake 0 [];
+}
 
 
 let null_class =
 let null_class =
 	let c = mk_class null_module ([],"") null_pos null_pos in
 	let c = mk_class null_module ([],"") null_pos null_pos in
 	c.cl_private <- true;
 	c.cl_private <- true;
 	c
 	c
 
 
+let null_typedef =
+	let t = mk_typedef null_module ([],"") null_pos null_pos (TDynamic None) in
+	t.t_private <- true;
+	t
+
+let null_tanon = { a_fields = PMap.empty; a_status = ref Closed }
+
+let null_enum = {
+	e_path = ([],"");
+	e_module = null_module;
+	e_pos = null_pos;
+	e_name_pos = null_pos;
+	e_private = true;
+	e_doc = None;
+	e_meta = [];
+	e_params = [];
+	e_using = [];
+	e_restore = (fun () -> ());
+	e_type = t_dynamic;
+	e_extern = false;
+	e_constrs = PMap.empty;
+	e_names = [];
+}
+
 let null_field = mk_field "" t_dynamic null_pos null_pos
 let null_field = mk_field "" t_dynamic null_pos null_pos
+let null_enum_field = {
+	ef_name = "";
+	ef_type = TEnum (null_enum, []);
+	ef_pos = null_pos;
+	ef_name_pos = null_pos;
+	ef_doc = None;
+	ef_index = 0;
+	ef_params = [];
+	ef_meta = [];
+}
 
 
 let null_abstract = {
 let null_abstract = {
 	a_path = ([],"");
 	a_path = ([],"");
@@ -373,15 +416,11 @@ let apply_params ?stack cparams params t =
 	let rec loop l1 l2 =
 	let rec loop l1 l2 =
 		match l1, l2 with
 		match l1, l2 with
 		| [] , [] -> []
 		| [] , [] -> []
-		| {ttp_type = TLazy f} as tp :: l1, _ -> loop ({tp with ttp_type = lazy_type f} :: l1) l2
-		| tp :: l1 , t2 :: l2 -> (tp.ttp_type,t2) :: loop l1 l2
+		| ttp :: l1 , t2 :: l2 -> (ttp.ttp_class,t2) :: loop l1 l2
 		| _ -> die "" __LOC__
 		| _ -> die "" __LOC__
 	in
 	in
 	let subst = loop cparams params in
 	let subst = loop cparams params in
 	let rec loop t =
 	let rec loop t =
-		try
-			List.assq t subst
-		with Not_found ->
 		match t with
 		match t with
 		| TMono r ->
 		| TMono r ->
 			(match r.tm_type with
 			(match r.tm_type with
@@ -444,6 +483,12 @@ let apply_params ?stack cparams params t =
 			(match tl with
 			(match tl with
 			| [] -> t
 			| [] -> t
 			| _ -> TAbstract (a,List.map loop tl))
 			| _ -> TAbstract (a,List.map loop tl))
+		| TInst ({cl_kind = KTypeParameter _} as c,[]) ->
+			begin try
+				List.assq c subst
+			with Not_found ->
+				t
+			end
 		| TInst (c,tl) ->
 		| TInst (c,tl) ->
 			(match tl with
 			(match tl with
 			| [] ->
 			| [] ->
@@ -516,6 +561,15 @@ let rec follow t =
 		follow t
 		follow t
 	| _ -> t
 	| _ -> t
 
 
+let rec follow_lazy t =
+	match t with
+	| TLazy f ->
+		(match !f with
+		| LAvailable t -> follow_lazy t
+		| _ -> follow_lazy (lazy_type f)
+		)
+	| _ -> t
+
 let follow_once t =
 let follow_once t =
 	match t with
 	match t with
 	| TMono r ->
 	| TMono r ->
@@ -553,6 +607,14 @@ let rec follow_without_type t =
 		follow_without_type t
 		follow_without_type t
 	| _ -> t
 	| _ -> t
 
 
+let rec follow_lazy_and_mono t = match t with
+	| TMono {tm_type = Some t} ->
+		follow_lazy_and_mono t
+	| TLazy f ->
+		follow_lazy_and_mono (lazy_type f)
+	| _ ->
+		t
+
 let rec ambiguate_funs t =
 let rec ambiguate_funs t =
 	match follow t with
 	match follow t with
 	| TFun _ -> TFun ([], t_dynamic)
 	| TFun _ -> TFun ([], t_dynamic)
@@ -653,9 +715,12 @@ let lookup_param n l =
 	in
 	in
 	loop l
 	loop l
 
 
-let mk_type_param n t def = {
-	ttp_name = n;
-	ttp_type = t;
+let mk_type_param c host def constraints = {
+	ttp_name = snd c.cl_path;
+	ttp_type = TInst(c,[]);
+	ttp_class = c;
+	ttp_host = host;
+	ttp_constraints = constraints;
 	ttp_default = def;
 	ttp_default = def;
 }
 }
 
 
@@ -687,13 +752,19 @@ let tconst_to_const = function
 	| TThis -> Ident "this"
 	| TThis -> Ident "this"
 	| TSuper -> Ident "super"
 	| TSuper -> Ident "super"
 
 
+let get_constraints ttp = match ttp.ttp_constraints with
+	| None ->
+		[]
+	| Some r ->
+		Lazy.force r
+
 let has_ctor_constraint c = match c.cl_kind with
 let has_ctor_constraint c = match c.cl_kind with
-	| KTypeParameter tl ->
+	| KTypeParameter ttp ->
 		List.exists (fun t -> match follow t with
 		List.exists (fun t -> match follow t with
 			| TAnon a when PMap.mem "new" a.a_fields -> true
 			| TAnon a when PMap.mem "new" a.a_fields -> true
 			| TAbstract({a_path=["haxe"],"Constructible"},_) -> true
 			| TAbstract({a_path=["haxe"],"Constructible"},_) -> true
 			| _ -> false
 			| _ -> false
-		) tl;
+		) (get_constraints ttp);
 	| _ -> false
 	| _ -> false
 
 
 (* ======= Field utility ======= *)
 (* ======= Field utility ======= *)
@@ -741,7 +812,7 @@ let rec raw_class_field build_type c tl i =
 			c2, apply_params c.cl_params tl t , f
 			c2, apply_params c.cl_params tl t , f
 	with Not_found ->
 	with Not_found ->
 		match c.cl_kind with
 		match c.cl_kind with
-		| KTypeParameter tl ->
+		| KTypeParameter ttp ->
 			let rec loop = function
 			let rec loop = function
 				| [] ->
 				| [] ->
 					raise Not_found
 					raise Not_found
@@ -762,7 +833,7 @@ let rec raw_class_field build_type c tl i =
 					| _ ->
 					| _ ->
 						loop ctl
 						loop ctl
 			in
 			in
-			loop tl
+			loop (get_constraints ttp)
 		| _ ->
 		| _ ->
 			if not (has_class_flag c CInterface) then raise Not_found;
 			if not (has_class_flag c CInterface) then raise Not_found;
 			(*
 			(*
@@ -868,3 +939,28 @@ let var_extra params e = {
 	v_params = params;
 	v_params = params;
 	v_expr = e;
 	v_expr = e;
 }
 }
+
+let class_module_type c =
+	let path = ([],"Class<" ^ (s_type_path c.cl_path) ^ ">") in
+	let t = mk_anon ~fields:c.cl_statics (ref (ClassStatics c)) in
+	{ (mk_typedef c.cl_module path c.cl_pos null_pos t) with t_private = true}
+
+let enum_module_type en fields =
+	let path = ([], "Enum<" ^ (s_type_path en.e_path) ^ ">") in
+	let t = mk_anon ~fields (ref (EnumStatics en)) in
+	{(mk_typedef en.e_module path en.e_pos null_pos t) with t_private = true}
+
+let abstract_module_type a tl =
+	let path = ([],Printf.sprintf "Abstract<%s>" (s_type_path a.a_path)) in
+	let t = mk_anon (ref (AbstractStatics a)) in
+	{(mk_typedef a.a_module path a.a_pos null_pos t) with t_private = true}
+
+let class_field_of_enum_field ef = {
+	(mk_field ef.ef_name ef.ef_type ef.ef_pos ef.ef_name_pos) with
+	cf_kind = (match follow ef.ef_type with
+		| TFun _ -> Method MethNormal
+		| _ -> Var { v_read = AccNormal; v_write = AccNo }
+	);
+	cf_doc = ef.ef_doc;
+	cf_params = ef.ef_params;
+}

+ 88 - 14
src/core/tOther.ml

@@ -2,7 +2,6 @@ open Globals
 open Ast
 open Ast
 open TType
 open TType
 open TFunctions
 open TFunctions
-open TPrinting
 
 
 module TExprToExpr = struct
 module TExprToExpr = struct
 	let tpath path module_path params =
 	let tpath path module_path params =
@@ -263,20 +262,95 @@ end
 
 
 let no_meta = []
 let no_meta = []
 
 
-let class_module_type c =
-	let path = ([],"Class<" ^ (s_type_path c.cl_path) ^ ">") in
-	let t = mk_anon ~fields:c.cl_statics (ref (ClassStatics c)) in
-	{ (mk_typedef c.cl_module path c.cl_pos null_pos t) with t_private = true}
+let mk_enum m path pos name_pos =
+	{
+		e_path = path;
+		e_module = m;
+		e_pos = pos;
+		e_name_pos = name_pos;
+		e_doc = None;
+		e_meta = [];
+		e_params = [];
+		e_using = [];
+		e_restore = (fun () -> ());
+		e_private = false;
+		e_extern = false;
+		e_constrs = PMap.empty;
+		e_names = [];
+		e_type = mk_mono();
+	}
 
 
-let enum_module_type m path p  =
-	let path = ([], "Enum<" ^ (s_type_path path) ^ ">") in
-	let t = mk_mono() in
-	{(mk_typedef m path p null_pos t) with t_private = true}
+let mk_abstract m path pos name_pos =
+	{
+		a_path = path;
+		a_private = false;
+		a_module = m;
+		a_pos = pos;
+		a_name_pos = name_pos;
+		a_doc = None;
+		a_params = [];
+		a_using = [];
+		a_restore = (fun () -> ());
+		a_meta = [];
+		a_from = [];
+		a_to = [];
+		a_from_field = [];
+		a_to_field = [];
+		a_ops = [];
+		a_unops = [];
+		a_impl = None;
+		a_array = [];
+		a_this = mk_mono();
+		a_read = None;
+		a_write = None;
+		a_enum = false;
+		a_call = None;
+	}
 
 
-let abstract_module_type a tl =
-	let path = ([],Printf.sprintf "Abstract<%s%s>" (s_type_path a.a_path) (s_type_params (ref []) tl)) in
-	let t = mk_anon (ref (AbstractStatics a)) in
-	{(mk_typedef a.a_module path a.a_pos null_pos t) with t_private = true}
+let mk_enum m path pos name_pos =
+	{
+		e_path = path;
+		e_module = m;
+		e_pos = pos;
+		e_name_pos = name_pos;
+		e_doc = None;
+		e_meta = [];
+		e_params = [];
+		e_using = [];
+		e_restore = (fun () -> ());
+		e_private = false;
+		e_extern = false;
+		e_constrs = PMap.empty;
+		e_names = [];
+		e_type = mk_mono();
+	}
+
+let mk_abstract m path pos name_pos =
+	{
+		a_path = path;
+		a_private = false;
+		a_module = m;
+		a_pos = pos;
+		a_name_pos = name_pos;
+		a_doc = None;
+		a_params = [];
+		a_using = [];
+		a_restore = (fun () -> ());
+		a_meta = [];
+		a_from = [];
+		a_to = [];
+		a_from_field = [];
+		a_to_field = [];
+		a_ops = [];
+		a_unops = [];
+		a_impl = None;
+		a_array = [];
+		a_this = mk_mono();
+		a_read = None;
+		a_write = None;
+		a_enum = false;
+		a_call = None;
+	}
 
 
 module TClass = struct
 module TClass = struct
 	let get_member_fields' self_too c0 tl =
 	let get_member_fields' self_too c0 tl =
@@ -345,4 +419,4 @@ let s_class_path c =
 		| KAbstractImpl a -> a.a_path
 		| KAbstractImpl a -> a.a_path
 		| _ -> c.cl_path
 		| _ -> c.cl_path
 	in
 	in
-	s_type_path path
+	s_type_path path

+ 49 - 27
src/core/tPrinting.ml

@@ -128,6 +128,18 @@ and s_constraint = function
 	| MOpenStructure -> "MOpenStructure"
 	| MOpenStructure -> "MOpenStructure"
 	| MEmptyStructure -> "MEmptyStructure"
 	| MEmptyStructure -> "MEmptyStructure"
 
 
+let s_type_param s_type ttp =
+	let s = match (get_constraints ttp) with
+		| [] -> ttp.ttp_name
+		| tl1 -> Printf.sprintf "%s:%s" ttp.ttp_name (String.concat " & " (List.map s_type tl1))
+	in
+	begin match ttp.ttp_default with
+	| None ->
+		s
+	| Some t ->
+		Printf.sprintf "%s = %s" s (s_type t)
+	end
+
 let s_access is_read = function
 let s_access is_read = function
 	| AccNormal -> "default"
 	| AccNormal -> "default"
 	| AccNo -> "null"
 	| AccNo -> "null"
@@ -380,8 +392,8 @@ let s_types ?(sep = ", ") tl =
 let s_class_kind = function
 let s_class_kind = function
 	| KNormal ->
 	| KNormal ->
 		"KNormal"
 		"KNormal"
-	| KTypeParameter tl ->
-		Printf.sprintf "KTypeParameter [%s]" (s_types tl)
+	| KTypeParameter ttp ->
+		Printf.sprintf "KTypeParameter [%s]" (s_types (get_constraints ttp))
 	| KExpr _ ->
 	| KExpr _ ->
 		"KExpr"
 		"KExpr"
 	| KGeneric ->
 	| KGeneric ->
@@ -441,27 +453,31 @@ module Printer = struct
 	let s_metadata metadata =
 	let s_metadata metadata =
 		s_list " " s_metadata_entry metadata
 		s_list " " s_metadata_entry metadata
 
 
-	let s_type_param tp = match follow tp.ttp_type with
-		| TInst({cl_kind = KTypeParameter tl1},tl2) ->
-			let s = match tl1 with
-				| [] -> tp.ttp_name
-				| _ -> Printf.sprintf "%s:%s" tp.ttp_name (String.concat " & " (List.map s_type tl1))
-			in
-			begin match tp.ttp_default with
-			| None ->
-				s
-			| Some t ->
-				Printf.sprintf "%s = %s" s (s_type t)
-			end
-		| _ -> die "" __LOC__
+	let s_ttp_host = function
+		| TPHType -> "TPHType"
+		| TPHConstructor -> "TPHConstructor"
+		| TPHMethod -> "TPHMethod"
+		| TPHEnumConstructor -> "TPHEnumConstructor"
+		| TPHAnonField -> "TPHAnonField"
+		| TPHLocal -> "TPHLocal"
 
 
-	let s_type_params tl =
-		s_list ", " s_type_param tl
+	let s_type_param tabs ttp =
+		s_record_fields tabs [
+			"name",ttp.ttp_name;
+			"class",s_type_path ttp.ttp_class.cl_path;
+			"host",s_ttp_host ttp.ttp_host;
+			"type",s_type_kind ttp.ttp_type;
+			"constraints",s_list ", " s_type_kind (get_constraints ttp)	;
+			"default",s_opt s_type_kind ttp.ttp_default;
+		]
+
+	let s_type_params tabs tl =
+		s_list ", " (s_type_param tabs) tl
 
 
 	let s_tclass_field_flags flags =
 	let s_tclass_field_flags flags =
 		s_flags flags flag_tclass_field_names
 		s_flags flags flag_tclass_field_names
 
 
-	let s_tclass_field tabs cf =
+	let rec s_tclass_field tabs cf =
 		s_record_fields tabs [
 		s_record_fields tabs [
 			"cf_name",cf.cf_name;
 			"cf_name",cf.cf_name;
 			"cf_doc",s_doc cf.cf_doc;
 			"cf_doc",s_doc cf.cf_doc;
@@ -470,9 +486,10 @@ module Printer = struct
 			"cf_name_pos",s_pos cf.cf_name_pos;
 			"cf_name_pos",s_pos cf.cf_name_pos;
 			"cf_meta",s_metadata cf.cf_meta;
 			"cf_meta",s_metadata cf.cf_meta;
 			"cf_kind",s_kind cf.cf_kind;
 			"cf_kind",s_kind cf.cf_kind;
-			"cf_params",s_type_params cf.cf_params;
+			"cf_params",s_type_params (tabs ^ "\t") cf.cf_params;
 			"cf_expr",s_opt (s_expr_ast true "\t\t" s_type) cf.cf_expr;
 			"cf_expr",s_opt (s_expr_ast true "\t\t" s_type) cf.cf_expr;
 			"cf_flags",s_tclass_field_flags cf.cf_flags;
 			"cf_flags",s_tclass_field_flags cf.cf_flags;
+			"cf_overloads",s_list "\n" (s_tclass_field (tabs ^ "\t")) cf.cf_overloads
 		]
 		]
 
 
 	let s_tclass tabs c =
 	let s_tclass tabs c =
@@ -484,7 +501,7 @@ module Printer = struct
 			"cl_private",string_of_bool c.cl_private;
 			"cl_private",string_of_bool c.cl_private;
 			"cl_doc",s_doc c.cl_doc;
 			"cl_doc",s_doc c.cl_doc;
 			"cl_meta",s_metadata c.cl_meta;
 			"cl_meta",s_metadata c.cl_meta;
-			"cl_params",s_type_params c.cl_params;
+			"cl_params",s_type_params (tabs ^ "\t") c.cl_params;
 			"cl_kind",s_class_kind c.cl_kind;
 			"cl_kind",s_class_kind c.cl_kind;
 			"cl_super",s_opt (fun (c,tl) -> s_type (TInst(c,tl))) c.cl_super;
 			"cl_super",s_opt (fun (c,tl) -> s_type (TInst(c,tl))) c.cl_super;
 			"cl_implements",s_list ", " (fun (c,tl) -> s_type (TInst(c,tl))) c.cl_implements;
 			"cl_implements",s_list ", " (fun (c,tl) -> s_type (TInst(c,tl))) c.cl_implements;
@@ -504,7 +521,7 @@ module Printer = struct
 			"t_private",string_of_bool t.t_private;
 			"t_private",string_of_bool t.t_private;
 			"t_doc",s_doc t.t_doc;
 			"t_doc",s_doc t.t_doc;
 			"t_meta",s_metadata t.t_meta;
 			"t_meta",s_metadata t.t_meta;
-			"t_params",s_type_params t.t_params;
+			"t_params",s_type_params (tabs ^ "\t") t.t_params;
 			"t_type",s_type_kind t.t_type
 			"t_type",s_type_kind t.t_type
 		]
 		]
 
 
@@ -516,7 +533,7 @@ module Printer = struct
 			"ef_name_pos",s_pos ef.ef_name_pos;
 			"ef_name_pos",s_pos ef.ef_name_pos;
 			"ef_type",s_type_kind ef.ef_type;
 			"ef_type",s_type_kind ef.ef_type;
 			"ef_index",string_of_int ef.ef_index;
 			"ef_index",string_of_int ef.ef_index;
-			"ef_params",s_type_params ef.ef_params;
+			"ef_params",s_type_params (tabs ^ "\t") ef.ef_params;
 			"ef_meta",s_metadata ef.ef_meta
 			"ef_meta",s_metadata ef.ef_meta
 		]
 		]
 
 
@@ -529,8 +546,8 @@ module Printer = struct
 			"e_private",string_of_bool en.e_private;
 			"e_private",string_of_bool en.e_private;
 			"d_doc",s_doc en.e_doc;
 			"d_doc",s_doc en.e_doc;
 			"e_meta",s_metadata en.e_meta;
 			"e_meta",s_metadata en.e_meta;
-			"e_params",s_type_params en.e_params;
-			"e_type",s_tdef "\t" en.e_type;
+			"e_params",s_type_params (tabs ^ "\t") en.e_params;
+			"e_type",s_type_kind en.e_type;
 			"e_extern",string_of_bool en.e_extern;
 			"e_extern",string_of_bool en.e_extern;
 			"e_constrs",s_list "\n\t" (s_tenum_field (tabs ^ "\t")) (PMap.fold (fun ef acc -> ef :: acc) en.e_constrs []);
 			"e_constrs",s_list "\n\t" (s_tenum_field (tabs ^ "\t")) (PMap.fold (fun ef acc -> ef :: acc) en.e_constrs []);
 			"e_names",String.concat ", " en.e_names
 			"e_names",String.concat ", " en.e_names
@@ -545,7 +562,7 @@ module Printer = struct
 			"a_private",string_of_bool a.a_private;
 			"a_private",string_of_bool a.a_private;
 			"a_doc",s_doc a.a_doc;
 			"a_doc",s_doc a.a_doc;
 			"a_meta",s_metadata a.a_meta;
 			"a_meta",s_metadata a.a_meta;
-			"a_params",s_type_params a.a_params;
+			"a_params",s_type_params (tabs ^ "\t") a.a_params;
 			"a_ops",s_list ", " (fun (op,cf) -> Printf.sprintf "%s: %s" (s_binop op) cf.cf_name) a.a_ops;
 			"a_ops",s_list ", " (fun (op,cf) -> Printf.sprintf "%s: %s" (s_binop op) cf.cf_name) a.a_ops;
 			"a_unops",s_list ", " (fun (op,flag,cf) -> Printf.sprintf "%s (%s): %s" (s_unop op) (if flag = Postfix then "postfix" else "prefix") cf.cf_name) a.a_unops;
 			"a_unops",s_list ", " (fun (op,flag,cf) -> Printf.sprintf "%s (%s): %s" (s_unop op) (if flag = Postfix then "postfix" else "prefix") cf.cf_name) a.a_unops;
 			"a_impl",s_opt (fun c -> s_type_path c.cl_path) a.a_impl;
 			"a_impl",s_opt (fun c -> s_type_path c.cl_path) a.a_impl;
@@ -560,7 +577,7 @@ module Printer = struct
 		]
 		]
 
 
 	let s_tvar_extra ve =
 	let s_tvar_extra ve =
-		Printf.sprintf "Some(%s, %s)" (s_type_params ve.v_params) (s_opt (s_expr_ast true "" s_type) ve.v_expr)
+		Printf.sprintf "Some(%s, %s)" (s_type_params "" ve.v_params) (s_opt (s_expr_ast true "" s_type) ve.v_expr)
 
 
 	let s_tvar v =
 	let s_tvar v =
 		s_record_fields "" [
 		s_record_fields "" [
@@ -594,11 +611,16 @@ module Printer = struct
 		| MExtern -> "MExtern"
 		| MExtern -> "MExtern"
 		| MImport -> "MImport"
 		| MImport -> "MImport"
 
 
+	let s_module_tainting_reason = function
+		| CheckDisplayFile -> "check_display_file"
+		| ServerInvalidate -> "server/invalidate"
+		| ServerInvalidateFiles -> "server_invalidate_files"
+
 	let s_module_skip_reason reason =
 	let s_module_skip_reason reason =
 		let rec loop stack = function
 		let rec loop stack = function
 			| DependencyDirty(path,reason) ->
 			| DependencyDirty(path,reason) ->
 				(Printf.sprintf "%s%s - %s" (if stack = [] then "DependencyDirty " else "") (s_type_path path) (if List.mem path stack then "rec" else loop (path :: stack) reason))
 				(Printf.sprintf "%s%s - %s" (if stack = [] then "DependencyDirty " else "") (s_type_path path) (if List.mem path stack then "rec" else loop (path :: stack) reason))
-			| Tainted cause -> "Tainted " ^ cause
+			| Tainted cause -> "Tainted " ^ (s_module_tainting_reason cause)
 			| FileChanged file -> "FileChanged " ^ file
 			| FileChanged file -> "FileChanged " ^ file
 			| Shadowed file -> "Shadowed " ^ file
 			| Shadowed file -> "Shadowed " ^ file
 			| LibraryChanged -> "LibraryChanged"
 			| LibraryChanged -> "LibraryChanged"

+ 37 - 16
src/core/tType.ml

@@ -32,9 +32,14 @@ type module_check_policy =
 	| NoCheckShadowing
 	| NoCheckShadowing
 	| Retype
 	| Retype
 
 
+type module_tainting_reason =
+	| CheckDisplayFile
+	| ServerInvalidate
+	| ServerInvalidateFiles
+
 type module_skip_reason =
 type module_skip_reason =
 	| DependencyDirty of path * module_skip_reason
 	| DependencyDirty of path * module_skip_reason
-	| Tainted of string
+	| Tainted of module_tainting_reason
 	| FileChanged of string
 	| FileChanged of string
 	| Shadowed of string
 	| Shadowed of string
 	| LibraryChanged
 	| LibraryChanged
@@ -44,6 +49,19 @@ type module_cache_state =
 	| MSBad of module_skip_reason
 	| MSBad of module_skip_reason
 	| MSUnknown
 	| MSUnknown
 
 
+type type_param_host =
+	| TPHType
+	| TPHConstructor
+	| TPHMethod
+	| TPHEnumConstructor
+	| TPHAnonField
+	| TPHLocal
+
+type cache_bound_object =
+	| Resource of string * string
+	| IncludeFile of string * string
+	| Warning of WarningList.warning * string * pos
+
 type t =
 type t =
 	| TMono of tmono
 	| TMono of tmono
 	| TEnum of tenum * tparams
 	| TEnum of tenum * tparams
@@ -92,8 +110,11 @@ and tparams = t list
 
 
 and typed_type_param = {
 and typed_type_param = {
 	ttp_name : string;
 	ttp_name : string;
-	ttp_type : t;
-	ttp_default : t option;
+	ttp_class : tclass;
+	ttp_host : type_param_host;
+	mutable ttp_type : t;
+	mutable ttp_constraints : t list Lazy.t option;
+	mutable ttp_default : t option;
 }
 }
 
 
 and type_params = typed_type_param list
 and type_params = typed_type_param list
@@ -232,7 +253,7 @@ and tclass_field = {
 
 
 and tclass_kind =
 and tclass_kind =
 	| KNormal
 	| KNormal
-	| KTypeParameter of t list
+	| KTypeParameter of typed_type_param
 	| KExpr of Ast.expr
 	| KExpr of Ast.expr
 	| KGeneric
 	| KGeneric
 	| KGenericInstance of tclass * tparams
 	| KGenericInstance of tclass * tparams
@@ -248,10 +269,10 @@ and tinfos = {
 	mt_module : module_def;
 	mt_module : module_def;
 	mt_pos : pos;
 	mt_pos : pos;
 	mt_name_pos : pos;
 	mt_name_pos : pos;
-	mt_private : bool;
-	mt_doc : Ast.documentation;
+	mutable mt_private : bool;
+	mutable mt_doc : Ast.documentation;
 	mutable mt_meta : metadata;
 	mutable mt_meta : metadata;
-	mt_params : type_params;
+	mutable mt_params : type_params;
 	mutable mt_using : (tclass * pos) list;
 	mutable mt_using : (tclass * pos) list;
 	mutable mt_restore : unit -> unit;
 	mutable mt_restore : unit -> unit;
 }
 }
@@ -305,14 +326,14 @@ and tenum = {
 	e_module : module_def;
 	e_module : module_def;
 	e_pos : pos;
 	e_pos : pos;
 	e_name_pos : pos;
 	e_name_pos : pos;
-	e_private : bool;
+	mutable e_private : bool;
 	mutable e_doc : Ast.documentation;
 	mutable e_doc : Ast.documentation;
 	mutable e_meta : metadata;
 	mutable e_meta : metadata;
 	mutable e_params : type_params;
 	mutable e_params : type_params;
 	mutable e_using : (tclass * pos) list;
 	mutable e_using : (tclass * pos) list;
 	mutable e_restore : unit -> unit;
 	mutable e_restore : unit -> unit;
 	(* do not insert any fields above *)
 	(* do not insert any fields above *)
-	e_type : tdef;
+	mutable e_type : t;
 	mutable e_extern : bool;
 	mutable e_extern : bool;
 	mutable e_constrs : (string , tenum_field) PMap.t;
 	mutable e_constrs : (string , tenum_field) PMap.t;
 	mutable e_names : string list;
 	mutable e_names : string list;
@@ -323,8 +344,8 @@ and tdef = {
 	t_module : module_def;
 	t_module : module_def;
 	t_pos : pos;
 	t_pos : pos;
 	t_name_pos : pos;
 	t_name_pos : pos;
-	t_private : bool;
-	t_doc : Ast.documentation;
+	mutable t_private : bool;
+	mutable t_doc : Ast.documentation;
 	mutable t_meta : metadata;
 	mutable t_meta : metadata;
 	mutable t_params : type_params;
 	mutable t_params : type_params;
 	mutable t_using : (tclass * pos) list;
 	mutable t_using : (tclass * pos) list;
@@ -338,7 +359,7 @@ and tabstract = {
 	a_module : module_def;
 	a_module : module_def;
 	a_pos : pos;
 	a_pos : pos;
 	a_name_pos : pos;
 	a_name_pos : pos;
-	a_private : bool;
+	mutable a_private : bool;
 	mutable a_doc : Ast.documentation;
 	mutable a_doc : Ast.documentation;
 	mutable a_meta : metadata;
 	mutable a_meta : metadata;
 	mutable a_params : type_params;
 	mutable a_params : type_params;
@@ -357,7 +378,7 @@ and tabstract = {
 	mutable a_read : tclass_field option;
 	mutable a_read : tclass_field option;
 	mutable a_write : tclass_field option;
 	mutable a_write : tclass_field option;
 	mutable a_call : tclass_field option;
 	mutable a_call : tclass_field option;
-	a_enum : bool;
+	mutable a_enum : bool;
 }
 }
 
 
 and module_type =
 and module_type =
@@ -382,7 +403,7 @@ and module_def_display = {
 
 
 and module_def_extra = {
 and module_def_extra = {
 	m_file : Path.UniqueKey.lazy_t;
 	m_file : Path.UniqueKey.lazy_t;
-	m_sign : string;
+	m_sign : Digest.t;
 	m_display : module_def_display;
 	m_display : module_def_display;
 	mutable m_check_policy : module_check_policy list;
 	mutable m_check_policy : module_check_policy list;
 	mutable m_time : float;
 	mutable m_time : float;
@@ -390,9 +411,9 @@ and module_def_extra = {
 	mutable m_added : int;
 	mutable m_added : int;
 	mutable m_checked : int;
 	mutable m_checked : int;
 	mutable m_processed : int;
 	mutable m_processed : int;
-	mutable m_deps : (int,(string (* sign *) * path)) PMap.t;
+	mutable m_deps : (int,(Digest.t (* sign *) * path)) PMap.t;
 	mutable m_kind : module_kind;
 	mutable m_kind : module_kind;
-	mutable m_binded_res : (string, string) PMap.t;
+	mutable m_cache_bound_objects : cache_bound_object DynArray.t;
 	mutable m_if_feature : (string * class_field_ref) list;
 	mutable m_if_feature : (string * class_field_ref) list;
 	mutable m_features : (string,bool) Hashtbl.t;
 	mutable m_features : (string,bool) Hashtbl.t;
 }
 }

+ 19 - 18
src/core/tUnification.ml

@@ -260,13 +260,13 @@ module Monomorph = struct
 
 
 	let spawn_constrained_monos map params =
 	let spawn_constrained_monos map params =
 		let checks = DynArray.create () in
 		let checks = DynArray.create () in
-		let monos = List.map (fun tp ->
+		let monos = List.map (fun ttp ->
 			let mono = create () in
 			let mono = create () in
-			begin match follow tp.ttp_type with
-				| TInst ({ cl_kind = KTypeParameter constr; cl_path = path },_) when constr <> [] ->
-					DynArray.add checks (mono,constr,s_type_path path)
-				| _ ->
+			begin match get_constraints ttp with
+				| [] ->
 					()
 					()
+				| constr ->
+					DynArray.add checks (mono,constr,s_type_path ttp.ttp_class.cl_path)
 			end;
 			end;
 			TMono mono
 			TMono mono
 		) params in
 		) params in
@@ -695,12 +695,13 @@ let rec unify (uctx : unification_context) a b =
 				loop cs (List.map (apply_params c.cl_params tl) tls)
 				loop cs (List.map (apply_params c.cl_params tl) tls)
 			) c.cl_implements
 			) c.cl_implements
 			|| (match c.cl_kind with
 			|| (match c.cl_kind with
-			| KTypeParameter pl -> List.exists (fun t ->
-				match follow t with
-				| TInst (cs,tls) -> loop cs (List.map (apply_params c.cl_params tl) tls)
-				| TAbstract(aa,tl) -> unifies_to uctx a b aa tl
-				| _ -> false
-			) pl
+			| KTypeParameter ttp ->
+				List.exists (fun t ->
+					match follow t with
+					| TInst (cs,tls) -> loop cs (List.map (apply_params c.cl_params tl) tls)
+					| TAbstract(aa,tl) -> unifies_to uctx a b aa tl
+					| _ -> false
+				) (get_constraints ttp)
 			| _ -> false)
 			| _ -> false)
 		in
 		in
 		if not (loop c1 tl1) then error [cannot_unify a b]
 		if not (loop c1 tl1) then error [cannot_unify a b]
@@ -722,9 +723,9 @@ let rec unify (uctx : unification_context) a b =
 				error (cannot_unify a b :: msg :: l))
 				error (cannot_unify a b :: msg :: l))
 	| TInst (c,tl) , TAnon an ->
 	| TInst (c,tl) , TAnon an ->
 		if PMap.is_empty an.a_fields then (match c.cl_kind with
 		if PMap.is_empty an.a_fields then (match c.cl_kind with
-			| KTypeParameter pl ->
+			| KTypeParameter ttp ->
 				(* one of the constraints must unify with { } *)
 				(* one of the constraints must unify with { } *)
-				if not (List.exists (fun t -> match follow t with TInst _ | TAnon _ -> true | _ -> false) pl) then error [cannot_unify a b]
+				if not (List.exists (fun t -> match follow t with TInst _ | TAnon _ -> true | _ -> false) (get_constraints ttp)) then error [cannot_unify a b]
 			| _ -> ());
 			| _ -> ());
 		ignore(c.cl_build());
 		ignore(c.cl_build());
 		(try
 		(try
@@ -824,9 +825,9 @@ let rec unify (uctx : unification_context) a b =
 	| TInst(c,tl),TAbstract({a_path = ["haxe"],"Constructible"},[t1]) ->
 	| TInst(c,tl),TAbstract({a_path = ["haxe"],"Constructible"},[t1]) ->
 		begin try
 		begin try
 			begin match c.cl_kind with
 			begin match c.cl_kind with
-				| KTypeParameter tl ->
+				| KTypeParameter ttp ->
 					(* type parameters require an equal Constructible constraint *)
 					(* type parameters require an equal Constructible constraint *)
-					if not (List.exists (fun t -> match follow t with TAbstract({a_path = ["haxe"],"Constructible"},[t2]) -> type_iseq uctx t1 t2 | _ -> false) tl) then error [cannot_unify a b]
+					if not (List.exists (fun t -> match follow t with TAbstract({a_path = ["haxe"],"Constructible"},[t2]) -> type_iseq uctx t1 t2 | _ -> false) (get_constraints ttp)) then error [cannot_unify a b]
 				| _ ->
 				| _ ->
 					let _,t,cf = class_field c tl "new" in
 					let _,t,cf = class_field c tl "new" in
 					if not (has_class_field_flag cf CfPublic) then error [invalid_visibility "new"];
 					if not (has_class_field_flag cf CfPublic) then error [invalid_visibility "new"];
@@ -884,12 +885,12 @@ let rec unify (uctx : unification_context) a b =
 		end
 		end
 	| TAbstract (aa,tl), _  ->
 	| TAbstract (aa,tl), _  ->
 		unify_to uctx a b aa tl
 		unify_to uctx a b aa tl
-	| TInst ({ cl_kind = KTypeParameter ctl } as c,pl), TAbstract (bb,tl) ->
+	| TInst ({ cl_kind = KTypeParameter ttp } as c,pl), TAbstract (bb,tl) ->
 		(* one of the constraints must satisfy the abstract *)
 		(* one of the constraints must satisfy the abstract *)
 		if not (List.exists (fun t ->
 		if not (List.exists (fun t ->
 			let t = apply_params c.cl_params pl t in
 			let t = apply_params c.cl_params pl t in
 			try unify uctx t b; true with Unify_error _ -> false
 			try unify uctx t b; true with Unify_error _ -> false
-		) ctl) then unify_from uctx a b bb tl
+		) (get_constraints ttp)) then unify_from uctx a b bb tl
 	| _, TAbstract (bb,tl) ->
 	| _, TAbstract (bb,tl) ->
 		unify_from uctx a b bb tl
 		unify_from uctx a b bb tl
 	| _ , _ ->
 	| _ , _ ->
@@ -1136,7 +1137,7 @@ module UnifyMinT = struct
 		let rec loop t = (match t with
 		let rec loop t = (match t with
 			| TInst(cl, params) ->
 			| TInst(cl, params) ->
 				(match cl.cl_kind with
 				(match cl.cl_kind with
-				| KTypeParameter tl -> List.iter loop tl
+				| KTypeParameter ttp -> List.iter loop (get_constraints ttp)
 				| _ -> ());
 				| _ -> ());
 				List.iter (fun (ic, ip) ->
 				List.iter (fun (ic, ip) ->
 					let t = apply_params cl.cl_params params (TInst (ic,ip)) in
 					let t = apply_params cl.cl_params params (TInst (ic,ip)) in

+ 4 - 5
src/core/texpr.ml

@@ -486,15 +486,14 @@ let foldmap f acc e =
 (* Collection of functions that return expressions *)
 (* Collection of functions that return expressions *)
 module Builder = struct
 module Builder = struct
 	let make_static_this c p =
 	let make_static_this c p =
-		let ta = mk_anon ~fields:c.cl_statics (ref (ClassStatics c)) in
-		mk (TTypeExpr (TClassDecl c)) ta p
+		mk (TTypeExpr (TClassDecl c)) (TType(TFunctions.class_module_type c,[])) p
 
 
 	let make_typeexpr mt pos =
 	let make_typeexpr mt pos =
 		let t =
 		let t =
 			match resolve_typedef mt with
 			match resolve_typedef mt with
-			| TClassDecl c -> mk_anon ~fields:c.cl_statics (ref (ClassStatics c))
-			| TEnumDecl e -> mk_anon (ref (EnumStatics e))
-			| TAbstractDecl a -> mk_anon (ref (AbstractStatics a))
+			| TClassDecl c -> TType(class_module_type c,[])
+			| TEnumDecl e -> e.e_type
+			| TAbstractDecl a -> TType(abstract_module_type a [],[])
 			| _ -> die "" __LOC__
 			| _ -> die "" __LOC__
 		in
 		in
 		mk (TTypeExpr mt) t pos
 		mk (TTypeExpr mt) t pos

+ 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 Common
 open Typecore
 open Typecore
 open Error
 open Error
-
-let haxe_exception_type_path = (["haxe"],"Exception")
-let value_exception_type_path = (["haxe"],"ValueException")
+open ExceptionFunctions
 
 
 type context = {
 type context = {
 	typer : typer;
 	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 std_is ctx e t p =
 	let t = follow t in
 	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 =
 	let isOfType_field =
 		try PMap.find "isOfType" std_cls.cl_statics
 		try PMap.find "isOfType" std_cls.cl_statics
 		with Not_found -> raise_typing_error ("Std has no field isOfType") p
 		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
 	let t = Abstract.follow_with_abstracts t in
 	t == t_dynamic || fast_eq ctx.haxe_exception_type t
 	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
 	Check if `v` variable is used in `e` expression

+ 5 - 209
src/filters/filters.ml

@@ -25,7 +25,7 @@ open Error
 open Globals
 open Globals
 open FiltersCommon
 open FiltersCommon
 
 
-let get_native_name = TypeloadCheck.get_native_name
+let get_native_name = Naming.get_native_name
 
 
 (* PASS 1 begin *)
 (* PASS 1 begin *)
 
 
@@ -66,66 +66,6 @@ let rec add_final_return e =
 			{ e with eexpr = TFunction f }
 			{ e with eexpr = TFunction f }
 		| _ -> e
 		| _ -> 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 *)
 (* CHECK LOCAL VARS INIT *)
 
 
@@ -356,12 +296,6 @@ let check_abstract_as_value e =
 
 
 (* PASS 2 begin *)
 (* 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 *)
 (* Removes extern and macro fields, also checks for Void fields *)
 
 
 let remove_extern_fields com t = match t with
 let remove_extern_fields com t = match t with
@@ -389,75 +323,10 @@ let remove_extern_fields com t = match t with
 let check_private_path com t = match t with
 let check_private_path com t = match t with
 	| TClassDecl c when c.cl_private ->
 	| TClassDecl c when c.cl_private ->
 		let rpath = (fst c.cl_module.m_path,"_" ^ snd c.cl_module.m_path) in
 		let rpath = (fst c.cl_module.m_path,"_" ^ snd c.cl_module.m_path) in
-		if com.type_to_module#mem rpath then raise_typing_error ("This private class name will clash with " ^ s_type_path rpath) c.cl_pos;
+		if com.module_lut#get_type_lut#mem rpath then raise_typing_error ("This private class name will clash with " ^ s_type_path rpath) c.cl_pos;
 	| _ ->
 	| _ ->
 		()
 		()
 
 
-(* 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 *)
 (* Adds the __rtti field if required *)
 let add_rtti com t =
 let add_rtti com t =
 	let rec has_rtti c =
 	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 *)
 (* Adds the __meta__ field if required *)
 let add_meta_field com t = match t with
 let add_meta_field com t = match t with
 	| TClassDecl c ->
 	| TClassDecl c ->
@@ -618,14 +422,6 @@ let check_reserved_type_paths com t =
 
 
 (* PASS 3 end *)
 (* 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 =
 let iter_expressions fl mt =
 	match mt with
 	match mt with
 	| TClassDecl c ->
 	| TClassDecl c ->
@@ -666,7 +462,7 @@ let destruction tctx detail_times main locals =
 	with_timer detail_times "type 2" None (fun () ->
 	with_timer detail_times "type 2" None (fun () ->
 		(* PASS 2: type filters pre-DCE *)
 		(* PASS 2: type filters pre-DCE *)
 		List.iter (fun t ->
 		List.iter (fun t ->
-			remove_generic_base t;
+			FiltersCommon.remove_generic_base t;
 			remove_extern_fields com t;
 			remove_extern_fields com t;
 			(* check @:remove metadata before DCE so it is ignored there (issue #2923) *)
 			(* check @:remove metadata before DCE so it is ignored there (issue #2923) *)
 			check_remove_metadata t;
 			check_remove_metadata t;
@@ -698,9 +494,9 @@ let destruction tctx detail_times main locals =
 	let type_filters = [
 	let type_filters = [
 		Exceptions.patch_constructors tctx; (* TODO: I don't believe this should load_instance anything at this point... *)
 		Exceptions.patch_constructors tctx; (* TODO: I don't believe this should load_instance anything at this point... *)
 		check_private_path com;
 		check_private_path com;
-		apply_native_paths;
+		Naming.apply_native_paths;
 		add_rtti com;
 		add_rtti com;
-		(match com.platform with | Jvm -> (fun _ -> ()) | _ -> (fun mt -> add_field_inits tctx.curclass.cl_path locals com mt));
+		(match com.platform with | Jvm -> (fun _ -> ()) | _ -> (fun mt -> AddFieldInits.add_field_inits tctx.curclass.cl_path locals com mt));
 		(match com.platform with Hl -> (fun _ -> ()) | _ -> add_meta_field com);
 		(match com.platform with Hl -> (fun _ -> ()) | _ -> add_meta_field com);
 		check_void_field;
 		check_void_field;
 		(match com.platform with | Cpp -> promote_first_interface_to_super | _ -> (fun _ -> ()));
 		(match com.platform with | Cpp -> promote_first_interface_to_super | _ -> (fun _ -> ()));

+ 17 - 5
src/filters/filtersCommon.ml

@@ -18,6 +18,7 @@
 *)
 *)
 open Globals
 open Globals
 open Type
 open Type
+open Common
 open Typecore
 open Typecore
 
 
 let rec is_removable_class c =
 let rec is_removable_class c =
@@ -27,11 +28,8 @@ let rec is_removable_class c =
 		(match c.cl_super with
 		(match c.cl_super with
 			| Some (c,_) -> is_removable_class c
 			| Some (c,_) -> is_removable_class c
 			| _ -> false) ||
 			| _ -> false) ||
-		List.exists (fun tp -> match follow tp.ttp_type with
-			| TInst(c,_) ->
-				has_ctor_constraint c || Meta.has Meta.Const c.cl_meta
-			| _ ->
-				false
+		List.exists (fun tp ->
+			has_ctor_constraint tp.ttp_class || Meta.has Meta.Const tp.ttp_class.cl_meta
 		) c.cl_params)
 		) c.cl_params)
 	| KTypeParameter _ ->
 	| KTypeParameter _ ->
 		(* this shouldn't happen, have to investigate (see #4092) *)
 		(* this shouldn't happen, have to investigate (see #4092) *)
@@ -39,6 +37,12 @@ let rec is_removable_class c =
 	| _ ->
 	| _ ->
 		false
 		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
 	Check if `field` is overridden in subclasses
 *)
 *)
@@ -85,3 +89,11 @@ let run_expression_filters ?(ignore_processed_status=false) ctx detail_times fil
 	| TEnumDecl _ -> ()
 	| TEnumDecl _ -> ()
 	| TTypeDecl _ -> ()
 	| TTypeDecl _ -> ()
 	| TAbstractDecl _ -> ()
 	| 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

+ 62 - 0
src/filters/localStatic.ml

@@ -0,0 +1,62 @@
+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 =
 let reserve_all_types ri com path_to_name =
 	List.iter (fun mt ->
 	List.iter (fun mt ->
 		let tinfos = t_infos mt in
 		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
 		match mt with
 		| TClassDecl c when native_name = "" ->
 		| TClassDecl c when native_name = "" ->
 			List.iter (fun cf ->
 			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
 				reserve_init ri native_name
 			) c.cl_ordered_statics
 			) c.cl_ordered_statics
 		| TClassDecl { cl_kind = KModuleFields m; cl_ordered_statics = fl } ->
 		| TClassDecl { cl_kind = KModuleFields m; cl_ordered_statics = fl } ->
 			let prefix = Path.flat_path m.m_path ^ "_" in
 			let prefix = Path.flat_path m.m_path ^ "_" in
 			List.iter (fun cf ->
 			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
 				reserve_init ri name
 			) fl
 			) fl
 		| _ ->
 		| _ ->

+ 23 - 3
src/generators/gencpp.ml

@@ -3442,7 +3442,7 @@ let cpp_class_hash interface =
 let rec is_constant_zero expr =
 let rec is_constant_zero expr =
   match expr.cppexpr with
   match expr.cppexpr with
   | CppFloat x when (float_of_string x) = 0.0 -> true
   | CppFloat x when (float_of_string x) = 0.0 -> true
-  | CppInt i when i = Int32.of_int 0 -> true
+  | CppInt i when i = Int32.zero -> true
   | CppCastScalar(expr,_) -> is_constant_zero(expr)
   | CppCastScalar(expr,_) -> is_constant_zero(expr)
   | _ -> false
   | _ -> false
 ;;
 ;;
@@ -5238,6 +5238,9 @@ let generate_enum_files baseCtx enum_def super_deps meta =
    let ctx = file_context baseCtx cpp_file debug false in
    let ctx = file_context baseCtx cpp_file debug false in
    let strq = strq ctx.ctx_common in
    let strq = strq ctx.ctx_common in
 
 
+   let classId = try Hashtbl.find baseCtx.ctx_type_ids (class_text enum_def.e_path) with Not_found -> Int32.zero in
+   let classIdTxt = Printf.sprintf "0x%08lx" classId in
+
    if (debug>1) then
    if (debug>1) then
       print_endline ("Found enum definition:" ^ (join_class_path  class_path "::" ));
       print_endline ("Found enum definition:" ^ (join_class_path  class_path "::" ));
 
 
@@ -5279,6 +5282,10 @@ let generate_enum_files baseCtx enum_def super_deps meta =
 
 
    output_cpp ("HX_DEFINE_CREATE_ENUM(" ^ class_name ^ ")\n\n");
    output_cpp ("HX_DEFINE_CREATE_ENUM(" ^ class_name ^ ")\n\n");
 
 
+   output_cpp ("bool " ^ class_name ^ "::_hx_isInstanceOf(int inClassId) {\n");
+   output_cpp ("\treturn inClassId == (int)0x00000001 || inClassId == ::hx::EnumBase_obj::_hx_ClassId || inClassId == _hx_ClassId;\n");
+   output_cpp ("}\n");
+
    output_cpp ("int " ^ class_name ^ "::__FindIndex(::String inName)\n{\n");
    output_cpp ("int " ^ class_name ^ "::__FindIndex(::String inName)\n{\n");
    PMap.iter (fun _ constructor ->
    PMap.iter (fun _ constructor ->
       let name = constructor.ef_name in
       let name = constructor.ef_name in
@@ -5390,13 +5397,15 @@ let generate_enum_files baseCtx enum_def super_deps meta =
    output_h ("{\n\ttypedef " ^ super ^ " super;\n");
    output_h ("{\n\ttypedef " ^ super ^ " super;\n");
    output_h ("\t\ttypedef " ^ class_name ^ " OBJ_;\n");
    output_h ("\t\ttypedef " ^ class_name ^ " OBJ_;\n");
    output_h "\n\tpublic:\n";
    output_h "\n\tpublic:\n";
+   output_h ("\t\tenum { _hx_ClassId = " ^ classIdTxt ^ " };\n\n");
    output_h ("\t\t" ^ class_name ^ "() {};\n");
    output_h ("\t\t" ^ class_name ^ "() {};\n");
    output_h ("\t\tHX_DO_ENUM_RTTI;\n");
    output_h ("\t\tHX_DO_ENUM_RTTI;\n");
    output_h ("\t\tstatic void __boot();\n");
    output_h ("\t\tstatic void __boot();\n");
    output_h ("\t\tstatic void __register();\n");
    output_h ("\t\tstatic void __register();\n");
    output_h ("\t\tstatic bool __GetStatic(const ::String &inName, Dynamic &outValue, ::hx::PropertyAccess inCallProp);\n");
    output_h ("\t\tstatic bool __GetStatic(const ::String &inName, Dynamic &outValue, ::hx::PropertyAccess inCallProp);\n");
    output_h ("\t\t::String GetEnumName( ) const { return " ^ (strq (join_class_path class_path "."))  ^ "; }\n" );
    output_h ("\t\t::String GetEnumName( ) const { return " ^ (strq (join_class_path class_path "."))  ^ "; }\n" );
-   output_h ("\t\t::String __ToString() const { return " ^ (strq (just_class_name ^ ".") )^ " + _hx_tag; }\n\n");
+   output_h ("\t\t::String __ToString() const { return " ^ (strq (just_class_name ^ ".") )^ " + _hx_tag; }\n");
+   output_h ("\t\tbool _hx_isInstanceOf(int inClassId);\n\n");
 
 
 
 
    PMap.iter (fun _ constructor ->
    PMap.iter (fun _ constructor ->
@@ -5761,7 +5770,7 @@ let generate_class_files baseCtx super_deps constructor_deps class_def inScripta
       then 0 else 1 in
       then 0 else 1 in
    let scriptable = inScriptable && not class_def.cl_private in
    let scriptable = inScriptable && not class_def.cl_private in
 
 
-   let classId = try Hashtbl.find baseCtx.ctx_type_ids (class_text class_def.cl_path) with Not_found -> Int32.of_int 0 in
+   let classId = try Hashtbl.find baseCtx.ctx_type_ids (class_text class_def.cl_path) with Not_found -> Int32.zero in
    let classIdTxt = Printf.sprintf "0x%08lx" classId in
    let classIdTxt = Printf.sprintf "0x%08lx" classId in
 
 
    (* Config *)
    (* Config *)
@@ -8564,6 +8573,17 @@ let generate_source ctx =
          if (is_internal) then
          if (is_internal) then
             (if (debug>1) then print_endline (" internal enum " ^ name ))
             (if (debug>1) then print_endline (" internal enum " ^ name ))
          else begin
          else begin
+            let rec makeId enum_name seed =
+               let id = gen_hash32 seed enum_name in
+               (* reserve first 100 ids for runtime *)
+               if id < Int32.of_int 100 || Hashtbl.mem existingIds id then
+                  makeId enum_name (seed+100)
+               else begin
+                  Hashtbl.add existingIds id true;
+                  Hashtbl.add ctx.ctx_type_ids enum_name id;
+               end in
+            makeId name 0;
+
             let meta = Texpr.build_metadata common_ctx.basic object_def in
             let meta = Texpr.build_metadata common_ctx.basic object_def in
             if (enum_def.e_extern) then
             if (enum_def.e_extern) then
                (if (debug>1) then print_endline ("external enum " ^ name ));
                (if (debug>1) then print_endline ("external enum " ^ name ));

+ 41 - 7
src/generators/genhl.ml

@@ -361,7 +361,7 @@ let make_debug ctx arr =
 let fake_tnull =
 let fake_tnull =
 	{null_abstract with
 	{null_abstract with
 		a_path = [],"Null";
 		a_path = [],"Null";
-		a_params = [{ttp_name = "T"; ttp_type = t_dynamic; ttp_default = None}];
+		a_params = [mk_type_param null_class TPHType None None];
 	}
 	}
 
 
 let get_rec_cache ctx t none_callback not_found_callback =
 let get_rec_cache ctx t none_callback not_found_callback =
@@ -435,7 +435,7 @@ let rec to_type ?tref ctx t =
 		HAbstract (name, alloc_string ctx name)
 		HAbstract (name, alloc_string ctx name)
 	| TInst (c,pl) ->
 	| TInst (c,pl) ->
 		(match c.cl_kind with
 		(match c.cl_kind with
-		| KTypeParameter tl ->
+		| KTypeParameter ttp ->
 			let rec loop = function
 			let rec loop = function
 				| [] -> HDyn
 				| [] -> HDyn
 				| t :: tl ->
 				| t :: tl ->
@@ -443,7 +443,7 @@ let rec to_type ?tref ctx t =
 					| TInst (c,_) as t when not (has_class_flag c CInterface) -> to_type ?tref ctx t
 					| TInst (c,_) as t when not (has_class_flag c CInterface) -> to_type ?tref ctx t
 					| _ -> loop tl
 					| _ -> loop tl
 			in
 			in
-			loop tl
+			loop (get_constraints ttp)
 		| _ -> class_type ~tref ctx c pl false)
 		| _ -> class_type ~tref ctx c pl false)
 	| TAbstract ({a_path = [],"Null"},[t1]) ->
 	| TAbstract ({a_path = [],"Null"},[t1]) ->
 		let t = to_type ?tref ctx t1 in
 		let t = to_type ?tref ctx t1 in
@@ -1384,7 +1384,7 @@ and get_access ctx e =
 				let t = to_type ctx t in
 				let t = to_type ctx t in
 				AArray (a,(t,t),i)
 				AArray (a,(t,t),i)
 			| TInst ({ cl_path = ["hl"],"Abstract" },[TInst({ cl_kind = KExpr (EConst (String("hl_carray",_)),_) },_)]) ->
 			| TInst ({ cl_path = ["hl"],"Abstract" },[TInst({ cl_kind = KExpr (EConst (String("hl_carray",_)),_) },_)]) ->
-				let a = eval_null_check ctx a in
+				let a = eval_expr ctx a in
 				hold ctx a;
 				hold ctx a;
 				let i = eval_to ctx i HI32 in
 				let i = eval_to ctx i HI32 in
 				free ctx a;
 				free ctx a;
@@ -2082,6 +2082,32 @@ and eval_expr ctx e =
 			| AInstanceField (f, index) -> op ctx (OPrefetch (eval_expr ctx f, index + 1, mode))
 			| AInstanceField (f, index) -> op ctx (OPrefetch (eval_expr ctx f, index + 1, mode))
 			| _ -> op ctx (OPrefetch (eval_expr ctx value, 0, mode)));
 			| _ -> op ctx (OPrefetch (eval_expr ctx value, 0, mode)));
 			alloc_tmp ctx HVoid
 			alloc_tmp ctx HVoid
+        | "$unsafecast", [value] ->
+			let r = alloc_tmp ctx (to_type ctx e.etype) in
+            op ctx (OUnsafeCast (r, eval_expr ctx value));
+			r
+		| "$asm", [mode; value] ->
+			let mode = (match get_const mode with
+				| TInt m -> Int32.to_int m
+				| _ -> abort "Constant mode required" e.epos
+			) in
+			let value = (match get_const value with
+				| TInt m -> Int32.to_int m
+				| _ -> abort "Constant value required" e.epos
+			) in
+			op ctx (OAsm (mode, value, 0));
+			alloc_tmp ctx HVoid
+		| "$asm", [mode; value; reg] ->
+			let mode = (match get_const mode with
+				| TInt m -> Int32.to_int m
+				| _ -> abort "Constant mode required" e.epos
+			) in
+			let value = (match get_const value with
+				| TInt m -> Int32.to_int m
+				| _ -> abort "Constant value required" e.epos
+			) in
+			op ctx (OAsm (mode, value, (eval_expr ctx reg) + 1));
+			alloc_tmp ctx HVoid
 		| _ ->
 		| _ ->
 			abort ("Unknown native call " ^ s) e.epos)
 			abort ("Unknown native call " ^ s) e.epos)
 	| TEnumIndex v ->
 	| TEnumIndex v ->
@@ -2169,9 +2195,9 @@ and eval_expr ctx e =
 				match follow t with
 				match follow t with
 				| TFun (_,rt) ->
 				| TFun (_,rt) ->
 					(match follow rt with
 					(match follow rt with
-					| TInst({ cl_kind = KTypeParameter tl },_) ->
+					| TInst({ cl_kind = KTypeParameter ttp },_) ->
 						(* don't allow if we have a constraint virtual, see hxbit.Serializer.getRef *)
 						(* don't allow if we have a constraint virtual, see hxbit.Serializer.getRef *)
-						not (List.exists (fun t -> match to_type ctx t with HVirtual _ -> true | _ -> false) tl)
+						not (List.exists (fun t -> match to_type ctx t with HVirtual _ -> true | _ -> false) (get_constraints ttp))
 					| _ -> false)
 					| _ -> false)
 				| _ ->
 				| _ ->
 					false
 					false
@@ -2469,6 +2495,14 @@ and eval_expr ctx e =
 				free ctx ra;
 				free ctx ra;
 				free ctx ridx;
 				free ctx ridx;
 				v
 				v
+            | ACArray (ra, _, ridx) ->
+				hold ctx ra;
+				hold ctx ridx;
+                let v = value() in
+                op ctx (OSetArray (ra,ridx,v));
+                free ctx ridx;
+                free ctx ra;
+                v
 			| ADynamic (ethis,f) ->
 			| ADynamic (ethis,f) ->
 				let obj = eval_null_check ctx ethis in
 				let obj = eval_null_check ctx ethis in
 				hold ctx obj;
 				hold ctx obj;
@@ -2480,7 +2514,7 @@ and eval_expr ctx e =
 				let r = value() in
 				let r = value() in
 				op ctx (OSetEnumField (ctx.m.mcaptreg,index,r));
 				op ctx (OSetEnumField (ctx.m.mcaptreg,index,r));
 				r
 				r
-			| AEnum _ | ANone | AInstanceFun _ | AInstanceProto _ | AStaticFun _ | AVirtualMethod _ | ACArray _ ->
+			| AEnum _ | ANone | AInstanceFun _ | AInstanceProto _ | AStaticFun _ | AVirtualMethod _ ->
 				die "" __LOC__)
 				die "" __LOC__)
 		| OpBoolOr ->
 		| OpBoolOr ->
 			let r = alloc_tmp ctx HBool in
 			let r = alloc_tmp ctx HBool in

+ 11 - 144
src/generators/genjs.ml

@@ -21,24 +21,7 @@ open Globals
 open Ast
 open Ast
 open Type
 open Type
 open Common
 open Common
-
-type sourcemap = {
-	sources : (string) DynArray.t;
-	sources_hash : (string, int) Hashtbl.t;
-	mappings : Rbuffer.t;
-
-	mutable source_last_pos : sourcemap_pos;
-	mutable print_comma : bool;
-	mutable output_last_col : int;
-	mutable output_current_col : int;
-	mutable current_expr : sourcemap_pos option;
-}
-
-and sourcemap_pos = {
-	file : int;
-	line : int;
-	col : int;
-}
+open JsSourcemap
 
 
 type ctx = {
 type ctx = {
 	com : Common.context;
 	com : Common.context;
@@ -154,13 +137,13 @@ let static_field ctx c f =
 
 
 let module_field m f =
 let module_field m f =
 	try
 	try
-		fst (TypeloadCheck.get_native_name f.cf_meta)
+		fst (Naming.get_native_name f.cf_meta)
 	with Not_found ->
 	with Not_found ->
 		Path.flat_path m.m_path ^ "_" ^ f.cf_name
 		Path.flat_path m.m_path ^ "_" ^ f.cf_name
 
 
 let module_field_expose_path mpath f =
 let module_field_expose_path mpath f =
 	try
 	try
-		fst (TypeloadCheck.get_native_name f.cf_meta)
+		fst (Naming.get_native_name f.cf_meta)
 	with Not_found ->
 	with Not_found ->
 		(dot_path mpath) ^ "." ^ f.cf_name
 		(dot_path mpath) ^ "." ^ f.cf_name
 
 
@@ -169,98 +152,6 @@ let add_feature ctx = Common.add_feature ctx.com
 
 
 let unsupported p = abort "This expression cannot be compiled to Javascript" p
 let unsupported p = abort "This expression cannot be compiled to Javascript" p
 
 
-let encode_mapping smap pos =
-	if smap.print_comma then
-		Rbuffer.add_char smap.mappings ','
-	else
-		smap.print_comma <- true;
-
-	let base64_vlq number =
-		let encode_digit digit =
-			let chars = [|
-				'A';'B';'C';'D';'E';'F';'G';'H';'I';'J';'K';'L';'M';'N';'O';'P';
-				'Q';'R';'S';'T';'U';'V';'W';'X';'Y';'Z';'a';'b';'c';'d';'e';'f';
-				'g';'h';'i';'j';'k';'l';'m';'n';'o';'p';'q';'r';'s';'t';'u';'v';
-				'w';'x';'y';'z';'0';'1';'2';'3';'4';'5';'6';'7';'8';'9';'+';'/'
-			|] in
-			Array.unsafe_get chars digit
-		in
-		let to_vlq number =
-			if number < 0 then
-				((-number) lsl 1) + 1
-			else
-				number lsl 1
-		in
-		let rec loop vlq =
-			let shift = 5 in
-			let base = 1 lsl shift in
-			let mask = base - 1 in
-			let continuation_bit = base in
-			let digit = vlq land mask in
-			let next = vlq asr shift in
-			Rbuffer.add_char smap.mappings (encode_digit (
-				if next > 0 then digit lor continuation_bit else digit));
-			if next > 0 then loop next else ()
-		in
-		loop (to_vlq number)
-	in
-
-	base64_vlq (smap.output_current_col - smap.output_last_col);
-	base64_vlq (pos.file - smap.source_last_pos.file);
-	base64_vlq (pos.line - smap.source_last_pos.line);
-	base64_vlq (pos.col - smap.source_last_pos.col);
-
-	smap.source_last_pos <- pos;
-	smap.output_last_col <- smap.output_current_col
-
-let noop () = ()
-
-let add_mapping smap pos =
-	if pos.pmin < 0 then noop else
-
-	let file = try
-		Hashtbl.find smap.sources_hash pos.pfile
-	with Not_found ->
-		let length = DynArray.length smap.sources in
-		Hashtbl.replace smap.sources_hash pos.pfile length;
-		DynArray.add smap.sources pos.pfile;
-		length
-	in
-
-	let pos =
-		let line, col = Lexer.find_pos pos in
-		let line = line - 1 in
-		{ file = file; line = line; col = col }
-	in
-
-	if smap.source_last_pos <> pos then begin
-		let old_current_expr = smap.current_expr in
-		smap.current_expr <- Some pos;
-		encode_mapping smap pos;
-		(fun () -> smap.current_expr <- old_current_expr)
-	end else
-		noop
-
-let add_mapping ctx e =
-	Option.map_default (fun smap -> add_mapping smap e.epos) noop ctx.smap
-
-let handle_newlines ctx str =
-	Option.may (fun smap ->
-		let rec loop from =
-			try begin
-				let next = String.index_from str from '\n' + 1 in
-				Rbuffer.add_char smap.mappings ';';
-				smap.output_last_col <- 0;
-				smap.output_current_col <- 0;
-				smap.print_comma <- false;
-				Option.may (encode_mapping smap) smap.current_expr;
-				loop next
-			end with Not_found ->
-				smap.output_current_col <- smap.output_current_col + (String.length str - from);
-		in
-		loop 0
-	) ctx.smap
-
 let flush ctx =
 let flush ctx =
 	let chan =
 	let chan =
 		match ctx.chan with
 		match ctx.chan with
@@ -275,43 +166,16 @@ let flush ctx =
 
 
 let spr ctx s =
 let spr ctx s =
 	ctx.separator <- false;
 	ctx.separator <- false;
-	handle_newlines ctx s;
+	handle_newlines ctx.smap s;
 	Rbuffer.add_string ctx.buf s
 	Rbuffer.add_string ctx.buf s
 
 
 let print ctx =
 let print ctx =
 	ctx.separator <- false;
 	ctx.separator <- false;
 	Printf.kprintf (fun s -> begin
 	Printf.kprintf (fun s -> begin
-		handle_newlines ctx s;
+		handle_newlines ctx.smap s;
 		Rbuffer.add_string ctx.buf s
 		Rbuffer.add_string ctx.buf s
 	end)
 	end)
 
 
-let write_mappings ctx smap =
-	let basefile = Filename.basename ctx.com.file in
-	print ctx "\n//# sourceMappingURL=%s.map" (url_encode_s basefile);
-	let channel = open_out_bin (ctx.com.file ^ ".map") in
-	let sources = DynArray.to_list smap.sources in
-	let to_url file =
-		ExtString.String.map (fun c -> if c == '\\' then '/' else c) (Path.get_full_path file)
-	in
-	output_string channel "{\n";
-	output_string channel "\"version\":3,\n";
-	output_string channel ("\"file\":\"" ^ (String.concat "\\\\" (ExtString.String.nsplit basefile "\\")) ^ "\",\n");
-	output_string channel ("\"sourceRoot\":\"\",\n");
-	output_string channel ("\"sources\":[" ^
-		(String.concat "," (List.map (fun s -> "\"file:///" ^ to_url s ^ "\"") sources)) ^
-		"],\n");
-	if Common.defined ctx.com Define.SourceMapContent then begin
-		output_string channel ("\"sourcesContent\":[" ^
-			(String.concat "," (List.map (fun s -> try "\"" ^ StringHelper.s_escape (Std.input_file ~bin:true s) ^ "\"" with _ -> "null") sources)) ^
-			"],\n");
-	end;
-	output_string channel "\"names\":[],\n";
-	output_string channel "\"mappings\":\"";
-	Rbuffer.output_buffer channel smap.mappings;
-	output_string channel "\"\n";
-	output_string channel "}";
-	close_out channel
-
 let newline ctx =
 let newline ctx =
 	match Rbuffer.nth ctx.buf (Rbuffer.length ctx.buf - 1) with
 	match Rbuffer.nth ctx.buf (Rbuffer.length ctx.buf - 1) with
 	| '}' | '{' | ':' | ';' when not ctx.separator -> print ctx "\n%s" ctx.tabs
 	| '}' | '{' | ':' | ';' when not ctx.separator -> print ctx "\n%s" ctx.tabs
@@ -613,7 +477,7 @@ and add_objectdecl_parens e =
 	loop e
 	loop e
 
 
 and gen_expr ctx e =
 and gen_expr ctx e =
-	let clear_mapping = add_mapping ctx e in
+	let clear_mapping = add_mapping ctx.smap e in
 	(match e.eexpr with
 	(match e.eexpr with
 	| TConst c -> gen_constant ctx e.epos c
 	| TConst c -> gen_constant ctx e.epos c
 	| TLocal v -> spr ctx (ident v.v_name)
 	| TLocal v -> spr ctx (ident v.v_name)
@@ -978,7 +842,7 @@ and gen_block_element ?(newline_after=false) ?(keep_blocks=false) ctx e =
 		if newline_after then newline ctx
 		if newline_after then newline ctx
 
 
 and gen_value ctx e =
 and gen_value ctx e =
-	let clear_mapping = add_mapping ctx e in
+	let clear_mapping = add_mapping ctx.smap e in
 	let assign e =
 	let assign e =
 		mk (TBinop (Ast.OpAssign,
 		mk (TBinop (Ast.OpAssign,
 			mk (TLocal (match ctx.in_value with None -> die "" __LOC__ | Some v -> v)) t_dynamic e.epos,
 			mk (TLocal (match ctx.in_value with None -> die "" __LOC__ | Some v -> v)) t_dynamic e.epos,
@@ -2138,7 +2002,10 @@ let generate com =
 	);
 	);
 
 
 	(match ctx.smap with
 	(match ctx.smap with
-	| Some smap -> write_mappings ctx smap
+	| Some smap ->
+		write_mappings ctx.com smap "file:///";
+		let basefile = Filename.basename com.file in
+		print ctx "\n//# sourceMappingURL=%s.map" (url_encode_s basefile);
 	| None -> try Sys.remove (com.file ^ ".map") with _ -> ());
 	| None -> try Sys.remove (com.file ^ ".map") with _ -> ());
 	flush ctx;
 	flush ctx;
 	Option.may (fun chan -> close_out chan) ctx.chan
 	Option.may (fun chan -> close_out chan) ctx.chan

+ 17 - 15
src/generators/genjvm.ml

@@ -202,8 +202,11 @@ let rec jsignature_of_type gctx stack t =
 		TObject((["haxe";"root"],"Array"),[TType(WNone,t)])
 		TObject((["haxe";"root"],"Array"),[TType(WNone,t)])
 	| TInst({cl_path = (["java"],"NativeArray")},[t]) ->
 	| TInst({cl_path = (["java"],"NativeArray")},[t]) ->
 		TArray(jsignature_of_type t,None)
 		TArray(jsignature_of_type t,None)
-	| TInst({cl_kind = KTypeParameter [t]},_) when t != t_dynamic -> jsignature_of_type t
-	| TInst({cl_kind = KTypeParameter _; cl_path = (_,name)},_) -> TTypeParameter name
+	| TInst({cl_kind = KTypeParameter ttp; cl_path = (_,name)},_) ->
+		begin match get_constraints ttp with
+			| [t] when t != t_dynamic -> jsignature_of_type t
+			| _ -> TTypeParameter name
+		end
 	| TInst({cl_path = ["_Class"],"Class_Impl_"},_) -> java_class_sig
 	| TInst({cl_path = ["_Class"],"Class_Impl_"},_) -> java_class_sig
 	| TInst({cl_path = ["_Enum"],"Enum_Impl_"},_) -> java_class_sig
 	| TInst({cl_path = ["_Enum"],"Enum_Impl_"},_) -> java_class_sig
 	| TInst(c,tl) -> TObject(c.cl_path,List.map jtype_argument_of_type tl)
 	| TInst(c,tl) -> TObject(c.cl_path,List.map jtype_argument_of_type tl)
@@ -392,7 +395,7 @@ let is_interface_var_access c cf =
 let follow = Abstract.follow_with_abstracts
 let follow = Abstract.follow_with_abstracts
 
 
 class haxe_exception gctx (t : Type.t) =
 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
 	and native_type = jsignature_of_type gctx t in
 object(self)
 object(self)
 	val native_path = (match native_type with TObject(path,_) -> path | _ -> die "" __LOC__)
 	val native_path = (match native_type with TObject(path,_) -> path | _ -> die "" __LOC__)
@@ -2113,7 +2116,11 @@ class texpr_to_jvm
 		| TEnumParameter(e1,ef,i) ->
 		| TEnumParameter(e1,ef,i) ->
 			self#texpr rvalue_any e1;
 			self#texpr rvalue_any e1;
 			let path,name,jsig_arg = match follow ef.ef_type with
 			let path,name,jsig_arg = match follow ef.ef_type with
-				| TFun(tl,TEnum(en,_)) ->
+				| TFun(tl,tr) ->
+					let en = match follow tr with
+						| TEnum(en,_) -> en
+						| _ -> die "" __LOC__
+					in
 					let n,_,t = List.nth tl i in
 					let n,_,t = List.nth tl i in
 					en.e_path,n,self#vtype t
 					en.e_path,n,self#vtype t
 				| _ -> die "" __LOC__
 				| _ -> die "" __LOC__
@@ -2127,7 +2134,7 @@ class texpr_to_jvm
 			self#texpr rvalue_any e1;
 			self#texpr rvalue_any e1;
 			(* There could be something like `throw throw`, so we should only throw if we aren't terminated (issue #10363) *)
 			(* 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 (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
 					let exc = new haxe_exception gctx e1.etype in
 					if not (List.exists (fun exc' -> exc#is_assignable_to exc') caught_exceptions) then
 					if not (List.exists (fun exc' -> exc#is_assignable_to exc') caught_exceptions) then
 						jm#add_thrown_exception exc#get_native_path;
 						jm#add_thrown_exception exc#get_native_path;
@@ -2640,16 +2647,11 @@ class tclass_to_jvm gctx c = object(self)
 		end
 		end
 
 
 	method private generate_signature =
 	method private generate_signature =
-		jc#set_type_parameters (List.map (fun tp ->
-			let jsigs = match follow tp.ttp_type with
-			| TInst({cl_kind = KTypeParameter tl},_) ->
-				List.map (fun t ->
-					get_boxed_type (jsignature_of_type gctx t)
-				 ) tl
-			| _ ->
-				[]
-			in
-			(tp.ttp_name,jsigs)
+		jc#set_type_parameters (List.map (fun ttp ->
+			let jsigs = List.map (fun t ->
+				get_boxed_type (jsignature_of_type gctx t)
+			) (get_constraints ttp) in
+			(ttp.ttp_name,jsigs)
 		) c.cl_params);
 		) c.cl_params);
 		match c.cl_super with
 		match c.cl_super with
 			| Some(c,tl) -> jc#set_super_parameters (List.map (jtype_argument_of_type gctx []) tl)
 			| Some(c,tl) -> jc#set_super_parameters (List.map (jtype_argument_of_type gctx []) tl)

+ 40 - 5
src/generators/genlua.ml

@@ -20,11 +20,13 @@
  * DEALINGS IN THE SOFTWARE.
  * DEALINGS IN THE SOFTWARE.
  *)
  *)
 
 
+open Extlib_leftovers
 open Ast
 open Ast
 open Type
 open Type
 open Common
 open Common
 open ExtList
 open ExtList
 open Error
 open Error
+open JsSourcemap
 
 
 type pos = Globals.pos
 type pos = Globals.pos
 
 
@@ -32,6 +34,7 @@ type ctx = {
     com : Common.context;
     com : Common.context;
     buf : Buffer.t;
     buf : Buffer.t;
     packages : (string list,unit) Hashtbl.t;
     packages : (string list,unit) Hashtbl.t;
+    smap : sourcemap option;
     mutable current : tclass;
     mutable current : tclass;
     mutable statics : (tclass * tclass_field * texpr) list;
     mutable statics : (tclass * tclass_field * texpr) list;
     mutable inits : texpr list;
     mutable inits : texpr list;
@@ -143,11 +146,15 @@ let temp ctx =
 
 
 let spr ctx s =
 let spr ctx s =
     ctx.separator <- false;
     ctx.separator <- false;
+	handle_newlines ctx.smap s;
     Buffer.add_string ctx.buf s
     Buffer.add_string ctx.buf s
 
 
 let print ctx =
 let print ctx =
     ctx.separator <- false;
     ctx.separator <- false;
-    Printf.kprintf (fun s -> Buffer.add_string ctx.buf s)
+    Printf.kprintf (fun s -> begin
+        handle_newlines ctx.smap s;
+        Buffer.add_string ctx.buf s
+    end)
 
 
 let newline ctx = print ctx "\n%s" ctx.tabs
 let newline ctx = print ctx "\n%s" ctx.tabs
 
 
@@ -281,7 +288,7 @@ let mk_mr_select com e ecall name =
 (* from genphp *)
 (* from genphp *)
 let rec is_string_type t =
 let rec is_string_type t =
     match follow t with
     match follow t with
-    | TInst ({cl_kind = KTypeParameter constraints}, _) -> List.exists is_string_type constraints
+    | TInst ({cl_kind = KTypeParameter ttp}, _) -> List.exists is_string_type (get_constraints ttp)
     | TInst ({cl_path = ([], "String")}, _) -> true
     | TInst ({cl_path = ([], "String")}, _) -> true
     | TAnon a ->
     | TAnon a ->
         (match !(a.a_status) with
         (match !(a.a_status) with
@@ -582,9 +589,10 @@ and gen_loop ctx cond do_while e =
     if do_while then
     if do_while then
         print ctx " or _hx_do_first_%i" ctx.break_depth;
         print ctx " or _hx_do_first_%i" ctx.break_depth;
     print ctx " do ";
     print ctx " do ";
-    if do_while then
+    if do_while then begin
         newline ctx;
         newline ctx;
         println ctx "_hx_do_first_%i = false;" ctx.break_depth;
         println ctx "_hx_do_first_%i = false;" ctx.break_depth;
+    end;
     if will_continue then print ctx "repeat ";
     if will_continue then print ctx "repeat ";
     gen_block_element ctx e;
     gen_block_element ctx e;
     if will_continue then begin
     if will_continue then begin
@@ -661,6 +669,7 @@ and lua_arg_name(a,_) =
         | _, _, _ ->  ident a.v_name;
         | _, _, _ ->  ident a.v_name;
 
 
 and gen_expr ?(local=true) ctx e = begin
 and gen_expr ?(local=true) ctx e = begin
+    let clear_mapping = add_mapping ctx.smap e in
     match e.eexpr with
     match e.eexpr with
       TConst c ->
       TConst c ->
         gen_constant ctx e.epos c;
         gen_constant ctx e.epos c;
@@ -1042,13 +1051,16 @@ and gen_expr ?(local=true) ctx e = begin
     | TCast (e1,None) ->
     | TCast (e1,None) ->
         gen_value ctx e1;
         gen_value ctx e1;
     | TIdent s ->
     | TIdent s ->
-        spr ctx s
+        spr ctx s;
+
+    clear_mapping ()
 end;
 end;
 
 
     (* gen_block_element handles expressions that map to "statements" in lua. *)
     (* gen_block_element handles expressions that map to "statements" in lua. *)
     (* It handles no-op situations, and ensures that expressions are formatted with newlines *)
     (* It handles no-op situations, and ensures that expressions are formatted with newlines *)
 and gen_block_element ctx e  =
 and gen_block_element ctx e  =
     ctx.iife_assign <- false;
     ctx.iife_assign <- false;
+    let clear_mapping = add_mapping ctx.smap e in
     begin match e.eexpr with
     begin match e.eexpr with
         | TTypeExpr _ | TConst _ | TLocal _ | TFunction _ ->
         | TTypeExpr _ | TConst _ | TLocal _ | TFunction _ ->
             ()
             ()
@@ -1108,6 +1120,7 @@ and gen_block_element ctx e  =
             gen_expr ctx e;
             gen_expr ctx e;
             semicolon ctx;
             semicolon ctx;
     end;
     end;
+    clear_mapping ()
 
 
 and is_const_null e =
 and is_const_null e =
     match e.eexpr with
     match e.eexpr with
@@ -1146,6 +1159,7 @@ and gen_anon_value ctx e =
         gen_value ctx e
         gen_value ctx e
 
 
 and gen_value ctx e =
 and gen_value ctx e =
+    let clear_mapping = add_mapping ctx.smap e in
     let assign e =
     let assign e =
         mk (TBinop (Ast.OpAssign,
         mk (TBinop (Ast.OpAssign,
                     mk (TLocal (match ctx.in_value with None -> Globals.die "" __LOC__ | Some v -> v)) t_dynamic e.epos,
                     mk (TLocal (match ctx.in_value with None -> Globals.die "" __LOC__ | Some v -> v)) t_dynamic e.epos,
@@ -1279,7 +1293,8 @@ and gen_value ctx e =
         gen_block_element ctx (mk (TTry (block (assign b),
         gen_block_element ctx (mk (TTry (block (assign b),
                                          List.map (fun (v,e) -> v, block (assign e)) catchs
                                          List.map (fun (v,e) -> v, block (assign e)) catchs
                                         )) e.etype e.epos);
                                         )) e.etype e.epos);
-        v()
+        v();
+    clear_mapping ()
 
 
 and gen_tbinop ctx op e1 e2 =
 and gen_tbinop ctx op e1 e2 =
     (match op, e1.eexpr, e2.eexpr with
     (match op, e1.eexpr, e2.eexpr with
@@ -1865,10 +1880,26 @@ let generate_type_forward ctx = function
     | TTypeDecl _ | TAbstractDecl _ -> ()
     | TTypeDecl _ | TAbstractDecl _ -> ()
 
 
 let alloc_ctx com =
 let alloc_ctx com =
+    let smap =
+		if com.debug || Common.defined com Define.SourceMap then
+			Some {
+				source_last_pos = { file = 0; line = 0; col = 0};
+				print_comma = false;
+				output_last_col = 0;
+				output_current_col = 0;
+				sources = DynArray.create();
+				sources_hash = Hashtbl.create 0;
+				mappings = Rbuffer.create 16;
+				current_expr = None;
+			}
+		else
+			None
+	in
     let ctx = {
     let ctx = {
         com = com;
         com = com;
         buf = Buffer.create 16000;
         buf = Buffer.create 16000;
         packages = Hashtbl.create 0;
         packages = Hashtbl.create 0;
+        smap = smap;
         statics = [];
         statics = [];
         inits = [];
         inits = [];
         current = null_class;
         current = null_class;
@@ -2174,6 +2205,10 @@ let generate com =
     if anyExposed then
     if anyExposed then
         println ctx "return _hx_exports";
         println ctx "return _hx_exports";
 
 
+    (match ctx.smap with
+    | Some smap -> write_mappings ctx.com smap ""
+    | None -> try Sys.remove (com.file ^ ".map") with _ -> ());
+
     let ch = open_out_bin com.file in
     let ch = open_out_bin com.file in
     output_string ch (Buffer.contents ctx.buf);
     output_string ch (Buffer.contents ctx.buf);
     close_out ch
     close_out ch

+ 1 - 2
src/generators/genpy.ml

@@ -38,8 +38,7 @@ module Utils = struct
 			abort (Printf.sprintf "Could not find type %s\n" (s_type_path path)) null_pos
 			abort (Printf.sprintf "Could not find type %s\n" (s_type_path path)) null_pos
 
 
 	let mk_static_field c cf p =
 	let mk_static_field c cf p =
-			let ta = mk_anon ~fields:c.cl_statics (ref (ClassStatics c)) in
-			let ethis = mk (TTypeExpr (TClassDecl c)) ta p in
+			let ethis = Texpr.Builder.make_static_this c p in
 			let t = monomorphs cf.cf_params cf.cf_type in
 			let t = monomorphs cf.cf_params cf.cf_type in
 			mk (TField (ethis,(FStatic (c,cf)))) t p
 			mk (TField (ethis,(FStatic (c,cf)))) t p
 
 

+ 1 - 3
src/generators/genswf.ml

@@ -149,9 +149,7 @@ let build_dependencies t =
 		| Some x -> add_inherit x);
 		| Some x -> add_inherit x);
 		List.iter (fun tp ->
 		List.iter (fun tp ->
 			(* add type-parameters constraints dependencies *)
 			(* add type-parameters constraints dependencies *)
-			match follow tp.ttp_type with
-			| TInst (c,_) -> List.iter add_inherit c.cl_implements
-			| _ -> ()
+			List.iter add_inherit tp.ttp_class.cl_implements
 		) c.cl_params;
 		) c.cl_params;
 		List.iter add_inherit c.cl_implements;
 		List.iter add_inherit c.cl_implements;
 	| TEnumDecl e when not e.e_extern ->
 	| TEnumDecl e when not e.e_extern ->

+ 4 - 4
src/generators/genswf9.ml

@@ -238,8 +238,8 @@ let rec type_id ctx t =
 		| _ -> def())
 		| _ -> def())
 	| TInst (c,_) ->
 	| TInst (c,_) ->
 		(match c.cl_kind with
 		(match c.cl_kind with
-		| KTypeParameter l ->
-			(match l with
+		| KTypeParameter ttp ->
+			(match get_constraints ttp with
 			| [t] -> type_id ctx t
 			| [t] -> type_id ctx t
 			| _ -> type_path ctx ([],"Object"))
 			| _ -> type_path ctx ([],"Object"))
 		| _ ->
 		| _ ->
@@ -1066,7 +1066,7 @@ let rec gen_expr_content ctx retval e =
 		gen_constant ctx c e.etype e.epos
 		gen_constant ctx c e.etype e.epos
 	| TThrow e ->
 	| TThrow e ->
 		ctx.infos.icond <- true;
 		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")));
 			getvar ctx (VGlobal (type_path ctx (["flash"],"Boot")));
 			let id = type_path ctx (["flash";"errors"],"Error") in
 			let id = type_path ctx (["flash";"errors"],"Error") in
 			write ctx (HFindPropStrict id);
 			write ctx (HFindPropStrict id);
@@ -1240,7 +1240,7 @@ let rec gen_expr_content ctx retval e =
 					| _ -> Type.iter call_loop e
 					| _ -> Type.iter call_loop e
 				in
 				in
 				let has_call = (try call_loop e; false with Exit -> true) 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);
 					getvar ctx (gen_local_access ctx v e.epos Read);
 					write ctx (HAsType (type_path ctx (["flash";"errors"],"Error")));
 					write ctx (HAsType (type_path ctx (["flash";"errors"],"Error")));
 					let j = jump ctx J3False in
 					let j = jump ctx J3False in

+ 16 - 2
src/generators/hl2c.ml

@@ -990,7 +990,15 @@ let generate_function ctx f =
 		| OGetMem (r,b,idx) ->
 		| OGetMem (r,b,idx) ->
 			sexpr "%s = *(%s*)(%s + %s)" (reg r) (ctype (rtype r)) (reg b) (reg idx)
 			sexpr "%s = *(%s*)(%s + %s)" (reg r) (ctype (rtype r)) (reg b) (reg idx)
 		| OGetArray (r, arr, idx) ->
 		| OGetArray (r, arr, idx) ->
-			sexpr "%s = ((%s*)(%s + 1))[%s]" (reg r) (ctype (rtype r)) (reg arr) (reg idx)
+            (match rtype arr with
+            | HAbstract _ ->
+                (match rtype r with
+                | HStruct _ | HObj _ ->
+			        sexpr "%s = ((%s)%s) + %s" (reg r) (ctype (rtype r)) (reg arr) (reg idx)
+                | _ ->
+			        sexpr "%s = ((%s*)%s)[%s]" (reg r) (ctype (rtype r)) (reg arr) (reg idx))
+            | _ ->
+			    sexpr "%s = ((%s*)(%s + 1))[%s]" (reg r) (ctype (rtype r)) (reg arr) (reg idx))
 		| OSetUI8 (b,idx,r) ->
 		| OSetUI8 (b,idx,r) ->
 			sexpr "*(unsigned char*)(%s + %s) = (unsigned char)%s" (reg b) (reg idx) (reg r)
 			sexpr "*(unsigned char*)(%s + %s) = (unsigned char)%s" (reg b) (reg idx) (reg r)
 		| OSetUI16 (b,idx,r) ->
 		| OSetUI16 (b,idx,r) ->
@@ -998,7 +1006,11 @@ let generate_function ctx f =
 		| OSetMem (b,idx,r) ->
 		| OSetMem (b,idx,r) ->
 			sexpr "*(%s*)(%s + %s) = %s" (ctype (rtype r)) (reg b) (reg idx) (reg r)
 			sexpr "*(%s*)(%s + %s) = %s" (ctype (rtype r)) (reg b) (reg idx) (reg r)
 		| OSetArray (arr,idx,v) ->
 		| OSetArray (arr,idx,v) ->
-			sexpr "((%s*)(%s + 1))[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v)
+            (match rtype arr with
+            | HAbstract _ ->
+			    sexpr "((%s*)%s)[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v)
+            | _ ->
+			    sexpr "((%s*)(%s + 1))[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v))
 		| OSafeCast (r,v) ->
 		| OSafeCast (r,v) ->
 			let tsrc = rtype v in
 			let tsrc = rtype v in
 			let t = rtype r in
 			let t = rtype r in
@@ -1098,6 +1110,8 @@ let generate_function ctx f =
 				Globals.die "" __LOC__
 				Globals.die "" __LOC__
 			)) in
 			)) in
 			sexpr "__hl_prefetch_m%d(%s)" mode expr
 			sexpr "__hl_prefetch_m%d(%s)" mode expr
+		| OAsm _ ->
+			sexpr "UNSUPPORTED ASM OPCODE";
 	) f.code;
 	) f.code;
 	flush_options (Array.length f.code);
 	flush_options (Array.length f.code);
 	unblock();
 	unblock();

+ 13 - 0
src/generators/hlcode.ml

@@ -202,6 +202,7 @@ type opcode =
 	| ORefOffset of reg * reg * reg
 	| ORefOffset of reg * reg * reg
 	| ONop of string
 	| ONop of string
 	| OPrefetch of reg * field index * int
 	| OPrefetch of reg * field index * int
+    | OAsm of int * int * reg
 
 
 type fundecl = {
 type fundecl = {
 	fpath : string * string;
 	fpath : string * string;
@@ -574,6 +575,18 @@ let ostr fstr o =
 	| ORefOffset (r,r2,off) -> Printf.sprintf "refoffset %d, %d, %d" r r2 off
 	| ORefOffset (r,r2,off) -> Printf.sprintf "refoffset %d, %d, %d" r r2 off
 	| ONop s -> if s = "" then "nop" else "nop " ^ s
 	| ONop s -> if s = "" then "nop" else "nop " ^ s
 	| OPrefetch (r,f,mode) -> Printf.sprintf "prefetch %d[%d] %d" r f mode
 	| OPrefetch (r,f,mode) -> Printf.sprintf "prefetch %d[%d] %d" r f mode
+	| OAsm (mode, value, reg) ->
+		match mode with
+		| 0 when reg = 0 ->
+			Printf.sprintf "asm %.2X" value
+		| 1 when reg = 0 ->
+			Printf.sprintf "asm scratch R%d" value
+		| 2 ->
+			Printf.sprintf "asm R%d := %d" value (reg - 1)
+		| 3 ->
+			Printf.sprintf "asm %d := R%d" (reg - 1) value
+		| _ ->
+			Printf.sprintf "asm[%d] %d%s" mode value (if reg = 0 then "" else ", " ^ string_of_int (reg-1))
 
 
 let fundecl_name f = if snd f.fpath = "" then "fun$" ^ (string_of_int f.findex) else (fst f.fpath) ^ "." ^ (snd f.fpath)
 let fundecl_name f = if snd f.fpath = "" then "fun$" ^ (string_of_int f.findex) else (fst f.fpath) ^ "." ^ (snd f.fpath)
 
 

+ 6 - 6
src/generators/hlinterp.ml

@@ -1154,6 +1154,8 @@ let interp ctx f args =
 			(match get r2, get off with
 			(match get r2, get off with
 			| VRef (RArray (a,pos),t), VInt i -> set r (VRef (RArray (a,pos + Int32.to_int i),t))
 			| VRef (RArray (a,pos),t), VInt i -> set r (VRef (RArray (a,pos + Int32.to_int i),t))
 			| _ -> Globals.die "" __LOC__)
 			| _ -> Globals.die "" __LOC__)
+		| OAsm _ ->
+			throw_msg ctx "Unsupported ASM"
 		| ONop _ | OPrefetch _ ->
 		| ONop _ | OPrefetch _ ->
 			()
 			()
 		);
 		);
@@ -2456,17 +2458,13 @@ let check code macros =
 				reg p HI32;
 				reg p HI32;
 				(match rtype v with HI32 | HI64 | HF32 | HF64 -> () | _ -> error (reg_inf r ^ " should be numeric"));
 				(match rtype v with HI32 | HI64 | HF32 | HF64 -> () | _ -> error (reg_inf r ^ " should be numeric"));
 			| OSetArray (a,i,v) ->
 			| OSetArray (a,i,v) ->
-				reg a HArray;
+				(match rtype a with HAbstract ("hl_carray",_) -> () | _ -> reg a HArray);
 				reg i HI32;
 				reg i HI32;
 				ignore(rtype v);
 				ignore(rtype v);
-			| OUnsafeCast (a,b) ->
-				is_dyn a;
-				is_dyn b;
-			| OSafeCast (a,b) ->
+            | OUnsafeCast (a,b) | OSafeCast (a,b) ->
 				ignore(rtype a);
 				ignore(rtype a);
 				ignore(rtype b);
 				ignore(rtype b);
 			| OArraySize (r,a) ->
 			| OArraySize (r,a) ->
-				(match rtype a with HAbstract ("hl_carray",_) -> () | _ -> reg a HArray);
 				reg r HI32
 				reg r HI32
 			| OType (r,_) ->
 			| OType (r,_) ->
 				reg r HType
 				reg r HType
@@ -2549,6 +2547,8 @@ let check code macros =
 				();
 				();
 			| OPrefetch (r,f,_) ->
 			| OPrefetch (r,f,_) ->
 				if f = 0 then ignore(rtype r) else ignore(tfield r (f - 1) false)
 				if f = 0 then ignore(rtype r) else ignore(tfield r (f - 1) false)
+			| OAsm (_,_,r) ->
+				if r > 0 then ignore(rtype (r - 1))
 		) f.code
 		) f.code
 		(* TODO : check that all path correctly initialize NULL values and reach a return *)
 		(* TODO : check that all path correctly initialize NULL values and reach a return *)
 	in
 	in

+ 11 - 0
src/generators/hlopt.ml

@@ -166,6 +166,12 @@ let opcode_fx frw op =
 		()
 		()
 	| OPrefetch (r,_,_) ->
 	| OPrefetch (r,_,_) ->
 		read r
 		read r
+    | OAsm (_,_,r) ->
+        if r > 0 then begin
+            (* assume both *)
+            read (r - 1);
+            write (r - 1);
+        end
 
 
 let opcode_eq a b =
 let opcode_eq a b =
 	match a, b with
 	match a, b with
@@ -437,6 +443,11 @@ let opcode_map read write op =
 	| OPrefetch (r, fid, mode) ->
 	| OPrefetch (r, fid, mode) ->
 		let r2 = read r in
 		let r2 = read r in
 		OPrefetch (r2, fid, mode)
 		OPrefetch (r2, fid, mode)
+	| OAsm (_, _, 0) ->
+		op
+	| OAsm (mode, value, r) ->
+		let r2 = read (r - 1) in
+		OAsm (mode, value, (write r2) + 1)
 
 
 (* build code graph *)
 (* build code graph *)
 
 

+ 158 - 0
src/generators/jsSourcemap.ml

@@ -0,0 +1,158 @@
+(*
+	The Haxe Compiler
+	Copyright (C) 2005-2019  Haxe Foundation
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *)
+open Extlib_leftovers
+open Globals
+open Type
+open Common
+
+type sourcemap = {
+	sources : (string) DynArray.t;
+	sources_hash : (string, int) Hashtbl.t;
+	mappings : Rbuffer.t;
+
+	mutable source_last_pos : sourcemap_pos;
+	mutable print_comma : bool;
+	mutable output_last_col : int;
+	mutable output_current_col : int;
+	mutable current_expr : sourcemap_pos option;
+}
+
+and sourcemap_pos = {
+	file : int;
+	line : int;
+	col : int;
+}
+
+let encode_mapping smap pos =
+	if smap.print_comma then
+		Rbuffer.add_char smap.mappings ','
+	else
+		smap.print_comma <- true;
+
+	let base64_vlq number =
+		let encode_digit digit =
+			let chars = [|
+				'A';'B';'C';'D';'E';'F';'G';'H';'I';'J';'K';'L';'M';'N';'O';'P';
+				'Q';'R';'S';'T';'U';'V';'W';'X';'Y';'Z';'a';'b';'c';'d';'e';'f';
+				'g';'h';'i';'j';'k';'l';'m';'n';'o';'p';'q';'r';'s';'t';'u';'v';
+				'w';'x';'y';'z';'0';'1';'2';'3';'4';'5';'6';'7';'8';'9';'+';'/'
+			|] in
+			Array.unsafe_get chars digit
+		in
+		let to_vlq number =
+			if number < 0 then
+				((-number) lsl 1) + 1
+			else
+				number lsl 1
+		in
+		let rec loop vlq =
+			let shift = 5 in
+			let base = 1 lsl shift in
+			let mask = base - 1 in
+			let continuation_bit = base in
+			let digit = vlq land mask in
+			let next = vlq asr shift in
+			Rbuffer.add_char smap.mappings (encode_digit (
+				if next > 0 then digit lor continuation_bit else digit));
+			if next > 0 then loop next else ()
+		in
+		loop (to_vlq number)
+	in
+
+	base64_vlq (smap.output_current_col - smap.output_last_col);
+	base64_vlq (pos.file - smap.source_last_pos.file);
+	base64_vlq (pos.line - smap.source_last_pos.line);
+	base64_vlq (pos.col - smap.source_last_pos.col);
+
+	smap.source_last_pos <- pos;
+	smap.output_last_col <- smap.output_current_col
+
+let noop () = ()
+
+let add_mapping smap pos =
+	if pos.pmin < 0 then noop else
+
+	let file = try
+		Hashtbl.find smap.sources_hash pos.pfile
+	with Not_found ->
+		let length = DynArray.length smap.sources in
+		Hashtbl.replace smap.sources_hash pos.pfile length;
+		DynArray.add smap.sources pos.pfile;
+		length
+	in
+
+	let pos =
+		let line, col = Lexer.find_pos pos in
+		let line = line - 1 in
+		{ file = file; line = line; col = col }
+	in
+
+	if smap.source_last_pos <> pos then begin
+		let old_current_expr = smap.current_expr in
+		smap.current_expr <- Some pos;
+		encode_mapping smap pos;
+		(fun () -> smap.current_expr <- old_current_expr)
+	end else
+		noop
+
+let add_mapping smap e =
+	Option.map_default (fun smap -> add_mapping smap e.epos) noop smap
+
+let handle_newlines smap str =
+	Option.may (fun smap ->
+		let rec loop from =
+			try begin
+				let next = String.index_from str from '\n' + 1 in
+				Rbuffer.add_char smap.mappings ';';
+				smap.output_last_col <- 0;
+				smap.output_current_col <- 0;
+				smap.print_comma <- false;
+				Option.may (encode_mapping smap) smap.current_expr;
+				loop next
+			end with Not_found ->
+				smap.output_current_col <- smap.output_current_col + (String.length str - from);
+		in
+		loop 0
+	) smap
+
+let write_mappings (com : Common.context) smap source_path_prefix =
+	let basefile = Filename.basename com.file in
+	let channel = open_out_bin (com.file ^ ".map") in
+	let sources = DynArray.to_list smap.sources in
+	let to_url file =
+		ExtString.String.map (fun c -> if c == '\\' then '/' else c) (Path.get_full_path file)
+	in
+	output_string channel "{\n";
+	output_string channel "\"version\":3,\n";
+	output_string channel ("\"file\":\"" ^ (String.concat "\\\\" (ExtString.String.nsplit basefile "\\")) ^ "\",\n");
+	output_string channel ("\"sourceRoot\":\"\",\n");
+	output_string channel ("\"sources\":[" ^
+		(String.concat "," (List.map (fun s -> "\"" ^ source_path_prefix ^ to_url s ^ "\"") sources)) ^
+		"],\n");
+	if Common.defined com Define.SourceMapContent then begin
+		output_string channel ("\"sourcesContent\":[" ^
+			(String.concat "," (List.map (fun s -> try "\"" ^ StringHelper.s_escape (Std.input_file ~bin:true s) ^ "\"" with _ -> "null") sources)) ^
+			"],\n");
+	end;
+	output_string channel "\"names\":[],\n";
+	output_string channel "\"mappings\":\"";
+	Rbuffer.output_buffer channel smap.mappings;
+	output_string channel "\"\n";
+	output_string channel "}";
+	close_out channel

+ 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 stdlib : builtins option ref = ref None
 	let macro_lib : (string,value) Hashtbl.t = Hashtbl.create 0
 	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
 end
 
 
 let get_ctx () = (!GlobalState.get_ctx_ref)()
 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};
 		DisplayPosition.display_position#set {p with pmin = offset; pmax = offset};
 		begin try
 		begin try
 			let e = parse_expr ctx text p in
 			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();
 			save();
 			let rec loop e = match fst e with
 			let rec loop e = match fst e with
 			| EDisplay(e1,DKDot) ->
 			| EDisplay(e1,DKDot) ->

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

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

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

@@ -554,7 +554,8 @@ let uv_error_fields = [
 						let messages = ref [] in
 						let messages = ref [] in
 						HaxeError.recurse_error (fun depth err ->
 						HaxeError.recurse_error (fun depth err ->
 							let cm = make_compiler_message ~from_macro:err.err_from_macro (HaxeError.error_msg err.err_message) err.err_pos depth DKCompilerMessage Error in
 							let cm = make_compiler_message ~from_macro:err.err_from_macro (HaxeError.error_msg err.err_message) err.err_pos depth DKCompilerMessage Error in
-							match MessageReporting.compiler_message_string cm with
+							let ectx = MessageReporting.create_error_context false in
+							match MessageReporting.compiler_message_string ectx cm with
 								| None -> ()
 								| None -> ()
 								| Some str -> messages := str :: !messages
 								| Some str -> messages := str :: !messages
 						) err;
 						) err;

+ 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 *)
 		Which is printing an error to stderr and exiting with code 2 *)
 	Luv.Error.set_on_unhandled_exception (fun ex ->
 	Luv.Error.set_on_unhandled_exception (fun ex ->
 		match ex with
 		match ex with
-		| Sys_exit _ -> raise ex
+		| EvalTypes.Sys_exit _ ->
+			raise ex
 		| _ ->
 		| _ ->
 			let msg = match ex with
 			let msg = match ex with
 				| Error.Error err ->
 				| Error.Error err ->

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

@@ -2590,7 +2590,7 @@ module StdSys = struct
 	)
 	)
 
 
 	let exit = vfun1 (fun code ->
 	let exit = vfun1 (fun code ->
-		raise (Sys_exit(decode_int code));
+		raise (EvalTypes.Sys_exit(decode_int code));
 	)
 	)
 
 
 	let getChar = vfun1 (fun echo ->
 	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
 		let msg = get_exc_error_message ctx v stack p in
 		prerr_endline msg;
 		prerr_endline msg;
 		close();
 		close();
-	| Sys_exit i ->
+	| EvalTypes.Sys_exit i ->
 		close();
 		close();
 		exit i;
 		exit i;
 	| exc ->
 	| exc ->

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

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

+ 10 - 38
src/macro/macroApi.ml

@@ -1142,7 +1142,7 @@ and encode_method_kind m =
 and encode_class_kind k =
 and encode_class_kind k =
 	let tag, pl = (match k with
 	let tag, pl = (match k with
 		| KNormal -> 0, []
 		| KNormal -> 0, []
-		| KTypeParameter pl -> 1, [encode_tparams pl]
+		| KTypeParameter ttp -> 1, [encode_tparams (get_constraints ttp)] (* TTPTODO *)
 		| KModuleFields m -> 2, [encode_string (s_type_path m.m_path)]
 		| KModuleFields m -> 2, [encode_string (s_type_path m.m_path)]
 		| KExpr e -> 3, [encode_expr e]
 		| KExpr e -> 3, [encode_expr e]
 		| KGeneric -> 4, []
 		| KGeneric -> 4, []
@@ -1442,14 +1442,6 @@ let decode_tconst c =
 	| 6, [] -> TSuper
 	| 6, [] -> TSuper
 	| _ -> raise Invalid_expr
 	| _ -> raise Invalid_expr
 
 
-let decode_type_params v =
-	List.map (fun v ->
-		let name = decode_string (field v "name") in
-		let t = decode_type (field v "t") in
-		let default = opt decode_type (field v "defaultType") in
-		mk_type_param name t default
-	) (decode_array v)
-
 let decode_tvar v =
 let decode_tvar v =
 	(Obj.obj (decode_unsafe (field v "$")) : tvar)
 	(Obj.obj (decode_unsafe (field v "$")) : tvar)
 
 
@@ -1478,31 +1470,6 @@ let decode_field_kind v =
 	| 1, [m] -> Method (decode_method_kind m)
 	| 1, [m] -> Method (decode_method_kind m)
 	| _ -> raise Invalid_expr
 	| _ -> raise Invalid_expr
 
 
-let decode_cfield v =
-	let public = decode_bool (field v "isPublic") in
-	let extern = decode_bool (field v "isExtern") in
-	let final = decode_bool (field v "isFinal") in
-	let abstract = decode_bool (field v "isAbstract") in
-	let cf = {
-		cf_name = decode_string (field v "name");
-		cf_type = decode_type (field v "type");
-		cf_pos = decode_pos (field v "pos");
-		cf_name_pos = decode_pos (field v "namePos");
-		cf_doc = decode_doc (field v "doc");
-		cf_meta = []; (* TODO *)
-		cf_kind = decode_field_kind (field v "kind");
-		cf_params = decode_type_params (field v "params");
-		cf_expr = None;
-		cf_expr_unoptimized = None;
-		cf_overloads = decode_ref (field v "overloads");
-		cf_flags = 0;
-	} in
-	if public then add_class_field_flag cf CfPublic;
-	if extern then add_class_field_flag cf CfExtern;
-	if final then add_class_field_flag cf CfFinal;
-	if abstract then add_class_field_flag cf CfAbstract;
-	cf
-
 let decode_efield v =
 let decode_efield v =
 	let rec get_enum t =
 	let rec get_enum t =
 		match follow t with
 		match follow t with
@@ -2120,7 +2087,7 @@ let macro_api ccom get_api =
 			if name = "" then failwith "Empty resource name";
 			if name = "" then failwith "Empty resource name";
 			Hashtbl.replace (ccom()).resources name data;
 			Hashtbl.replace (ccom()).resources name data;
 			let m = (get_api()).current_module() in
 			let m = (get_api()).current_module() in
-			m.m_extra.m_binded_res <- PMap.add name data m.m_extra.m_binded_res;
+			DynArray.add m.m_extra.m_cache_bound_objects (Resource(name,data));
 			vnull
 			vnull
 		);
 		);
 		"get_resources", vfun0 (fun() ->
 		"get_resources", vfun0 (fun() ->
@@ -2303,10 +2270,13 @@ let macro_api ccom get_api =
 		"apply_params", vfun3 (fun tpl tl t ->
 		"apply_params", vfun3 (fun tpl tl t ->
 			let tl = List.map decode_type (decode_array tl) in
 			let tl = List.map decode_type (decode_array tl) in
 			let tpl = List.map (fun v ->
 			let tpl = List.map (fun v ->
-				let name = decode_string (field v "name") in
 				let t = decode_type (field v "t") in
 				let t = decode_type (field v "t") in
 				let default = None in (* we don't care here *)
 				let default = None in (* we don't care here *)
-				mk_type_param  name t default
+				let c = match t with
+					| TInst(c,_) -> c
+					| _ -> die "" __LOC__
+				in
+				mk_type_param c TPHType default None
 			) (decode_array tpl) in
 			) (decode_array tpl) in
 			let rec map t = match t with
 			let rec map t = match t with
 				| TInst({cl_kind = KTypeParameter _},_) ->
 				| TInst({cl_kind = KTypeParameter _},_) ->
@@ -2330,6 +2300,8 @@ let macro_api ccom get_api =
 					failwith ("unable to find file for inclusion: " ^ file)
 					failwith ("unable to find file for inclusion: " ^ file)
 			in
 			in
 			(ccom()).include_files <- (file, position) :: (ccom()).include_files;
 			(ccom()).include_files <- (file, position) :: (ccom()).include_files;
+			let m = (get_api()).current_module() in
+			DynArray.add m.m_extra.m_cache_bound_objects (IncludeFile(file,position));
 			vnull
 			vnull
 		);
 		);
 		(* Compilation server *)
 		(* Compilation server *)
@@ -2345,7 +2317,7 @@ let macro_api ccom get_api =
 			List.iter (fun v ->
 			List.iter (fun v ->
 				let s = decode_string v in
 				let s = decode_string v in
 				let s = com.file_keys#get s in
 				let s = com.file_keys#get s in
-				cs#taint_modules s "server_invalidate_files";
+				cs#taint_modules s ServerInvalidateFiles;
 				cs#remove_files s;
 				cs#remove_files s;
 			) (decode_array a);
 			) (decode_array a);
 			vnull
 			vnull

+ 2 - 2
src/optimization/analyzer.ml

@@ -375,11 +375,11 @@ module ConstPropagation = DataFlow(struct
 	let top = Top
 	let top = Top
 	let bottom = Bottom
 	let bottom = Bottom
 
 
-	let rec equals lat1 lat2 = match lat1,lat2 with
+	let equals lat1 lat2 = match lat1,lat2 with
 		| Top,Top | Bottom,Bottom -> true
 		| Top,Top | Bottom,Bottom -> true
 		| Const ct1,Const ct2 -> ct1 = ct2
 		| Const ct1,Const ct2 -> ct1 = ct2
 		| Null t1,Null t2 -> t1 == t2
 		| Null t1,Null t2 -> t1 == t2
-		| EnumValue(i1,tl1),EnumValue(i2,tl2) -> i1 = i2 && safe_for_all2 equals tl1 tl2
+		| EnumValue(i1,[]),EnumValue(i2,[]) -> i1 = i2
 		| ModuleType(mt1,_),ModuleType (mt2,_) -> mt1 == mt2
 		| ModuleType(mt1,_),ModuleType (mt2,_) -> mt1 == mt2
 		| _ -> false
 		| _ -> false
 
 

+ 26 - 23
src/optimization/dce.ml

@@ -50,19 +50,9 @@ let push_class dce c =
 		dce.curclass <- old
 		dce.curclass <- old
 	)
 	)
 
 
-let find_field c name kind =
-	match kind with
-	| CfrConstructor ->
-		begin match c.cl_constructor with Some cf -> cf | None -> raise Not_found end
-	| CfrStatic ->
-		PMap.find name c.cl_statics
-	| CfrMember ->
-		PMap.find name c.cl_fields
-
 let resolve_class_field_ref ctx cfr =
 let resolve_class_field_ref ctx cfr =
 	let ctx = if cfr.cfr_is_macro && not ctx.is_macro_context then Option.get (ctx.get_macros()) else ctx in
 	let ctx = if cfr.cfr_is_macro && not ctx.is_macro_context then Option.get (ctx.get_macros()) else ctx in
-	let path = ctx.type_to_module#find cfr.cfr_path in
-	let m = ctx.module_lut#find path in
+	let m = ctx.module_lut#find_by_type cfr.cfr_path in
 
 
 	Option.get (ExtList.List.find_map (fun mt -> match mt with
 	Option.get (ExtList.List.find_map (fun mt -> match mt with
 		| TClassDecl c when c.cl_path = cfr.cfr_path ->
 		| TClassDecl c when c.cl_path = cfr.cfr_path ->
@@ -247,10 +237,10 @@ and mark_t dce p t =
 	if not (List.exists (fun t2 -> Type.fast_eq t t2) dce.t_stack) then begin
 	if not (List.exists (fun t2 -> Type.fast_eq t t2) dce.t_stack) then begin
 		dce.t_stack <- t :: dce.t_stack;
 		dce.t_stack <- t :: dce.t_stack;
 		begin match follow t with
 		begin match follow t with
-		| TInst({cl_kind = KTypeParameter tl} as c,pl) ->
+		| TInst({cl_kind = KTypeParameter ttp} as c,pl) ->
 			if not (Meta.has Meta.Used c.cl_meta) then begin
 			if not (Meta.has Meta.Used c.cl_meta) then begin
 				c.cl_meta <- (mk_used_meta c.cl_pos) :: c.cl_meta;
 				c.cl_meta <- (mk_used_meta c.cl_pos) :: c.cl_meta;
-				List.iter (mark_t dce p) tl;
+				List.iter (mark_t dce p) (get_constraints ttp);
 			end;
 			end;
 			List.iter (mark_t dce p) pl
 			List.iter (mark_t dce p) pl
 		| TInst(c,pl) ->
 		| TInst(c,pl) ->
@@ -358,7 +348,7 @@ and field dce c n kind =
 		end else match c.cl_super with Some (csup,_) -> field dce csup n kind | None -> raise Not_found
 		end else match c.cl_super with Some (csup,_) -> field dce csup n kind | None -> raise Not_found
 	with Not_found -> try
 	with Not_found -> try
 		match c.cl_kind with
 		match c.cl_kind with
-		| KTypeParameter tl ->
+		| KTypeParameter ttp ->
 			let rec loop tl = match tl with
 			let rec loop tl = match tl with
 				| [] -> raise Not_found
 				| [] -> raise Not_found
 				| TInst(c,_) :: cl ->
 				| TInst(c,_) :: cl ->
@@ -366,7 +356,7 @@ and field dce c n kind =
 				| t :: tl ->
 				| t :: tl ->
 					loop tl
 					loop tl
 			in
 			in
-			loop tl
+			loop (get_constraints ttp)
 		| _ -> raise Not_found
 		| _ -> raise Not_found
 	with Not_found ->
 	with Not_found ->
 		if dce.debug then prerr_endline ("[DCE] Field " ^ n ^ " not found on " ^ (s_type_path c.cl_path)) else ())
 		if dce.debug then prerr_endline ("[DCE] Field " ^ n ^ " not found on " ^ (s_type_path c.cl_path)) else ())
@@ -511,6 +501,15 @@ and expr_field dce e fa is_call_expr =
 	end;
 	end;
 	expr dce e;
 	expr dce e;
 
 
+and check_op dce op = match op with
+	| OpMod ->
+		check_and_add_feature dce "binop_%";
+	| OpUShr ->
+		check_and_add_feature dce "binop_>>>";
+	| OpAssignOp op ->
+		check_op dce op
+	| _ ->
+		()
 
 
 and expr dce e =
 and expr dce e =
 	mark_t dce e.epos e.etype;
 	mark_t dce e.epos e.etype;
@@ -605,7 +604,12 @@ and expr dce e =
 		check_and_add_feature dce "dynamic_array_read";
 		check_and_add_feature dce "dynamic_array_read";
 		expr dce e1;
 		expr dce e1;
 		expr dce e2;
 		expr dce e2;
-	| TBinop( (OpAssign | OpAssignOp _), ({eexpr = TArray({etype = TDynamic None},_)} as e1), e2) ->
+	| TBinop(OpAssign, ({eexpr = TArray({etype = TDynamic None},_)} as e1), e2) ->
+		check_and_add_feature dce "dynamic_array_write";
+		expr dce e1;
+		expr dce e2;
+	| TBinop(OpAssignOp op, ({eexpr = TArray({etype = TDynamic None},_)} as e1), e2) ->
+		check_op dce op;
 		check_and_add_feature dce "dynamic_array_write";
 		check_and_add_feature dce "dynamic_array_write";
 		expr dce e1;
 		expr dce e1;
 		expr dce e2;
 		expr dce e2;
@@ -629,10 +633,12 @@ and expr dce e =
 		expr dce e1;
 		expr dce e1;
 		expr dce e2;
 		expr dce e2;
 	| TBinop(OpAssignOp op,({eexpr = TField(_,(FDynamic _ as fa) )} as e1),e2) ->
 	| TBinop(OpAssignOp op,({eexpr = TField(_,(FDynamic _ as fa) )} as e1),e2) ->
+		check_op dce op;
 		check_dynamic_write dce fa;
 		check_dynamic_write dce fa;
 		expr dce e1;
 		expr dce e1;
 		expr dce e2;
 		expr dce e2;
 	| TBinop(OpAssignOp op,({eexpr = TField(_,(FAnon cf as fa) )} as e1),e2) ->
 	| TBinop(OpAssignOp op,({eexpr = TField(_,(FAnon cf as fa) )} as e1),e2) ->
+		check_op dce op;
 		if Meta.has Meta.Optional cf.cf_meta then
 		if Meta.has Meta.Optional cf.cf_meta then
 			check_anon_optional_write dce fa
 			check_anon_optional_write dce fa
 		else
 		else
@@ -655,12 +661,8 @@ and expr dce e =
 		check_and_add_feature dce "type_param_binop_!=";
 		check_and_add_feature dce "type_param_binop_!=";
 		expr dce e1;
 		expr dce e1;
 		expr dce e2;
 		expr dce e2;
-	| TBinop(OpMod,e1,e2) ->
-		check_and_add_feature dce "binop_%";
-		expr dce e1;
-		expr dce e2;
-	| TBinop((OpUShr | OpAssignOp OpUShr),e1,e2) ->
-		check_and_add_feature dce "binop_>>>";
+	| TBinop(op,e1,e2) ->
+		check_op dce op;
 		expr dce e1;
 		expr dce e1;
 		expr dce e2;
 		expr dce e2;
 	| TCall(({ eexpr = TField(ef, fa) } as e2), el ) ->
 	| TCall(({ eexpr = TField(ef, fa) } as e2), el ) ->
@@ -721,8 +723,9 @@ let collect_entry_points dce com =
 		match t with
 		match t with
 		| TClassDecl c ->
 		| TClassDecl c ->
 			let keep_class = keep_whole_class dce c && (not (has_class_flag c CExtern) || (has_class_flag c CInterface)) in
 			let keep_class = keep_whole_class dce c && (not (has_class_flag c CExtern) || (has_class_flag c CInterface)) in
+			let is_struct = dce.com.platform = Hl && Meta.has Meta.Struct c.cl_meta in
 			let loop kind cf =
 			let loop kind cf =
-				if keep_class || keep_field dce cf c kind then mark_field dce c cf kind
+				if keep_class || is_struct || keep_field dce cf c kind then mark_field dce c cf kind
 			in
 			in
 			List.iter (loop CfrStatic) c.cl_ordered_statics;
 			List.iter (loop CfrStatic) c.cl_ordered_statics;
 			List.iter (loop CfrMember) c.cl_ordered_fields;
 			List.iter (loop CfrMember) c.cl_ordered_fields;

+ 6 - 4
src/optimization/inline.ml

@@ -6,6 +6,8 @@ open Common
 open Typecore
 open Typecore
 open Error
 open Error
 
 
+let maybe_reapply_overload_call_ref = ref (fun _ _ -> assert false)
+
 let mk_untyped_call name p params =
 let mk_untyped_call name p params =
 	{
 	{
 		eexpr = TCall({ eexpr = TIdent name; etype = t_dynamic; epos = p }, params);
 		eexpr = TCall({ eexpr = TIdent name; etype = t_dynamic; epos = p }, params);
@@ -100,7 +102,7 @@ let api_inline ctx c field params p =
 		let m = (try ctx.com.module_lut#find path with Not_found -> die "" __LOC__) in
 		let m = (try ctx.com.module_lut#find path with Not_found -> die "" __LOC__) in
 		add_dependency ctx.m.curmod m;
 		add_dependency ctx.m.curmod m;
 		Option.get (ExtList.List.find_map (function
 		Option.get (ExtList.List.find_map (function
-			| TClassDecl cl when cl.cl_path = path -> Some (make_static_this cl p)
+			| TClassDecl cl when cl.cl_path = path -> Some (Texpr.Builder.make_static_this cl p)
 			| _ -> None
 			| _ -> None
 		) m.m_types)
 		) m.m_types)
 	in
 	in
@@ -160,7 +162,7 @@ let api_inline ctx c field params p =
 			None)
 			None)
 	| (["js"],"Boot"),"__downcastCheck",[o; {eexpr = TTypeExpr (TClassDecl cls) } as t] when ctx.com.platform = Js ->
 	| (["js"],"Boot"),"__downcastCheck",[o; {eexpr = TTypeExpr (TClassDecl cls) } as t] when ctx.com.platform = Js ->
 		if (has_class_flag cls CInterface) then
 		if (has_class_flag cls CInterface) then
-			Some (Texpr.Builder.fcall (make_static_this c p) "__implements" [o;t] tbool p)
+			Some (Texpr.Builder.fcall (Texpr.Builder.make_static_this c p) "__implements" [o;t] tbool p)
 		else
 		else
 			Some (Texpr.Builder.fcall (eJsSyntax()) "instanceof" [o;t] tbool p)
 			Some (Texpr.Builder.fcall (eJsSyntax()) "instanceof" [o;t] tbool p)
 	| (["haxe";"ds";"_Vector"],"Vector_Impl_"),("fromArrayCopy"),[{ eexpr = TArrayDecl args } as edecl] -> (try
 	| (["haxe";"ds";"_Vector"],"Vector_Impl_"),("fromArrayCopy"),[{ eexpr = TArrayDecl args } as edecl] -> (try
@@ -221,7 +223,7 @@ let inline_default_config cf t =
 			c.cl_params @ ct, pl @ cpl
 			c.cl_params @ ct, pl @ cpl
 	in
 	in
 	let rec loop t = match follow t with
 	let rec loop t = match follow t with
-		| TInst({cl_kind = KTypeParameter tl},_) -> List.fold_left (fun (params',tl') (params,tl) -> (params @ params',tl @ tl')) ([],[]) (List.map loop tl)
+		| TInst({cl_kind = KTypeParameter ttp},_) -> List.fold_left (fun (params',tl') (params,tl) -> (params @ params',tl @ tl')) ([],[]) (List.map loop (get_constraints ttp))
 		| TInst (c,pl) -> get_params c pl
 		| TInst (c,pl) -> get_params c pl
 		| _ -> ([],[])
 		| _ -> ([],[])
 	in
 	in
@@ -614,7 +616,7 @@ class inline_state ctx ethis params cf f p = object(self)
 				else map_type
 				else map_type
 			in
 			in
 			let e = Type.map_expr_type (map_expr_type map_type) map_type (map_var map_type) e 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
 		in
 		let e = map_expr_type map_type e in
 		let e = map_expr_type map_type e in
 		let rec drop_unused_vars e =
 		let rec drop_unused_vars e =

+ 18 - 2
src/syntax/grammar.mly

@@ -1715,8 +1715,24 @@ and parse_call_params f p1 s =
 				let e = check_signature_mark e p1 p2 in
 				let e = check_signature_mark e p1 p2 in
 				f (List.rev (e :: acc)) p2
 				f (List.rev (e :: acc)) p2
 			| [< '(Comma,p2); '(PClose,p3) >] ->
 			| [< '(Comma,p2); '(PClose,p3) >] ->
-				let e = check_signature_mark e p1 p3 in
-				f (List.rev (e :: acc)) p3
+				if (is_signature_display()) then begin
+					let prev_arg_pos = punion p1 p2 in
+					let comma_paren_pos = punion p2 p3 in
+					(* first check wether the display position is within the previous argument *)
+					if encloses_position_gt display_position#get prev_arg_pos then begin
+						(* wrap the argument that was just parsed *)
+						let e = mk_display_expr e DKMarked in
+						f (List.rev (e :: acc)) p3
+					(* then check wether the display position is between the comma and the closing parenthesis *)
+					end else if encloses_position_gt display_position#get comma_paren_pos then begin
+						(* add a dummy final argument *)
+						let e2 = mk_display_expr (mk_null_expr comma_paren_pos) DKMarked in
+						f (List.rev (e2 :: e :: acc)) p3
+					end else f (List.rev (e :: acc)) p3
+				end else begin
+				(* if not in signature display mode don't check anything *)
+					f (List.rev (e :: acc)) p3
+				end
 			| [< '(Comma,p2) >] ->
 			| [< '(Comma,p2) >] ->
 				let e = check_signature_mark e p1 p2 in
 				let e = check_signature_mark e p1 p2 in
 				parse_next_param (e :: acc) p2
 				parse_next_param (e :: acc) p2

+ 26 - 10
src/typing/callUnification.ml

@@ -5,6 +5,7 @@ open Common
 open Typecore
 open Typecore
 open Error
 open Error
 open FieldAccess
 open FieldAccess
+open FieldCallCandidate
 
 
 let unify_call_args ctx el args r callp inline force_inline in_overload =
 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
 	let call_error err p = raise_error_msg (Call_error err) p in
@@ -350,14 +351,6 @@ let unify_field_call ctx fa el_typed el p inline =
 		in
 		in
 		loop candidates
 		loop candidates
 	in
 	in
-	let fail_fun () =
-		let tf = TFun(List.map (fun _ -> ("",false,t_dynamic)) el,t_dynamic) in
-		let call () =
-			let ef = mk (TField(fa.fa_on,FieldAccess.apply_fa fa.fa_field fa.fa_host)) tf fa.fa_pos in
-			mk (TCall(ef,[])) t_dynamic p
-		in
-		make_field_call_candidate [] t_dynamic [] tf fa.fa_field call
-	in
 	let maybe_check_access cf =
 	let maybe_check_access cf =
 		(* type_field doesn't check access for overloads, so let's check it here *)
 		(* type_field doesn't check access for overloads, so let's check it here *)
 		begin match co with
 		begin match co with
@@ -367,13 +360,34 @@ let unify_field_call ctx fa el_typed el p inline =
 			()
 			()
 		end;
 		end;
 	in
 	in
+	(* There's always a chance that we never even came across the EDisplay in an argument, so let's look for it (issue #11422). *)
+	let check_display_args () =
+		if ctx.is_display_file then begin
+			let rec loop el = match el with
+				| [] ->
+					()
+				| e :: el ->
+					if Ast.exists (function EDisplay _ -> true | _ -> false) e then
+						ignore(type_expr ctx e WithType.value)
+					else
+						loop el
+			in
+			loop el
+		end;
+	in
 	match candidates with
 	match candidates with
 	| [cf] ->
 	| [cf] ->
 		if overload_kind = OverloadProper then maybe_check_access cf;
 		if overload_kind = OverloadProper then maybe_check_access cf;
 		begin try
 		begin try
 			commit_delayed_display (attempt_call cf false)
 			commit_delayed_display (attempt_call cf false)
 		with Error _ when Common.ignore_error ctx.com ->
 		with Error _ when Common.ignore_error ctx.com ->
-			fail_fun();
+			check_display_args();
+			let tf = TFun(List.map (fun _ -> ("",false,t_dynamic)) el,t_dynamic) in
+			let call () =
+				let ef = mk (TField(fa.fa_on,FieldAccess.apply_fa fa.fa_field fa.fa_host)) tf fa.fa_pos in
+				mk (TCall(ef,[])) t_dynamic p
+			in
+			make_field_call_candidate [] t_dynamic [] tf fa.fa_field call
 		end
 		end
 	| _ ->
 	| _ ->
 		let candidates,failures = attempt_calls candidates in
 		let candidates,failures = attempt_calls candidates in
@@ -385,6 +399,7 @@ let unify_field_call ctx fa el_typed el p inline =
 				) delayed_display;
 				) delayed_display;
 				cf,err
 				cf,err
 			) failures in
 			) failures in
+			check_display_args();
 			let failures = remove_duplicates (fun (_,e1) (_,e2) -> (MessageReporting.print_error e1) <> (MessageReporting.print_error e2)) failures in
 			let failures = remove_duplicates (fun (_,e1) (_,e2) -> (MessageReporting.print_error e1) <> (MessageReporting.print_error e2)) failures in
 			begin match failures with
 			begin match failures with
 			| [_,err] ->
 			| [_,err] ->
@@ -408,7 +423,8 @@ let unify_field_call ctx fa el_typed el p inline =
 			end
 			end
 		in
 		in
 		if overload_kind = OverloadProper then begin match Overloads.Resolution.reduce_compatible candidates with
 		if overload_kind = OverloadProper then begin match Overloads.Resolution.reduce_compatible candidates with
-			| [] -> fail()
+			| [] ->
+				fail()
 			| [fcc] ->
 			| [fcc] ->
 				maybe_check_access fcc.fc_field;
 				maybe_check_access fcc.fc_field;
 				commit_delayed_display fcc
 				commit_delayed_display fcc

+ 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)
+	]

+ 2 - 2
src/typing/fields.ml

@@ -319,11 +319,11 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) =
 				snd (class_field_with_access e c tl)
 				snd (class_field_with_access e c tl)
 			with Not_found -> try
 			with Not_found -> try
 				match c.cl_kind with
 				match c.cl_kind with
-				| KTypeParameter tl ->
+				| KTypeParameter ttp ->
 					type_field_by_list (fun t -> match follow t with
 					type_field_by_list (fun t -> match follow t with
 						| TAbstract _ -> type_field_by_e type_field_by_type (mk_cast e t p);
 						| TAbstract _ -> type_field_by_e type_field_by_type (mk_cast e t p);
 						| _ -> raise Not_found
 						| _ -> raise Not_found
-					) tl
+					) (get_constraints ttp)
 				| _ -> raise Not_found
 				| _ -> raise Not_found
 			with Not_found ->
 			with Not_found ->
 				type_field_by_interfaces e c
 				type_field_by_interfaces e c

+ 4 - 4
src/typing/finalization.ml

@@ -42,14 +42,14 @@ let get_main ctx types =
 			| _ -> raise_typing_error ("Invalid -main : " ^ s_type_path path ^ " has invalid main function") c.cl_pos
 			| _ -> raise_typing_error ("Invalid -main : " ^ s_type_path path ^ " has invalid main function") c.cl_pos
 		in
 		in
 		if not (ExtType.is_void (follow r)) then raise_typing_error (Printf.sprintf "Return type of main function should be Void (found %s)" (s_type (print_context()) r)) f.cf_name_pos;
 		if not (ExtType.is_void (follow r)) then raise_typing_error (Printf.sprintf "Return type of main function should be Void (found %s)" (s_type (print_context()) r)) f.cf_name_pos;
-		f.cf_meta <- (Dce.mk_keep_meta f.cf_pos) :: f.cf_meta;
+		if not (Meta.has Meta.Keep f.cf_meta) then f.cf_meta <- (Dce.mk_keep_meta f.cf_pos) :: f.cf_meta;
 		let emain = type_module_type ctx (TClassDecl c) null_pos in
 		let emain = type_module_type ctx (TClassDecl c) null_pos in
 		let main = mk (TCall (mk (TField (emain,fmode)) ft null_pos,[])) r null_pos in
 		let main = mk (TCall (mk (TField (emain,fmode)) ft null_pos,[])) r null_pos in
 		let call_static path method_name =
 		let call_static path method_name =
 			let et = List.find (fun t -> t_path t = path) types in
 			let et = List.find (fun t -> t_path t = path) types in
 			let ec = (match et with TClassDecl c -> c | _ -> die "" __LOC__) in
 			let ec = (match et with TClassDecl c -> c | _ -> die "" __LOC__) in
 			let ef = PMap.find method_name ec.cl_statics in
 			let ef = PMap.find method_name ec.cl_statics in
-			let et = mk (TTypeExpr et) (mk_anon (ref (ClassStatics ec))) null_pos in
+			let et = Texpr.Builder.make_typeexpr et null_pos in
 			mk (TCall (mk (TField (et,FStatic (ec,ef))) ef.cf_type null_pos,[])) ctx.t.tvoid null_pos
 			mk (TCall (mk (TField (et,FStatic (ec,ef))) ef.cf_type null_pos,[])) ctx.t.tvoid null_pos
 		in
 		in
 		(* add haxe.EntryPoint.run() call *)
 		(* add haxe.EntryPoint.run() call *)
@@ -101,7 +101,7 @@ type state =
 	| Done
 	| Done
 	| NotYet
 	| NotYet
 
 
-let sort_types com (modules : (path,module_def) lookup) =
+let sort_types com (modules : module_lut) =
 	let types = ref [] in
 	let types = ref [] in
 	let states = Hashtbl.create 0 in
 	let states = Hashtbl.create 0 in
 	let state p = try Hashtbl.find states p with Not_found -> NotYet in
 	let state p = try Hashtbl.find states p with Not_found -> NotYet in
@@ -112,7 +112,7 @@ let sort_types com (modules : (path,module_def) lookup) =
 		match state p with
 		match state p with
 		| Done -> ()
 		| Done -> ()
 		| Generating ->
 		| Generating ->
-			com.warning WStaticInitOrder [] ("Warning : maybe loop in static generation of " ^ s_type_path p) (t_infos t).mt_pos;
+			module_warning com (t_infos t).mt_module WStaticInitOrder [] ("Warning : maybe loop in static generation of " ^ s_type_path p) (t_infos t).mt_pos;
 		| NotYet ->
 		| NotYet ->
 			Hashtbl.add states p Generating;
 			Hashtbl.add states p Generating;
 			let t = (match t with
 			let t = (match t with

+ 1 - 1
src/typing/forLoop.ml

@@ -267,7 +267,7 @@ module IterationKind = struct
 		let t_void = ctx.t.tvoid in
 		let t_void = ctx.t.tvoid in
 		let t_int = ctx.t.tint in
 		let t_int = ctx.t.tint in
 		let mk_field e n =
 		let mk_field e n =
-			TField (e,try quick_field e.etype n with Not_found -> die "" __LOC__)
+			TField (e,try quick_field e.etype n with Not_found -> Error.raise_msg (Printf.sprintf "Could not find field %s on %s" n (s_type_kind e.etype)) e.epos)
 		in
 		in
 		let get_array_length arr p =
 		let get_array_length arr p =
 			mk (mk_field arr "length") ctx.com.basic.tint p
 			mk (mk_field arr "length") ctx.com.basic.tint p

+ 1 - 1
src/typing/functionArguments.ml

@@ -22,7 +22,7 @@ let type_function_arg_value ctx t c do_display =
 		| None -> None
 		| None -> None
 		| Some e ->
 		| Some e ->
 			let p = pos e in
 			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
 			let e = Optimizer.reduce_expression ctx (type_expr ctx e (WithType.with_type t)) in
 			unify ctx e.etype t p;
 			unify ctx e.etype t p;
 			let rec loop e = match e.eexpr with
 			let rec loop e = match e.eexpr with

+ 22 - 23
src/typing/generic.ml

@@ -5,6 +5,7 @@ open Ast
 open Type
 open Type
 open Typecore
 open Typecore
 open Error
 open Error
+open FieldCallCandidate
 
 
 type generic_context = {
 type generic_context = {
 	ctx : typer;
 	ctx : typer;
@@ -62,7 +63,7 @@ let make_generic ctx ps pt debug p =
 	let rec loop acc_name acc_subst ttpl tl = match ttpl,tl with
 	let rec loop acc_name acc_subst ttpl tl = match ttpl,tl with
 		| ttp :: ttpl,t :: tl ->
 		| ttp :: ttpl,t :: tl ->
 			let name,t = try process t with Exit -> raise_typing_error ("Could not determine type for parameter " ^ ttp.ttp_name) p in
 			let name,t = try process t with Exit -> raise_typing_error ("Could not determine type for parameter " ^ ttp.ttp_name) p in
-			loop (name :: acc_name) ((follow ttp.ttp_type,t) :: acc_subst) ttpl tl
+			loop (name :: acc_name) ((ttp.ttp_type,t) :: acc_subst) ttpl tl
 		| [],[] ->
 		| [],[] ->
 			let name = String.concat "_" (List.rev acc_name) in
 			let name = String.concat "_" (List.rev acc_name) in
 			name,acc_subst
 			name,acc_subst
@@ -174,13 +175,13 @@ let static_method_container gctx c cf p =
 		| TInst(cg,_) -> cg
 		| TInst(cg,_) -> cg
 		| _ -> raise_typing_error ("Cannot specialize @:generic static method because the generated type name is already used: " ^ name) p
 		| _ -> raise_typing_error ("Cannot specialize @:generic static method because the generated type name is already used: " ^ name) p
 	with Error { err_message = Module_not_found path } when path = (pack,name) ->
 	with Error { err_message = Module_not_found path } when path = (pack,name) ->
-		let m = (try ctx.com.module_lut#find (ctx.com.type_to_module#find c.cl_path) with Not_found -> die "" __LOC__) in
+		let m = c.cl_module in
 		let mg = {
 		let mg = {
 			m_id = alloc_mid();
 			m_id = alloc_mid();
 			m_path = (pack,name);
 			m_path = (pack,name);
 			m_types = [];
 			m_types = [];
 			m_statics = None;
 			m_statics = None;
-			m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake m.m_extra.m_check_policy;
+			m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake gctx.ctx.com.compilation_step m.m_extra.m_check_policy;
 		} in
 		} in
 		gctx.mg <- Some mg;
 		gctx.mg <- Some mg;
 		let cg = mk_class mg (pack,name) c.cl_pos c.cl_name_pos in
 		let cg = mk_class mg (pack,name) c.cl_pos c.cl_name_pos in
@@ -239,8 +240,9 @@ let build_generic_class ctx c p tl =
 		| TInst (c2,tl) ->
 		| TInst (c2,tl) ->
 			(match c2.cl_kind with
 			(match c2.cl_kind with
 			| KTypeParameter tl ->
 			| KTypeParameter tl ->
-				if not (TypeloadCheck.is_generic_parameter ctx c2) && has_ctor_constraint c2 then
-					raise_typing_error "Type parameters with a constructor cannot be used non-generically" p;
+				(* TPTODO *)
+				(* if not (TypeloadCheck.is_generic_parameter ctx c2) && has_ctor_constraint c2 then
+					raise_typing_error "Type parameters with a constructor cannot be used non-generically" p; *)
 				recurse := true
 				recurse := true
 			| _ -> ());
 			| _ -> ());
 			List.iter check_recursive tl;
 			List.iter check_recursive tl;
@@ -259,7 +261,7 @@ let build_generic_class ctx c p tl =
 		| TInst({ cl_kind = KGenericInstance (csup,_) },_) when c == csup -> t
 		| TInst({ cl_kind = KGenericInstance (csup,_) },_) when c == csup -> t
 		| _ -> raise_typing_error ("Cannot specialize @:generic because the generated type name is already used: " ^ name) p
 		| _ -> raise_typing_error ("Cannot specialize @:generic because the generated type name is already used: " ^ name) p
 	with Error { err_message = Module_not_found path } when path = (pack,name) ->
 	with Error { err_message = Module_not_found path } when path = (pack,name) ->
-		let m = (try ctx.com.module_lut#find (ctx.com.type_to_module#find c.cl_path) with Not_found -> die "" __LOC__) in
+		let m = c.cl_module in
 		if gctx.generic_debug then begin
 		if gctx.generic_debug then begin
 			print_endline (Printf.sprintf "[GENERIC] Building @:generic class %s as %s with:" (s_type_path c.cl_path) name);
 			print_endline (Printf.sprintf "[GENERIC] Building @:generic class %s as %s with:" (s_type_path c.cl_path) name);
 			List.iter (fun (t1,(t2,eo)) ->
 			List.iter (fun (t1,(t2,eo)) ->
@@ -280,7 +282,7 @@ let build_generic_class ctx c p tl =
 			m_path = (pack,name);
 			m_path = (pack,name);
 			m_types = [];
 			m_types = [];
 			m_statics = None;
 			m_statics = None;
-			m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake m.m_extra.m_check_policy;
+			m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake gctx.ctx.com.compilation_step m.m_extra.m_check_policy;
 		} in
 		} in
 		gctx.mg <- Some mg;
 		gctx.mg <- Some mg;
 		let cg = mk_class mg (pack,name) c.cl_pos c.cl_name_pos in
 		let cg = mk_class mg (pack,name) c.cl_pos c.cl_name_pos in
@@ -305,24 +307,21 @@ let build_generic_class ctx c p tl =
 		add_dependency ctx.m.curmod mg;
 		add_dependency ctx.m.curmod mg;
 		set_type_parameter_dependencies mg tl;
 		set_type_parameter_dependencies mg tl;
 		let build_field cf_old =
 		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) tp -> match follow tp.ttp_type with
-				| TInst(c,tl) as t ->
-					let t2 = TInst({c with cl_module = mg;},tl) in
-					(t,(t2,None)) :: subst,({tp with ttp_type=t2}) :: params
-				| _ -> die "" __LOC__
-			) ([],[]) cf_old.cf_params in
+			let params = List.map (fun ttp ->
+				let c = {ttp.ttp_class with cl_module = mg} in
+				let def = Option.map (generic_substitute_type gctx) ttp.ttp_default in
+				let constraints = match ttp.ttp_constraints with
+					| None -> None
+					| Some constraints -> Some (lazy (List.map (generic_substitute_type gctx) (Lazy.force constraints)))
+				in
+				let ttp' = mk_type_param c ttp.ttp_host def constraints in
+				c.cl_kind <- KTypeParameter ttp';
+				(ttp.ttp_type,ttp')
+			) cf_old.cf_params in
+			let param_subst = List.map (fun (t,ttp) -> t,(ttp.ttp_type,None)) params in
 			let gctx = {gctx with subst = param_subst @ gctx.subst} in
 			let gctx = {gctx with subst = param_subst @ gctx.subst} in
 			let cf_new = {cf_old with cf_pos = cf_old.cf_pos; cf_expr_unoptimized = None} in (* copy *)
 			let cf_new = {cf_old with cf_pos = cf_old.cf_pos; cf_expr_unoptimized = None} in (* copy *)
-			(* Type parameter constraints are substituted here. *)
-			cf_new.cf_params <- List.rev_map (fun tp -> match follow tp.ttp_type with
-				| TInst({cl_kind = KTypeParameter tl1} as c,_) ->
-					let tl1 = List.map (generic_substitute_type gctx) tl1 in
-					c.cl_kind <- KTypeParameter tl1;
-					tp (* TPTODO: weird mapping *)
-				| _ -> die "" __LOC__
-			) params;
+			cf_new.cf_params <- List.map (fun (_,ttp) -> ttp) params;
 			let f () =
 			let f () =
 				ignore(follow cf_old.cf_type);
 				ignore(follow cf_old.cf_type);
 				(* We update here because the follow could resolve some TLazy things that end up modifying flags, such as
 				(* We update here because the follow could resolve some TLazy things that end up modifying flags, such as

+ 9 - 17
src/typing/macroContext.ml

@@ -26,14 +26,6 @@ open Resolution
 open Error
 open Error
 open Globals
 open Globals
 
 
-module Eval = struct
-	include EvalEncode
-	include EvalDecode
-	include EvalValue
-	include EvalContext
-	include EvalMain
-end
-
 module InterpImpl = Eval (* Hlmacro *)
 module InterpImpl = Eval (* Hlmacro *)
 
 
 module Interp = struct
 module Interp = struct
@@ -48,7 +40,7 @@ let macro_interp_cache = ref None
 let safe_decode com v expected t p f =
 let safe_decode com v expected t p f =
 	try
 	try
 		f ()
 		f ()
-	with MacroApi.Invalid_expr | EvalContext.RunTimeException _ ->
+	with MacroApi.Invalid_expr ->
 		let path = [dump_path com;"decoding_error"] in
 		let path = [dump_path com;"decoding_error"] in
 		let ch = Path.create_file false ".txt" [] path  in
 		let ch = Path.create_file false ".txt" [] path  in
 		let errors = Interp.handle_decoding_error (output_string ch) v t 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
 			!macro_enable_cache
 		);
 		);
 		format_string = (fun s p ->
 		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 ->
 		cast_or_unify = (fun t e p ->
 			Interp.exc_string "unsupported"
 			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 *)
 	(* we should maybe ensure that all filters in Main are applied. Not urgent atm *)
 	let expr_filters = [
 	let expr_filters = [
 		"handle_abstract_casts",AbstractCast.handle_abstract_casts mctx;
 		"handle_abstract_casts",AbstractCast.handle_abstract_casts mctx;
-		"local_statics",Filters.LocalStatic.run mctx;
+		"local_statics",LocalStatic.run mctx;
 		"Exceptions",Exceptions.filter mctx;
 		"Exceptions",Exceptions.filter mctx;
 		"captured_vars",CapturedVars.captured_vars mctx.com;
 		"captured_vars",CapturedVars.captured_vars mctx.com;
 	] in
 	] in
@@ -668,14 +660,14 @@ and flush_macro_context mint mctx =
 			()
 			()
 	in
 	in
 	let type_filters = [
 	let type_filters = [
-		Filters.remove_generic_base;
+		FiltersCommon.remove_generic_base;
 		Exceptions.patch_constructors mctx;
 		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;
 		minimal_restore;
-		Filters.apply_native_paths
+		Naming.apply_native_paths
 	] in
 	] in
 	let ready = fun t ->
 	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
 		List.iter (fun f -> f t) type_filters
 	in
 	in
 	(try Interp.add_types mint types ready
 	(try Interp.add_types mint types ready
@@ -747,7 +739,7 @@ let get_macro_context ctx =
 		mctx
 		mctx
 
 
 let load_macro_module mctx com cpath display p =
 let load_macro_module mctx com cpath display p =
-	let m = (try com.type_to_module#find cpath with Not_found -> cpath) in
+	let m = (try com.module_lut#get_type_lut#find cpath with Not_found -> cpath) in
 	(* Temporarily enter display mode while typing the macro. *)
 	(* Temporarily enter display mode while typing the macro. *)
 	let old = mctx.com.display in
 	let old = mctx.com.display in
 	if display then mctx.com.display <- com.display;
 	if display then mctx.com.display <- com.display;
@@ -996,7 +988,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 						else try
 						else try
 							let ct = Interp.decode_ctype v in
 							let ct = Interp.decode_ctype v in
 							Typeload.load_complex_type ctx false ct;
 							Typeload.load_complex_type ctx false ct;
-						with MacroApi.Invalid_expr | EvalContext.RunTimeException _ ->
+						with MacroApi.Invalid_expr  | EvalContext.RunTimeException _ ->
 							Interp.decode_type v
 							Interp.decode_type v
 						in
 						in
 						ctx.ret <- t;
 						ctx.ret <- t;

+ 6 - 2
src/typing/matcher/exprToPattern.ml

@@ -252,7 +252,11 @@ let rec make pctx toplevel t e =
 		| ECall(e1,el) ->
 		| ECall(e1,el) ->
 			let e1 = type_expr ctx e1 (WithType.with_type t) in
 			let e1 = type_expr ctx e1 (WithType.with_type t) in
 			begin match e1.eexpr,follow e1.etype with
 			begin match e1.eexpr,follow e1.etype with
-				| TField(_, FEnum(en,ef)),TFun(_,TEnum(_,tl)) ->
+				| TField(_, FEnum(en,ef)),TFun(_,tr) ->
+					let tl = match follow tr with
+						| TEnum(_,tl) -> tl
+						| _ -> fail()
+					in
 					let map = apply_params en.e_params tl in
 					let map = apply_params en.e_params tl in
 					let monos = Monomorph.spawn_constrained_monos map ef.ef_params in
 					let monos = Monomorph.spawn_constrained_monos map ef.ef_params in
 					let map t = map (apply_params ef.ef_params monos t) in
 					let map t = map (apply_params ef.ef_params monos t) in
@@ -442,4 +446,4 @@ let rec make pctx toplevel t e =
 			fail()
 			fail()
 	in
 	in
 	let pat = loop e in
 	let pat = loop e in
-	pat,p
+	pat,p

+ 6 - 2
src/typing/operators.ml

@@ -118,9 +118,9 @@ let rec classify t =
 	| TAbstract ({ a_path = [],"Int" },[]) -> KInt
 	| TAbstract ({ a_path = [],"Int" },[]) -> KInt
 	| TAbstract ({ a_path = [],"Float" },[]) -> KFloat
 	| TAbstract ({ a_path = [],"Float" },[]) -> KFloat
 	| TAbstract (a,[]) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) a.a_to -> KNumParam t
 	| TAbstract (a,[]) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) a.a_to -> KNumParam t
-	| TInst ({ cl_kind = KTypeParameter ctl },_) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) ctl -> KNumParam t
+	| TInst ({ cl_kind = KTypeParameter ttp },_) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) (get_constraints ttp) -> KNumParam t
 	| TAbstract (a,[]) when List.exists (fun t -> match classify t with KString -> true | _ -> false) a.a_to -> KStrParam t
 	| TAbstract (a,[]) when List.exists (fun t -> match classify t with KString -> true | _ -> false) a.a_to -> KStrParam t
-	| TInst ({ cl_kind = KTypeParameter ctl },_) when List.exists (fun t -> match classify t with KString -> true | _ -> false) ctl -> KStrParam t
+	| TInst ({ cl_kind = KTypeParameter ttp },_) when List.exists (fun t -> match classify t with KString -> true | _ -> false) (get_constraints ttp) -> KStrParam t
 	| TMono r when r.tm_type = None -> KUnk
 	| TMono r when r.tm_type = None -> KUnk
 	| TDynamic _ -> KDyn
 	| TDynamic _ -> KDyn
 	| _ -> KOther
 	| _ -> KOther
@@ -630,6 +630,10 @@ let type_non_assign_op ctx op e1 e2 is_assign_op abstract_overload_only with_typ
 			WithType.value
 			WithType.value
 	in
 	in
 	let e1 = type_expr ctx e1 wt in
 	let e1 = type_expr ctx e1 wt in
+	let e1 = match wt with
+		| WithType.WithType(t,_) -> AbstractCast.cast_or_unify ctx t e1 e1.epos
+		| _ -> e1
+	in
 	let result = if abstract_overload_only then begin
 	let result = if abstract_overload_only then begin
 		let e2 = type_binop_rhs ctx op e1 e2 is_assign_op with_type p in
 		let e2 = type_binop_rhs ctx op e1 e2 is_assign_op with_type p in
 		try_abstract_binop_overloads ctx op e1 e2 is_assign_op p
 		try_abstract_binop_overloads ctx op e1 e2 is_assign_op p

+ 1 - 1
src/typing/overloadResolution.ml

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

+ 36 - 16
src/typing/tanon_identification.ml

@@ -135,29 +135,30 @@ object(self)
 		in
 		in
 		loop td.t_type
 		loop td.t_type
 
 
-	method identify (accept_anons : bool) (t : Type.t) =
-		match t with
-		| TType(td,tl) ->
+	method identity_anon (an : tanon) =
+		let make_pfm path = {
+			pfm_path = path;
+			pfm_params = [];
+			pfm_fields = an.a_fields;
+			pfm_converted = None;
+			pfm_arity = count_fields an.a_fields;
+		} in
+		match !(an.a_status) with
+		| ClassStatics {cl_path = path} | EnumStatics {e_path = path} | AbstractStatics {a_path = path} ->
 			begin try
 			begin try
-				Some (Hashtbl.find pfms td.t_path)
+				Some (Hashtbl.find pfms path)			
 			with Not_found ->
 			with Not_found ->
-				self#identify accept_anons (apply_typedef td tl)
+				let pfm = make_pfm path in
+				self#add_pfm path pfm;
+				Some pfm
 			end
 			end
-		| TMono {tm_type = Some t} ->
-			self#identify accept_anons t
-		| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) ->
-			self#identify accept_anons (Abstract.get_underlying_type a tl)
-		| TAbstract({a_path=([],"Null")},[t]) ->
-			self#identify accept_anons t
-		| TLazy f ->
-			self#identify accept_anons (lazy_type f)
-		| TAnon an when accept_anons && not (PMap.is_empty an.a_fields) ->
+		| _ ->
 			let arity = PMap.fold (fun cf i ->
 			let arity = PMap.fold (fun cf i ->
 				replace_mono cf.cf_type;
 				replace_mono cf.cf_type;
 				i + 1
 				i + 1
 			) an.a_fields 0 in
 			) an.a_fields 0 in
 			begin try
 			begin try
-				Some (self#find_compatible arity t)
+				Some (self#find_compatible arity (TAnon an))
 			with Not_found ->
 			with Not_found ->
 				let id = num in
 				let id = num in
 				num <- num + 1;
 				num <- num + 1;
@@ -171,7 +172,26 @@ object(self)
 				} in
 				} in
 				self#add_pfm path pfm;
 				self#add_pfm path pfm;
 				Some pfm
 				Some pfm
-			end;
+			end
+
+	method identify (accept_anons : bool) (t : Type.t) =
+		match t with
+		| TType(td,tl) ->
+			begin try
+				Some (Hashtbl.find pfms td.t_path)
+			with Not_found ->
+				self#identify accept_anons (apply_typedef td tl)
+			end
+		| TMono {tm_type = Some t} ->
+			self#identify accept_anons t
+		| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) ->
+			self#identify accept_anons (Abstract.get_underlying_type a tl)
+		| TAbstract({a_path=([],"Null")},[t]) ->
+			self#identify accept_anons t
+		| TLazy f ->
+			self#identify accept_anons (lazy_type f)
+		| TAnon an when accept_anons && not (PMap.is_empty an.a_fields) ->
+			self#identity_anon an
 		| _ ->
 		| _ ->
 			None
 			None
 end
 end

+ 76 - 96
src/typing/typeload.ml

@@ -35,7 +35,7 @@ open Globals
 
 
 let build_count = ref 0
 let build_count = ref 0
 
 
-let type_function_params_rec = ref (fun _ _ _ _ -> die "" __LOC__)
+let type_function_params_ref = ref (fun _ _ _ _ _ -> die "" __LOC__)
 
 
 let check_field_access ctx cff =
 let check_field_access ctx cff =
 	let display_access = ref None in
 	let display_access = ref None in
@@ -102,17 +102,6 @@ let find_type_in_module_raise ctx m tname p =
 	with Not_found ->
 	with Not_found ->
 		raise_typing_error_ext (make_error (Type_not_found (m.m_path,tname,Not_defined)) p)
 		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 **)
 (** 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 =
 let find_type_in_current_module_context ctx pack name =
@@ -286,28 +275,24 @@ let make_extension_type ctx tl =
 	let ta = mk_anon ~fields (ref (Extend tl)) in
 	let ta = mk_anon ~fields (ref (Extend tl)) in
 	ta
 	ta
 
 
-let check_param_constraints ctx t map c p =
-	match follow t with
-	| TMono _ -> ()
-	| _ ->
-		let ctl = (match c.cl_kind with KTypeParameter l -> l | _ -> []) in
-		List.iter (fun ti ->
-			let ti = map ti in
-			try
-				unify_raise t ti p
-			with Error ({ err_message = Unify l } as err) ->
-				let fail() =
-					if not ctx.untyped then display_error_ext ctx.com { err with err_message = (Unify (Constraint_failure (s_type_path c.cl_path) :: l)) }
-				in
-				match follow t with
-				| TInst({cl_kind = KExpr e},_) ->
-					let e = type_expr {ctx with locals = PMap.empty} e (WithType.with_type ti) in
-					begin try unify_raise e.etype ti p
-					with Error { err_message = Unify _ } -> fail() end
-				| _ ->
-					fail()
+let check_param_constraints ctx t map ttp p =
+	List.iter (fun ti ->
+		let ti = map ti in
+		try
+			unify_raise t ti p
+		with Error ({ err_message = Unify l } as err) ->
+			let fail() =
+				if not ctx.untyped then display_error_ext ctx.com { err with err_message = (Unify (Constraint_failure (s_type_path ttp.ttp_class.cl_path) :: l)) }
+			in
+			match follow t with
+			| TInst({cl_kind = KExpr e},_) ->
+				let e = type_expr {ctx with locals = PMap.empty} e (WithType.with_type ti) in
+				begin try unify_raise e.etype ti p
+				with Error { err_message = Unify _ } -> fail() end
+			| _ ->
+				fail()
 
 
-		) ctl
+	) (get_constraints ttp)
 
 
 type load_instance_param_mode =
 type load_instance_param_mode =
 	| ParamNormal
 	| ParamNormal
@@ -357,7 +342,8 @@ let rec load_params ctx info params p =
 	in
 	in
 	let checks = DynArray.create () in
 	let checks = DynArray.create () in
 	let rec loop tl1 tl2 is_rest = match tl1,tl2 with
 	let rec loop tl1 tl2 is_rest = match tl1,tl2 with
-		| t :: tl1,({ttp_name=name;ttp_type=t2}) :: tl2 ->
+		| t :: tl1,ttp:: tl2 ->
+			let name = ttp.ttp_name in
 			let t,pt = load_param t in
 			let t,pt = load_param t in
 			let check_const c =
 			let check_const c =
 				let is_expression = (match t with TInst ({ cl_kind = KExpr _ },_) -> true | _ -> false) in
 				let is_expression = (match t with TInst ({ cl_kind = KExpr _ },_) -> true | _ -> false) in
@@ -370,15 +356,14 @@ let rec load_params ctx info params p =
 					raise_typing_error "Type parameter is expected to be a constant value" p
 					raise_typing_error "Type parameter is expected to be a constant value" p
 			in
 			in
 			let is_rest = is_rest || name = "Rest" && info.build_kind = BuildGenericBuild in
 			let is_rest = is_rest || name = "Rest" && info.build_kind = BuildGenericBuild in
-			let t = match follow t2 with
-				| TInst ({ cl_kind = KTypeParameter [] } as c, []) when (match info.build_kind with BuildGeneric _ -> false | _ -> true) ->
-					check_const c;
+			let t = match ttp.ttp_constraints with
+				| None when (match info.build_kind with BuildGeneric _ -> false | _ -> true) ->
+					check_const ttp.ttp_class;
 					t
 					t
-				| TInst (c,[]) ->
-					check_const c;
-					DynArray.add checks (t,c,pt);
+				| _ ->
+					check_const ttp.ttp_class;
+					DynArray.add checks (t,ttp,pt);
 					t
 					t
-				| _ -> die "" __LOC__
 			in
 			in
 			t :: loop tl1 tl2 is_rest
 			t :: loop tl1 tl2 is_rest
 		| [],[] ->
 		| [],[] ->
@@ -429,7 +414,7 @@ and load_instance' ctx ptp get_params =
 		if t.tparams <> [] then raise_typing_error ("Class type parameter " ^ t.tname ^ " can't have parameters") ptp.pos_full;
 		if t.tparams <> [] then raise_typing_error ("Class type parameter " ^ t.tname ^ " can't have parameters") ptp.pos_full;
 		pt
 		pt
 	with Not_found ->
 	with Not_found ->
-		let mt = load_type_def ctx ptp.pos_path t in
+		let mt = load_type_def ctx (if ptp.pos_path == null_pos then ptp.pos_full else ptp.pos_path) t in
 		let info = ctx.g.get_build_info ctx mt ptp.pos_full in
 		let info = ctx.g.get_build_info ctx mt ptp.pos_full in
 		if info.build_path = ([],"Dynamic") then match t.tparams with
 		if info.build_path = ([],"Dynamic") then match t.tparams with
 			| [] -> t_dynamic
 			| [] -> t_dynamic
@@ -591,7 +576,7 @@ and load_complex_type' ctx allow_display (t,p) =
 					no_expr e;
 					no_expr e;
 					topt t, Var { v_read = AccNormal; v_write = AccNormal }
 					topt t, Var { v_read = AccNormal; v_write = AccNormal }
 				| FFun fd ->
 				| FFun fd ->
-					params := (!type_function_params_rec) ctx fd (fst f.cff_name) p;
+					params := (!type_function_params_ref) ctx fd TPHAnonField (fst f.cff_name) p;
 					no_expr fd.f_expr;
 					no_expr fd.f_expr;
 					let old = ctx.type_params in
 					let old = ctx.type_params in
 					ctx.type_params <- !params @ old;
 					ctx.type_params <- !params @ old;
@@ -684,11 +669,11 @@ and init_meta_overloads ctx co cf =
 				| [] ->
 				| [] ->
 					()
 					()
 				| l ->
 				| l ->
-					ctx.type_params <- List.filter (fun t ->
-						not (List.mem t l) (* TODO: this still looks suspicious *)
+					ctx.type_params <- List.filter (fun ttp ->
+						ttp.ttp_host <> TPHMethod
 					) ctx.type_params
 					) ctx.type_params
 			end;
 			end;
-			let params : type_params = (!type_function_params_rec) ctx f cf.cf_name p in
+			let params : type_params = (!type_function_params_ref) ctx f TPHMethod cf.cf_name p in
 			ctx.type_params <- params @ ctx.type_params;
 			ctx.type_params <- params @ ctx.type_params;
 			let topt = function None -> raise_typing_error "Explicit type required" p | Some t -> load_complex_type ctx true t in
 			let topt = function None -> raise_typing_error "Explicit type required" p | Some t -> load_complex_type ctx true t in
 			let args =
 			let args =
@@ -743,17 +728,10 @@ let load_type_hint ?(opt=false) ctx pcur t =
 (* ---------------------------------------------------------------------- *)
 (* ---------------------------------------------------------------------- *)
 (* PASS 1 & 2 : Module and Class Structure *)
 (* PASS 1 & 2 : Module and Class Structure *)
 
 
-type type_param_host =
-	| TPHType
-	| TPHConstructor
-	| TPHMethod
-	| TPHEnumConstructor
-
 let rec type_type_param ctx host path get_params p tp =
 let rec type_type_param ctx host path get_params p tp =
 	let n = fst tp.tp_name in
 	let n = fst tp.tp_name in
 	let c = mk_class ctx.m.curmod (fst path @ [snd path],n) (pos tp.tp_name) (pos tp.tp_name) in
 	let c = mk_class ctx.m.curmod (fst path @ [snd path],n) (pos tp.tp_name) (pos tp.tp_name) in
 	c.cl_params <- type_type_params ctx host c.cl_path get_params p tp.tp_params;
 	c.cl_params <- type_type_params ctx host c.cl_path get_params p tp.tp_params;
-	c.cl_kind <- KTypeParameter [];
 	c.cl_meta <- tp.Ast.tp_meta;
 	c.cl_meta <- tp.Ast.tp_meta;
 	if host = TPHEnumConstructor then c.cl_meta <- (Meta.EnumConstructorParam,[],null_pos) :: c.cl_meta;
 	if host = TPHEnumConstructor then c.cl_meta <- (Meta.EnumConstructorParam,[],null_pos) :: c.cl_meta;
 	let t = TInst (c,extract_param_types c.cl_params) in
 	let t = TInst (c,extract_param_types c.cl_params) in
@@ -770,39 +748,46 @@ let rec type_type_param ctx host path get_params p tp =
 					()
 					()
 				| TPHConstructor
 				| TPHConstructor
 				| TPHMethod
 				| TPHMethod
-				| TPHEnumConstructor ->
+				| TPHEnumConstructor
+				| TPHAnonField
+				| TPHLocal ->
 					display_error ctx.com "Default type parameters are only supported on types" (pos ct)
 					display_error ctx.com "Default type parameters are only supported on types" (pos ct)
 				end;
 				end;
 				t
 				t
 			) "default" in
 			) "default" in
 			Some (TLazy r)
 			Some (TLazy r)
 	in
 	in
-	match tp.tp_constraints with
-	| None ->
-		mk_type_param n t default
-	| Some th ->
-		let r = make_lazy ctx t (fun r ->
-			let ctx = { ctx with type_params = ctx.type_params @ get_params() } in
-			let rec loop th = match fst th with
-				| CTIntersection tl -> List.map (load_complex_type ctx true) tl
-				| CTParent ct -> loop ct
-				| _ -> [load_complex_type ctx true th]
-			in
-			let constr = loop th in
-			(* check against direct recursion *)
-			let rec loop t =
-				match follow t with
-				| TInst (c2,_) when c == c2 -> raise_typing_error "Recursive constraint parameter is not allowed" p
-				| TInst ({ cl_kind = KTypeParameter cl },_) ->
-					List.iter loop cl
-				| _ ->
-					()
-			in
-			List.iter loop constr;
-			c.cl_kind <- KTypeParameter constr;
-			t
-		) "constraint" in
-		mk_type_param n (TLazy r) default
+	let ttp = match tp.tp_constraints with
+		| None ->
+			mk_type_param c host default None
+		| Some th ->
+			let current_type_params = ctx.type_params in
+			let constraints = lazy (
+				let ctx = { ctx with type_params = get_params() @ current_type_params } in
+				let rec loop th = match fst th with
+					| CTIntersection tl -> List.map (load_complex_type ctx true) tl
+					| CTParent ct -> loop ct
+					| _ -> [load_complex_type ctx true th]
+				in
+				let constr = loop th in
+				(* check against direct recursion *)
+				let rec loop t =
+					match follow t with
+					| TInst (c2,_) when c == c2 ->
+						raise_typing_error "Recursive constraint parameter is not allowed" p
+					| TInst ({ cl_kind = KTypeParameter ttp },_) ->
+						List.iter loop (get_constraints ttp)
+					| _ ->
+						()
+				in
+				List.iter loop constr;
+				constr
+			) in
+			delay ctx PConnectField (fun () -> ignore (Lazy.force constraints));
+			mk_type_param c host default (Some constraints)
+	in
+	c.cl_kind <- KTypeParameter ttp;
+	ttp
 
 
 and type_type_params ctx host path get_params p tpl =
 and type_type_params ctx host path get_params p tpl =
 	let names = ref [] in
 	let names = ref [] in
@@ -845,21 +830,16 @@ let load_core_class ctx c =
 let init_core_api ctx c =
 let init_core_api ctx c =
 	let ccore = load_core_class ctx c in
 	let ccore = load_core_class ctx c in
 	begin try
 	begin try
-		List.iter2 (fun tp1 tp2 -> match follow tp1.ttp_type, follow tp2.ttp_type with
-			| TInst({cl_kind = KTypeParameter l1},_),TInst({cl_kind = KTypeParameter l2},_) ->
-				begin try
-					List.iter2 (fun t1 t2 -> type_eq EqCoreType t2 t1) l1 l2
-				with
-					| Invalid_argument _ ->
-						raise_typing_error "Type parameters must have the same number of constraints as core type" c.cl_pos
-					| Unify_error l ->
-						(* TODO send as one call with sub errors *)
-						display_error ctx.com ("Type parameter " ^ tp2.ttp_name ^ " has different constraint than in core type") c.cl_pos;
-						display_error ctx.com (error_msg (Unify l)) c.cl_pos;
-				end
-			| t1,t2 ->
-				Printf.printf "%s %s" (s_type (print_context()) t1) (s_type (print_context()) t2);
-				die "" __LOC__
+		List.iter2 (fun ttp1 ttp2 ->
+			try
+				List.iter2 (fun t1 t2 -> type_eq EqCoreType t2 t1) (get_constraints ttp1) (get_constraints ttp2)
+			with
+				| Invalid_argument _ ->
+					raise_typing_error "Type parameters must have the same number of constraints as core type" c.cl_pos
+				| Unify_error l ->
+					(* TODO send as one call with sub errors *)
+					display_error ctx.com ("Type parameter " ^ ttp2.ttp_name ^ " has different constraint than in core type") c.cl_pos;
+					display_error ctx.com (error_msg (Unify l)) c.cl_pos;
 		) ccore.cl_params c.cl_params;
 		) ccore.cl_params c.cl_params;
 	with Invalid_argument _ ->
 	with Invalid_argument _ ->
 		raise_typing_error "Class must have the same number of type parameters as core type" c.cl_pos
 		raise_typing_error "Class must have the same number of type parameters as core type" c.cl_pos
@@ -912,4 +892,4 @@ let init_core_api ctx c =
 	| Some cf, _ when not (has_class_field_flag cf CfPublic) -> ()
 	| Some cf, _ when not (has_class_field_flag cf CfPublic) -> ()
 	| Some f, Some f2 -> compare_fields f f2
 	| Some f, Some f2 -> compare_fields f f2
 	| None, Some cf when not (has_class_field_flag cf CfPublic) -> ()
 	| None, Some cf when not (has_class_field_flag cf CfPublic) -> ()
-	| _ -> raise_typing_error "Constructor differs from core type" c.cl_pos)
+	| _ -> raise_typing_error "Constructor differs from core type" c.cl_pos)

+ 23 - 56
src/typing/typeloadCheck.ml

@@ -62,28 +62,27 @@ let valid_redefinition ctx map1 map2 f1 t1 f2 t2 = (* child, parent *)
 		| l1, l2 when List.length l1 = List.length l2 ->
 		| l1, l2 when List.length l1 = List.length l2 ->
 			let to_check = ref [] in
 			let to_check = ref [] in
 			(* TPTODO: defaults *)
 			(* TPTODO: defaults *)
-			let monos = List.map2 (fun tp1 tp2 ->
-				(match follow tp1.ttp_type, follow tp2.ttp_type with
-				| TInst ({ cl_kind = KTypeParameter ct1 } as c1,pl1), TInst ({ cl_kind = KTypeParameter ct2 } as c2,pl2) ->
-					(match ct1, ct2 with
-					| [], [] -> ()
-					| _, _ when List.length ct1 = List.length ct2 ->
-						(* if same constraints, they are the same type *)
-						let check monos =
-							List.iter2 (fun t1 t2  ->
-								try
-									let t1 = apply_params l1 monos (apply_params c1.cl_params pl1 (map2 t1)) in
-									let t2 = apply_params l2 monos (apply_params c2.cl_params pl2 (map1 t2)) in
-									type_eq EqStrict t1 t2
-								with Unify_error l ->
-									raise (Unify_error (Unify_custom "Constraints differ" :: l))
-							) ct1 ct2
-						in
-						to_check := check :: !to_check;
-					| _ ->
-						raise (Unify_error [Unify_custom "Different number of constraints"]))
-				| _ -> ());
-				TInst (mk_class null_module ([],tp1.ttp_name) null_pos null_pos,[])
+			let monos = List.map2 (fun ttp1 ttp2 ->
+				let ct1 = get_constraints ttp1 in
+				let ct2 = get_constraints ttp2 in
+				(match ct1, ct2 with
+				| [], [] -> ()
+				| _, _ when List.length ct1 = List.length ct2 ->
+					(* if same constraints, they are the same type *)
+					let check monos =
+						List.iter2 (fun t1 t2  ->
+							try
+								let t1 = apply_params l1 monos (map2 t1) in
+								let t2 = apply_params l2 monos (map1 t2) in
+								type_eq EqStrict t1 t2
+							with Unify_error l ->
+								raise (Unify_error (Unify_custom "Constraints differ" :: l))
+						) ct1 ct2
+					in
+					to_check := check :: !to_check;
+				| _ ->
+					raise (Unify_error [Unify_custom "Different number of constraints"]));
+				TInst (mk_class null_module ([],ttp1.ttp_name) null_pos null_pos,[])
 			) l1 l2 in
 			) l1 l2 in
 			List.iter (fun f -> f monos) !to_check;
 			List.iter (fun f -> f monos) !to_check;
 			apply_params l1 monos t1, apply_params l2 monos t2
 			apply_params l1 monos t1, apply_params l2 monos t2
@@ -131,24 +130,6 @@ let copy_meta meta_src meta_target sl =
 	) meta_src;
 	) meta_src;
 	!meta
 	!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 check_native_name_override ctx child base =
 	let error base_pos child_pos =
 	let error base_pos child_pos =
 		(* TODO construct error *)
 		(* TODO construct error *)
@@ -156,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
 		display_error ~depth:1 ctx.com (compl_msg "Base field is defined here") base_pos
 	in
 	in
 	try
 	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
 		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
 			if base_name <> child_name then
 				error base_pos child_pos
 				error base_pos child_pos
 		with Not_found ->
 		with Not_found ->
@@ -351,20 +332,6 @@ let check_global_metadata ctx meta f_add mpath tpath so =
 	) ctx.com.global_metadata;
 	) ctx.com.global_metadata;
 	if ctx.is_display_file then delay ctx PCheckConstraint (fun () -> DisplayEmitter.check_display_metadata ctx meta)
 	if ctx.is_display_file then delay ctx PCheckConstraint (fun () -> DisplayEmitter.check_display_metadata ctx meta)
 
 
-let check_module_types ctx m p t =
-	let t = t_infos t in
-	try
-		let path2 = ctx.com.type_to_module#find t.mt_path in
-		if m.m_path <> path2 && String.lowercase_ascii (s_type_path path2) = String.lowercase_ascii (s_type_path m.m_path) then raise_typing_error ("Module " ^ s_type_path path2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p;
-		let m2 = ctx.com.module_lut#find path2 in
-		let hex1 = Digest.to_hex m.m_extra.m_sign in
-		let hex2 = Digest.to_hex m2.m_extra.m_sign in
-		let s = if hex1 = hex2 then hex1 else Printf.sprintf "was %s, is %s" hex2 hex1 in
-		raise_typing_error (Printf.sprintf "Type name %s is redefined from module %s (%s)" (s_type_path t.mt_path)  (s_type_path path2) s) p
-	with
-		Not_found ->
-			ctx.com.type_to_module#add t.mt_path m.m_path
-
 module Inheritance = struct
 module Inheritance = struct
 	let is_basic_class_path path = match path with
 	let is_basic_class_path path = match path with
 		| ([],("Array" | "String" | "Date" | "Xml")) -> true
 		| ([],("Array" | "String" | "Date" | "Xml")) -> true

+ 10 - 14
src/typing/typeloadFields.ml

@@ -633,7 +633,7 @@ let create_field_context ctx cctx cff is_display_file display_modifier =
 	fctx
 	fctx
 
 
 let create_typer_context_for_field ctx cctx fctx cff =
 let create_typer_context_for_field ctx cctx fctx cff =
-	DeprecationCheck.check_is ctx.com ctx.curclass.cl_meta cff.cff_meta (fst cff.cff_name) cff.cff_meta (snd cff.cff_name);
+	DeprecationCheck.check_is ctx.com ctx.m.curmod ctx.curclass.cl_meta cff.cff_meta (fst cff.cff_name) cff.cff_meta (snd cff.cff_name);
 	let ctx = {
 	let ctx = {
 		ctx with
 		ctx with
 		pass = PBuildClass; (* will be set later to PTypeExpr *)
 		pass = PBuildClass; (* will be set later to PTypeExpr *)
@@ -692,7 +692,7 @@ let transform_field (ctx,cctx) c f fields p =
 	in
 	in
 	if List.mem_assoc AMacro f.cff_access then
 	if List.mem_assoc AMacro f.cff_access then
 		(match ctx.g.macros with
 		(match ctx.g.macros with
-		| Some (_,mctx) when mctx.com.type_to_module#mem c.cl_path ->
+		| Some (_,mctx) when mctx.com.module_lut#get_type_lut#mem c.cl_path ->
 			(* assume that if we had already a macro with the same name, it has not been changed during the @:build operation *)
 			(* assume that if we had already a macro with the same name, it has not been changed during the @:build operation *)
 			if not (List.exists (fun f2 -> f2.cff_name = f.cff_name && List.mem_assoc AMacro f2.cff_access) (!fields)) then
 			if not (List.exists (fun f2 -> f2.cff_name = f.cff_name && List.mem_assoc AMacro f2.cff_access) (!fields)) then
 				raise_typing_error "Class build macro cannot return a macro function when the class has already been compiled into the macro context" p
 				raise_typing_error "Class build macro cannot return a macro function when the class has already been compiled into the macro context" p
@@ -701,7 +701,7 @@ let transform_field (ctx,cctx) c f fields p =
 
 
 let type_var_field ctx t e stat do_display p =
 let type_var_field ctx t e stat do_display p =
 	if stat then ctx.curfun <- FunStatic else ctx.curfun <- FunMember;
 	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 = type_expr ctx e (WithType.with_type t) in
 	let e = AbstractCast.cast_or_unify ctx t e p in
 	let e = AbstractCast.cast_or_unify ctx t e p in
 	match t with
 	match t with
@@ -950,7 +950,7 @@ module TypeBinding = struct
 							| NothingToDo ->
 							| NothingToDo ->
 								(fun () -> ())
 								(fun () -> ())
 							| NormalOverride rctx ->
 							| NormalOverride rctx ->
-								(fun () -> 
+								(fun () ->
 									TypeloadCheck.check_override_field ctx cf.cf_name_pos rctx
 									TypeloadCheck.check_override_field ctx cf.cf_name_pos rctx
 								)
 								)
 							| OverloadOverride f ->
 							| OverloadOverride f ->
@@ -958,7 +958,7 @@ module TypeBinding = struct
 							end
 							end
 						| _ ->
 						| _ ->
 							(fun () -> ())
 							(fun () -> ())
-					in					
+					in
 					let e = TypeloadFunction.type_function ctx args ret fmode e fctx.is_display_field p in
 					let e = TypeloadFunction.type_function ctx args ret fmode e fctx.is_display_field p in
 					f_check();
 					f_check();
 					(* Disabled for now, see https://github.com/HaxeFoundation/haxe/issues/3033 *)
 					(* Disabled for now, see https://github.com/HaxeFoundation/haxe/issues/3033 *)
@@ -1288,7 +1288,7 @@ let setup_args_ret ctx cctx fctx name fd p =
 
 
 let create_method (ctx,cctx,fctx) c f fd p =
 let create_method (ctx,cctx,fctx) c f fd p =
 	let name = fst f.cff_name in
 	let name = fst f.cff_name in
-	let params = TypeloadFunction.type_function_params ctx fd name p in
+	let params = TypeloadFunction.type_function_params ctx fd TPHMethod name p in
 	if fctx.is_generic then begin
 	if fctx.is_generic then begin
 		if params = [] then raise_typing_error "Generic functions must have type parameters" p;
 		if params = [] then raise_typing_error "Generic functions must have type parameters" p;
 	end;
 	end;
@@ -1775,12 +1775,7 @@ let init_class ctx c p herits fields =
 		| _ :: l ->
 		| _ :: l ->
 			check_require l
 			check_require l
 	in
 	in
-	let rec check_if_feature = function
-		| [] -> []
-		| (Meta.IfFeature,el,_) :: _ -> List.map (fun (e,p) -> match e with EConst (String(s,_)) -> s | _ -> raise_typing_error "String expected" p) el
-		| _ :: l -> check_if_feature l
-	in
-	let cl_if_feature = check_if_feature c.cl_meta in
+	let cl_if_feature = Feature.check_if_feature c.cl_meta in
 	let cl_req = check_require c.cl_meta in
 	let cl_req = check_require c.cl_meta in
 	let has_init = ref false in
 	let has_init = ref false in
 	List.iter (fun f ->
 	List.iter (fun f ->
@@ -1805,10 +1800,11 @@ let init_class ctx c p herits fields =
 					| FKConstructor -> CfrConstructor
 					| FKConstructor -> CfrConstructor
 					| _ -> if fctx.is_static then CfrStatic else CfrMember
 					| _ -> if fctx.is_static then CfrStatic else CfrMember
 				in
 				in
-				ctx.m.curmod.m_extra.m_if_feature <- (s, (mk_class_field_ref c cf ref_kind fctx.is_macro)) :: ctx.m.curmod.m_extra.m_if_feature;
+				let cf_ref = mk_class_field_ref c cf ref_kind fctx.is_macro in
+				Feature.set_feature ctx.m.curmod cf_ref s;
 			in
 			in
 			List.iter set_feature cl_if_feature;
 			List.iter set_feature cl_if_feature;
-			List.iter set_feature (check_if_feature cf.cf_meta);
+			List.iter set_feature (Feature.check_if_feature cf.cf_meta);
 			let req = check_require f.cff_meta in
 			let req = check_require f.cff_meta in
 			let req = (match req with None -> if fctx.is_static || fctx.field_kind = FKConstructor then cl_req else None | _ -> req) in
 			let req = (match req with None -> if fctx.is_static || fctx.field_kind = FKConstructor then cl_req else None | _ -> req) in
 			(match req with
 			(match req with

+ 4 - 4
src/typing/typeloadFunction.ml

@@ -43,9 +43,9 @@ let save_field_state ctx =
 		ctx.in_function <- old_in_function;
 		ctx.in_function <- old_in_function;
 	)
 	)
 
 
-let type_function_params ctx fd fname p =
+let type_function_params ctx fd host fname p =
 	let params = ref [] in
 	let params = ref [] in
-	params := Typeload.type_type_params ctx TPHMethod ([],fname) (fun() -> !params) p fd.f_params;
+	params := Typeload.type_type_params ctx host ([],fname) (fun() -> !params) p fd.f_params;
 	!params
 	!params
 
 
 let type_function ctx (args : function_arguments) ret fmode e do_display p =
 let type_function ctx (args : function_arguments) ret fmode e do_display p =
@@ -78,7 +78,7 @@ let type_function ctx (args : function_arguments) ret fmode e do_display p =
 	end else begin
 	end else begin
 		let is_display_debug = Meta.has (Meta.Custom ":debug.display") ctx.curfield.cf_meta in
 		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));
 		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));
 		if is_display_debug then print_endline ("after processing:\n" ^ (Expr.dump_with_pos e));
 		type_expr ctx e NoValue
 		type_expr ctx e NoValue
 	end in
 	end in
@@ -257,4 +257,4 @@ let add_constructor ctx c force_constructor p =
 		(* nothing to do *)
 		(* nothing to do *)
 		()
 		()
 ;;
 ;;
-Typeload.type_function_params_rec := type_function_params
+Typeload.type_function_params_ref := type_function_params

+ 15 - 31
src/typing/typeloadModule.ml

@@ -50,12 +50,11 @@ module ModuleLevel = struct
 			m_path = mpath;
 			m_path = mpath;
 			m_types = [];
 			m_types = [];
 			m_statics = None;
 			m_statics = None;
-			m_extra = module_extra (Path.get_full_path file) (Define.get_signature ctx.com.defines) (file_time file) (if ctx.com.is_macro_context then MMacro else MCode) (get_policy ctx.g mpath);
+			m_extra = module_extra (Path.get_full_path file) (Define.get_signature ctx.com.defines) (file_time file) (if ctx.com.is_macro_context then MMacro else MCode) ctx.com.compilation_step (get_policy ctx.g mpath);
 		} in
 		} in
 		m
 		m
 
 
 	let add_module ctx m p =
 	let add_module ctx m p =
-		List.iter (TypeloadCheck.check_module_types ctx m p) m.m_types;
 		ctx.com.module_lut#add m.m_path m
 		ctx.com.module_lut#add m.m_path m
 
 
 	(*
 	(*
@@ -66,7 +65,7 @@ module ModuleLevel = struct
 		let decls = ref [] in
 		let decls = ref [] in
 		let statics = ref [] in
 		let statics = ref [] in
 		let check_name name meta also_statics p =
 		let check_name name meta also_statics p =
-			DeprecationCheck.check_is com meta [] name meta p;
+			DeprecationCheck.check_is com ctx.m.curmod meta [] name meta p;
 			let error prev_pos =
 			let error prev_pos =
 				display_error ctx.com ("Name " ^ name ^ " is already defined in this module") p;
 				display_error ctx.com ("Name " ^ name ^ " is already defined in this module") p;
 				raise_typing_error ~depth:1 (compl_msg "Previous declaration here") prev_pos;
 				raise_typing_error ~depth:1 (compl_msg "Previous declaration here") prev_pos;
@@ -132,20 +131,11 @@ module ModuleLevel = struct
 				let path = make_path name priv d.d_meta p in
 				let path = make_path name priv d.d_meta p in
 				if Meta.has (Meta.Custom ":fakeEnum") d.d_meta then raise_typing_error "@:fakeEnum enums is no longer supported in Haxe 4, use extern enum abstract instead" p;
 				if Meta.has (Meta.Custom ":fakeEnum") d.d_meta then raise_typing_error "@:fakeEnum enums is no longer supported in Haxe 4, use extern enum abstract instead" p;
 				let e = {
 				let e = {
-					e_path = path;
-					e_module = m;
-					e_pos = p;
-					e_name_pos = (pos d.d_name);
+					(mk_enum m path p (pos d.d_name)) with
 					e_doc = d.d_doc;
 					e_doc = d.d_doc;
 					e_meta = d.d_meta;
 					e_meta = d.d_meta;
-					e_params = [];
-					e_using = [];
-					e_restore = (fun () -> ());
 					e_private = priv;
 					e_private = priv;
 					e_extern = List.mem EExtern d.d_flags;
 					e_extern = List.mem EExtern d.d_flags;
-					e_constrs = PMap.empty;
-					e_names = [];
-					e_type = enum_module_type m path p;
 				} in
 				} in
 				if not e.e_extern then check_type_name name d.d_meta;
 				if not e.e_extern then check_type_name name d.d_meta;
 				decls := (TEnumDecl e, decl) :: !decls;
 				decls := (TEnumDecl e, decl) :: !decls;
@@ -205,7 +195,7 @@ module ModuleLevel = struct
 					| None -> ()
 					| None -> ()
 					| Some p ->
 					| Some p ->
 						let options = Warning.from_meta d.d_meta in
 						let options = Warning.from_meta d.d_meta in
-						ctx.com.warning WDeprecatedEnumAbstract options "`@:enum abstract` is deprecated in favor of `enum abstract`" p
+						module_warning ctx.com ctx.m.curmod WDeprecatedEnumAbstract options "`@:enum abstract` is deprecated in favor of `enum abstract`" p
 				end;
 				end;
 				decls := (TAbstractDecl a, decl) :: !decls;
 				decls := (TAbstractDecl a, decl) :: !decls;
 				match d.d_data with
 				match d.d_data with
@@ -388,16 +378,8 @@ module TypeLevel = struct
 			ef_params = params;
 			ef_params = params;
 			ef_meta = c.ec_meta;
 			ef_meta = c.ec_meta;
 		} in
 		} in
-		DeprecationCheck.check_is ctx.com e.e_meta f.ef_meta f.ef_name f.ef_meta f.ef_name_pos;
-		let cf = {
-			(mk_field f.ef_name f.ef_type p f.ef_name_pos) with
-			cf_kind = (match follow f.ef_type with
-				| TFun _ -> Method MethNormal
-				| _ -> Var { v_read = AccNormal; v_write = AccNo }
-			);
-			cf_doc = f.ef_doc;
-			cf_params = f.ef_params;
-		} in
+		DeprecationCheck.check_is ctx.com ctx.m.curmod e.e_meta f.ef_meta f.ef_name f.ef_meta f.ef_name_pos;
+		let cf = class_field_of_enum_field f in
 		if ctx.is_display_file && DisplayPosition.display_position#enclosed_in f.ef_name_pos then
 		if ctx.is_display_file && DisplayPosition.display_position#enclosed_in f.ef_name_pos then
 			DisplayEmitter.display_enum_field ctx e f p;
 			DisplayEmitter.display_enum_field ctx e f p;
 		f,cf
 		f,cf
@@ -535,8 +517,7 @@ module TypeLevel = struct
 		) (!constructs);
 		) (!constructs);
 		e.e_names <- List.rev !names;
 		e.e_names <- List.rev !names;
 		e.e_extern <- e.e_extern;
 		e.e_extern <- e.e_extern;
-		e.e_type.t_params <- e.e_params;
-		e.e_type.t_type <- mk_anon ~fields:!fields (ref (EnumStatics e));
+		unify ctx (TType(enum_module_type e !fields,[])) e.e_type p;
 		if !is_flat then e.e_meta <- (Meta.FlatEnum,[],null_pos) :: e.e_meta;
 		if !is_flat then e.e_meta <- (Meta.FlatEnum,[],null_pos) :: e.e_meta;
 		if Meta.has Meta.InheritDoc e.e_meta then
 		if Meta.has Meta.InheritDoc e.e_meta then
 			delay ctx PConnectField (fun() -> InheritDoc.build_enum_doc ctx e);
 			delay ctx PConnectField (fun() -> InheritDoc.build_enum_doc ctx e);
@@ -592,7 +573,7 @@ module TypeLevel = struct
 		| TMono r ->
 		| TMono r ->
 			(match r.tm_type with
 			(match r.tm_type with
 			| None -> Monomorph.bind r tt;
 			| None -> Monomorph.bind r tt;
-			| Some _ -> die "" __LOC__);
+			| Some t' -> die (Printf.sprintf "typedef %s is already initialized to %s, but new init to %s was attempted" (s_type_path t.t_path) (s_type_kind t') (s_type_kind tt)) __LOC__);
 		| _ -> die "" __LOC__);
 		| _ -> die "" __LOC__);
 		TypeloadFields.build_module_def ctx (TTypeDecl t) t.t_meta (fun _ -> []) (fun _ -> ())
 		TypeloadFields.build_module_def ctx (TTypeDecl t) t.t_meta (fun _ -> []) (fun _ -> ())
 
 
@@ -702,7 +683,7 @@ let make_curmod ctx m =
 	let rl = new resolution_list ["import";s_type_path m.m_path] in
 	let rl = new resolution_list ["import";s_type_path m.m_path] in
 	List.iter (fun mt ->
 	List.iter (fun mt ->
 		rl#add (module_type_resolution mt None null_pos))
 		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;
 		curmod = m;
 		import_resolution = rl;
 		import_resolution = rl;
@@ -756,11 +737,14 @@ let type_types_into_module ctx m tdecls p =
 	let ctx = create_typer_context_for_module ctx m in
 	let ctx = create_typer_context_for_module ctx m in
 	let decls,tdecls = ModuleLevel.create_module_types ctx m tdecls p in
 	let decls,tdecls = ModuleLevel.create_module_types ctx m tdecls p in
 	let types = List.map fst decls in
 	let types = List.map fst decls in
-	List.iter (TypeloadCheck.check_module_types ctx m p) types;
+	(* During the initial module_lut#add in type_module, m has no m_types yet by design.
+	   We manually add them here. This and module_lut#add itself should be the only places
+	   in the compiler that call add_module_type. *)
+	List.iter (fun mt -> ctx.com.module_lut#add_module_type m mt) types;
 	m.m_types <- m.m_types @ types;
 	m.m_types <- m.m_types @ types;
 	(* define the per-module context for the next pass *)
 	(* 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 *)
 		(* 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)
 		ignore(load_instance ctx (make_ptp (mk_type_path (["std"],"String")) null_pos) ParamNormal)
 	end;
 	end;

+ 26 - 172
src/typing/typer.ml

@@ -702,7 +702,7 @@ and type_vars ctx vl p =
 	let vl = List.map (fun ev ->
 	let vl = List.map (fun ev ->
 		let n = fst ev.ev_name
 		let n = fst ev.ev_name
 		and pv = snd ev.ev_name in
 		and pv = snd ev.ev_name in
-		DeprecationCheck.check_is ctx.com ctx.curclass.cl_meta ctx.curfield.cf_meta n ev.ev_meta pv;
+		DeprecationCheck.check_is ctx.com ctx.m.curmod ctx.curclass.cl_meta ctx.curfield.cf_meta n ev.ev_meta pv;
 		try
 		try
 			let t = Typeload.load_type_hint ctx p ev.ev_type in
 			let t = Typeload.load_type_hint ctx p ev.ev_type in
 			let e = (match ev.ev_expr with
 			let e = (match ev.ev_expr with
@@ -745,9 +745,9 @@ and type_vars ctx vl p =
 		mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos
 		mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos
 
 
 and format_string ctx s p =
 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
 		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
 		else
 			enext,p
 			enext,p
 	)
 	)
@@ -1041,9 +1041,9 @@ and type_new ctx ptp el with_type force_inline p =
 		unify_constructor_call c fa
 		unify_constructor_call c fa
 	in
 	in
 	try begin match Abstract.follow_with_forward_ctor t with
 	try begin match Abstract.follow_with_forward_ctor t with
-	| TInst ({cl_kind = KTypeParameter tl} as c,params) ->
+	| TInst ({cl_kind = KTypeParameter ttp} as c,params) ->
 		if not (TypeloadCheck.is_generic_parameter ctx c) then raise_typing_error "Only generic type parameters can be constructed" p;
 		if not (TypeloadCheck.is_generic_parameter ctx c) then raise_typing_error "Only generic type parameters can be constructed" p;
- 		begin match get_constructible_constraint ctx tl p with
+ 		begin match get_constructible_constraint ctx (get_constraints ttp) p with
 		| None ->
 		| None ->
 			raise_typing_error_ext (make_error (No_constructor (TClassDecl c)) p)
 			raise_typing_error_ext (make_error (No_constructor (TClassDecl c)) p)
 		| Some(tl,tr) ->
 		| Some(tl,tr) ->
@@ -1213,7 +1213,7 @@ and type_map_declaration ctx e1 el with_type p =
 
 
 and type_local_function ctx kind f with_type p =
 and type_local_function ctx kind f with_type p =
 	let name,inline = match kind with FKNamed (name,inline) -> Some name,inline | _ -> None,false in
 	let name,inline = match kind with FKNamed (name,inline) -> Some name,inline | _ -> None,false in
-	let params = TypeloadFunction.type_function_params ctx f (match name with None -> "localfun" | Some (n,_) -> n) p in
+	let params = TypeloadFunction.type_function_params ctx f TPHLocal (match name with None -> "localfun" | Some (n,_) -> n) p in
 	if params <> [] then begin
 	if params <> [] then begin
 		if name = None then display_error ctx.com "Type parameters not supported in unnamed local functions" p;
 		if name = None then display_error ctx.com "Type parameters not supported in unnamed local functions" p;
 		if with_type <> WithType.NoValue then raise_typing_error "Type parameters are not supported for rvalue functions" p
 		if with_type <> WithType.NoValue then raise_typing_error "Type parameters are not supported for rvalue functions" p
@@ -1557,8 +1557,7 @@ and type_cast ctx e t p =
 	let texpr = loop t in
 	let texpr = loop t in
 	mk (TCast (type_expr ctx e WithType.value,Some texpr)) t p
 	mk (TCast (type_expr ctx e WithType.value,Some texpr)) t p
 
 
-and make_if_then_else ctx e0 e1 e2 with_type p =
-	let e1,e2,t = match with_type with
+and get_if_then_else_operands ctx e1 e2 with_type = match with_type with
 	| WithType.NoValue -> e1,e2,ctx.t.tvoid
 	| WithType.NoValue -> e1,e2,ctx.t.tvoid
 	| WithType.Value _ -> e1,e2,unify_min ctx [e1; e2]
 	| WithType.Value _ -> e1,e2,unify_min ctx [e1; e2]
 	| WithType.WithType(t,src) when (match follow t with TMono _ -> true | t -> ExtType.is_void t) ->
 	| WithType.WithType(t,src) when (match follow t with TMono _ -> true | t -> ExtType.is_void t) ->
@@ -1567,7 +1566,9 @@ and make_if_then_else ctx e0 e1 e2 with_type p =
 		let e1 = AbstractCast.cast_or_unify ctx t e1 e1.epos in
 		let e1 = AbstractCast.cast_or_unify ctx t e1 e1.epos in
 		let e2 = AbstractCast.cast_or_unify ctx t e2 e2.epos in
 		let e2 = AbstractCast.cast_or_unify ctx t e2 e2.epos in
 		e1,e2,t
 		e1,e2,t
-	in
+
+and make_if_then_else ctx e0 e1 e2 with_type p =
+	let e1,e2,t = get_if_then_else_operands ctx e1 e2 with_type in
 	mk (TIf (e0,e1,Some e2)) t p
 	mk (TIf (e0,e1,Some e2)) t p
 
 
 and type_if ctx e e1 e2 with_type is_ternary p =
 and type_if ctx e e1 e2 with_type is_ternary p =
@@ -1842,26 +1843,22 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 		let vr = new value_reference ctx in
 		let vr = new value_reference ctx in
 		let e1 = type_expr ctx (Expr.ensure_block e1) with_type in
 		let e1 = type_expr ctx (Expr.ensure_block e1) with_type in
 		let e2 = type_expr ctx (Expr.ensure_block e2) (WithType.with_type e1.etype) in
 		let e2 = type_expr ctx (Expr.ensure_block e2) (WithType.with_type e1.etype) in
-		let tmin = unify_min ctx [e1; e2] in
-		let e1 = vr#as_var "tmp" {e1 with etype = ctx.t.tnull tmin} in
-		let e_null = Builder.make_null e1.etype e1.epos in
-		let e_cond = mk (TBinop(OpNotEq,e1,e_null)) ctx.t.tbool e1.epos in
-
+		let e1,e2,tmin = get_if_then_else_operands ctx e1 e2 with_type in
 		let rec follow_null t =
 		let rec follow_null t =
 			match t with
 			match t with
 			| TAbstract({a_path = [],"Null"},[t]) -> follow_null t
 			| TAbstract({a_path = [],"Null"},[t]) -> follow_null t
 			| _ -> t
 			| _ -> t
 		in
 		in
 		let iftype = if DeadEnd.has_dead_end e2 then
 		let iftype = if DeadEnd.has_dead_end e2 then
-			WithType.with_type (follow_null e1.etype)
-		else
-			let t = match e2.etype with
-				| TAbstract({a_path = [],"Null"},[t]) -> tmin
-				| _ -> follow_null tmin
-			in
-			WithType.with_type t
+			follow_null e1.etype
+		else match e2.etype with
+			| TAbstract({a_path = [],"Null"},[t]) -> tmin
+			| _ -> follow_null tmin
 		in
 		in
-		let e_if = make_if_then_else ctx e_cond e1 e2 iftype p in
+		let e1 = vr#as_var "tmp" {e1 with etype = ctx.t.tnull tmin} in
+		let e_null = Builder.make_null e1.etype e1.epos in
+		let e_cond = mk (TBinop(OpNotEq,e1,e_null)) ctx.t.tbool e1.epos in
+		let e_if = mk (TIf(e_cond,e1,Some e2)) iftype p in
 		vr#to_texpr e_if
 		vr#to_texpr e_if
 	| EBinop (OpAssignOp OpNullCoal,e1,e2) ->
 	| EBinop (OpAssignOp OpNullCoal,e1,e2) ->
 		let e_cond = EBinop(OpNotEq,e1,(EConst(Ident "null"), p)) in
 		let e_cond = EBinop(OpNotEq,e1,(EConst(Ident "null"), p)) in
@@ -2013,160 +2010,18 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 				DisplayEmitter.display_module_type ctx mt p_t;
 				DisplayEmitter.display_module_type ctx mt p_t;
 			let e_t = type_module_type ctx mt p_t in
 			let e_t = type_module_type ctx mt p_t in
 			let e_Std_isOfType =
 			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
 			in
 			mk (TCall (e_Std_isOfType, [e; e_t])) ctx.com.basic.tbool p
 			mk (TCall (e_Std_isOfType, [e; e_t])) ctx.com.basic.tbool p
 		| _ ->
 		| _ ->
 			display_error ctx.com "Unsupported type for `is` operator" p_t;
 			display_error ctx.com "Unsupported type for `is` operator" p_t;
 			Texpr.Builder.make_bool ctx.com.basic false p
 			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_ref := unify_min;
 unify_min_for_type_source_ref := unify_min_for_type_source;
 unify_min_for_type_source_ref := unify_min_for_type_source;
@@ -2174,5 +2029,4 @@ make_call_ref := make_call;
 type_call_target_ref := type_call_target;
 type_call_target_ref := type_call_target;
 type_access_ref := type_access;
 type_access_ref := type_access;
 type_block_ref := type_block;
 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);
 type_expr_ref := (fun ?(mode=MGet) ctx e with_type -> type_expr ~mode ctx e with_type);

+ 3 - 4
src/typing/typerBase.ml

@@ -210,8 +210,7 @@ let type_module_type ctx t p =
 			let t_tmp = class_module_type c in
 			let t_tmp = class_module_type c in
 			mk (TTypeExpr (TClassDecl c)) (TType (t_tmp,[])) p
 			mk (TTypeExpr (TClassDecl c)) (TType (t_tmp,[])) p
 		| TEnumDecl e ->
 		| TEnumDecl e ->
-			let types = (match tparams with None -> Monomorph.spawn_constrained_monos (fun t -> t) e.e_params | Some l -> l) in
-			mk (TTypeExpr (TEnumDecl e)) (TType (e.e_type,types)) p
+			mk (TTypeExpr (TEnumDecl e)) e.e_type p
 		| TTypeDecl s ->
 		| TTypeDecl s ->
 			let t = apply_typedef s (List.map (fun _ -> spawn_monomorph ctx p) s.t_params) in
 			let t = apply_typedef s (List.map (fun _ -> spawn_monomorph ctx p) s.t_params) in
 			DeprecationCheck.check_typedef (create_deprecation_context ctx) s p;
 			DeprecationCheck.check_typedef (create_deprecation_context ctx) s p;
@@ -309,8 +308,8 @@ let get_constructible_constraint ctx tl p =
 				end;
 				end;
 			| TAbstract({a_path = ["haxe"],"Constructible"},[t1]) ->
 			| TAbstract({a_path = ["haxe"],"Constructible"},[t1]) ->
 				Some (extract_function t1)
 				Some (extract_function t1)
-			| TInst({cl_kind = KTypeParameter tl1},_) ->
-				begin match loop tl1 with
+			| TInst({cl_kind = KTypeParameter ttp},_) ->
+				begin match loop (get_constraints ttp) with
 				| None -> loop tl
 				| None -> loop tl
 				| Some _ as t -> t
 				| Some _ as t -> t
 				end
 				end

+ 3 - 3
src/typing/typerDisplay.ml

@@ -251,14 +251,14 @@ let rec handle_signature_display ctx e_ast with_type =
 		l
 		l
 	in
 	in
 	let find_constructor_types t = match follow t with
 	let find_constructor_types t = match follow t with
-		| TInst ({cl_kind = KTypeParameter tl} as c,_) ->
+		| TInst ({cl_kind = KTypeParameter ttp} as c,_) ->
 			let rec loop tl = match tl with
 			let rec loop tl = match tl with
 				| [] -> raise_typing_error_ext (make_error (No_constructor (TClassDecl c)) p)
 				| [] -> raise_typing_error_ext (make_error (No_constructor (TClassDecl c)) p)
 				| t :: tl -> match follow t with
 				| t :: tl -> match follow t with
 					| TAbstract({a_path = ["haxe"],"Constructible"},[t]) -> t
 					| TAbstract({a_path = ["haxe"],"Constructible"},[t]) -> t
 					| _ -> loop tl
 					| _ -> loop tl
 			in
 			in
-			[loop tl,None,PMap.empty]
+			[loop (get_constraints ttp),None,PMap.empty]
 		| TInst (c,tl) | TAbstract({a_impl = Some c},tl) ->
 		| TInst (c,tl) | TAbstract({a_impl = Some c},tl) ->
 			Display.merge_core_doc ctx (TClassDecl c);
 			Display.merge_core_doc ctx (TClassDecl c);
 			let fa = get_constructor_access c tl p in
 			let fa = get_constructor_access c tl p in
@@ -628,7 +628,7 @@ let handle_display ctx e_ast dk mode with_type =
 						false
 						false
 					end
 					end
 				end
 				end
-			| ITTypeParameter {cl_kind = KTypeParameter tl} when get_constructible_constraint ctx tl null_pos <> None ->
+			| ITTypeParameter {cl_kind = KTypeParameter ttp} when get_constructible_constraint ctx (get_constraints ttp) null_pos <> None ->
 				true
 				true
 			| _ -> false
 			| _ -> false
 		) r.fitems in
 		) r.fitems in

+ 167 - 0
src/typing/typerEntry.ml

@@ -0,0 +1,167 @@
+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 Lookup.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" ->
+				let t = (TAbstract (a,[])) in
+				Type.unify t ctx.t.tfloat;
+				ctx.t.tfloat <- t
+			| "Int" ->
+				let t = (TAbstract (a,[])) in
+				Type.unify t ctx.t.tint;
+				ctx.t.tint <- t
+			| "Bool" ->
+				let t = (TAbstract (a,[])) in
+				Type.unify t ctx.t.tbool;
+				ctx.t.tbool <- t
+			| "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 ->
+			let t = (TInst (c,[])) in
+			Type.unify t ctx.t.tstring;
+			ctx.t.tstring <- t
+		| _ -> ()
+	) 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;

+ 3 - 0
std/hl/Api.hx

@@ -26,6 +26,9 @@ extern class Api {
 	static inline function rethrow(v:Dynamic):Void {
 	static inline function rethrow(v:Dynamic):Void {
 		untyped $rethrow(v);
 		untyped $rethrow(v);
 	}
 	}
+	static inline function unsafeCast<From,To>(v:From):To {
+		return untyped $unsafecast(v);
+	}
 	@:hlNative("std", "obj_get_field") static function getField(obj:Dynamic, hash:Int):Dynamic;
 	@:hlNative("std", "obj_get_field") static function getField(obj:Dynamic, hash:Int):Dynamic;
 	@:hlNative("std", "obj_set_field") static function setField(obj:Dynamic, hash:Int, value:Dynamic):Void;
 	@:hlNative("std", "obj_set_field") static function setField(obj:Dynamic, hash:Int, value:Dynamic):Void;
 	@:hlNative("std", "obj_has_field") static function hasField(obj:Dynamic, hash:Int):Bool;
 	@:hlNative("std", "obj_has_field") static function hasField(obj:Dynamic, hash:Int):Bool;

+ 4 - 21
std/hl/CArray.hx

@@ -1,35 +1,18 @@
 package hl;
 package hl;
 
 
-#if (hl_ver >= version("1.13.0"))
+#if (hl_ver >= version("1.14.0"))
 /**
 /**
 	CArray is a compact array where all objects are memory aligned and stored as a single GC block.
 	CArray is a compact array where all objects are memory aligned and stored as a single GC block.
 	You must hold a reference to the CArray while any of the objects it contains is still referenced somewhere.
 	You must hold a reference to the CArray while any of the objects it contains is still referenced somewhere.
  **/
  **/
 abstract CArray<T>(Abstract<"hl_carray">) {
 abstract CArray<T>(Abstract<"hl_carray">) {
 
 
-	public var length(get,never) : Int;
-
-
-	#if (hl_ver >= version("1.14.0"))
-	inline function get_length() return untyped $asize(this);
 	@:arrayAccess inline function get( index : Int ) : T return untyped this[index];
 	@:arrayAccess inline function get( index : Int ) : T return untyped this[index];
-	#else
-	inline function get_length() return getLen(cast this);
-	@:arrayAccess inline function get( index : Int ) : T return getIndex(cast this, index);
-	#end
-
-	public static function alloc<T>( cl : Class<T>, size : Int ) : CArray<T> {
-		return cast alloc_carray( (cast cl:BaseType).__type__ , size );
-	}
 
 
-	@:hlNative("?std","carray_get")
-	static function getIndex( arr : CArray<Dynamic>, index : Int ) : Dynamic {
-		return null;
-	}
+	public inline function unsafeSet( index : Int, v : T ) return untyped this[index] = v;
 
 
-	@:hlNative("?std","carray_length")
-	static function getLen( arr : CArray<Dynamic> ) : Int {
-		return 0;
+	public static inline function alloc<T>( cl : Class<T>, size : Int ) : CArray<T> {
+		return cast alloc_carray( (cast cl:BaseType).__type__ , size );
 	}
 	}
 
 
 	@:hlNative("?std","alloc_carray")
 	@:hlNative("?std","alloc_carray")

+ 1 - 1
std/js/Object.hx

@@ -24,4 +24,4 @@ package js;
 
 
 @:deprecated typedef Object = js.lib.Object;
 @:deprecated typedef Object = js.lib.Object;
 @:deprecated typedef ObjectPrototype = js.lib.Object.ObjectPrototype;
 @:deprecated typedef ObjectPrototype = js.lib.Object.ObjectPrototype;
-@:deprecated typedef ObjectPropertyDescriptor = js.lib.Object.ObjectPropertyDescriptor;
+@:deprecated typedef ObjectPropertyDescriptor<TProp> = js.lib.Object.ObjectPropertyDescriptor<TProp>;

+ 43 - 1
std/js/html/Navigator.hx

@@ -106,6 +106,11 @@ extern class Navigator {
 	var onLine(default,null) : Bool;
 	var onLine(default,null) : Bool;
 	var storage(default,null) : StorageManager;
 	var storage(default,null) : StorageManager;
 
 
+	/**
+		Returns a `WakeLock` object which allows a document to acquire a screen wake lock.
+	**/
+	var wakeLock(default,null) : WakeLock;
+
 	@:overload( function( duration : Int ) : Bool {} )
 	@:overload( function( duration : Int ) : Bool {} )
 	function vibrate( pattern : Array<Int> ) : Bool;
 	function vibrate( pattern : Array<Int> ) : Bool;
 	function javaEnabled() : Bool;
 	function javaEnabled() : Bool;
@@ -122,4 +127,41 @@ extern class Navigator {
 	function sendBeacon( url : String, ?data : Blob ) : Bool;
 	function sendBeacon( url : String, ?data : Blob ) : Bool;
 	function requestMediaKeySystemAccess( keySystem : String, supportedConfigurations : Array<js.html.eme.MediaKeySystemConfiguration> ) : Promise<js.html.eme.MediaKeySystemAccess>;
 	function requestMediaKeySystemAccess( keySystem : String, supportedConfigurations : Array<js.html.eme.MediaKeySystemConfiguration> ) : Promise<js.html.eme.MediaKeySystemAccess>;
 	function taintEnabled() : Bool;
 	function taintEnabled() : Bool;
-}
+
+	/**
+		Returns `true` if the equivalent call to `share()` would succeed.
+		Returns `false` if the data cannot be validated.
+	**/
+	function canShare(?data: NavigatorShareData): Bool;
+
+	/**
+		Invokes the native sharing mechanism of the device to share data such as text, URLs, or files.
+	**/
+	function share(data: NavigatorShareData): Promise<Void>;
+}
+
+/**
+	An object containing data to share.
+**/
+typedef NavigatorShareData = {
+
+	/**
+		An array of `File` objects representing files to be shared.
+	**/
+	var ?files: Array<File>;
+
+	/**
+		A string representing text to be shared.
+	**/
+	var ?text: String;
+
+	/**
+		A string representing the title to be shared.
+	**/
+	var ?title: String;
+
+	/**
+		A string representing a URL to be shared
+	**/
+	var ?url: String;
+}

+ 74 - 0
std/js/html/WakeLock.hx

@@ -0,0 +1,74 @@
+/*
+ * Copyright (C)2005-2023 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package js.html;
+
+import js.lib.Promise;
+
+/**
+	Prevents device screens from dimming or locking when an application needs to keep running.
+
+	Documentation [WakeLock](https://developer.mozilla.org/en-US/docs/Web/API/WakeLock) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/WakeLock/contributors.txt), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/).
+
+	@see <https://developer.mozilla.org/en-US/docs/Web/API/WakeLock>
+**/
+@:native("WakeLock")
+extern class WakeLock {
+
+	/**
+		Returns a `Promise` that resolves with a `WakeLockSentinel` object, which allows control over screen dimming and locking.
+	**/
+	function request(?type: WakeLockType): Promise<WakeLockSentinel>;
+}
+
+/**
+	Provides a handle to the underlying platform wake lock and can be manually released and reacquired.
+
+	Documentation [WakeLockSentinel](https://developer.mozilla.org/en-US/docs/Web/API/WakeLockSentinel) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/WakeLockSentinel/contributors.txt), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/).
+
+	@see <https://developer.mozilla.org/en-US/docs/Web/API/WakeLockSentinel>
+**/
+@:native("WakeLockSentinel")
+extern class WakeLockSentinel  extends EventTarget {
+
+	/**
+		A boolean a that indicates whether a `WakeLockSentinel` has been released yet.
+	**/
+	final released: Bool;
+
+	/**
+		A string representation of the currently acquired `WakeLockSentinel` type.
+	**/
+	final type: WakeLockType;
+
+	/**
+		Releases the `WakeLockSentinel`, returning a `Promise` that is resolved once the sentinel has been successfully released.
+	**/
+	function release(): Promise<Void>;
+}
+
+/**
+	Indicates the type of `WakeLockSentinel` to be acquired.
+**/
+enum abstract WakeLockType(String) from String to String {
+	var Screen = "screen";
+}

+ 151 - 53
std/js/lib/Object.hx

@@ -33,35 +33,64 @@ import haxe.DynamicAccess;
 @:native("Object")
 @:native("Object")
 extern class Object {
 extern class Object {
 	/**
 	/**
-		Copies the values of all enumerable own properties from one or more
-		source objects to a target object.
+		The Object.assign() method is used to copy the values of all enumerable
+		own properties from one or more source objects to a target object. It
+		will return the target object.
+
+		Note: this is an ES2015 feature
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
 	**/
 	**/
-	static function assign<T:{}>(target:T, sources:Rest<{}>):T;
+	static function assign<TSource:{}, TDest:{}>(target:TSource, sources:Rest<{}>):TDest;
 
 
 	/**
 	/**
-		Creates a new object with the specified prototype object and properties.
+		The Object.create() method create a new object, using an existing object
+		to provide the newly created object's __proto__ . (see browser console
+		for visual evidence.)
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
 	**/
 	**/
-	@:pure static function create<T>(proto:{}, ?propertiesObject:DynamicAccess<ObjectPropertyDescriptor>):T;
+	@:pure static function create<T>(proto:Null<{}>, ?propertiesObject:DynamicAccess<ObjectPropertyDescriptor<Any>>):T;
 
 
 	/**
 	/**
-		Adds the named properties described by the given descriptors to an object.
+		The Object.defineProperties() method defines new or modifies existing
+		properties directly on an object, returning the object.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties
 	**/
 	**/
-	static function defineProperties<T:{}>(obj:T, props:DynamicAccess<ObjectPropertyDescriptor>):T;
+	static function defineProperties<T:{}>(obj:T, props:DynamicAccess<ObjectPropertyDescriptor<Any>>):T;
 
 
 	/**
 	/**
-		Adds the named property described by a given descriptor to an object.
+		The static method Object.defineProperty() defines a new property directly
+		on an object, or modifies an existing property on an object, and returns
+		the object.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
 	**/
 	**/
-	@:overload(function<T:{}>(obj:T, prop:Symbol, descriptor:ObjectPropertyDescriptor):T {})
-	static function defineProperty<T:{}>(obj:T, prop:String, descriptor:ObjectPropertyDescriptor):T;
+	@:overload(function<T:{}, TProp>(obj:T, prop:Symbol, descriptor:ObjectPropertyDescriptor<TProp>):T {})
+	static function defineProperty<T:{}, TProp>(obj:T, prop:String, descriptor:ObjectPropertyDescriptor<TProp>):T;
 
 
 	/**
 	/**
-		Returns an array containing all of the [key, value] pairs of a given
-		object's own enumerable string properties.
+		The Object.entries() method returns an array of a given object's own
+		enumerable property [key, value] pairs, in the same order as that
+		provided by a for...in loop (the difference being that a for-in loop
+		enumerates properties in the prototype chain as well).
+
+		Note: this is an ES2017 feature
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
 	**/
 	**/
-	@:pure static function entries(obj:{}):Array<ObjectEntry>;
+	@:pure static function entries<T:{}>(obj:T):Array<ObjectEntry>;
 
 
 	/**
 	/**
-		Freezes an object: other code can't delete or change any properties.
+		The Object.freeze() method freezes an object: that is, prevents new
+		properties from being added to it; prevents existing properties from
+		being removed; and prevents existing properties, or their enumerability,
+		configurability, or writability, from being changed, it also prevents the
+		prototype from being changed.
+		The method returns the passed object.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
 	**/
 	**/
 	static function freeze<T:{}>(obj:T):T;
 	static function freeze<T:{}>(obj:T):T;
 
 
@@ -72,76 +101,149 @@ extern class Object {
 	@:pure static function fromEntries<T:{}>(iterable:Any):T;
 	@:pure static function fromEntries<T:{}>(iterable:Any):T;
 
 
 	/**
 	/**
-		Returns a property descriptor for a named property on an object.
+		The Object.getOwnPropertyDescriptor() method returns a property
+		descriptor for an own property (that is, one directly present on an
+		object and not in the object's prototype chain) of a given object.
+
+		In ES5, if the first argument to this method is not an object (a
+		primitive), then it will cause a TypeError. In ES2015, a non-object
+		first argument will be coerced to an object at first.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor
 	**/
 	**/
-	@:overload(function<T>(target:Array<T>, propertyKey:Int):Null<ObjectPropertyDescriptor> {})
-	@:overload(function(obj:{}, prop:Symbol):Null<ObjectPropertyDescriptor> {})
-	@:pure static function getOwnPropertyDescriptor(obj:{}, prop:String):Null<ObjectPropertyDescriptor>;
+	@:overload(function(obj:String, prop:Symbol):Null<ObjectPropertyDescriptor<String>> {})
+	@:overload(function(obj:String, prop:String):Null<ObjectPropertyDescriptor<String>> {})
+	@:overload(function<T>(target:Array<T>, propertyKey:Int):Null<ObjectPropertyDescriptor<T>> {})
+	@:overload(function<T, TProp>(obj:T, prop:Symbol):Null<ObjectPropertyDescriptor<TProp>> {})
+	@:pure static function getOwnPropertyDescriptor<T, TProp>(obj:T, prop:String):Null<ObjectPropertyDescriptor<TProp>>;
 
 
 	/**
 	/**
-		Returns an array containing the names of all of the given object's own
-		enumerable and non-enumerable properties.
+		The Object.getOwnPropertyDescriptors() method returns all own property
+		descriptors of a given object.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors
 	**/
 	**/
-	@:pure static function getOwnPropertyNames(obj:{}):Array<String>;
+	@:overload(function(target:String):DynamicAccess<ObjectPropertyDescriptor<String>> {})
+	@:overload(function<T>(target:Array<T>):DynamicAccess<ObjectPropertyDescriptor<T>> {})
+	@:pure static function getOwnPropertyDescriptors<T>(obj:T):DynamicAccess<ObjectPropertyDescriptor<Any>>;
 
 
 	/**
 	/**
-		Returns an array of all symbol properties found directly upon a given object.
+		The Object.getOwnPropertyNames() method returns an array of all
+		properties (including non-enumerable properties except for those which
+		use Symbol) found directly upon a given object.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames
 	**/
 	**/
-	@:pure static function getOwnPropertySymbols(obj:{}):Array<Symbol>;
+	@:pure static function getOwnPropertyNames<T:{}>(obj:T):Array<String>;
 
 
 	/**
 	/**
-		Returns the prototype of the specified object.
+		The Object.getOwnPropertySymbols() method returns an array of all symbol
+		properties found directly upon a given object.
+
+		Note: this is an ES2015 feature
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols
 	**/
 	**/
-	@:pure static function getPrototypeOf<TProto:{}>(obj:{}):Null<TProto>;
+	@:pure static function getOwnPropertySymbols<T:{}>(obj:T):Array<Symbol>;
 
 
 	/**
 	/**
-		Compares if two values are the same value. Equates all NaN values
-		(which differs from both Abstract Equality Comparison and
-		Strict Equality Comparison).
+		The Object.getPrototypeOf() method returns the prototype (i.e. the value
+		of the internal [[Prototype]] property) of the specified object.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf
 	**/
 	**/
-	@:pure static function is<T>(value1:T, value2:T):Bool;
+	@:pure static function getPrototypeOf<T:{}, TProto>(obj:T):TProto;
 
 
 	/**
 	/**
-		Determines if extending of an object is allowed.
+		The Object.is() method determines whether two values are the same value.
+
+		Note: this is an ES2015 feature
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
 	**/
 	**/
-	@:pure static function isExtensible(obj:{}):Bool;
+	@:native("is") @:pure static function isSame<T:{}>(obj1:T, obj2:T):Bool;
 
 
 	/**
 	/**
-		Determines if an object was frozen.
+		The Object.is() method determines whether two values are the same value.
+
+		Note: this is an ES2015 feature
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
 	**/
 	**/
-	@:pure static function isFrozen(obj:{}):Bool;
+	@:deprecated("Use Object.isSame()")
+	@:pure static function is<T:{}>(obj1:T, obj2:T):Bool;
 
 
 	/**
 	/**
-		Determines if an object is sealed.
+		The Object.isExtensible() method determines if an object is extensible
+		(whether it can have new properties added to it).
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
 	**/
 	**/
-	@:pure static function isSealed(obj:{}):Bool;
+	@:pure static function isExtensible<T:{}>(obj:T):Bool;
 
 
 	/**
 	/**
-		Returns an array containing the names of all of the given object's own
-		enumerable string properties.
+		The Object.isFrozen() determines if an object is frozen.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
+	**/
+	@:pure static function isFrozen<T:{}>(obj:T):Bool;
+
+	/**
+		The Object.isSealed() method determines if an object is sealed.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
 	**/
 	**/
-	@:pure static function keys(obj:{}):Array<String>;
+	@:pure static function isSealed<T:{}>(obj:T):Bool;
 
 
 	/**
 	/**
-		Prevents any extensions of an object.
+		The Object.keys() method returns an array of a given object's own
+		enumerable properties, in the same order as that provided by a for...in
+		loop (the difference being that a for-in loop enumerates properties in
+		the prototype chain as well).
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
+	**/
+	@:pure static function keys<T:{}>(obj:T):Array<String>;
+
+	/**
+		The Object.preventExtensions() method prevents new properties from ever
+		being added to an object (i.e. prevents future extensions to the object).
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions
 	**/
 	**/
 	static function preventExtensions<T:{}>(obj:T):T;
 	static function preventExtensions<T:{}>(obj:T):T;
 
 
 	/**
 	/**
-		Prevents other code from deleting properties of an object.
+		The Object.seal() method seals an object, preventing new properties from
+		being added to it and marking all existing properties as
+		non-configurable. Values of present properties can still be changed as
+		long as they are writable.
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal
 	**/
 	**/
 	static function seal<T:{}>(obj:T):T;
 	static function seal<T:{}>(obj:T):T;
 
 
 	/**
 	/**
-		Sets the prototype (i.e., the internal Prototype property).
+		The Object.setPrototypeOf() method sets the prototype (i.e., the internal
+		[[Prototype]] property) of a specified object to another object or null.
+
+		Note: this is an ES2015 feature
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf
 	**/
 	**/
-	static function setPrototypeOf<T:{}>(obj:T, prototype:Null<{}>):T;
+	static function setPrototypeOf<T:{}, TProto:{}>(obj:T, proto:Null<TProto>):T;
 
 
 	/**
 	/**
-		Returns an array containing the values that correspond to all of
-		a given object's own enumerable string properties.
+		The Object.values() method returns an array of a given object's own
+		enumerable property values, in the same order as that provided by a
+		for...in loop (the difference being that a for-in loop enumerates
+		properties in the prototype chain as well).
+
+		Note: this is an ES2017 feature
+
+		See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
 	**/
 	**/
-	@:pure static function values(obj:{}):Array<Any>;
+	@:pure static function values<T:{}>(obj:T):Array<Any>;
 
 
 	/**
 	/**
 		Allows the addition of properties to all objects of type Object.
 		Allows the addition of properties to all objects of type Object.
@@ -196,11 +298,10 @@ typedef ObjectPrototype = {
 /**
 /**
 	@see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty>
 	@see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty>
 **/
 **/
-typedef ObjectPropertyDescriptor = {
+typedef ObjectPropertyDescriptor<TProp> = {
 	/**
 	/**
 		`true` if and only if the type of this property descriptor may be
 		`true` if and only if the type of this property descriptor may be
 		changed and if the property may be deleted from the corresponding object.
 		changed and if the property may be deleted from the corresponding object.
-
 		Defaults to `false`.
 		Defaults to `false`.
 	**/
 	**/
 	var ?configurable:Bool;
 	var ?configurable:Bool;
@@ -208,7 +309,6 @@ typedef ObjectPropertyDescriptor = {
 	/**
 	/**
 		`true` if and only if this property shows up during enumeration of the
 		`true` if and only if this property shows up during enumeration of the
 		properties on the corresponding object.
 		properties on the corresponding object.
-
 		Defaults to `false`.
 		Defaults to `false`.
 	**/
 	**/
 	var ?enumerable:Bool;
 	var ?enumerable:Bool;
@@ -217,12 +317,11 @@ typedef ObjectPropertyDescriptor = {
 		The value associated with the property.
 		The value associated with the property.
 		Can be any valid JavaScript value (number, object, function, etc).
 		Can be any valid JavaScript value (number, object, function, etc).
 	**/
 	**/
-	var ?value:Any;
+	var ?value:TProp;
 
 
 	/**
 	/**
 		`true` if and only if the value associated with the property may be
 		`true` if and only if the value associated with the property may be
 		changed with an assignment operator.
 		changed with an assignment operator.
-
 		Defaults to `false`.
 		Defaults to `false`.
 	**/
 	**/
 	var ?writable:Bool;
 	var ?writable:Bool;
@@ -235,7 +334,7 @@ typedef ObjectPropertyDescriptor = {
 		property is defined due to inheritance).
 		property is defined due to inheritance).
 		The return value will be used as the value of the property.
 		The return value will be used as the value of the property.
 	**/
 	**/
-	var ?get:Void->Any;
+	var ?get:Void->TProp;
 
 
 	/**
 	/**
 		A function which serves as a setter for the property, or undefined if
 		A function which serves as a setter for the property, or undefined if
@@ -243,7 +342,7 @@ typedef ObjectPropertyDescriptor = {
 		is called with one argument (the value being assigned to the property)
 		is called with one argument (the value being assigned to the property)
 		and with `this` set to the object through which the property is assigned.
 		and with `this` set to the object through which the property is assigned.
 	**/
 	**/
-	var ?set:Any->Void;
+	var ?set:TProp->Void;
 }
 }
 
 
 /**
 /**
@@ -252,7 +351,6 @@ typedef ObjectPropertyDescriptor = {
 abstract ObjectEntry(Array<Any>) {
 abstract ObjectEntry(Array<Any>) {
 	public var key(get, never):String;
 	public var key(get, never):String;
 	public var value(get, never):Any;
 	public var value(get, never):Any;
-
 	inline function get_key():String
 	inline function get_key():String
 		return this[0];
 		return this[0];
 
 

+ 2 - 2
std/js/lib/Proxy.hx

@@ -65,12 +65,12 @@ typedef ProxyHandler<T:{}> = {
 	/**
 	/**
 		A trap for `Object.getOwnPropertyDescriptor`.
 		A trap for `Object.getOwnPropertyDescriptor`.
 	**/
 	**/
-	var ?getOwnPropertyDescriptor:(target:T, prop:EitherType<String, Symbol>) -> Null<ObjectPropertyDescriptor>;
+	var ?getOwnPropertyDescriptor:(target:T, prop:EitherType<String, Symbol>) -> Null<ObjectPropertyDescriptor<Any>>;
 
 
 	/**
 	/**
 		A trap for `Object.defineProperty`.
 		A trap for `Object.defineProperty`.
 	**/
 	**/
-	var ?defineProperty:(target:T, property:EitherType<String, Symbol>, descriptor:ObjectPropertyDescriptor) -> Bool;
+	var ?defineProperty:(target:T, property:EitherType<String, Symbol>, descriptor:ObjectPropertyDescriptor<Any>) -> Bool;
 
 
 	/**
 	/**
 		A trap for the `in` operator.
 		A trap for the `in` operator.

部分文件因为文件数量过多而无法显示