Bläddra i källkod

Merge branch 'development' into out_of_curiosity

# Conflicts:
#	src-json/meta.json
#	src/codegen/dotnet.ml
#	src/codegen/java.ml
#	src/typing/strictMeta.ml
#	src/typing/typeloadCheck.ml
#	tests/runci/targets/Java.hx
#	tests/runci/targets/Jvm.hx
Simon Krajewski 1 år sedan
förälder
incheckning
0fbae13533
100 ändrade filer med 1337 tillägg och 4361 borttagningar
  1. 1 2
      .vscode/schemas/meta.schema.json
  2. 1 0
      haxe.opam
  3. 2 2
      src-json/meta.json
  4. 12 0
      src-prebuild/prebuild.ml
  5. 66 30
      src/codegen/javaModern.ml
  6. 18 14
      src/codegen/swfLoader.ml
  7. 8 3
      src/compiler/args.ml
  8. 24 20
      src/compiler/compiler.ml
  9. 15 5
      src/compiler/displayOutput.ml
  10. 8 6
      src/compiler/displayProcessing.ml
  11. 6 6
      src/compiler/retyper.ml
  12. 13 10
      src/compiler/server.ml
  13. 2 2
      src/context/abstractCast.ml
  14. 9 5
      src/context/common.ml
  15. 37 36
      src/context/display/diagnostics.ml
  16. 10 6
      src/context/display/diagnosticsPrinter.ml
  17. 3 3
      src/context/display/display.ml
  18. 4 11
      src/context/display/displayEmitter.ml
  19. 115 9
      src/context/display/displayJson.ml
  20. 2 2
      src/context/display/displayTexpr.ml
  21. 5 5
      src/context/display/syntaxExplorer.ml
  22. 10 1
      src/context/typecore.ml
  23. 31 10
      src/core/ast.ml
  24. 50 15
      src/core/define.ml
  25. 13 34
      src/core/display/completionItem.ml
  26. 16 3
      src/core/display/displayPosition.ml
  27. 9 3
      src/core/displayTypes.ml
  28. 2 2
      src/core/globals.ml
  29. 2 2
      src/core/inheritDoc.ml
  30. 2 2
      src/core/json/genjson.ml
  31. 52 22
      src/core/meta.ml
  32. 6 6
      src/core/tOther.ml
  33. 2 2
      src/core/tPrinting.ml
  34. 3 2
      src/core/tType.ml
  35. 1 1
      src/dune
  36. 6 4
      src/filters/exceptions.ml
  37. 2 1
      src/filters/filters.ml
  38. 75 52
      src/generators/genjvm.ml
  39. 1 1
      src/generators/genpy.ml
  40. 2 2
      src/generators/hl2c.ml
  41. 9 0
      src/generators/jvm/jvmAttribute.ml
  42. 15 8
      src/generators/jvm/jvmBuilder.ml
  43. 27 16
      src/generators/jvm/jvmMethod.ml
  44. 2 1
      src/macro/eval/evalDebugMisc.ml
  45. 2 13
      src/macro/eval/evalMain.ml
  46. 39 16
      src/macro/macroApi.ml
  47. 4 4
      src/optimization/analyzer.ml
  48. 2 1
      src/optimization/analyzerTexpr.ml
  49. 31 16
      src/optimization/analyzerTexprTransformer.ml
  50. 0 1
      src/optimization/inline.ml
  51. 6 1
      src/optimization/inlineConstructors.ml
  52. 0 2
      src/optimization/optimizer.ml
  53. 43 39
      src/syntax/grammar.mly
  54. 4 0
      src/syntax/parser.ml
  55. 17 14
      src/syntax/reification.ml
  56. 18 10
      src/typing/callUnification.ml
  57. 26 25
      src/typing/forLoop.ml
  58. 2 1
      src/typing/functionArguments.ml
  59. 2 2
      src/typing/generic.ml
  60. 4 4
      src/typing/instanceBuilder.ml
  61. 31 25
      src/typing/macroContext.ml
  62. 2 2
      src/typing/matcher/exprToPattern.ml
  63. 2 2
      src/typing/matcher/texprConverter.ml
  64. 26 20
      src/typing/operators.ml
  65. 72 26
      src/typing/strictMeta.ml
  66. 28 54
      src/typing/typeload.ml
  67. 105 69
      src/typing/typeloadCheck.ml
  68. 26 39
      src/typing/typeloadFields.ml
  69. 2 1
      src/typing/typeloadFunction.ml
  70. 5 7
      src/typing/typeloadModule.ml
  71. 17 17
      src/typing/typeloadParse.ml
  72. 39 35
      src/typing/typer.ml
  73. 5 3
      src/typing/typerBase.ml
  74. 23 5
      src/typing/typerDisplay.ml
  75. 0 228
      std/cpp/_std/sys/db/Mysql.hx
  76. 0 203
      std/cpp/_std/sys/db/Sqlite.hx
  77. 0 6
      std/cpp/cppia/HostClasses.hx
  78. 9 1
      std/haxe/display/Diagnostic.hx
  79. 43 0
      std/haxe/display/Display.hx
  80. 0 36
      std/hl/_std/sys/db/Connection.hx
  81. 0 250
      std/hl/_std/sys/db/Mysql.hx
  82. 0 36
      std/hl/_std/sys/db/ResultSet.hx
  83. 0 283
      std/hl/_std/sys/db/Sqlite.hx
  84. 0 56
      std/java/_std/sys/db/Mysql.hx
  85. 0 42
      std/java/_std/sys/db/Sqlite.hx
  86. 0 318
      std/java/db/Jdbc.hx
  87. 1 1
      std/jvm/annotation/ClassReflectionInformation.hx
  88. 1 1
      std/jvm/annotation/EnumReflectionInformation.hx
  89. 1 1
      std/jvm/annotation/EnumValueReflectionInformation.hx
  90. 0 409
      std/neko/Web.hx
  91. 0 213
      std/neko/_std/sys/db/Mysql.hx
  92. 0 199
      std/neko/_std/sys/db/Sqlite.hx
  93. 0 482
      std/php/Web.hx
  94. 0 268
      std/php/_std/sys/db/Mysql.hx
  95. 0 218
      std/php/_std/sys/db/Sqlite.hx
  96. 0 100
      std/php/db/Mysqli.hx
  97. 0 38
      std/php/db/Mysqli_driver.hx
  98. 0 62
      std/php/db/Mysqli_result.hx
  99. 0 57
      std/php/db/Mysqli_stmt.hx
  100. 0 32
      std/php/db/Mysqli_warning.hx

+ 1 - 2
.vscode/schemas/meta.schema.json

@@ -29,8 +29,7 @@
 						"flash",
 						"php",
 						"cpp",
-						"cs",
-						"java",
+						"jvm",
 						"python",
 						"hl",
 						"eval"

+ 1 - 0
haxe.opam

@@ -33,4 +33,5 @@ depends: [
   "conf-neko"
   "luv" {>= "0.5.12"}
   "ipaddr"
+  "terminal_size"
 ]

+ 2 - 2
src-json/meta.json

@@ -35,7 +35,8 @@
 	{
 		"name": "Annotation",
 		"metadata": ":annotation",
-		"doc": "Annotation (`@interface`) definitions on `--java-lib` imports will be annotated with this metadata. Has no effect on types compiled by Haxe.",
+		"doc": "Marks a class as a Java annotation",
+		"params": ["Retention policy"],
 		"platforms": ["jvm"],
 		"targets": ["TClass"]
 	},
@@ -520,7 +521,6 @@
 		"metadata": ":java.default",
 		"doc": "Equivalent to the default modifier of the Java language",
 		"platforms": ["jvm"],
-		"params": [],
 		"targets": ["TClassField"]
 	},
 	{

+ 12 - 0
src-prebuild/prebuild.ml

@@ -297,6 +297,18 @@ let parse_meta_usage = function
 	| \"TVariable\" -> TVariable
 	| t -> raise (failwith (\"invalid metadata target \" ^ t))
 
+let print_meta_usage = function
+	| TClass -> \"TClass\"
+	| TClassField -> \"TClassField\"
+	| TAbstract -> \"TAbstract\"
+	| TAbstractField -> \"TAbstractField\"
+	| TEnum -> \"TEnum\"
+	| TTypedef -> \"TTypedef\"
+	| TAnyField -> \"TAnyField\"
+	| TExpr -> \"TExpr\"
+	| TTypeParameter -> \"TTypeParameter\"
+	| TVariable -> \"TVariable\"
+
 type meta_parameter =
 	| HasParam of string
 	| Platforms of platform list

+ 66 - 30
src/codegen/javaModern.ml

@@ -18,6 +18,7 @@ module AccessFlags = struct
 		| MAbstract
 		| MStrict
 		| MSynthetic
+		| MAnnotation
 		| MEnum
 
 	let to_int = function
@@ -34,6 +35,7 @@ module AccessFlags = struct
 		| MAbstract -> 0x400
 		| MStrict -> 0x800
 		| MSynthetic -> 0x1000
+		| MAnnotation -> 0x2000
 		| MEnum -> 0x4000
 
 	let has_flag b flag =
@@ -615,46 +617,48 @@ type java_lib_ctx = {
 module SignatureConverter = struct
 	open PathConverter
 
-	let mk_type_path path params =
+	let mk_type_path path params p =
 		let pack,(mname,name) = jpath_to_hx path in
-		match mname with
+		let path = match mname with
 		| None ->
-			CTPath {
+			{
 				tpackage = pack;
 				tname = name;
 				tparams = params;
 				tsub = None;
 			}
 		| Some mname ->
-			CTPath {
+			{
 				tpackage = pack;
 				tname = mname;
 				tparams = params;
 				tsub = Some name;
 			}
+		in
+		make_ptp_ct path p
 
-	let ct_type_param name = CTPath {
+	let ct_type_param name = make_ptp_ct_null {
 		tpackage = [];
 		tname = name;
 		tparams = [];
 		tsub = None
 	}
 
-	let ct_void = CTPath {
+	let ct_void = make_ptp_ct_null {
 		tpackage = [];
 		tname = "Void";
 		tparams = [];
 		tsub = None;
 	}
 
-	let ct_dynamic = CTPath {
+	let ct_dynamic = make_ptp_ct_null {
 		tpackage = [];
 		tname = "Dynamic";
 		tparams = [];
 		tsub = None;
 	}
 
-	let ct_string = CTPath {
+	let ct_string = make_ptp_ct_null {
 		tpackage = [];
 		tname = "String";
 		tparams = [];
@@ -663,33 +667,33 @@ module SignatureConverter = struct
 
 	let rec convert_arg ctx p arg =
 		match arg with
-		| TAny | TType (WSuper, _) -> TPType (mk_type_path ([], "Dynamic") [],p)
+		| TAny | TType (WSuper, _) -> TPType (mk_type_path ([], "Dynamic") [] p,p)
 		| TType (_, jsig) -> TPType (convert_signature ctx p jsig,p)
 
 	and convert_signature ctx p jsig =
 		match jsig with
-		| TByte -> mk_type_path (["java"; "types"], "Int8") []
-		| TChar -> mk_type_path (["java"; "types"], "Char16") []
-		| TDouble -> mk_type_path ([], "Float") []
-		| TFloat -> mk_type_path ([], "Single") []
-		| TInt -> mk_type_path ([], "Int") []
-		| TLong -> mk_type_path (["haxe"], "Int64") []
-		| TShort -> mk_type_path (["java"; "types"], "Int16") []
-		| TBool -> mk_type_path ([], "Bool") []
-		| TObject ( (["haxe";"root"], name), args ) -> mk_type_path ([], name) (List.map (convert_arg ctx p) args)
-		| TObject ( (["java";"lang"], "Object"), [] ) -> mk_type_path ([], "Dynamic") []
-		| TObject ( (["java";"lang"], "String"), [] ) -> mk_type_path ([], "String") []
-		| TObject ( (["java";"lang"], "Enum"), [_] ) -> mk_type_path ([], "EnumValue") []
+		| TByte -> mk_type_path (["java"; "types"], "Int8") [] p
+		| TChar -> mk_type_path (["java"; "types"], "Char16") [] p
+		| TDouble -> mk_type_path ([], "Float") [] p
+		| TFloat -> mk_type_path ([], "Single") [] p
+		| TInt -> mk_type_path ([], "Int") [] p
+		| TLong -> mk_type_path (["haxe"], "Int64") [] p
+		| TShort -> mk_type_path (["java"; "types"], "Int16") [] p
+		| TBool -> mk_type_path ([], "Bool") [] p
+		| TObject ( (["haxe";"root"], name), args ) -> mk_type_path ([], name) (List.map (convert_arg ctx p) args) p
+		| TObject ( (["java";"lang"], "Object"), [] ) -> mk_type_path ([], "Dynamic") [] p
+		| TObject ( (["java";"lang"], "String"), [] ) -> mk_type_path ([], "String") [] p
+		| TObject ( (["java";"lang"], "Enum"), [_] ) -> mk_type_path ([], "EnumValue") [] p
 		| TObject ( path, [] ) ->
-			mk_type_path path []
-		| TObject ( path, args ) -> mk_type_path path (List.map (convert_arg ctx p) args)
+			mk_type_path path [] p
+		| TObject ( path, args ) -> mk_type_path path (List.map (convert_arg ctx p) args) p
 		| TObjectInner (pack, (name, params) :: inners) ->
 			let actual_param = match List.rev inners with
 			| (_, p) :: _ -> p
 			| _ -> die "" __LOC__ in
-			mk_type_path (pack, name ^ "$" ^ String.concat "$" (List.map fst inners)) (List.map (fun param -> convert_arg ctx p param) actual_param)
+			mk_type_path (pack, name ^ "$" ^ String.concat "$" (List.map fst inners)) (List.map (fun param -> convert_arg ctx p param) actual_param) p
 		| TObjectInner (pack, inners) -> die "" __LOC__
-		| TArray (jsig, _) -> mk_type_path (["java"], "NativeArray") [ TPType (convert_signature ctx p jsig,p) ]
+		| TArray (jsig, _) -> mk_type_path (["java"], "NativeArray") [ TPType (convert_signature ctx p jsig,p) ] p
 		| TMethod _ -> failwith "TMethod cannot be converted directly into Complex Type"
 		| TTypeParameter s ->
 			try
@@ -698,7 +702,7 @@ module SignatureConverter = struct
 				ct_dynamic
 end
 
-let get_type_path ct = match ct with | CTPath p -> p | _ -> die "" __LOC__
+let get_type_path ct = match ct with | CTPath ptp -> ptp | _ -> die "" __LOC__
 
 module Converter = struct
 
@@ -706,6 +710,27 @@ module Converter = struct
 	open PathConverter
 	open SignatureConverter
 
+	let extract_retention_policy l =
+		let rec loop2 l = match l with
+			| [] ->
+				None
+			| ann :: l ->
+				match ann.ann_type,ann.ann_elements with
+				| TObject((["java";"lang";"annotation"],"Retention"),_),[("value",ValEnum(_,name))] ->
+					Some name
+				| _ ->
+					loop2 l
+		in
+		let rec loop l = match l with
+			| [] ->
+				None
+			| AttrVisibleAnnotations l :: _ ->
+				loop2 l
+			| _ :: l ->
+				loop l
+		in
+		loop l
+
 	let convert_type_parameter ctx (name,extends,implements) p =
 		let jsigs = match extends with
 			| Some jsig -> jsig :: implements
@@ -867,7 +892,7 @@ module Converter = struct
 						let hx_sig =
 							match jsig with
 							| TArray (jsig1,_) when is_varargs && i + 1 = args_count && is_eligible_for_haxe_rest_args jsig1 ->
-								mk_type_path (["haxe"], "Rest") [TPType (convert_signature ctx p jsig1,p)]
+								mk_type_path (["haxe"], "Rest") [TPType (convert_signature ctx p jsig1,p)] p
 							| _ ->
 								convert_signature ctx p jsig
 						in
@@ -908,15 +933,17 @@ module Converter = struct
 		let is_interface = AccessFlags.has_flag jc.jc_flags MInterface in
 		if is_interface then add_flag HInterface
 		else if AccessFlags.has_flag jc.jc_flags MAbstract then add_flag HAbstract;
+		let is_annotation = AccessFlags.has_flag jc.jc_flags MAnnotation in
 		begin match jc.jc_super with
 			| TObject(([],""),_)
 			| TObject((["java";"lang"],"Object"),_) ->
-				()
+				if is_annotation then
+					add_flag (HExtends (make_ptp {tpackage = ["java";"lang";"annotation"]; tname = "Annotation"; tsub = None; tparams = []} p))
 			| jsig ->
-				add_flag (HExtends (get_type_path (convert_signature ctx p jsig),p))
+				add_flag (HExtends (get_type_path (convert_signature ctx p jsig)))
 		end;
 		List.iter (fun jsig ->
-			let path = (get_type_path (convert_signature ctx p jsig),p) in
+			let path = get_type_path (convert_signature ctx p jsig) in
 			if is_interface then
 				add_flag (HExtends path)
 			else
@@ -957,6 +984,15 @@ module Converter = struct
 		end;
 		let _,class_name = jname_to_hx (snd jc.jc_path) in
 		add_meta (Meta.Native, [EConst (String (s_type_path jc.jc_path,SDoubleQuotes) ),p],p);
+		if is_annotation then begin
+			let args = match extract_retention_policy jc.jc_attributes with
+				| None ->
+					[]
+				| Some v ->
+					[EConst (String(v,SDoubleQuotes)),p]
+			in
+			add_meta (Meta.Annotation,args,p)
+		end;
 		let d = {
 			d_name = (class_name,p);
 			d_doc = None;

+ 18 - 14
src/codegen/swfLoader.ml

@@ -42,18 +42,19 @@ let lowercase_pack pack =
 	loop [] pack
 
 
-let tp_dyn = { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None; }
+let tp_dyn = make_ptp { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None; } null_pos
 
 let ct_dyn = CTPath tp_dyn
 
-let ct_rest = CTPath {
+let ct_rest = make_ptp_ct_null {
 	tpackage = ["haxe"];
 	tname = "Rest";
 	tparams = [TPType (ct_dyn,null_pos)];
 	tsub = None;
 }
 
-let rec make_tpath = function
+let rec make_tpath x =
+	let path = match x with
 	| HMPath (pack,name) ->
 		let pdyn = ref false in
 		let pack, name = match pack, name with
@@ -116,7 +117,10 @@ let rec make_tpath = function
 		die "" __LOC__
 	| HMParams (t,params) ->
 		let params = List.map (fun t -> TPType (CTPath (make_tpath t),null_pos)) params in
-		{ (make_tpath t) with tparams = params }
+		let ptp = make_tpath t in
+		{ptp.path with tparams = params}
+	in
+	make_ptp path null_pos
 
 let make_topt = function
 	| None -> tp_dyn
@@ -126,7 +130,7 @@ let make_type t = CTPath (make_topt t)
 
 let make_dyn_type t =
 	match make_topt t with
-	| { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") } -> make_type None
+	| {path = { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") }} -> make_type None
 	| o -> CTPath o
 
 let is_valid_path com pack name =
@@ -142,7 +146,7 @@ let is_valid_path com pack name =
 	loop com.load_extern_type || (try ignore(Common.find_file com file); true with Not_found -> false)
 
 let build_class com c file =
-	let path = make_tpath c.hlc_name in
+	let path = (make_tpath c.hlc_name).path in
 	let pos = { pfile = file ^ "@" ^ s_type_path (path.tpackage,path.tname); pmin = 0; pmax = 0 } in
 	match path with
 	| { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") } ->
@@ -162,7 +166,7 @@ let build_class com c file =
 	let flags = (match c.hlc_super with
 		| None | Some (HMPath ([],"Object")) -> flags
 		| Some (HMPath ([],"Function")) -> flags (* found in AIR SDK *)
-		| Some s -> HExtends (make_tpath s,null_pos) :: flags
+		| Some s -> HExtends (make_tpath s) :: flags
 	) in
 	let flags = List.map (fun i ->
 		let i = (match i with
@@ -176,9 +180,9 @@ let build_class com c file =
 			| HMPath _ -> i
 			| _ -> die "" __LOC__
 		) in
-		if c.hlc_interface then HExtends (make_tpath i,null_pos) else HImplements (make_tpath i,null_pos)
+		if c.hlc_interface then HExtends (make_tpath i) else HImplements (make_tpath i)
 	) (Array.to_list c.hlc_implements) @ flags in
-	let flags = if c.hlc_sealed || Common.defined com Define.FlashStrict then flags else HImplements (tp_dyn,null_pos) :: flags in
+	let flags = if c.hlc_sealed || Common.defined com Define.FlashStrict then flags else HImplements tp_dyn :: flags in
 	(* make fields *)
 	let getters = Hashtbl.create 0 in
 	let setters = Hashtbl.create 0 in
@@ -209,7 +213,7 @@ let build_class com c file =
 		) in
 		if flags = [] then acc else
 		let flags = if stat then (AStatic,null_pos) :: flags else flags in
-		let name = (make_tpath f.hlf_name).tname in
+		let name = (make_tpath f.hlf_name).path.tname in
 		let mk_meta() =
 			List.map (fun (s,cl) -> s, List.map (fun c -> EConst c,pos) cl, pos) (!meta)
 		in
@@ -395,8 +399,8 @@ let build_class com c file =
 			| [] -> []
 			| f :: l ->
 				match f.cff_kind with
-				| FVar (Some ((CTPath { tpackage = []; tname = ("String" | "Int" | "UInt")} as real_t),_),None)
-				| FProp (("default",_),("never",_),Some ((CTPath { tpackage = []; tname = ("String" | "Int" | "UInt")}) as real_t,_),None) when List.mem_assoc AStatic f.cff_access ->
+				| FVar (Some ((CTPath {path = { tpackage = []; tname = ("String" | "Int" | "UInt")}} as real_t),_),None)
+				| FProp (("default",_),("never",_),Some ((CTPath { path = { tpackage = []; tname = ("String" | "Int" | "UInt")}}) as real_t,_),None) when List.mem_assoc AStatic f.cff_access ->
 					(match !real_type with
 					| None ->
 						real_type := Some real_t
@@ -457,7 +461,7 @@ let extract_data (_,tags) =
 	let loop_field f =
 		match f.hlf_kind with
 		| HFClass c ->
-			let path = make_tpath f.hlf_name in
+			let path = (make_tpath f.hlf_name).path in
 			(match path with
 			| { tpackage = []; tname = "Float" | "Bool" | "Int" | "UInt" | "Dynamic" } -> ()
 			| { tpackage = _; tname = "MethodClosure" } -> ()
@@ -650,7 +654,7 @@ let remove_classes toremove lib l =
 						let loop f =
 							match f.hlf_kind with
 							| HFClass _ ->
-								let path = make_tpath f.hlf_name in
+								let path = (make_tpath f.hlf_name).path in
 								not (List.mem (path.tpackage,path.tname) classes)
 							| _ -> true
 						in

+ 8 - 3
src/compiler/args.ml

@@ -2,8 +2,10 @@ open Globals
 open Common
 open CompilationContext
 
+let columns = lazy (match Terminal_size.get_columns () with None -> 80 | Some c -> c)
+
 let limit_string s offset =
-	let rest = 80 - offset in
+	let rest = (Lazy.force columns) - offset in
 	let words = ExtString.String.nsplit s " " in
 	let rec loop i words = match words with
 		| word :: words ->
@@ -132,6 +134,9 @@ let parse_args com =
 				| Some value -> Common.external_define_value com flag value
 				| None -> Common.external_define com flag;
 		),"<var[=value]>","define a conditional compilation flag");
+		("Compilation",["--undefine"],[],Arg.String (fun var ->
+			Common.external_undefine com var
+		),"","remove a conditional compilation flag");
 		("Debug",["-v";"--verbose"],[],Arg.Unit (fun () ->
 			com.verbose <- true
 		),"","turn on verbose mode");
@@ -158,7 +163,7 @@ let parse_args com =
 				let all,max_length = Define.get_user_documentation_list com.user_defines in
 				let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" max_length n (limit_string doc (max_length + 3))) all in
 				List.iter (fun msg -> com.print (msg ^ "\n")) all;
-				exit 0
+				raise Abort
 			)
 		),"","print help for all user defines");
 		("Miscellaneous",["--help-metas"],[], Arg.Unit (fun() ->
@@ -173,7 +178,7 @@ let parse_args com =
 				let all,max_length = Meta.get_user_documentation_list com.user_metas in
 				let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" max_length n (limit_string doc (max_length + 3))) all in
 				List.iter (fun msg -> com.print (msg ^ "\n")) all;
-				exit 0
+				raise Abort
 			)
 		),"","print help for all user metadatas");
 	] in

+ 24 - 20
src/compiler/compiler.ml

@@ -2,29 +2,35 @@ open Globals
 open Common
 open CompilationContext
 
-let run_or_diagnose ctx f arg =
+let run_or_diagnose ctx f =
 	let com = ctx.com in
-	let handle_diagnostics ?(depth = 0) msg p kind =
+	let handle_diagnostics msg p kind =
 		ctx.has_error <- true;
-		add_diagnostics_message ~depth com msg p kind Error;
-		DisplayOutput.emit_diagnostics ctx.com
+		add_diagnostics_message com msg p kind Error;
+		match com.report_mode with
+		| RMLegacyDiagnostics _ -> DisplayOutput.emit_legacy_diagnostics ctx.com
+		| RMDiagnostics _ -> DisplayOutput.emit_diagnostics ctx.com
+		| _ -> die "" __LOC__
 	in
 	if is_diagnostics com then begin try
-			f arg
+			f ()
 		with
 		| Error.Error err ->
 			ctx.has_error <- true;
 			Error.recurse_error (fun depth err ->
 				add_diagnostics_message ~depth com (Error.error_msg err.err_message) err.err_pos DKCompilerMessage Error
 			) err;
-			DisplayOutput.emit_diagnostics ctx.com
+			(match com.report_mode with
+			| RMLegacyDiagnostics _ -> DisplayOutput.emit_legacy_diagnostics ctx.com
+			| RMDiagnostics _ -> DisplayOutput.emit_diagnostics ctx.com
+			| _ -> die "" __LOC__)
 		| Parser.Error(msg,p) ->
 			handle_diagnostics (Parser.error_msg msg) p DKParserError
 		| Lexer.Error(msg,p) ->
 			handle_diagnostics (Lexer.error_msg msg) p DKParserError
 		end
 	else
-		f arg
+		f ()
 
 let run_command ctx cmd =
 	let t = Timer.timer ["command";cmd] in
@@ -193,18 +199,14 @@ module Setup = struct
 				let share_path = Filename.concat prefix_path "share" in
 				[
 					"";
-					Path.add_trailing_slash (Filename.concat lib_path "haxe/std");
-					Path.add_trailing_slash (Filename.concat lib_path "haxe/extraLibs");
 					Path.add_trailing_slash (Filename.concat share_path "haxe/std");
-					Path.add_trailing_slash (Filename.concat share_path "haxe/extraLibs");
+					Path.add_trailing_slash (Filename.concat lib_path "haxe/std");
 					Path.add_trailing_slash (Filename.concat base_path "std");
-					Path.add_trailing_slash (Filename.concat base_path "extraLibs")
 				]
 			else
 				[
 					"";
 					Path.add_trailing_slash (Filename.concat base_path "std");
-					Path.add_trailing_slash (Filename.concat base_path "extraLibs")
 				]
 
 	let setup_common_context ctx =
@@ -291,7 +293,7 @@ let do_type ctx mctx actx display_file_dot_path macro_cache_enabled =
 			if com.display.dms_kind <> DMNone then DisplayTexpr.check_display_file tctx cs;
 			List.iter (fun cpath -> ignore(tctx.Typecore.g.Typecore.do_load_module tctx cpath null_pos)) (List.rev actx.classes);
 			Finalization.finalize tctx;
-		) ();
+		);
 	end with TypeloadParse.DisplayInMacroBlock ->
 		ignore(DisplayProcessing.load_display_module_in_macro tctx display_file_dot_path true)
 	);
@@ -311,16 +313,16 @@ let finalize_typing ctx tctx =
 	let com = ctx.com in
 	enter_stage com CFilteringStart;
 	ServerMessage.compiler_stage com;
-	let main, types, modules = run_or_diagnose ctx Finalization.generate tctx in
+	let main, types, modules = run_or_diagnose ctx (fun () -> Finalization.generate tctx) in
 	com.main <- main;
 	com.types <- types;
 	com.modules <- modules;
 	t()
 
-let filter ctx tctx =
+let filter ctx tctx before_destruction =
 	let t = Timer.timer ["filters"] in
 	DeprecationCheck.run ctx.com;
-	Filters.run tctx ctx.com.main;
+	run_or_diagnose ctx (fun () -> Filters.run tctx ctx.com.main before_destruction);
 	t()
 
 let compile ctx actx callbacks =
@@ -357,8 +359,12 @@ let compile ctx actx callbacks =
 		let (tctx,display_file_dot_path) = do_type ctx mctx actx display_file_dot_path macro_cache_enabled in
 		DisplayProcessing.handle_display_after_typing ctx tctx display_file_dot_path;
 		finalize_typing ctx tctx;
-		DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path;
-		filter ctx tctx;
+		if is_diagnostics com then
+			filter ctx tctx (fun () -> DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path)
+		else begin
+			DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path;
+			filter ctx tctx (fun () -> ());
+		end;
 		if ctx.has_error then raise Abort;
 		Generate.check_auxiliary_output com actx;
 		enter_stage com CGenerationStart;
@@ -385,8 +391,6 @@ with
 		()
 	| Error.Fatal_error err ->
 		error_ext ctx err
-	| Common.Abort err ->
-		error_ext ctx err
 	| Lexer.Error (m,p) ->
 		error ctx (Lexer.error_msg m) p
 	| Parser.Error (m,p) ->

+ 15 - 5
src/compiler/displayOutput.ml

@@ -67,8 +67,8 @@ let print_fields fields =
 		| ITPackage(path,_) -> "package",snd path,"",None
 		| ITModule path -> "type",snd path,"",None
 		| ITMetadata  meta ->
-			let s,(doc,_),_ = Meta.get_info meta in
-			"metadata","@" ^ s,"",doc_from_string doc
+			let s,data  = Meta.get_info meta in
+			"metadata","@" ^ s,"",doc_from_string data.m_doc
 		| ITTimer(name,value) -> "timer",name,"",doc_from_string value
 		| ITLiteral s ->
 			let t = match k.ci_type with None -> t_dynamic | Some (t,_) -> t in
@@ -346,8 +346,8 @@ let handle_type_path_exception ctx p c is_import pos =
 			| Some (c,cur_package) ->
 				let ctx = Typer.create com None in
 				DisplayPath.TypePathHandler.complete_type_path_inner ctx p c cur_package is_import
-		end with Common.Abort msg ->
-			error_ext ctx msg;
+		end with Error.Fatal_error err ->
+			error_ext ctx err;
 			None
 	in
 	begin match ctx.com.json_out,fields with
@@ -368,12 +368,22 @@ let handle_type_path_exception ctx p c is_import pos =
 		api.send_result (DisplayException.fields_to_json ctx fields kind (DisplayTypes.make_subject None pos));
 	end
 
-let emit_diagnostics com =
+let emit_legacy_diagnostics com =
 	let dctx = Diagnostics.run com in
 	let s = Json.string_of_json (DiagnosticsPrinter.json_of_diagnostics com dctx) in
 	DisplayPosition.display_position#reset;
 	raise (Completion s)
 
+let emit_diagnostics com =
+	(match com.Common.json_out with
+	| None -> die "" __LOC__
+	| Some api ->
+		let dctx = Diagnostics.run com in
+		let diagnostics = DiagnosticsPrinter.json_of_diagnostics com dctx in
+		DisplayPosition.display_position#reset;
+		api.send_result diagnostics;
+		raise Abort (* not reached because send_result always raises *))
+
 let emit_statistics tctx =
 	let stats = Statistics.collect_statistics tctx [SFFile (DisplayPosition.display_position#get).pfile] true in
 	let s = Statistics.Printer.print_statistics stats in

+ 8 - 6
src/compiler/displayProcessing.ml

@@ -22,7 +22,7 @@ let handle_display_argument_old com file_pos actx =
 		actx.did_something <- true;
 		(try Memory.display_memory com with e -> prerr_endline (Printexc.get_backtrace ()));
 	| "diagnostics" ->
-		com.report_mode <- RMDiagnostics []
+		com.report_mode <- RMLegacyDiagnostics []
 	| _ ->
 		let file, pos = try ExtString.String.split file_pos "@" with _ -> failwith ("Invalid format: " ^ file_pos) in
 		let file = Helper.unquote file in
@@ -46,7 +46,7 @@ let handle_display_argument_old com file_pos actx =
 			| "module-symbols" ->
 				create (DMModuleSymbols None)
 			| "diagnostics" ->
-				com.report_mode <- RMDiagnostics [file_unique];
+				com.report_mode <- RMLegacyDiagnostics [file_unique];
 				let dm = create DMNone in
 				{dm with dms_display_file_policy = DFPAlso; dms_per_file = true; dms_populate_cache = !ServerConfig.populate_cache_from_display}
 			| "statistics" ->
@@ -143,11 +143,11 @@ let process_display_file com actx =
 		| DFPOnly when (DisplayPosition.display_position#get).pfile = file_input_marker ->
 			actx.classes <- [];
 			com.main_class <- None;
-			begin match !TypeloadParse.current_stdin with
-			| Some input ->
-				TypeloadParse.current_stdin := None;
+			begin match com.file_contents with
+			| [_, Some input] ->
+				com.file_contents <- [];
 				DPKInput input
-			| None ->
+			| _ ->
 				DPKNone
 			end
 		| dfp ->
@@ -348,6 +348,8 @@ let handle_display_after_finalization ctx tctx display_file_dot_path =
 	end;
 	process_global_display_mode com tctx;
 	begin match com.report_mode with
+	| RMLegacyDiagnostics _ ->
+		DisplayOutput.emit_legacy_diagnostics com
 	| RMDiagnostics _ ->
 		DisplayOutput.emit_diagnostics com
 	| RMStatistics ->

+ 6 - 6
src/compiler/retyper.ml

@@ -89,16 +89,16 @@ let pair_classes rctx c d p =
 		let has_extends = ref false in
 		let implements = ref c.cl_implements in
 		List.iter (function
-			| HExtends(path,p) ->
+			| HExtends ptp ->
 				has_extends := true;
 				begin match c.cl_super with
 				| None ->
-					fail rctx (Printf.sprintf "parent %s appeared" (Ast.Printer.s_complex_type_path "" (path,p)))
+					fail rctx (Printf.sprintf "parent %s appeared" (Ast.Printer.s_complex_type_path "" ptp))
 				| Some(c,tl) ->
-					let th = pair_type (Some(CTPath path,p)) (TInst(c,tl)) in
+					let th = pair_type (Some(CTPath ptp,ptp.pos_full)) (TInst(c,tl)) in
 					ignore (disable_typeloading rctx ctx (fun () -> Typeload.load_complex_type ctx false th))
 				end
-			| HImplements(path,p) ->
+			| HImplements ptp ->
 				begin match !implements with
 					| (c,tl) :: rest ->
 						(* TODO: I think this should somehow check if it's actually the same interface. There could be cases
@@ -106,10 +106,10 @@ let pair_classes rctx c d p =
 						   However, this doesn't matter until we start retyping invalidated modules.
 						*)
 						implements := rest;
-						let th = pair_type (Some(CTPath path,p)) (TInst(c,tl)) in
+						let th = pair_type (Some(CTPath ptp,ptp.pos_full)) (TInst(c,tl)) in
 						ignore (disable_typeloading rctx ctx (fun () -> Typeload.load_complex_type ctx false th));
 					| [] ->
-						fail rctx (Printf.sprintf "interface %s appeared" (Ast.Printer.s_complex_type_path "" (path,p)))
+						fail rctx (Printf.sprintf "interface %s appeared" (Ast.Printer.s_complex_type_path "" ptp))
 				end
 			| _ ->
 				()

+ 13 - 10
src/compiler/server.ml

@@ -16,15 +16,7 @@ let has_error ctx =
 	ctx.has_error || ctx.com.Common.has_error
 
 let check_display_flush ctx f_otherwise = match ctx.com.json_out with
-	| None ->
-		if is_diagnostics ctx.com then begin
-			List.iter (fun cm ->
-				add_diagnostics_message ~depth:cm.cm_depth ctx.com cm.cm_message cm.cm_pos cm.cm_kind cm.cm_severity
-			) (List.rev ctx.messages);
-			raise (Completion (Diagnostics.print ctx.com))
-		end else
-			f_otherwise ()
-	| Some api ->
+	| Some api when not (is_diagnostics ctx.com) ->
 		if has_error ctx then begin
 			let errors = List.map (fun cm ->
 				JObject [
@@ -35,6 +27,17 @@ let check_display_flush ctx f_otherwise = match ctx.com.json_out with
 			) (List.rev ctx.messages) in
 			api.send_error errors
 		end
+	| _ ->
+		if is_diagnostics ctx.com then begin
+			List.iter (fun cm ->
+				add_diagnostics_message ~depth:cm.cm_depth ctx.com cm.cm_message cm.cm_pos cm.cm_kind cm.cm_severity
+			) (List.rev ctx.messages);
+			(match ctx.com.report_mode with
+			| RMDiagnostics _ -> ()
+			| RMLegacyDiagnostics _ -> raise (Completion (Diagnostics.print ctx.com))
+			| _ -> die "" __LOC__)
+		end else
+			f_otherwise ()
 
 let current_stdin = ref None
 
@@ -44,7 +47,7 @@ let parse_file cs com file p =
 	and fkey = com.file_keys#get file in
 	let is_display_file = DisplayPosition.display_position#is_in_file (com.file_keys#get ffile) in
 	match is_display_file, !current_stdin with
-	| true, Some stdin when Common.defined com Define.DisplayStdin ->
+	| true, Some stdin when (com.file_contents <> [] || Common.defined com Define.DisplayStdin) ->
 		TypeloadParse.parse_file_from_string com file p stdin
 	| _ ->
 		let ftime = file_time ffile in

+ 2 - 2
src/context/abstractCast.ml

@@ -14,8 +14,8 @@ let rec make_static_call ctx c cf a pl args t p =
 				let e,f = push_this ctx e in
 				ctx.with_type_stack <- (WithType.with_type t) :: ctx.with_type_stack;
 				let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name [e] p with
-					| Some e -> type_expr ctx e (WithType.with_type t)
-					| None ->  type_expr ctx (EConst (Ident "null"),p) WithType.value
+					| MSuccess e -> type_expr ctx e (WithType.with_type t)
+					| _ ->  type_expr ctx (EConst (Ident "null"),p) WithType.value
 				in
 				ctx.with_type_stack <- List.tl ctx.with_type_stack;
 				let e = try cast_or_unify_raise ctx t e p with Error { err_message = Unify _ } -> raise Not_found in

+ 9 - 5
src/context/common.ml

@@ -289,7 +289,8 @@ let s_compiler_stage = function
 
 type report_mode =
 	| RMNone
-	| RMDiagnostics of Path.UniqueKey.t list
+	| RMLegacyDiagnostics of (Path.UniqueKey.t list)
+	| RMDiagnostics of (Path.UniqueKey.t list)
 	| RMStatistics
 
 class virtual ['key,'value] lookup = object(self)
@@ -400,6 +401,7 @@ type context = {
 	display_information : display_information;
 	file_lookup_cache : (string,string option) lookup;
 	file_keys : file_keys;
+	mutable file_contents : (Path.UniqueKey.t * string option) list;
 	readdir_cache : (string * string,(string array) option) lookup;
 	parser_cache : (string,(type_def * pos) list) lookup;
 	module_to_file : (path,string) lookup;
@@ -436,8 +438,6 @@ let enter_stage com stage =
 	(* print_endline (Printf.sprintf "Entering stage %s" (s_compiler_stage stage)); *)
 	com.stage <- stage
 
-exception Abort of Error.error
-
 let ignore_error com =
 	let b = com.display.dms_error_policy = EPIgnore in
 	if b then com.has_error <- true;
@@ -507,6 +507,9 @@ let external_define_value ctx k v =
 let external_define ctx k =
 	Define.raw_define ctx.defines (convert_and_validate k)
 
+let external_undefine ctx k =
+	Define.raw_undefine ctx.defines (convert_and_validate k)
+
 let defines_for_external ctx =
 	PMap.foldi (fun k v acc ->
 		let added_underscore = PMap.add k v acc in
@@ -837,6 +840,7 @@ let create compilation_step cs version args =
 		};
 		file_lookup_cache = new hashtbl_lookup;
 		file_keys = new file_keys;
+		file_contents = [];
 		readdir_cache = new hashtbl_lookup;
 		module_to_file = new hashtbl_lookup;
 		stored_typed_exprs = new hashtbl_lookup;
@@ -852,7 +856,7 @@ let create compilation_step cs version args =
 	com
 
 let is_diagnostics com = match com.report_mode with
-	| RMDiagnostics _ -> true
+	| RMLegacyDiagnostics _ | RMDiagnostics _ -> true
 	| _ -> false
 
 let disable_report_mode com =
@@ -1036,7 +1040,7 @@ let allow_package ctx s =
 	with Not_found ->
 		()
 
-let abort ?(depth = 0) msg p = raise (Abort (Error.make_error ~depth (Custom msg) p))
+let abort ?(depth = 0) msg p = raise (Error.Fatal_error (Error.make_error ~depth (Custom msg) p))
 
 let platform ctx p = ctx.platform = p
 

+ 37 - 36
src/context/display/diagnostics.ml

@@ -4,8 +4,13 @@ open Type
 open Common
 open DisplayTypes
 
-let add_removable_code ctx s p prange =
-	ctx.removable_code <- (s,p,prange) :: ctx.removable_code
+let add_replaceable_code ctx reason replacement display_range replace_range =
+	ctx.replaceable_code <- {
+		reason = reason;
+		replacement = replacement;
+		display_range = display_range;
+		replace_range = replace_range;
+	} :: ctx.replaceable_code
 
 let error_in_diagnostics_run com p =
 	let b = DiagnosticsPrinter.is_diagnostics_file com (com.file_keys#get p.pfile) in
@@ -16,24 +21,25 @@ let find_unused_variables com e =
 	let vars = Hashtbl.create 0 in
 	let pmin_map = Hashtbl.create 0 in
 	let rec loop e = match e.eexpr with
-		| TVar({v_kind = VUser _} as v,eo) when v.v_name <> "_" ->
+		| TVar({v_kind = VUser origin} as v,eo) when v.v_name <> "_" && not (has_var_flag v VUsedByTyper) ->
 			Hashtbl.add pmin_map e.epos.pmin v;
-			let p = match eo with
-				| None -> e.epos
-				| Some e1 ->
-					loop e1;
-					{ e.epos with pmax = e1.epos.pmin }
+			let p,replacement = match eo with
+			| Some e1 when origin <> TVOPatternVariable ->
+				loop e1;
+				{ e.epos with pmax = e1.epos.pmin },""
+			| _ ->
+				e.epos,"_"
 			in
-			Hashtbl.replace vars v.v_id (v,p);
+			Hashtbl.replace vars v.v_id (v,p,replacement);
 		| TLocal ({v_kind = VUser _} as v) ->
 			Hashtbl.remove vars v.v_id;
 		| _ ->
 			Type.iter loop e
 	in
 	loop e;
-	Hashtbl.iter (fun _ (v,p) ->
+	Hashtbl.iter (fun _ (v,p,replacement) ->
 		let p = match (Hashtbl.find_all pmin_map p.pmin) with [_] -> p | _ -> null_pos in
-		add_removable_code com "Unused variable" v.v_pos p
+		add_replaceable_code com "Unused variable" replacement v.v_pos p
 	) vars
 
 let check_other_things com e =
@@ -44,18 +50,18 @@ let check_other_things com e =
 	let pointless_compound s p =
 		add_diagnostics_message com (Printf.sprintf "This %s has no effect, but some of its sub-expressions do" s) p DKCompilerMessage Warning;
 	in
-	let rec compound compiler_generated s el p =
+	let rec compound s el p =
 		let old = !had_effect in
 		had_effect := false;
-		List.iter (loop true compiler_generated) el;
-		if not !had_effect then no_effect p else if not compiler_generated then pointless_compound s p;
+		List.iter (loop true) el;
+		if not !had_effect then no_effect p else pointless_compound s p;
 		had_effect := old;
-	and loop in_value compiler_generated e = match e.eexpr with
+	and loop in_value e = match e.eexpr with
 		| TBlock el ->
 			let rec loop2 el = match el with
 				| [] -> ()
-				| [e] -> loop in_value compiler_generated e
-				| e :: el -> loop false compiler_generated e; loop2 el
+				| [e] -> loop in_value e
+				| e :: el -> loop false e; loop2 el
 			in
 			loop2 el
 		| TMeta((Meta.Extern,_,_),_) ->
@@ -67,29 +73,27 @@ let check_other_things com e =
 			()
 		| TField (_, fa) when PurityState.is_explicitly_impure fa -> ()
 		| TFunction tf ->
-			loop false compiler_generated tf.tf_expr
-		| TCall({eexpr = TField(e1,fa)},el) when not in_value && PurityState.is_pure_field_access fa -> compound compiler_generated "call" el e.epos
+			loop false tf.tf_expr
+		| TCall({eexpr = TField(e1,fa)},el) when not in_value && PurityState.is_pure_field_access fa -> compound "call" el e.epos
 		| TNew _ | TCall _ | TBinop ((Ast.OpAssignOp _ | Ast.OpAssign),_,_) | TUnop ((Ast.Increment | Ast.Decrement),_,_)
 		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _)
 		| TIf _ | TTry _ | TSwitch _ | TWhile _ | TFor _ ->
 			had_effect := true;
-			Type.iter (loop true compiler_generated) e
-		| TMeta((Meta.CompilerGenerated,_,_),e1) ->
-			loop in_value true e1
+			Type.iter (loop true) e
 		| TParenthesis e1 | TMeta(_,e1) ->
-			loop in_value compiler_generated e1
+			loop in_value e1
 		| TArray _ | TCast (_,None) | TBinop _ | TUnop _
 		| TField _ | TArrayDecl _ | TObjectDecl _ when in_value ->
-			Type.iter (loop true compiler_generated) e;
-		| TArray(e1,e2) -> compound compiler_generated "array access" [e1;e2] e.epos
-		| TCast(e1,None) -> compound compiler_generated "cast" [e1] e.epos
-		| TBinop(op,e1,e2) -> compound compiler_generated (Printf.sprintf "'%s' operator" (s_binop op)) [e1;e2] e.epos
-		| TUnop(op,_,e1) -> compound compiler_generated (Printf.sprintf "'%s' operator" (s_unop op)) [e1] e.epos
-		| TField(e1,_) -> compound compiler_generated "field access" [e1] e.epos
-		| TArrayDecl el -> compound compiler_generated "array declaration" el e.epos
-		| TObjectDecl fl -> compound compiler_generated "object declaration" (List.map snd fl) e.epos
+			Type.iter (loop true) e;
+		| TArray(e1,e2) -> compound "array access" [e1;e2] e.epos
+		| TCast(e1,None) -> compound "cast" [e1] e.epos
+		| TBinop(op,e1,e2) -> compound (Printf.sprintf "'%s' operator" (s_binop op)) [e1;e2] e.epos
+		| TUnop(op,_,e1) -> compound (Printf.sprintf "'%s' operator" (s_unop op)) [e1] e.epos
+		| TField(e1,_) -> compound "field access" [e1] e.epos
+		| TArrayDecl el -> compound "array declaration" el e.epos
+		| TObjectDecl fl -> compound "object declaration" (List.map snd fl) e.epos
 	in
-	loop true false e
+	loop true e
 
 let prepare_field dctx dectx com cf = match cf.cf_expr with
 	| None -> ()
@@ -136,7 +140,7 @@ let collect_diagnostics dctx com =
 
 let prepare com =
 	let dctx = {
-		removable_code = [];
+		replaceable_code = [];
 		import_positions = PMap.empty;
 		dead_blocks = Hashtbl.create 0;
 		diagnostics_messages = [];
@@ -177,9 +181,6 @@ let prepare com =
 	dctx.unresolved_identifiers <- com.display_information.unresolved_identifiers;
 	dctx
 
-let secure_generated_code ctx e =
-	if is_diagnostics ctx then mk (TMeta((Meta.CompilerGenerated,[],e.epos),e)) e.etype e.epos else e
-
 let print com =
 	let dctx = prepare com in
 	Json.string_of_json (DiagnosticsPrinter.json_of_diagnostics com dctx)

+ 10 - 6
src/context/display/diagnosticsPrinter.ml

@@ -26,8 +26,8 @@ let make_diagnostic kd p sev code args = {
 
 let is_diagnostics_file com file_key =
 	match com.report_mode with
-	| RMDiagnostics [] -> true
-	| RMDiagnostics file_keys -> List.exists (fun key' -> file_key = key') file_keys
+	| RMLegacyDiagnostics [] | RMDiagnostics [] -> true
+	| RMLegacyDiagnostics file_keys | RMDiagnostics file_keys -> List.mem file_key file_keys
 	| _ -> false
 
 module UnresolvedIdentifierSuggestion = struct
@@ -64,7 +64,7 @@ let json_of_diagnostics com dctx =
 	let add dk p sev code args =
 		let append = match dk with
 			| DKUnusedImport
-			| DKRemovableCode
+			| DKReplacableCode
 			| DKDeprecationWarning
 			| DKInactiveBlock ->
 				false
@@ -193,9 +193,13 @@ let json_of_diagnostics com dctx =
 	PMap.iter (fun p r ->
 		if not !r then add DKUnusedImport p MessageSeverity.Warning None (JArray [])
 	) dctx.import_positions;
-	List.iter (fun (s,p,prange) ->
-		add DKRemovableCode p MessageSeverity.Warning None (JObject ["description",JString s;"range",if prange = null_pos then JNull else Genjson.generate_pos_as_range prange])
-	) dctx.removable_code;
+	List.iter (fun rc ->
+		add DKReplacableCode rc.display_range MessageSeverity.Warning None (JObject [
+			"description",JString rc.reason;
+			"newCode",JString rc.replacement;
+			"range",if rc.replace_range = null_pos then JNull else Genjson.generate_pos_as_range rc.replace_range
+		])
+	) dctx.replaceable_code;
 	Hashtbl.iter (fun file ranges ->
 		List.iter (fun (p,e) ->
 			let jo = JObject [

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

@@ -127,12 +127,12 @@ module ExprPreprocessing = struct
 			| ECall(e1,el) when is_annotated (pos e) && is_completion ->
 				let el = loop_el el in
 				ECall(e1,el),(pos e)
-			| ENew((tp,pp),el) when is_annotated (pos e) && is_completion ->
-				if is_annotated pp || pp.pmax >= (DisplayPosition.display_position#get).pmax then
+			| 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((tp,pp),el),(pos e)
+					ENew(ptp,el),(pos e)
 				end
 			| EArrayDecl el when is_annotated (pos e) && is_completion ->
 				let el = loop_el el in

+ 4 - 11
src/context/display/displayEmitter.ml

@@ -66,20 +66,13 @@ let rec display_type ctx t p =
 			| _ ->
 				()
 
-let check_display_type ctx t path =
+let check_display_type ctx t ptp =
 	let add_type_hint () =
-		ctx.g.type_hints <- (ctx.m.curmod.m_extra.m_display,pos path,t) :: ctx.g.type_hints;
+		ctx.g.type_hints <- (ctx.m.curmod.m_extra.m_display,ptp.pos_full,t) :: ctx.g.type_hints;
 	in
 	let maybe_display_type () =
-		if ctx.is_display_file && display_position#enclosed_in (pos path) then
-			let p =
-				match path with
-				| ({ tpackage = pack; tname = name; tsub = sub },p) ->
-					let strings = match sub with None -> name :: pack | Some s -> s :: name :: pack in
-					let length = String.length (String.concat "." strings) in
-					{ p with pmax = p.pmin + length }
-			in
-			display_type ctx t p
+		if ctx.is_display_file && display_position#enclosed_in ptp.pos_full then
+			display_type ctx t ptp.pos_path
 	in
 	add_type_hint();
 	maybe_display_type()

+ 115 - 9
src/context/display/displayJson.ml

@@ -59,18 +59,49 @@ class display_handler (jsonrpc : jsonrpc_handler) com (cs : CompilationCache.t)
 			let file = jsonrpc#get_string_param "file" in
 			Path.get_full_path file
 		) file_input_marker in
-		let pos = if requires_offset then jsonrpc#get_int_param "offset" else (-1) in
-		TypeloadParse.current_stdin := jsonrpc#get_opt_param (fun () ->
+		let contents = jsonrpc#get_opt_param (fun () ->
 			let s = jsonrpc#get_string_param "contents" in
-			Common.define com Define.DisplayStdin; (* TODO: awkward *)
 			Some s
-		) None;
+		) None in
+
+		let pos = if requires_offset then jsonrpc#get_int_param "offset" else (-1) in
 		Parser.was_auto_triggered := was_auto_triggered;
-		DisplayPosition.display_position#set {
-			pfile = file;
-			pmin = pos;
-			pmax = pos;
-		}
+
+		if file <> file_input_marker then begin
+			let file_unique = com.file_keys#get file in
+
+			DisplayPosition.display_position#set {
+				pfile = file;
+				pmin = pos;
+				pmax = pos;
+			};
+
+			com.file_contents <- [file_unique, contents];
+		end else begin
+			let file_contents = jsonrpc#get_opt_param (fun () ->
+				jsonrpc#get_opt_param (fun () -> jsonrpc#get_array_param "fileContents") []
+			) [] in
+
+			let file_contents = List.map (fun fc -> match fc with
+				| JObject fl ->
+					let file = jsonrpc#get_string_field "fileContents" "file" fl in
+					let file = Path.get_full_path file in
+					let file_unique = com.file_keys#get file in
+					let contents = jsonrpc#get_opt_param (fun () ->
+						let s = jsonrpc#get_string_field "fileContents" "contents" fl in
+						Some s
+					) None in
+					(file_unique, contents)
+				| _ -> invalid_arg "fileContents"
+			) file_contents in
+
+			let files = (List.map (fun (k, _) -> k) file_contents) in
+			com.file_contents <- file_contents;
+
+			match files with
+			| [] | [_] -> DisplayPosition.display_position#set { pfile = file; pmin = pos; pmax = pos; };
+			| _ -> DisplayPosition.display_position#set_files files;
+		end
 end
 
 type handler_context = {
@@ -125,6 +156,16 @@ let handler =
 			hctx.display#set_display_file false true;
 			hctx.display#enable_display DMDefinition;
 		);
+		"display/diagnostics", (fun hctx ->
+			hctx.display#set_display_file false false;
+			hctx.display#enable_display DMNone;
+			hctx.com.report_mode <- RMDiagnostics (List.map (fun (f,_) -> f) hctx.com.file_contents);
+
+			(match hctx.com.file_contents with
+			| [file, None] ->
+				hctx.com.display <- { hctx.com.display with dms_display_file_policy = DFPAlso; dms_per_file = true; dms_populate_cache = !ServerConfig.populate_cache_from_display};
+			| _ -> ());
+		);
 		"display/implementation", (fun hctx ->
 			hctx.display#set_display_file false true;
 			hctx.display#enable_display (DMImplementation);
@@ -155,6 +196,71 @@ let handler =
 			hctx.display#set_display_file (hctx.jsonrpc#get_bool_param "wasAutoTriggered") true;
 			hctx.display#enable_display DMSignature
 		);
+		"display/metadata", (fun hctx ->
+			let include_compiler_meta = hctx.jsonrpc#get_bool_param "compiler" in
+			let include_user_meta = hctx.jsonrpc#get_bool_param "user" in
+
+			hctx.com.callbacks#add_after_init_macros (fun () ->
+				let all = Meta.get_meta_list hctx.com.user_metas in
+				let all = List.filter (fun (_, (data:Meta.meta_infos)) ->
+					match data.m_origin with
+					| Compiler when include_compiler_meta -> true
+					| UserDefined _ when include_user_meta -> true
+					| _ -> false
+				) all in
+
+				hctx.send_result (jarray (List.map (fun (t, (data:Meta.meta_infos)) ->
+					let fields = [
+						"name", jstring t;
+						"doc", jstring data.m_doc;
+						"parameters", jarray (List.map jstring data.m_params);
+						"platforms", jarray (List.map (fun p -> jstring (platform_name p)) data.m_platforms);
+						"targets", jarray (List.map (fun u -> jstring (Meta.print_meta_usage u)) data.m_used_on);
+						"internal", jbool data.m_internal;
+						"origin", jstring (match data.m_origin with
+							| Compiler -> "haxe compiler"
+							| UserDefined None -> "user-defined"
+							| UserDefined (Some o) -> o
+						);
+						"links", jarray (List.map jstring data.m_links)
+					] in
+
+					(jobject fields)
+				) all))
+			)
+		);
+		"display/defines", (fun hctx ->
+			let include_compiler_defines = hctx.jsonrpc#get_bool_param "compiler" in
+			let include_user_defines = hctx.jsonrpc#get_bool_param "user" in
+
+			hctx.com.callbacks#add_after_init_macros (fun () ->
+				let all = Define.get_define_list hctx.com.user_defines in
+				let all = List.filter (fun (_, (data:Define.define_infos)) ->
+					match data.d_origin with
+					| Compiler when include_compiler_defines -> true
+					| UserDefined _ when include_user_defines -> true
+					| _ -> false
+				) all in
+
+				hctx.send_result (jarray (List.map (fun (t, (data:Define.define_infos)) ->
+					let fields = [
+						"name", jstring t;
+						"doc", jstring data.d_doc;
+						"parameters", jarray (List.map jstring data.d_params);
+						"platforms", jarray (List.map (fun p -> jstring (platform_name p)) data.d_platforms);
+						"origin", jstring (match data.d_origin with
+							| Compiler -> "haxe compiler"
+							| UserDefined None -> "user-defined"
+							| UserDefined (Some o) -> o
+						);
+						"deprecated", jopt jstring data.d_deprecated;
+						"links", jarray (List.map jstring data.d_links)
+					] in
+
+					(jobject fields)
+				) all))
+			)
+		);
 		"server/readClassPaths", (fun hctx ->
 			hctx.com.callbacks#add_after_init_macros (fun () ->
 				let cc = hctx.display#get_cs#get_context (Define.get_signature hctx.com.defines) in

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

@@ -89,8 +89,8 @@ let check_display_class ctx decls c =
 		let sc = find_class_by_position decls c.cl_name_pos in
 		ignore(Typeload.type_type_params ctx TPHType c.cl_path (fun() -> c.cl_params) null_pos sc.d_params);
 		List.iter (function
-			| (HExtends(ct,p) | HImplements(ct,p)) when display_position#enclosed_in p ->
-				ignore(Typeload.load_instance ~allow_display:true ctx (ct,p) ParamNormal)
+			| (HExtends ptp | HImplements ptp) when display_position#enclosed_in ptp.pos_full ->
+				ignore(Typeload.load_instance ~allow_display:true ctx ptp ParamNormal)
 			| _ ->
 				()
 		) sc.d_flags;

+ 5 - 5
src/context/display/syntaxExplorer.ml

@@ -29,7 +29,7 @@ let find_in_syntax symbols (pack,decls) =
 					()
 		) symbols
 	in
-	let rec type_path kind path =
+	let rec type_path kind { path } =
 		check KModuleType path.tname;
 		Option.may (check KModuleType) path.tsub;
 		List.iter (function
@@ -45,7 +45,7 @@ let find_in_syntax symbols (pack,decls) =
 		| CTAnonymous cffl ->
 			List.iter field cffl
 		| CTExtend(tl,cffl) ->
-			List.iter (fun (path,_) -> type_path KModuleType path) tl;
+			List.iter (fun ptp -> type_path KModuleType ptp) tl;
 			List.iter field cffl;
 		| CTIntersection tl ->
 			List.iter type_hint tl
@@ -67,8 +67,8 @@ let find_in_syntax symbols (pack,decls) =
 		| ECast(e1,tho) ->
 			expr e1;
 			Option.may type_hint tho;
-		| ENew((path,_),el) ->
-			type_path KConstructor path;
+		| ENew(ptp,el) ->
+			type_path KConstructor ptp;
 			List.iter expr el;
 		| EFunction(_,f) ->
 			func f
@@ -129,7 +129,7 @@ let find_in_syntax symbols (pack,decls) =
 		| EClass d ->
 			check KModuleType (fst d.d_name);
 			List.iter (function
-				| HExtends(path,_) | HImplements(path,_) -> type_path KModuleType path
+				| HExtends ptp | HImplements ptp -> type_path KModuleType ptp
 				| _ -> ()
 			) d.d_flags;
 			List.iter type_param d.d_params;

+ 10 - 1
src/context/typecore.ml

@@ -86,6 +86,11 @@ type build_info = {
 	build_apply : Type.t list -> Type.t;
 }
 
+type macro_result =
+	| MSuccess of expr
+	| MError
+	| MMacroInMacro
+
 type typer_globals = {
 	mutable delayed : delay list;
 	mutable debug_delayed : (typer_pass * ((unit -> unit) * (string * string list) * typer) list) list;
@@ -103,7 +108,7 @@ type typer_globals = {
 	mutable load_only_cached_modules : bool;
 	functional_interface_lut : (path,tclass_field) lookup;
 	(* api *)
-	do_macro : typer -> macro_mode -> path -> string -> expr list -> pos -> expr option;
+	do_macro : typer -> macro_mode -> path -> string -> expr list -> pos -> macro_result;
 	do_load_macro : typer -> bool -> path -> string -> pos -> ((string * bool * t) list * t * tclass * Type.tclass_field);
 	do_load_module : typer -> path -> pos -> module_def;
 	do_load_type_def : typer -> pos -> type_path -> module_type;
@@ -459,6 +464,10 @@ let rec flush_pass ctx p where =
 let make_pass ctx f = f
 
 let init_class_done ctx =
+	ctx.pass <- PConnectField
+
+let enter_field_typing_pass ctx info =
+	flush_pass ctx PConnectField info;
 	ctx.pass <- PTypeField
 
 let make_lazy ?(force=true) ctx t_proc f where =

+ 31 - 10
src/core/ast.ml

@@ -159,14 +159,18 @@ type type_path = {
 	tsub : string option;
 }
 
-and placed_type_path = type_path * pos
+and placed_type_path = {
+	path : type_path;
+	pos_full : pos;
+	pos_path : pos;
+}
 
 and type_param_or_const =
 	| TPType of type_hint
 	| TPExpr of expr
 
 and complex_type =
-	| CTPath of type_path
+	| CTPath of placed_type_path
 	| CTFunction of type_hint list * type_hint
 	| CTAnonymous of class_field list
 	| CTParent of type_hint
@@ -327,9 +331,6 @@ and evar = {
 	ev_meta : metadata;
 }
 
-(* TODO: should we introduce CTMono instead? *)
-let ct_mono = CTPath { tpackage = ["$"]; tname = "_hx_mono"; tparams = []; tsub = None }
-
 type enum_flag =
 	| EPrivate
 	| EExtern
@@ -405,6 +406,26 @@ let mk_evar ?(final=false) ?(static=false) ?(t:type_hint option) ?eo ?(meta=[])
 		ev_meta = meta;
 	}
 
+let make_ptp path ?p_path p_full = {
+	path = path;
+	pos_full = p_full;
+	pos_path = Option.default p_full p_path;
+}
+
+let make_ptp_ct path ?p_path p_full =
+	CTPath (make_ptp path ?p_path p_full)
+
+let make_ptp_ct_null path =
+	CTPath (make_ptp path null_pos)
+
+let make_ptp_th path ?p_path p_full =
+	(make_ptp_ct path ?p_path p_full,p_full)
+
+let make_ptp_th_null path =
+	make_ptp_th path null_pos
+
+let ct_mono = make_ptp_ct_null { tpackage = ["$"]; tname = "_hx_mono"; tparams = []; tsub = None }
+
 let is_lower_ident i =
 	if String.length i = 0 then
 		raise (Invalid_argument "Identifier name must not be empty")
@@ -692,7 +713,7 @@ let map_expr loop (e,p) =
 				FProp (get,set,t,e))
 		}
 	and type_hint (t,p) = (match t with
-		| CTPath t -> CTPath { t with tparams = List.map tparam t.tparams }
+		| CTPath ptp -> CTPath { ptp with path = { ptp.path with tparams = List.map tparam ptp.path.tparams }}
 		| CTFunction (cl,c) ->
 			let cl = List.map type_hint cl in
 			let c = type_hint c in
@@ -727,7 +748,7 @@ let map_expr loop (e,p) =
 			f_type = t;
 			f_expr = e;
 		}
-	and tpath (t,p) = { t with tparams = List.map tparam t.tparams },p
+	and tpath ptp = { ptp with path = { ptp.path with tparams = List.map tparam ptp.path.tparams }}
 	in
 	let e = (match e with
 	| EConst _ -> e
@@ -896,7 +917,7 @@ module Printer = struct
 		| EDisplay (e1,dk) -> Printf.sprintf "#DISPLAY(%s, %s)" (s_expr_inner tabs e1) (s_display_kind dk)
 	and s_expr_list tabs el sep =
 		(String.concat sep (List.map (s_expr_inner tabs) el))
-	and s_complex_type_path tabs (t,_) =
+	and s_complex_type_path tabs {path = t} =
 		Printf.sprintf "%s%s%s"
 			(s_type_path (t.tpackage,t.tname))
 			(Option.map_default (fun s -> "." ^ s) "" t.tsub)
@@ -911,7 +932,7 @@ module Printer = struct
 		| TPExpr e -> s_expr_inner tabs e
 	and s_complex_type tabs ct =
 		match ct with
-		| CTPath t -> s_complex_type_path tabs (t,null_pos)
+		| CTPath ptp -> s_complex_type_path tabs ptp
 		| CTFunction (cl,(c,_)) -> if List.length cl > 0 then String.concat " -> " (List.map (fun (t,_) -> s_complex_type tabs t) cl) else "Void" ^ " -> " ^ s_complex_type tabs c
 		| CTAnonymous fl -> "{ " ^ String.concat "; " (List.map (s_class_field tabs) fl) ^ "}";
 		| CTParent(t,_) -> "(" ^ s_complex_type tabs t ^ ")"
@@ -1116,7 +1137,7 @@ module Expr = struct
 				add "ECall";
 				loop e1;
 				List.iter loop el
-			| ENew((tp,_),el) ->
+			| ENew({path = tp},el) ->
 				add ("ENew " ^ s_type_path(tp.tpackage,tp.tname));
 				List.iter loop el
 			| EUnop(op,_,e1) ->

+ 50 - 15
src/core/define.ml

@@ -19,7 +19,35 @@ type define_origin =
 	| Compiler
 	| UserDefined of string option
 
-let infos ?user_defines d = match (user_defines,d) with
+type define_infos = {
+	d_doc : string;
+	d_params : string list;
+	d_platforms : Globals.platform list;
+	d_origin : define_origin;
+	d_links : string list;
+	d_deprecated : string option;
+}
+
+let infos ?user_defines d =
+	let extract_infos (t, (doc, flags), origin) =
+		let params = ref [] and pfs = ref [] and links = ref [] and deprecated = ref None in
+		List.iter (function
+			| HasParam s -> params := s :: !params
+			| Platforms fl -> pfs := fl @ !pfs
+			| Link url -> links := url :: !links
+			| Deprecated s -> deprecated := Some s
+		) flags;
+		(t, {
+			d_doc = doc;
+			d_params = !params;
+			d_platforms = !pfs;
+			d_origin = origin;
+			d_links = !links;
+			d_deprecated = !deprecated;
+		})
+	in
+
+	extract_infos (match (user_defines,d) with
 	| (Some(user_defines), Custom(s)) when (Hashtbl.mem user_defines s) ->
 		let infos = Hashtbl.find user_defines s in
 		(s, (infos.doc, infos.flags), (UserDefined infos.source))
@@ -27,30 +55,23 @@ let infos ?user_defines d = match (user_defines,d) with
 		(s, ("", []), Compiler)
 	| _ ->
 		let def,infos = DefineList.infos d in
-		(def, infos, Compiler)
+		(def, infos, Compiler))
 
 let get_define_key d =
-	match (infos d) with (s,_,_) -> s
+	match (infos d) with (s,_) -> s
 
 let get_documentation user_defines d =
-	let t, (doc,flags), origin = infos ~user_defines:user_defines d in
-	let params = ref [] and pfs = ref [] in
-	List.iter (function
-		| HasParam s -> params := s :: !params
-		| Platforms fl -> pfs := fl @ !pfs
-		| Link _ -> ()
-		| Deprecated _ -> ()
-	) flags;
-	let params = (match List.rev !params with
+	let t, data = infos ~user_defines:user_defines d in
+	let params = (match List.rev data.d_params with
 		| [] -> ""
 		| l -> "<" ^ String.concat ">, <" l ^ "> "
 	) in
-	let origin = match origin with
+	let origin = match data.d_origin with
 		| UserDefined Some s -> " (from " ^ s ^ ")"
 		| Compiler | UserDefined None -> ""
 	in
-	let pfs = platform_list_help (List.rev !pfs) in
-	(String.concat "-" (ExtString.String.nsplit t "_")), params ^ doc ^ pfs ^ origin
+	let pfs = platform_list_help (List.rev data.d_platforms) in
+	(String.concat "-" (ExtString.String.nsplit t "_")), params ^ data.d_doc ^ pfs ^ origin
 
 let get_documentation_list user_defines =
 	let m = ref 0 in
@@ -77,6 +98,16 @@ let get_user_documentation_list user_defines =
 	let all = List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) user_defines_list in
 	all,!m
 
+let get_define_list user_defines =
+	let rec loop i acc =
+		let d = Obj.magic i in
+		if d <> Last then (infos ~user_defines d) :: loop (i + 1) acc
+		else acc
+	in
+
+	let all = loop 0 (Hashtbl.fold (fun str _ acc -> (infos ~user_defines (Custom str)) :: acc) user_defines []) in
+	List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) all
+
 let raw_defined ctx k =
 	PMap.mem k ctx.values
 
@@ -103,6 +134,10 @@ let define_value ctx k v =
 let raw_define ctx k =
 	raw_define_value ctx k "1"
 
+let raw_undefine ctx k =
+	ctx.values <- PMap.remove k ctx.values;
+	ctx.defines_signature <- None
+
 let define ctx k =
 	raw_define_value ctx (get_define_key k) "1"
 

+ 13 - 34
src/core/display/completionItem.ml

@@ -761,42 +761,21 @@ let to_json ctx index item =
 		]
 		| ITMetadata meta ->
 			let open Meta in
-			let name,(doc,params),origin = Meta.get_info meta in
+			let name,data = Meta.get_info meta in
 			let name = "@" ^ name in
-			let usage_to_string = function
-				| TClass -> "TClass"
-				| TClassField -> "TClassField"
-				| TAbstract -> "TAbstract"
-				| TAbstractField -> "TAbstractField"
-				| TEnum -> "TEnum"
-				| TTypedef -> "TTypedef"
-				| TAnyField -> "TAnyField"
-				| TExpr -> "TExpr"
-				| TTypeParameter -> "TTypeParameter"
-				| TVariable -> "TVariable"
-			in
-			let origin = match origin with
-				| Compiler -> Some "haxe compiler"
-				| UserDefined s -> s
-			in
-			let rec loop internal params platforms targets links l = match l with
-				| HasParam s :: l -> loop internal (s :: params) platforms targets links l
-				| Platforms pls :: l -> loop internal params ((List.map platform_name pls) @ platforms) targets links l
-				| UsedOn usages :: l -> loop internal params platforms ((List.map usage_to_string usages) @ targets) links l
-				| UsedInternally :: l -> loop true params platforms targets links l
-				| Link url :: l -> loop internal params platforms targets (url :: links) l
-				| [] -> internal,params,platforms,targets,links
-			in
-			let internal,params,platforms,targets,links = loop false [] [] [] [] params in
 			"Metadata",jobject [
-				"name",jstring name;
-				"doc",jstring doc;
-				"parameters",jlist jstring params;
-				"platforms",jlist jstring platforms;
-				"targets",jlist jstring targets;
-				"internal",jbool internal;
-				"links",jlist jstring links;
-				"origin",jopt jstring origin;
+				"name", jstring name;
+				"doc", jstring data.m_doc;
+				"parameters", jarray (List.map jstring data.m_params);
+				"platforms", jarray (List.map (fun p -> jstring (platform_name p)) data.m_platforms);
+				"targets", jarray (List.map (fun u -> jstring (Meta.print_meta_usage u)) data.m_used_on);
+				"internal", jbool data.m_internal;
+				"origin", jstring (match data.m_origin with
+					| Compiler -> "haxe compiler"
+					| UserDefined None -> "user-defined"
+					| UserDefined (Some o) -> o
+				);
+				"links", jarray (List.map jstring data.m_links)
 			]
 		| ITKeyword kwd ->"Keyword",jobject [
 			"name",jstring (s_keyword kwd)

+ 16 - 3
src/core/display/displayPosition.ml

@@ -11,6 +11,7 @@ class display_position_container =
 		(** Current display position *)
 		val mutable pos = null_pos
 		val mutable file_key = None
+		val mutable file_keys = []
 		(**
 			Display position value which was set with the latest `display_position#set p` call.
 			Kept even after `display_position#reset` call.
@@ -23,6 +24,10 @@ class display_position_container =
 			pos <- p;
 			last_pos <- p;
 			file_key <- None
+
+		method set_files files =
+			file_keys <- files
+
 		(**
 			Get current display position
 		*)
@@ -43,7 +48,8 @@ class display_position_container =
 		*)
 		method reset =
 			pos <- null_pos;
-			file_key <- None
+			file_key <- None;
+			file_keys <- []
 		(**
 			Check if `p` contains current display position
 		*)
@@ -53,8 +59,15 @@ class display_position_container =
 			Check if a file with `file_key` contains current display position
 		*)
 		method is_in_file file_key =
-			pos.pfile <> "?"
-			&& self#get_file_key = file_key
+			(pos.pfile <> "?" && self#get_file_key = file_key) || self#has_file file_key
+
+		(**
+			This is a hack; currently used by Diagnostics.collect_diagnostics when sending multiple files
+			to run diagnostics on via json rpc
+		*)
+		method has_file file_key =
+			List.mem file_key file_keys
+
 		(**
 			Cut `p` at the position of the latest `display_position#set pos` call.
 		*)

+ 9 - 3
src/core/displayTypes.ml

@@ -233,7 +233,6 @@ module DisplayMode = struct
 		| DMDefault | DMDefinition | DMTypeDefinition | DMPackage | DMHover | DMSignature -> settings
 		| DMUsage _ | DMImplementation -> { settings with
 				dms_full_typing = true;
-				dms_populate_cache = !ServerConfig.populate_cache_from_display;
 				dms_force_macro_typing = true;
 				dms_display_file_policy = DFPAlso;
 				dms_exit_during_typing = false
@@ -329,8 +328,15 @@ and missing_fields_diagnostics = {
 and module_diagnostics =
 	| MissingFields of missing_fields_diagnostics
 
+type replaceable_code = {
+	reason : string;
+	replacement : string;
+	display_range : pos;
+	replace_range : pos;
+}
+
 type diagnostics_context = {
-	mutable removable_code : (string * pos * pos) list;
+	mutable replaceable_code : replaceable_code list;
 	mutable import_positions : (pos,bool ref) PMap.t;
 	mutable dead_blocks : (Path.UniqueKey.t,(pos * expr) list) Hashtbl.t;
 	mutable unresolved_identifiers : (string * pos * (string * CompletionItem.t * int) list) list;
@@ -346,4 +352,4 @@ type display_exception_kind =
 	| DisplayPositions of pos list
 	| DisplayFields of fields_result
 	| DisplayPackage of string list
-	| DisplayNoResult
+	| DisplayNoResult

+ 2 - 2
src/core/globals.ml

@@ -189,7 +189,7 @@ module MessageKind = struct
 		| DKUnusedImport
 		| DKUnresolvedIdentifier
 		| DKCompilerMessage
-		| DKRemovableCode
+		| DKReplacableCode
 		| DKParserError
 		| DKDeprecationWarning
 		| DKInactiveBlock
@@ -199,7 +199,7 @@ module MessageKind = struct
 		| DKUnusedImport -> 0
 		| DKUnresolvedIdentifier -> 1
 		| DKCompilerMessage -> 2
-		| DKRemovableCode -> 3
+		| DKReplacableCode -> 3
 		| DKParserError -> 4
 		| DKDeprecationWarning -> 5
 		| DKInactiveBlock -> 6

+ 2 - 2
src/core/inheritDoc.ml

@@ -34,8 +34,8 @@ let rec get_class_field c field_name =
 		| None -> raise Not_found
 		| Some (csup, _) -> get_class_field csup field_name
 
-let find_type ctx tp =
-	try Typeload.load_instance' ctx tp ParamSpawnMonos
+let find_type ctx (tp,p) =
+	try Typeload.load_instance' ctx (make_ptp tp p) ParamSpawnMonos
 	with _ -> raise Not_found
 
 (**

+ 2 - 2
src/core/json/genjson.ml

@@ -177,8 +177,8 @@ and generate_metadata_entry ctx (m,el,p) =
 
 and generate_metadata ctx ml =
 	let ml = List.filter (fun (m,_,_) ->
-		let (_,(_,flags),_) = Meta.get_info m in
-		not (List.mem UsedInternally flags)
+		let (_,data) = Meta.get_info m in
+		not data.m_internal
 	) ml in
 	jlist (generate_metadata_entry ctx) ml
 

+ 52 - 22
src/core/meta.ml

@@ -20,18 +20,49 @@ type meta_origin =
 	| Compiler
 	| UserDefined of string option
 
+type meta_infos = {
+	m_internal : bool;
+	m_doc : string;
+	m_params : string list;
+	m_platforms : Globals.platform list;
+	m_used_on : meta_usage list;
+	m_origin : meta_origin;
+	m_links : string list;
+}
+
 let register_user_meta user_metas s data =
 	Hashtbl.replace user_metas s data
 
-let get_info ?user_metas m = match (user_metas,m) with
+let get_info ?user_metas m =
+	let extract_infos (t, (doc, flags), origin) =
+			let params = ref [] and used = ref [] and pfs = ref [] and links = ref [] and internal = ref false in
+			List.iter (function
+				| HasParam s -> params := s :: !params
+				| Platforms fl -> pfs := fl @ !pfs
+				| UsedOn ul -> used := ul @ !used
+				| UsedInternally -> internal := true
+				| Link url -> links := url :: !links
+			) flags;
+			(t,{
+				m_internal = !internal;
+				m_doc = doc;
+				m_params = !params;
+				m_platforms = !pfs;
+				m_used_on = !used;
+				m_origin = origin;
+				m_links = !links;
+			})
+	in
+
+	extract_infos (match (user_metas,m) with
 	| (Some(user_metas), Custom(s)) when (Hashtbl.mem user_metas s) ->
 		let infos = Hashtbl.find user_metas s in
 		(s, (infos.doc, infos.flags), (UserDefined infos.source))
 	| _ ->
 		let meta,infos = MetaList.get_info m in
-		(meta, infos, Compiler)
+		(meta, infos, Compiler))
 
-let to_string m = match (get_info m) with (s,_,_) -> s
+let to_string m = match (get_info m) with (s,_) -> s
 
 let hmeta =
 	let h = Hashtbl.create 0 in
@@ -53,30 +84,19 @@ let from_string s =
 	| '$' -> Dollar (String.sub s 1 (String.length s - 1))
 	| _ -> Custom s
 
-let get_documentation user_metas d =
-	let t, (doc,flags), origin = get_info ~user_metas:user_metas d in
-	if not (List.mem UsedInternally flags) then begin
-		let params = ref [] and used = ref [] and pfs = ref [] in
-		List.iter (function
-			| HasParam s -> params := s :: !params
-			| Platforms fl -> pfs := fl @ !pfs
-			| UsedOn ul -> used := ul @ !used
-			| UsedInternally -> die "" __LOC__
-			| Link _ -> ()
-		) flags;
-		let params = (match List.rev !params with
+let get_documentation user_metas m =
+	let t, data = get_info ~user_metas:user_metas m in
+	if data.m_internal then None else
+		let params = (match List.rev data.m_params with
 			| [] -> ""
 			| l -> "(<" ^ String.concat ">, <" l ^ ">) "
 		) in
-		let pfs = platform_list_help (List.rev !pfs) in
-		let origin = match origin with
+		let pfs = platform_list_help (List.rev data.m_platforms) in
+		let origin = match data.m_origin with
 			| UserDefined Some s -> " (from " ^ s ^ ")"
 			| Compiler | UserDefined None -> ""
 		in
-		let str = "@" ^ t in
-		Some (str,params ^ doc ^ pfs ^ origin)
-	end else
-		None
+		Some ("@" ^ t, params ^ data.m_doc ^ pfs ^ origin)
 
 let get_documentation_list user_metas =
 	let m = ref 0 in
@@ -93,6 +113,16 @@ let get_documentation_list user_metas =
 	let all = List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) (loop 0) in
 	all,!m
 
+let get_meta_list user_metas =
+	let rec loop i acc =
+		let d = Obj.magic i in
+		if d <> Last then (get_info ~user_metas d) :: loop (i + 1) acc
+		else acc
+	in
+
+	let all = loop 0 (Hashtbl.fold (fun str _ acc -> (get_info ~user_metas (Custom str)) :: acc) user_metas []) in
+	List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) all
+
 let get_all user_metas =
 	let rec loop i acc =
 		let d = Obj.magic i in
@@ -108,7 +138,7 @@ let get_user_documentation_list user_metas =
 	let user_meta_list = (Hashtbl.fold (fun meta _ acc ->
 		begin match get_documentation user_metas (Custom meta) with
 			| None -> acc
-			| Some (str, desc) ->
+			| Some (str,desc) ->
 				if String.length str > !m then m := String.length str;
 				(str,desc) :: acc
 		end

+ 6 - 6
src/core/tOther.ml

@@ -5,11 +5,11 @@ open TFunctions
 open TPrinting
 
 module TExprToExpr = struct
-	let tpath p mp pl =
-		if snd mp = snd p then
-			CTPath (mk_type_path ~params:pl p)
+	let tpath path module_path params =
+		if snd module_path = snd path then
+			make_ptp_ct_null (mk_type_path ~params path)
 		else
-			CTPath (mk_type_path ~params:pl ~sub:(snd p) mp)
+			make_ptp_ct_null (mk_type_path ~params ~sub:(snd path) module_path)
 
 	let rec convert_type = function
 		| TMono r ->
@@ -20,7 +20,7 @@ module TExprToExpr = struct
 		| TEnum ({e_private = true; e_path=_,name},tl)
 		| TType ({t_private = true; t_path=_,name},tl)
 		| TAbstract ({a_private = true; a_path=_,name},tl) ->
-			CTPath (mk_type_path ~params:(List.map tparam tl) ([],name))
+			make_ptp_ct_null (mk_type_path ~params:(List.map tparam tl) ([],name))
 		| TEnum (e,pl) ->
 			tpath e.e_path e.e_module.m_path (List.map tparam pl)
 		| TInst({cl_kind = KExpr e} as c,pl) ->
@@ -133,7 +133,7 @@ module TExprToExpr = struct
 		| TObjectDecl fl -> EObjectDecl (List.map (fun (k,e) -> k, convert_expr e) fl)
 		| TArrayDecl el -> EArrayDecl (List.map convert_expr el)
 		| TCall (e,el) -> ECall (convert_expr e,List.map convert_expr el)
-		| TNew (c,pl,el) -> ENew ((match (try convert_type (TInst (c,pl)) with Exit -> convert_type (TInst (c,[]))) with CTPath p -> p,null_pos | _ -> die "" __LOC__),List.map convert_expr el)
+		| TNew (c,pl,el) -> ENew ((match (try convert_type (TInst (c,pl)) with Exit -> convert_type (TInst (c,[]))) with CTPath ptp -> ptp| _ -> die "" __LOC__),List.map convert_expr el)
 		| TUnop (op,p,e) -> EUnop (op,p,convert_expr e)
 		| TFunction f ->
 			let arg (v,c) = (v.v_name,v.v_pos), false, v.v_meta, mk_type_hint v.v_type null_pos, (match c with None -> None | Some c -> Some (convert_expr c)) in

+ 2 - 2
src/core/tPrinting.ml

@@ -645,8 +645,8 @@ module Printer = struct
 		| HInterface -> "HInterface"
 		| HExtern -> "HExtern"
 		| HPrivate -> "HPrivate"
-		| HExtends tp -> "HExtends " ^ (s_type_path (fst tp))
-		| HImplements tp -> "HImplements " ^ (s_type_path (fst tp))
+		| HExtends ptp -> "HExtends " ^ (s_type_path ptp.path)
+		| HImplements ptp -> "HImplements " ^ (s_type_path ptp.path)
 		| HFinal -> "HFinal"
 		| HAbstract -> "HAbstract"
 

+ 3 - 2
src/core/tType.ml

@@ -467,11 +467,12 @@ let flag_tclass_field_names = [
 type flag_tvar =
 	| VCaptured
 	| VFinal
-	| VUsed (* used by the analyzer *)
+	| VAnalyzed
 	| VAssigned
 	| VCaught
 	| VStatic
+	| VUsedByTyper (* Set if the typer looked up this variable *)
 
 let flag_tvar_names = [
-	"VCaptured";"VFinal";"VUsed";"VAssigned";"VCaught";"VStatic"
+	"VCaptured";"VFinal";"VAnalyzed";"VAssigned";"VCaught";"VStatic";"VUsedByTyper"
 ]

+ 1 - 1
src/dune

@@ -20,7 +20,7 @@
 		extc extproc extlib_leftovers mbedtls neko objsize pcre2 camlp-streams swflib ttflib ziplib
 		json
 		unix ipaddr str bigarray threads dynlink
-		xml-light extlib sha
+		xml-light extlib sha terminal_size
 		luv
 	)
 	(modules (:standard \ haxe))

+ 6 - 4
src/filters/exceptions.ml

@@ -525,11 +525,13 @@ let filter tctx =
 	| Php | Js | Jvm | Python | Lua | Eval | Neko | Flash | Hl | Cpp ->
 		let config = tctx.com.config.pf_exceptions in
 		let tp (pack,name) =
-			match List.rev pack with
+			let tp = match List.rev pack with
 			| module_name :: pack_rev when not (Ast.is_lower_ident module_name) ->
-				(mk_type_path ~sub:name (List.rev pack_rev,module_name), null_pos)
+				mk_type_path ~sub:name (List.rev pack_rev,module_name)
 			| _ ->
-				(mk_type_path (pack,name), null_pos)
+				mk_type_path (pack,name)
+			in
+			make_ptp tp null_pos
 		in
 		let wildcard_catch_type =
 			let t = Typeload.load_instance tctx (tp config.ec_wildcard_catch) ParamSpawnMonos in
@@ -664,7 +666,7 @@ let insert_save_stacks tctx =
 	Adds `this.__shiftStack()` calls to constructors of classes which extend `haxe.Exception`
 *)
 let patch_constructors tctx =
-	let tp = (mk_type_path haxe_exception_type_path, null_pos) in
+	let tp = make_ptp (mk_type_path haxe_exception_type_path) null_pos in
 	match Typeload.load_instance tctx tp ParamSpawnMonos with
 	(* Add only if `__shiftStack` method exists *)
 	| TInst(cls,_) when PMap.mem "__shiftStack" cls.cl_fields ->

+ 2 - 1
src/filters/filters.ml

@@ -859,7 +859,7 @@ let save_class_state com t =
 			a.a_meta <- List.filter (fun (m,_,_) -> m <> Meta.ValueUsed) a.a_meta
 		)
 
-let run tctx main =
+let run tctx main before_destruction =
 	let com = tctx.com in
 	let detail_times = (try int_of_string (Common.defined_value_safe com ~default:"0" Define.FilterTimes) with _ -> 0) in
 	let new_types = List.filter (fun t ->
@@ -954,4 +954,5 @@ let run tctx main =
 	with_timer detail_times "callbacks" None (fun () ->
 		com.callbacks#run com.error_ext com.callbacks#get_after_save;
 	);
+	before_destruction();
 	destruction tctx detail_times main locals

+ 75 - 52
src/generators/genjvm.ml

@@ -141,48 +141,54 @@ end
 
 open NativeSignatures
 
+let jsignature_of_path path = match path with
+	| [],"Bool" -> TBool
+	| ["java"],"Int8" -> TByte
+	| ["java"],"Int16" -> TShort
+	| [],"Int" -> TInt
+	| ["haxe"],"Int32" -> TInt
+	| ["haxe"],"Int64" -> TLong
+	| ["java"],"Int64" -> TLong
+	| ["java"],"Char16" -> TChar
+	| [],"Single" -> TFloat
+	| [],"Float" -> TDouble
+	| [],"Dynamic" -> object_sig
+	| _ -> raise Exit
+
 let rec jsignature_of_type gctx stack t =
 	if List.exists (fast_eq t) stack then object_sig else
 	let jsignature_of_type = jsignature_of_type gctx (t :: stack) in
 	let jtype_argument_of_type t = jtype_argument_of_type gctx stack t in
 	match t with
 	| TAbstract(a,tl) ->
-		begin match a.a_path with
-			| [],"Bool" -> TBool
-			| ["java"],"Int8" -> TByte
-			| ["java"],"Int16" -> TShort
-			| [],"Int" -> TInt
-			| ["haxe"],"Int32" -> TInt
-			| ["haxe"],"Int64" -> TLong
-			| ["java"],"Int64" -> TLong
-			| ["java"],"Char16" -> TChar
-			| [],"Single" -> TFloat
-			| [],"Float" -> TDouble
-			| [],"Void" -> void_sig
-			| [],"Null" ->
-				begin match tl with
-				| [t] -> get_boxed_type (jsignature_of_type t)
-				| _ -> die "" __LOC__
-				end
-			| ["haxe";"ds"],"Vector" ->
-				begin match tl with
-				| [t] -> TArray(jsignature_of_type t,None)
-				| _ -> die "" __LOC__
-				end
-			| [],"Dynamic" ->
-				object_sig
-			| [],("Class" | "Enum") ->
-				begin match tl with
-				| [t] -> TObject(java_class_path,[TType(WNone,jsignature_of_type t)])
-				| _ -> java_class_sig
-				end
-			| [],"EnumValue" ->
-				java_enum_sig object_sig
-			| _ ->
-				if Meta.has Meta.CoreType a.a_meta then
-					TObject(a.a_path,List.map jtype_argument_of_type tl)
-				else
-					jsignature_of_type (Abstract.get_underlying_type a tl)
+		begin try
+			jsignature_of_path a.a_path
+		with Exit ->
+			begin match a.a_path with
+				| [],"Void" -> void_sig
+				| [],"Null" ->
+					begin match tl with
+					| [t] -> get_boxed_type (jsignature_of_type t)
+					| _ -> die "" __LOC__
+					end
+				| ["haxe";"ds"],"Vector" ->
+					begin match tl with
+					| [t] -> TArray(jsignature_of_type t,None)
+					| _ -> die "" __LOC__
+					end
+				| [],("Class" | "Enum") ->
+					begin match tl with
+					| [t] -> TObject(java_class_path,[TType(WNone,jsignature_of_type t)])
+					| _ -> java_class_sig
+					end
+				| [],"EnumValue" ->
+					java_enum_sig object_sig
+				| _ ->
+					if Meta.has Meta.CoreType a.a_meta then
+						TObject(a.a_path,List.map jtype_argument_of_type tl)
+					else
+						jsignature_of_type (Abstract.get_underlying_type a tl)
+			end
 		end
 	| TDynamic _ -> object_sig
 	| TMono r ->
@@ -259,6 +265,19 @@ module AnnotationHandler = struct
 			| EConst (Ident "true") -> ABool true
 			| EConst (Ident "false") -> ABool false
 			| EArrayDecl el -> AArray (List.map parse_value el)
+			| EField(e1,"class",_) ->
+				let path = parse_path e1 in
+				let jsig =  try
+					Some (jsignature_of_path path)
+				with Exit -> match path with
+					| ([],"Void") ->
+						None
+					| ([],name) ->
+						Some (TObject((["haxe";"root"],name),[]))
+					| _ ->
+						Some (TObject(path,[]))
+				in
+				AClass jsig
 			| EField(e1,s,_) ->
 				let path = parse_path e1 in
 				AEnum(object_path_sig path,s)
@@ -287,20 +306,25 @@ module AnnotationHandler = struct
 				Error.raise_typing_error "Call expression expected" (pos e)
 		in
 		ExtList.List.filter_map (fun (m,el,_) -> match m,el with
-			| Meta.Meta,[e] ->
-				let path,annotation = parse_expr e in
+			| Meta.Meta,(e1 :: el) ->
+				let path,annotation = parse_expr e1 in
 				let path = match path with
 					| [],name -> ["haxe";"root"],name
 					| _ -> path
 				in
-				Some(path,annotation)
+				(* If there's no value this was an untyped @:meta. Let's assume RUNTIME retention. *)
+				let is_runtime_visible = match el with
+					| [(EConst (String("CLASS",_)),_)] -> false
+					| _ -> true
+				in
+				Some(path,annotation,is_runtime_visible)
 			| _ ->
 				None
 		) meta
 
 	let generate_annotations builder meta =
-		List.iter (fun (path,annotation) ->
-			builder#add_annotation path annotation
+		List.iter (fun (path,annotation,is_runtime_visible) ->
+			builder#add_annotation path annotation is_runtime_visible
 		) (convert_annotations meta)
 end
 
@@ -2286,8 +2310,11 @@ class tclass_to_jvm gctx c = object(self)
 		if is_annotation then begin
 			jc#add_access_flag 0x2000;
 			jc#add_interface (["java";"lang";"annotation"],"Annotation") [];
-			(* TODO: this should be done via Haxe metadata instead of hardcoding it here *)
-			jc#add_annotation retention_path ["value",(AEnum(retention_policy_sig,"RUNTIME"))];
+			let value = match get_meta_string c.cl_meta Meta.Annotation with
+				| None -> "CLASS"
+				| Some value -> value
+			in
+			jc#add_annotation retention_path ["value",(AEnum(retention_policy_sig,value))] true;
 		end;
 		if (has_class_flag c CAbstract) then jc#add_access_flag 0x0400; (* abstract *)
 		if Meta.has Meta.JvmSynthetic c.cl_meta then jc#add_access_flag 0x1000 (* synthetic *)
@@ -2436,12 +2463,8 @@ class tclass_to_jvm gctx c = object(self)
 		let handler = new texpr_to_jvm gctx field_info jc jm tr in
 		List.iter (fun (v,_) ->
 			let slot,_,_ = handler#add_local v VarArgument in
-			let annot = AnnotationHandler.convert_annotations v.v_meta in
-			match annot with
-			| [] ->
-				()
-			| _ ->
-				jm#add_argument_annotation slot annot;
+			let l = AnnotationHandler.convert_annotations v.v_meta in
+			List.iter (fun (path,annotation,is_runtime_visible) -> jm#add_argument_annotation slot path annotation is_runtime_visible) l;
 		) args;
 		jm#finalize_arguments;
 		begin match mtype with
@@ -2634,7 +2657,7 @@ class tclass_to_jvm gctx c = object(self)
 
 	method generate_annotations =
 		AnnotationHandler.generate_annotations (jc :> JvmBuilder.base_builder) c.cl_meta;
-		jc#add_annotation (["haxe";"jvm";"annotation"],"ClassReflectionInformation") (["hasSuperClass",(ABool (c.cl_super <> None))])
+		jc#add_annotation (["haxe";"jvm";"annotation"],"ClassReflectionInformation") (["hasSuperClass",(ABool (c.cl_super <> None))]) true
 
 	method private do_generate =
 		self#set_access_flags;
@@ -2758,7 +2781,7 @@ let generate_enum gctx en =
 				jm_ctor#add_argument_and_field n jsig [FdPublic;FdFinal]
 			) args;
 			jm_ctor#return;
-			jc_ctor#add_annotation (["haxe";"jvm";"annotation"],"EnumValueReflectionInformation") (["argumentNames",AArray (List.map (fun (name,_) -> AString name) args)]);
+			jc_ctor#add_annotation (["haxe";"jvm";"annotation"],"EnumValueReflectionInformation") (["argumentNames",AArray (List.map (fun (name,_) -> AString name) args)]) true;
 			if args <> [] then begin
 				let jm_params = jc_ctor#spawn_method "_hx_getParameters" (method_sig [] (Some (array_sig object_sig))) [MPublic;MSynthetic] in
 				let jm_equals,compare_field = generate_enum_equals gctx jc_ctor in
@@ -2825,7 +2848,7 @@ let generate_enum gctx en =
 		jm_clinit#return;
 	end;
 	AnnotationHandler.generate_annotations (jc_enum :> JvmBuilder.base_builder) en.e_meta;
-	jc_enum#add_annotation (["haxe";"jvm";"annotation"],"EnumReflectionInformation") (["constructorNames",AArray names]);
+	jc_enum#add_annotation (["haxe";"jvm";"annotation"],"EnumReflectionInformation") (["constructorNames",AArray names]) true;
 	write_class gctx en.e_path (jc_enum#export_class gctx.default_export_config)
 
 let generate_module_type ctx mt =

+ 1 - 1
src/generators/genpy.ml

@@ -1494,7 +1494,7 @@ module Printer = struct
 					Codegen.interpolate_code pctx.pc_com code tl (Buffer.add_string buf) (fun e -> Buffer.add_string buf (print_expr pctx e)) ecode.epos
 				in
 				let old = pctx.pc_com.error_ext in
-				pctx.pc_com.error_ext <- (fun err -> raise (Abort err));
+				pctx.pc_com.error_ext <- (fun err -> raise (Error.Fatal_error err));
 				Std.finally (fun() -> pctx.pc_com.error_ext <- old) interpolate ();
 				Buffer.contents buf
 			| ("python_Syntax._pythonCode"), [e] ->

+ 2 - 2
src/generators/hl2c.ml

@@ -98,13 +98,13 @@ let keywords =
 	"typeof";
 	(* C11 *)
 	"_Alignas";"_Alignof";"_Atomic";"_Bool";"_Complex";"_Generic";"_Imaginary";"_Noreturn";"_Static_assert";"_Thread_local";"_Pragma";
-	"inline";"restrict"
+	"inline";"restrict";"_restrict"
 	] in
 	let h = Hashtbl.create 0 in
 	List.iter (fun i -> Hashtbl.add h i ()) c_kwds;
 	h
 
-let ident i = if (Hashtbl.mem keywords i) || (ExtString.String.starts_with "__" i) then "_hx_" ^ i else i
+let ident i = if (Hashtbl.mem keywords i) || (ExtString.String.starts_with i "__") then "_hx_" ^ i else i
 
 let s_comp = function
 	| CLt -> "<"

+ 9 - 0
src/generators/jvm/jvmAttribute.ml

@@ -85,7 +85,9 @@ type j_attribute =
 	| AttributeInnerClasses of jvm_inner_class array
 	| AttributeEnclosingMethod of jvm_constant_pool_index * jvm_constant_pool_index
 	| AttributeRuntimeVisibleAnnotations of j_annotation array
+	| AttributeRuntimeInvisibleAnnotations of j_annotation array
 	| AttributeRuntimeVisibleParameterAnnotations of j_annotation array array
+	| AttributeRuntimeInvisibleParameterAnnotations of j_annotation array array
 	| AttributeBootstrapMethods of j_bootstrap_method array
 
 let write_verification_type ch = function
@@ -236,10 +238,17 @@ let write_attribute pool jvma =
 	| AttributeRuntimeVisibleAnnotations al ->
 		write_array16 ch write_annotation al;
 		"RuntimeVisibleAnnotations"
+	| AttributeRuntimeInvisibleAnnotations al ->
+		write_array16 ch write_annotation al;
+		"RuntimeInvisibleAnnotations"
 	| AttributeRuntimeVisibleParameterAnnotations al ->
 		write_byte ch (Array.length al);
 		Array.iter (write_array16 ch write_annotation) al;
 		"RuntimeVisibleParameterAnnotations"
+	| AttributeRuntimeInvisibleParameterAnnotations al ->
+		write_byte ch (Array.length al);
+		Array.iter (write_array16 ch write_annotation) al;
+		"RuntimeInvisibleParameterAnnotations"
 	| AttributeBootstrapMethods a ->
 		write_array16 ch (fun _ bm ->
 			write_ui16 ch bm.bm_method_ref;

+ 15 - 8
src/generators/jvm/jvmBuilder.ml

@@ -29,6 +29,7 @@ type annotation_kind =
 	| AEnum of jsignature * string
 	| AArray of annotation_kind list
 	| AAnnotation of jsignature * annotation
+	| AClass of jsignature option
 
 and annotation = (string * annotation_kind) list
 
@@ -58,7 +59,8 @@ let convert_annotations pool annotations =
 				| AAnnotation (jsig, a) ->
 					let ann = process_annotation (jsig, a) in
 					'@',ValAnnotation(ann)
-
+				| AClass jsig ->
+					'c',ValClass(pool#add_string (Option.map_default (generate_signature false) "V" jsig))
 			in
 			offset,loop ak
 		) l in
@@ -67,13 +69,13 @@ let convert_annotations pool annotations =
 			ann_elements = Array.of_list l;
 		}
 	in
-	let a = Array.map process_annotation annotations in
-	a
+	Array.map process_annotation annotations
 
 class base_builder = object(self)
 	val mutable access_flags = 0
 	val attributes = DynArray.create ()
-	val annotations = DynArray.create ()
+	val runtime_visible_annotations = DynArray.create ()
+	val runtime_invisible_annotations = DynArray.create ()
 	val mutable was_exported = false
 
 	method add_access_flag i =
@@ -82,14 +84,19 @@ class base_builder = object(self)
 	method add_attribute (a : j_attribute) =
 		DynArray.add attributes a
 
-	method add_annotation (path : jpath) (a : annotation) =
-		DynArray.add annotations ((TObject(path,[])),a)
+	method add_annotation (path : jpath) (a : annotation) (is_runtime_visible : bool) =
+		DynArray.add (if is_runtime_visible then runtime_visible_annotations else runtime_invisible_annotations) ((TObject(path,[])),a)
 
 	method private commit_annotations pool =
-		if DynArray.length annotations > 0 then begin
+		if DynArray.length runtime_visible_annotations > 0 then begin
 			let open JvmAttribute in
-			let a = convert_annotations pool (DynArray.to_array annotations) in
+			let a = convert_annotations pool (DynArray.to_array runtime_visible_annotations) in
 			self#add_attribute (AttributeRuntimeVisibleAnnotations a)
+		end;
+		if DynArray.length runtime_invisible_annotations > 0 then begin
+			let open JvmAttribute in
+			let a = convert_annotations pool (DynArray.to_array runtime_invisible_annotations) in
+			self#add_attribute (AttributeRuntimeInvisibleAnnotations a)
 		end
 
 	method export_attributes (pool : JvmConstantPool.constant_pool) =

+ 27 - 16
src/generators/jvm/jvmMethod.ml

@@ -155,7 +155,8 @@ class builder jc name jsig = object(self)
 	val mutable stack_frames = []
 	val mutable exceptions = []
 	val mutable argument_locals = []
-	val mutable argument_annotations = Hashtbl.create 0
+	val mutable runtime_visible_argument_annotations = Hashtbl.create 0
+	val mutable runtime_invisible_argument_annotations = Hashtbl.create 0
 	val mutable thrown_exceptions = Hashtbl.create 0
 	val mutable regex_count = 0
 
@@ -1011,9 +1012,15 @@ class builder jc name jsig = object(self)
 	method replace_top jsig =
 		code#get_stack#replace jsig
 
-	method add_argument_annotation (slot : int) (a : (path * annotation) list) =
-		let a = Array.of_list (List.map (fun (path,annot) -> TObject(path,[]),annot) a) in
-		Hashtbl.add argument_annotations slot a
+	method add_argument_annotation (slot : int) (path : jpath) (a : annotation) (is_runtime_visible : bool) =
+		let h = if is_runtime_visible then runtime_visible_argument_annotations else runtime_invisible_argument_annotations in
+		try
+			let d = Hashtbl.find h slot in
+			DynArray.add d (TObject(path,[]),a)
+		with Not_found ->
+			let d = DynArray.create () in
+			DynArray.add d (TObject(path,[]),a);
+			Hashtbl.add h slot d
 
 	(** This function has to be called once all arguments are declared. *)
 	method finalize_arguments =
@@ -1137,18 +1144,22 @@ class builder jc name jsig = object(self)
 		end;
 		if Hashtbl.length thrown_exceptions > 0 then
 			self#add_attribute (AttributeExceptions (Array.of_list (Hashtbl.fold (fun k _ c -> k :: c) thrown_exceptions [])));
-		if Hashtbl.length argument_annotations > 0 then begin
-			let l = List.length argument_locals in
-			let offset = if self#has_method_flag MStatic then 0 else 1 in
-			let a = Array.init (l - offset) (fun i ->
-				try
-					let annot = Hashtbl.find argument_annotations (i + offset) in
-					convert_annotations jc#get_pool annot
-				with Not_found ->
-					[||]
-			) in
-			DynArray.add attributes (AttributeRuntimeVisibleParameterAnnotations a)
-		end;
+		let collect_annotations h f =
+			if Hashtbl.length h > 0 then begin
+				let l = List.length argument_locals in
+				let offset = if self#has_method_flag MStatic then 0 else 1 in
+				let a = Array.init (l - offset) (fun i ->
+					try
+						let d = Hashtbl.find h (i + offset) in
+						convert_annotations jc#get_pool (DynArray.to_array d)
+					with Not_found ->
+						[||]
+				) in
+				f a
+			end;
+		in
+		collect_annotations runtime_visible_argument_annotations (fun a -> DynArray.add attributes (AttributeRuntimeVisibleParameterAnnotations a));
+		collect_annotations runtime_invisible_argument_annotations (fun a -> DynArray.add attributes (AttributeRuntimeInvisibleParameterAnnotations a));
 		let attributes = self#export_attributes jc#get_pool in
 		let offset_name = jc#get_pool#add_string name in
 		let offset_desc = jc#get_pool#add_string descriptor in

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

@@ -351,12 +351,13 @@ let rec expr_to_value ctx env e =
 			if flag = DoWhile then ignore(loop e2);
 			loop2();
 			vnull
-		| ENew((tp,_),el) ->
+		| ENew(ptp,el) ->
 			let rec loop2 v sl = match sl with
 				| [] -> v
 				| s :: sl ->
 					loop2 (EvalField.field v (hash s)) sl
 			in
+			let tp = ptp.path in
 			let v1 = loop2 ctx.toplevel tp.tpackage in
 			let v1 = loop2 v1 [match tp.tsub with None -> tp.tname | Some s -> s] in
 			let vl = List.map loop el in

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

@@ -376,19 +376,8 @@ let init ctx = ()
 
 let setup get_api =
 	let api = get_api (fun() -> (get_ctx()).curapi.get_com()) (fun() -> (get_ctx()).curapi) in
-	List.iter (fun (n,v) -> match v with
-		| VFunction(f,b) ->
-			let f vl = try
-				f vl
-			with
-			| Sys_error msg | Failure msg | Invalid_argument msg ->
-				exc_string msg
-			| MacroApi.Invalid_expr ->
-				exc_string "Invalid expression"
-			in
-			let v = VFunction (f,b) in
-			Hashtbl.replace GlobalState.macro_lib n v
-		| _ -> die "" __LOC__
+	List.iter (fun (n,v) ->
+		Hashtbl.replace GlobalState.macro_lib n v
 	) api;
 	Globals.macro_platform := Globals.Eval
 

+ 39 - 16
src/macro/macroApi.ml

@@ -70,6 +70,7 @@ type 'value compiler_api = {
 	display_error : ?depth:int -> (string -> pos -> unit);
 	with_imports : 'a . import list -> placed_name list list -> (unit -> 'a) -> 'a;
 	with_options : 'a . compiler_options -> (unit -> 'a) -> 'a;
+	exc_string : 'a . string -> 'a;
 }
 
 
@@ -290,13 +291,19 @@ let encode_path (p,n) =
 	]
 
 (* Ast.placed_type_path *)
-let rec encode_ast_path (t,p) =
+let rec encode_ast_path ptp =
+	let t = ptp.path in
 	let fields = [
 		"pack", encode_array (List.map encode_string t.tpackage);
 		"name", encode_string t.tname;
 		"params", encode_array (List.map encode_tparam t.tparams);
-		"pos", encode_pos p;
+		"pos", encode_pos ptp.pos_full;
 	] in
+	let fields = if ptp.pos_full <> ptp.pos_path then
+		("posPath", encode_pos ptp.pos_path) :: fields
+	else
+		fields
+	in
 	encode_obj (match t.tsub with
 		| None -> fields
 		| Some s -> ("sub", encode_string s) :: fields)
@@ -351,8 +358,8 @@ and encode_field (f:class_field) =
 
 and encode_ctype t =
 	let tag, pl = match fst t with
-	| CTPath p ->
-		0, [encode_ast_path (p,Globals.null_pos)]
+	| CTPath ptp ->
+		0, [encode_ast_path ptp]
 	| CTFunction (pl,r) ->
 		1, [encode_array (List.map encode_ctype pl);encode_ctype r]
 	| CTAnonymous fl ->
@@ -743,12 +750,15 @@ let decode_opt_array f v =
 
 (* Ast.placed_type_path *)
 let rec decode_ast_path t =
-	let p = field t "pos" in
 	let pack = List.map decode_string (decode_array (field t "pack"))
 	and name = decode_string (field t "name")
 	and params = decode_opt_array decode_tparam (field t "params")
 	and sub = opt decode_string (field t "sub") in
-	mk_type_path ~params ?sub (pack,name), if p = vnull then Globals.null_pos else decode_pos p
+	let p_full = field t "pos" in
+	let p_full = if p_full = vnull then Globals.null_pos else decode_pos p_full in
+	let p_path = field t "posPath" in
+	let p_path = if p_path = vnull then Globals.null_pos else decode_pos p_path in
+	make_ptp (mk_type_path ~params ?sub (pack,name)) ~p_path p_full
 
 and decode_tparam v =
 	match decode_enum v with
@@ -841,7 +851,7 @@ and decode_ctype t =
 	let (i,args),p = decode_enum_with_pos t in
 	(match i,args with
 	| 0, [p] ->
-		CTPath (fst (decode_ast_path p))
+		CTPath (decode_ast_path p)
 	| 1, [a;r] ->
 		CTFunction (List.map decode_ctype (decode_array a), decode_ctype r)
 	| 2, [fl] ->
@@ -1003,12 +1013,9 @@ let encode_meta m set =
 			encode_meta_content (!meta)
 		);
 		"add", vfun3 (fun k vl p ->
-			(try
-				let el = List.map decode_expr (decode_array vl) in
-				meta := (Meta.from_string (decode_string k), el, decode_pos p) :: !meta;
-				set (!meta)
-			with Invalid_expr ->
-				failwith "Invalid expression");
+			let el = List.map decode_expr (decode_array vl) in
+			meta := (Meta.from_string (decode_string k), el, decode_pos p) :: !meta;
+			set (!meta);
 			vnull
 		);
 		"extract", vfun1 (fun k ->
@@ -1789,6 +1796,19 @@ let rec make_const e =
 **)
 
 let macro_api ccom get_api =
+	let decode_type v =
+		try decode_type v
+		with Invalid_expr -> (get_api()).exc_string "Invalid expression"
+	in
+	let decode_expr v =
+		try decode_expr v
+		with Invalid_expr -> (get_api()).exc_string "Invalid expression"
+	in
+	let decode_texpr v =
+		try decode_texpr v
+		with Invalid_expr -> (get_api()).exc_string "Invalid expression"
+	in
+	let failwith s = (get_api()).exc_string s in
 	[
 		"contains_display_position", vfun1 (fun p ->
 			let p = decode_pos p in
@@ -1919,14 +1939,17 @@ let macro_api ccom get_api =
 		);
 		"do_parse", vfun3 (fun s p b ->
 			let s = decode_string s in
-			if s = "" then raise Invalid_expr;
+			if s = "" then (get_api()).exc_string "Invalid expression";
 			encode_expr ((get_api()).parse_string s (decode_pos p) (decode_bool b))
 		);
 		"make_expr", vfun2 (fun v p ->
 			encode_expr (value_to_expr v (decode_pos p))
 		);
 		"signature", vfun1 (fun v ->
-			encode_string (Digest.to_hex (value_signature v))
+			try
+				encode_string (Digest.to_hex (value_signature v))
+			with Invalid_argument msg ->
+				(get_api()).exc_string msg
 		);
 		"to_complex_type", vfun1 (fun v ->
 			try	encode_ctype (TExprToExpr.convert_type' (decode_type v))
@@ -2173,7 +2196,7 @@ let macro_api ccom get_api =
 			encode_type t
 		);
 		"define_module", vfun4 (fun path vl ui ul ->
-			(get_api()).define_module (decode_string path) (decode_array vl) (List.map decode_import (decode_array ui)) (List.map fst (List.map decode_ast_path (decode_array ul)));
+			(get_api()).define_module (decode_string path) (decode_array vl) (List.map decode_import (decode_array ui)) (List.map (fun ptp -> ptp.path) (List.map decode_ast_path (decode_array ul)));
 			vnull
 		);
 		"add_class_path", vfun1 (fun cp ->

+ 4 - 4
src/optimization/analyzer.ml

@@ -661,14 +661,14 @@ module LocalDce = struct
 
 	let apply ctx =
 		let is_used v =
-			has_var_flag v VUsed
+			has_var_flag v VAnalyzed
 		in
 		let keep v =
 			is_used v || ((match v.v_kind with VUser _ | VInlined -> true | _ -> false) && not ctx.config.local_dce) || ExtType.has_reference_semantics v.v_type || has_var_flag v VCaptured || Meta.has Meta.This v.v_meta
 		in
 		let rec use v =
 			if not (is_used v) then begin
-				add_var_flag v VUsed;
+				add_var_flag v VAnalyzed;
 				(try expr (get_var_value ctx.graph v) with Not_found -> ());
 				begin match Ssa.get_reaching_def ctx.graph v with
 					| None ->
@@ -676,7 +676,7 @@ module LocalDce = struct
 						   reaching definition (issue #10972). Simply marking it as being used should be sufficient. *)
 						let v' = get_var_origin ctx.graph v in
 						if not (is_used v') then
-							add_var_flag v' VUsed
+							add_var_flag v' VAnalyzed
 					| Some v ->
 						use v;
 				end
@@ -1098,7 +1098,7 @@ module Run = struct
 			let e = try
 				run_on_expr actx e
 			with
-			| Error.Error _ | Abort _ | Sys.Break as exc ->
+			| Error.Error _ | Sys.Break as exc ->
 				maybe_debug();
 				raise exc
 			| exc ->

+ 2 - 1
src/optimization/analyzerTexpr.ml

@@ -62,6 +62,7 @@ let map_values ?(allow_control_flow=true) f e =
 				let e = {e with eexpr = TBlock (List.rev (e1 :: el))} in
 				{e with eexpr = TMeta((Meta.MergeBlock,[],e.epos),e)}
 			| [] ->
+				if not complex then raise Exit;
 				f e
 			end
 		| TTry(e1,catches) ->
@@ -730,7 +731,7 @@ module Fusion = struct
 			(* no-side-effect *)
 			| {eexpr = TFunction _ | TConst _ | TTypeExpr _} :: el ->
 				loop acc el
-			| {eexpr = TMeta((Meta.Pure,_,_),_)} :: el ->
+			| {eexpr = TMeta((Meta.Pure,_,_) as meta,_)} :: el when PurityState.get_purity_from_meta [meta] = Pure ->
 				loop acc el
 			| {eexpr = TCall({eexpr = TField(e1,fa)},el1)} :: el2 when PurityState.is_pure_field_access fa && config.local_dce ->
 				loop acc (e1 :: el1 @ el2)

+ 31 - 16
src/optimization/analyzerTexprTransformer.ml

@@ -118,11 +118,15 @@ let rec func ctx bb tf t p =
 			let bb,e2 = value bb e2 in
 			bb,{e with eexpr = TBinop(op,e1,e2)}
 		| TBinop(op,e1,e2) ->
-			let bb,e1,e2 = match ordered_value_list bb [e1;e2] with
-				| bb,[e1;e2] -> bb,e1,e2
-				| _ -> die "" __LOC__
-			in
-			bb,{e with eexpr = TBinop(op,e1,e2)}
+			begin match ordered_value_list bb [e1;e2] with
+				| bb,[e1;e2] ->
+					bb,{e with eexpr = TBinop(op,e1,e2)}
+				| bb,[e] ->
+					assert(bb == g.g_unreachable);
+					bb,e
+				| _ ->
+					die "" __LOC__
+				end
 		| TUnop(op,flag,e1) ->
 			let bb,e1 = value bb e1 in
 			bb,{e with eexpr = TUnop(op,flag,e1)}
@@ -139,11 +143,16 @@ let rec func ctx bb tf t p =
 			let bb,e1 = value bb e1 in
 			bb,{e with eexpr = TField(e1,fa)}
 		| TArray(e1,e2) ->
-			let bb,e1,e2 = match ordered_value_list bb [e1;e2] with
-				| bb,[e1;e2] -> bb,e1,e2
-				| _ -> die "" __LOC__
-			in
-			bb,{e with eexpr = TArray(e1,e2)}
+			begin match ordered_value_list bb [e1;e2] with
+				| bb,[e1;e2] ->
+					bb,{e with eexpr = TArray(e1,e2)}
+
+				| bb,[e] ->
+					assert(bb == g.g_unreachable);
+					bb,e
+				| _ ->
+					die "" __LOC__
+				end
 		| TMeta(m,e1) ->
 			let bb,e1 = value bb e1 in
 			bb,{e with eexpr = TMeta(m,e1)}
@@ -369,14 +378,14 @@ let rec func ctx bb tf t p =
 			bb
 		(* branching *)
 		| TMeta((Meta.MergeBlock,_,_),{eexpr = TBlock el}) ->
-			block_el bb el
+			block_el true bb el
 		| TBlock [] when (ExtType.is_void (follow e.etype)) ->
 			bb
 		| TBlock el ->
 			let bb_sub = create_node BKSub e.etype e.epos in
 			add_cfg_edge bb bb_sub CFGGoto;
 			close_node bb;
-			let bb_sub_next = block_el bb_sub el in
+			let bb_sub_next = block_el true bb_sub el in
 			if bb_sub_next != g.g_unreachable then begin
 				let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in
 				set_syntax_edge bb (SESubBlock(bb_sub,bb_next));
@@ -619,12 +628,18 @@ let rec func ctx bb tf t p =
 			let bb = block_element bb e1 in
 			block_element bb e2
 		| TArrayDecl el ->
-			block_el bb el
+			block_el false bb el
 		| TObjectDecl fl ->
-			block_el bb (List.map snd fl)
+			block_el false bb (List.map snd fl)
 		| TFor _ | TWhile(_,_,DoWhile) ->
 			die "" __LOC__
-	and block_el bb el =
+	and block_el allow_void bb el =
+		let block_element = if allow_void then
+			block_element
+		else (fun bb e ->
+			no_void e.etype e.epos;
+			block_element bb e
+		) in
 		match !b_try_stack with
 		| [] ->
 			let rec loop bb el = match el with
@@ -656,7 +671,7 @@ let rec func ctx bb tf t p =
 			| TBlock el -> el
 			| _ -> [e]
 		in
-		block_el bb el
+		block_el true bb el
 	in
 	let bb_last = block bb_root tf.tf_expr in
 	close_node bb_last;

+ 0 - 1
src/optimization/inline.ml

@@ -576,7 +576,6 @@ class inline_state ctx ethis params cf f p = object(self)
 				mk (TBlock (DynArray.to_list el)) tret e.epos
 		in
 		let e = inline_metadata e cf.cf_meta in
-		let e = Diagnostics.secure_generated_code ctx.com e in
 		if has_params then begin
 			let mt = map_type cf.cf_type in
 			let unify_func () = unify_raise mt (TFun (tl,tret)) p in

+ 6 - 1
src/optimization/inlineConstructors.ml

@@ -625,7 +625,12 @@ let inline_constructors ctx original_e =
 				default_case e
 			end
 		| TVar(v, None) when v.v_id < 0 ->
-			(get_iv_var_decls (get_iv v.v_id)), None
+			let iv = get_iv v.v_id in
+			if iv.iv_state = IVSUnassigned then
+				(* If the variable is unassigned, leave the expression unchanged *)
+				([e], None)
+			else
+				(get_iv_var_decls (iv)), None
 		| TVar(v,Some e) when v.v_id < 0 ->
 			let el = (get_iv_var_decls (get_iv v.v_id)) in
 			let e,_ = (final_map ~unwrap_block:true e) in (e@el, None)

+ 0 - 2
src/optimization/optimizer.ml

@@ -224,8 +224,6 @@ let reduce_expr com e =
 			) l with
 			| [] -> ec
 			| l -> { e with eexpr = TBlock (List.rev (ec :: l)) })
-	| TMeta ((Meta.CompilerGenerated,_,_),ec) ->
-		{ ec with epos = e.epos }
 	| TParenthesis ec ->
 		{ ec with epos = e.epos }
 	| TTry (e,[]) ->

+ 43 - 39
src/syntax/grammar.mly

@@ -193,18 +193,18 @@ and parse_class_content doc meta flags n p1 s =
 				syntax_completion (if List.mem HInterface n then SCInterfaceRelation else SCClassRelation) None (display_position#with_pos p1)
 		in
 		match s with parser
-		| [< '(Kwd Extends,p1); t,b = parse_type_path_or_resume p1 >] ->
+		| [< '(Kwd Extends,p1); ptp,b = parse_type_path_or_resume p1 >] ->
 			check_display {p1 with pmin = p0.pmax; pmax = p1.pmin};
-			let p0 = pos t in
+			let p0 = ptp.pos_full in
 			(* If we don't have type parameters, we have to offset by one so to not complete `extends`
 				and `implements` after the identifier. *)
-			let p0 = {p0 with pmax = p0.pmax + (if (fst t).tparams = [] then 1 else 0)} in
-			loop (had_display || b) p0 ((HExtends t) :: acc)
-		| [< '(Kwd Implements,p1); t,b = parse_type_path_or_resume p1 >] ->
+			let p0 = {p0 with pmax = p0.pmax + (if ptp.path.tparams = [] then 1 else 0)} in
+			loop (had_display || b) p0 ((HExtends ptp) :: acc)
+		| [< '(Kwd Implements,p1); ptp,b = parse_type_path_or_resume p1 >] ->
 			check_display {p1 with pmin = p0.pmax; pmax = p1.pmin};
-			let p0 = pos t in
-			let p0 = {p0 with pmax = p0.pmax + (if (fst t).tparams = [] then 1 else 0)} in
-			loop (had_display || b) p0 ((HImplements t) :: acc)
+			let p0 = ptp.pos_full in
+			let p0 = {p0 with pmax = p0.pmax + (if ptp.path.tparams = [] then 1 else 0)} in
+			loop (had_display || b) p0 ((HImplements ptp) :: acc)
 		| [< '(BrOpen,p1) >] ->
 			check_display {p1 with pmin = p0.pmax; pmax = p1.pmin};
 			List.rev acc
@@ -446,7 +446,7 @@ and parse_abstract_relations s =
 		if !in_display_file && p1.pmax < (display_position#get).pmin && p2.pmin >= (display_position#get).pmax then
 			(* This means we skipped the display position between the to/from and the type-hint we parsed.
 			   Very weird case, it was probably a {} like in #7137. Let's discard it and use magic. *)
-			((CTPath magic_type_path,display_position#with_pos p2))
+			(magic_type_th (display_position#with_pos p2))
 		else
 			(ct,p2)
 	in
@@ -629,7 +629,7 @@ and parse_complex_type_at p = parser
 	| [< t = parse_complex_type >] -> t
 	| [< s >] ->
 		if would_skip_display_position p false s then
-			CTPath magic_type_path,display_position#with_pos p
+			(magic_type_th (display_position#with_pos p))
 		else
 			serror()
 
@@ -638,9 +638,8 @@ and parse_type_hint = parser
 		let f () = parse_complex_type_at p1 s in
 		check_resume_range p1 s
 			(fun p2 ->
-				let ct = CTPath magic_type_path in
 				pignore(f);
-				ct,display_position#with_pos p1
+				magic_type_th (display_position#with_pos p1)
 			)
 			f
 
@@ -682,8 +681,10 @@ and parse_structural_extension = parser
 					| [< '(Comma,_) >] -> ()
 					| [< >] -> ()
 				end;
-				magic_type_path,display_position#with_pos p1
-			end else raise Stream.Failure
+				let p = display_position#with_pos p1 in
+				make_ptp magic_type_path p
+			end else
+				raise Stream.Failure
 
 and parse_complex_type_inner allow_named = parser
 	| [< '(POpen,p1); t = parse_complex_type; '(PClose,p2) >] -> CTParent t,punion p1 p2
@@ -705,7 +706,8 @@ and parse_complex_type_inner allow_named = parser
 			| CTNamed (_,hint) -> hint
 			| _ -> (t,p2)
 		in
-		CTPath (mk_type_path ~params:[TPType hint] (["haxe"],"Rest")),punion p1 p2
+		let p = punion p1 p2 in
+		CTPath (make_ptp (mk_type_path ~params:[TPType hint] (["haxe"],"Rest")) p),p
 	| [< n = dollar_ident; s >] ->
 		(match s with parser
 		| [< '(DblDot,_) when allow_named; t = parse_complex_type >] ->
@@ -714,10 +716,10 @@ and parse_complex_type_inner allow_named = parser
 			CTNamed (n,t),punion p1 p2
 		| [< s >] ->
 			let n,p = n in
-			let t,p = parse_type_path2 None [] n p s in
-			CTPath t,p)
-	| [< t,p = parse_type_path >] ->
-		CTPath t,p
+			let ptp = parse_type_path2 None [] n p s in
+			CTPath ptp,ptp.pos_full)
+	| [< ptp = parse_type_path >] ->
+		CTPath ptp,ptp.pos_full
 
 and parse_type_path s = parse_type_path1 None [] s
 
@@ -725,14 +727,14 @@ and parse_type_path1 p0 pack = parser
 	| [< name, p1 = dollar_ident_macro pack; s >] ->
 		parse_type_path2 p0 pack name p1 s
 
-and parse_type_path2 p0 pack name p1 s =
+and parse_type_path2 p0 pack name p1 s : placed_type_path =
 	let check_display f =
 		let p = match p0 with
 			| None -> p1
 			| Some p -> punion p p1
 		in
 		if !in_display_file && display_position#enclosed_in p then begin
-			mk_type_path (List.rev pack,name), p
+			make_ptp (mk_type_path (List.rev pack,name)) p
 		end else
 			f()
 	in
@@ -756,6 +758,8 @@ and parse_type_path2 p0 pack name p1 s =
 					| [< >] -> serror()))
 			| [< >] -> None,p1
 		) in
+		let p1 = match p0 with None -> p1 | Some p -> p in
+		let p_path = punion p1 p2 in
 		let params,p2 = (match s with parser
 			| [< '(Binop OpLt,plt); l = psep Comma (parse_type_path_or_const plt) >] ->
 				begin match s with parser
@@ -766,8 +770,8 @@ and parse_type_path2 p0 pack name p1 s =
 			| [< >] -> [],p2
 		) in
 		let tp = mk_type_path ~params ?sub (List.rev pack,name)
-		and pos = punion (match p0 with None -> p1 | Some p -> p) p2 in
-		tp,pos
+		and p_full = punion p1 p2 in
+		make_ptp tp ~p_path p_full
 
 and type_name = parser
 	| [< '(Const (Ident name),p); s >] ->
@@ -790,8 +794,7 @@ and parse_type_path_or_const plt = parser
 	| [< s >] ->
 		if !in_display_file then begin
 			if would_skip_display_position plt false s then begin
-				let ct = CTPath magic_type_path in
-				TPType (ct,display_position#with_pos plt)
+				TPType (magic_type_th (display_position#with_pos plt))
 			end else
 				raise Stream.Failure
 		end else
@@ -816,8 +819,8 @@ and parse_complex_type_next (t : type_hint) s =
 		| [< t2,p2 = parse_complex_type >] -> make_fun t2 p2
 		| [< >] ->
 			if would_skip_display_position pa false s then begin
-				let ct = CTPath magic_type_path in
-				make_fun ct (display_position#with_pos pa)
+				let p = display_position#with_pos pa in
+				make_fun (magic_type_ct p) p
 			end else serror()
 		end
 	| [< '(Binop OpAnd,pa); s >] ->
@@ -825,8 +828,8 @@ and parse_complex_type_next (t : type_hint) s =
 		| [< t2,p2 = parse_complex_type >] -> make_intersection t2 p2
 		| [< >] ->
 			if would_skip_display_position pa false s then begin
-				let ct = CTPath magic_type_path in
-				make_intersection ct (display_position#with_pos pa)
+				let p = display_position#with_pos pa in
+				make_intersection (magic_type_ct p) p
 			end else serror()
 		end
 	| [< >] -> t
@@ -836,7 +839,7 @@ and parse_function_type_next tl p1 = parser
 		begin match s with parser
 		| [< tret = parse_complex_type_inner false >] -> CTFunction (tl,tret), punion p1 (snd tret)
 		| [< >] -> if would_skip_display_position pa false s then begin
-				let ct = (CTPath magic_type_path),(display_position#with_pos pa) in
+				let ct = magic_type_th (display_position#with_pos pa) in
 				CTFunction (tl,ct), punion p1 pa
 			end else serror()
 		end
@@ -1035,7 +1038,7 @@ and parse_fun_param s =
 	| [< name, pn = dollar_ident; t = popt parse_type_hint; c = parse_fun_param_value >] -> ((name,pn),false,meta,t,c)
 	| [< '(Spread,_); name, pn = dollar_ident; t = popt parse_type_hint; c = parse_fun_param_value >] ->
 		let t = match t with Some t -> t | None -> (ct_mono,null_pos) in
-		let t = CTPath (mk_type_path ~params:[TPType t] (["haxe"],"Rest")), snd t in
+		let t = CTPath (make_ptp (mk_type_path ~params:[TPType t] (["haxe"],"Rest")) (snd t)),(snd t) in
 		((name,pn),false,meta,Some t,c)
 
 and parse_fun_param_value = parser
@@ -1091,9 +1094,10 @@ and parse_constraint_param s =
 
 and parse_type_path_or_resume p1 s =
 	let check_resume exc =
-		if would_skip_display_position p1 true s then
-			(magic_type_path,display_position#with_pos p1),true
-		else
+		if would_skip_display_position p1 true s then begin
+			let p = display_position#with_pos p1 in
+			make_ptp magic_type_path p,true
+		end else
 			raise exc
 	in
 	try
@@ -1138,8 +1142,6 @@ and block_with_pos' acc f p s =
 		| Stream.Error msg when !in_display_file ->
 			handle_stream_error msg s;
 			(block_with_pos acc (next_pos s) s)
-		| Error (e,p) when !in_display_file ->
-			block_with_pos acc p s
 
 and block_with_pos acc p s =
 	block_with_pos' acc parse_block_elt p s
@@ -1283,7 +1285,8 @@ and parse_macro_expr p = parser
 	| [< '(DblDot,_); t = parse_complex_type >] ->
 		let _, to_type, _  = reify !in_macro in
 		let t = to_type t p in
-		(ECheckType (t,(CTPath (mk_type_path ~sub:"ComplexType" (["haxe";"macro"],"Expr")),null_pos)),p)
+		let ct = make_ptp_ct_null (mk_type_path ~sub:"ComplexType" (["haxe";"macro"],"Expr")) in
+		(ECheckType (t,(ct,p)),p)
 	| [< '(Kwd Var,p1); vl = psep Comma (parse_var_decl false) >] ->
 		reify_expr (EVars vl,p1) !in_macro
 	| [< '(Kwd Final,p1); s >] ->
@@ -1296,7 +1299,8 @@ and parse_macro_expr p = parser
 		end
 	| [< d = parse_class None [] [] false >] ->
 		let _,_,to_type = reify !in_macro in
-		(ECheckType (to_type d,(CTPath (mk_type_path ~sub:"TypeDefinition" (["haxe";"macro"],"Expr")),null_pos)),p)
+		let ct = make_ptp_ct_null (mk_type_path ~sub:"TypeDefinition" (["haxe";"macro"],"Expr")) in
+		(ECheckType (to_type d,(ct,null_pos)),p)
 	| [< e = secure_expr >] ->
 		reify_expr e !in_macro
 
@@ -1440,7 +1444,7 @@ and expr = parser
 		begin match s with parser
 		| [< '(POpen,po); e = parse_call_params (fun el p2 -> (ENew(t,el)),punion p1 p2) po >] -> expr_next e s
 		| [< >] ->
-			syntax_error (Expected ["("]) s (ENew(t,[]),punion p1 (pos t))
+			syntax_error (Expected ["("]) s (ENew(t,[]),punion p1 t.pos_full)
 		end
 	| [< '(POpen,p1); s >] -> (match s with parser
 		| [< '(PClose,p2); er = arrow_expr; >] ->

+ 4 - 0
src/syntax/parser.ml

@@ -244,6 +244,10 @@ let serror() = raise (Stream.Error "")
 let magic_display_field_name = " - display - "
 let magic_type_path = { tpackage = []; tname = ""; tparams = []; tsub = None }
 
+let magic_type_ct p = make_ptp_ct magic_type_path p
+
+let magic_type_th p = magic_type_ct p,p
+
 let delay_syntax_completion kind so p =
 	delayed_syntax_completion := Some(kind,DisplayTypes.make_subject so p)
 

+ 17 - 14
src/syntax/reification.ml

@@ -105,7 +105,9 @@ let reify in_macro =
 			| TPExpr e -> "TPExpr", to_expr e p
 		) in
 		mk_enum "TypeParam" n [v] p
-	and to_tpath (t,_) p =
+	and to_tpath ptp =
+		let t = ptp.path in
+		let p = ptp.pos_full in
 		let len = String.length t.tname in
 		if t.tpackage = [] && len > 1 && t.tname.[0] = '$' then begin
 			let name = String.sub t.tname 1 (len - 1) in
@@ -134,13 +136,13 @@ let reify in_macro =
 	and to_ctype t p =
 		let ct n vl = mk_enum "ComplexType" n vl p in
 		match fst t with
-		| CTPath ({ tpackage = []; tparams = []; tsub = None; tname = n }) when n.[0] = '$' ->
+		| CTPath ({ path = {tpackage = []; tparams = []; tsub = None; tname = n }}) when n.[0] = '$' ->
 			to_string n p
-		| CTPath t -> ct "TPath" [to_tpath (t,p) p]
+		| CTPath t -> ct "TPath" [to_tpath t]
 		| CTFunction (args,ret) -> ct "TFunction" [to_array to_type_hint args p; to_type_hint ret p]
 		| CTAnonymous fields -> ct "TAnonymous" [to_array to_cfield fields p]
 		| CTParent t -> ct "TParent" [to_type_hint t p]
-		| CTExtend (tl,fields) -> ct "TExtend" [to_array to_tpath tl p; to_array to_cfield fields p]
+		| CTExtend (tl,fields) -> ct "TExtend" [to_array (fun ptp _ -> to_tpath ptp) tl p; to_array to_cfield fields p]
 		| CTOptional t -> ct "TOptional" [to_type_hint t p]
 		| CTNamed (n,t) -> ct "TNamed" [to_placed_name n; to_type_hint t p]
 		| CTIntersection tl -> ct "TIntersection" [to_array to_ctype tl p]
@@ -277,8 +279,8 @@ let reify in_macro =
 			expr "EArrayDecl" [to_expr_array el p]
 		| ECall (e,el) ->
 			expr "ECall" [loop e;to_expr_array el p]
-		| ENew (t,el) ->
-			expr "ENew" [to_tpath t p;to_expr_array el p]
+		| ENew (ptp,el) ->
+			expr "ENew" [to_tpath ptp;to_expr_array el p]
 		| EUnop (op,flag,e) ->
 			let op = mk_enum "Unop" (match op with
 				| Increment -> "OpIncrement"
@@ -359,9 +361,9 @@ let reify in_macro =
 			(* TODO: can $v and $i be implemented better? *)
 			| Meta.Dollar "v", _ ->
 				begin match fst e1 with
-				| EParenthesis (ECheckType (e2, (CTPath{tname="String";tpackage=[]},_)),_) -> expr "EConst" [mk_enum "Constant" "CString" [e2] (pos e2)]
-				| EParenthesis (ECheckType (e2, (CTPath{tname="Int";tpackage=[]},_)),_) -> expr "EConst" [mk_enum "Constant" "CInt" [e2] (pos e2)]
-				| EParenthesis (ECheckType (e2, (CTPath{tname="Float";tpackage=[]},_)),_) -> expr "EConst" [mk_enum "Constant" "CFloat" [e2] (pos e2)]
+				| EParenthesis (ECheckType (e2, (CTPath({path = {tname="String";tpackage=[]}}),_)),_) -> expr "EConst" [mk_enum "Constant" "CString" [e2] (pos e2)]
+				| EParenthesis (ECheckType (e2, (CTPath({path = {tname="Int";tpackage=[]}}),_)),_) -> expr "EConst" [mk_enum "Constant" "CInt" [e2] (pos e2)]
+				| EParenthesis (ECheckType (e2, (CTPath({path = {tname="Float";tpackage=[]}}),_)),_) -> expr "EConst" [mk_enum "Constant" "CFloat" [e2] (pos e2)]
 				| EConst (Int (s, Some "i64")) ->
 					expr "EConst" [mk_enum "Constant" "CInt" [ (EConst(String (s, SDoubleQuotes)),(pos e1)); (EConst(String ("i64", SDoubleQuotes)),(pos e1)) ] (pos e1)]
 				| _ ->
@@ -394,13 +396,14 @@ let reify in_macro =
 			List.iter (function
 				| HExtern | HPrivate -> ()
 				| HInterface -> interf := true;
-				| HExtends t -> ext := (match !ext with
-					| None -> Some (to_tpath t p)
+				| HExtends ptp -> ext := (match !ext with
+					| None ->
+						Some (to_tpath ptp)
 					| Some _ -> begin
-						impl := (to_tpath t p) :: !impl;
+						impl := (to_tpath ptp) :: !impl;
 						!ext
 						end)
-				| HImplements i-> impl := (to_tpath i p) :: !impl
+				| HImplements ptp -> impl := (to_tpath ptp) :: !impl
 				| HFinal -> final := true
 				| HAbstract -> abstract := true
 			) d.d_flags;
@@ -421,4 +424,4 @@ let reify in_macro =
 let reify_expr e in_macro =
 	let to_expr,_,_ = reify in_macro in
 	let e = to_expr e in
-	(ECheckType (e,(CTPath (mk_type_path (["haxe";"macro"],"Expr")),null_pos)),pos e)
+	(ECheckType (e,(make_ptp_ct_null (mk_type_path (["haxe";"macro"],"Expr")),null_pos)),pos e)

+ 18 - 10
src/typing/callUnification.ml

@@ -113,10 +113,10 @@ let unify_call_args ctx el args r callp inline force_inline in_overload =
 								let e = EArrayDecl el,p in
 								(* typer requires dynamic arrays to be explicitly declared as Array<Dynamic> *)
 								if follow arg_t == t_dynamic then begin
-									let dynamic = CTPath(mk_type_path ([],"Dynamic")),p in
+									let dynamic = make_ptp_th (mk_type_path ([],"Dynamic")) p in
 									let params = [TPType dynamic] in
-									let tp = mk_type_path ~params ([],"Array") in
-									do_type (ECheckType(e,(CTPath tp, p)),p) (* ([arg1, arg2...]:Array<Dynamic>) *)
+									let ct = make_ptp_ct (mk_type_path ~params ([],"Array")) p in
+									do_type (ECheckType(e,(ct, p)),p) (* ([arg1, arg2...]:Array<Dynamic>) *)
 								end else
 									do_type e
 							with WithTypeError e ->
@@ -453,13 +453,21 @@ object(self)
 		ctx.macro_depth <- ctx.macro_depth + 1;
 		ctx.with_type_stack <- with_type :: ctx.with_type_stack;
 		let ethis_f = ref (fun () -> ()) in
+		let macro_in_macro () =
+			(fun () ->
+				let e = (EThrow((EConst(String("macro-in-macro",SDoubleQuotes))),p),p) in
+				type_expr ~mode ctx e with_type
+			)
+		in
 		let f = (match ethis.eexpr with
 		| TTypeExpr (TClassDecl c) ->
 			DeprecationCheck.check_cf (create_deprecation_context ctx) cf p;
-			(match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name el p with
-			| None -> (fun() -> type_expr ~mode ctx (EConst (Ident "null"),p) WithType.value)
-			| Some (EMeta((Meta.MergeBlock,_,_),(EBlock el,_)),_) -> (fun () -> let e = (!type_block_ref) ctx el with_type p in mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos)
-			| Some e -> (fun() -> type_expr ~mode ctx e with_type))
+			begin match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name el p with
+				| MError -> (fun() -> type_expr ~mode ctx (EConst (Ident "null"),p) WithType.value)
+				| MSuccess (EMeta((Meta.MergeBlock,_,_),(EBlock el,_)),_) -> (fun () -> let e = (!type_block_ref) ctx el with_type p in mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos)
+				| MSuccess e -> (fun() -> type_expr ~mode ctx e with_type)
+				| MMacroInMacro -> macro_in_macro ()
+			end
 		| _ ->
 			(* member-macro call : since we will make a static call, let's find the actual class and not its subclass *)
 			(match follow ethis.etype with
@@ -469,8 +477,9 @@ object(self)
 						let eparam,f = push_this ctx ethis in
 						ethis_f := f;
 						let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name (eparam :: el) p with
-							| None -> (fun() -> type_expr ~mode ctx (EConst (Ident "null"),p) WithType.value)
-							| Some e -> (fun() -> type_expr ~mode ctx e WithType.value)
+							| MError -> (fun() -> type_expr ~mode ctx (EConst (Ident "null"),p) WithType.value)
+							| MSuccess e -> (fun() -> type_expr ~mode ctx e with_type)
+							| MMacroInMacro -> macro_in_macro ()
 						in
 						e
 					else
@@ -503,7 +512,6 @@ object(self)
 			!ethis_f();
 			raise exc
 		in
-		let e = Diagnostics.secure_generated_code ctx.com e in
 		ctx.com.error_ext <- old;
 		!ethis_f();
 		e

+ 26 - 25
src/typing/forLoop.ml

@@ -84,7 +84,7 @@ module IterationKind = struct
 		(mk (TArray (arr,iexpr)) pt p)
 
 	let check_iterator ?(resume=false) ?last_resort ctx s e p =
-		let t,pt = Typeload.t_iterator ctx in
+		let t,pt = Typeload.t_iterator ctx p in
 		let dynamic_iterator = ref None in
 		let e1 = try
 			let e = AbstractCast.cast_or_unify_raise ctx t e p in
@@ -457,29 +457,7 @@ type iteration_kind =
 	| IKNormal of iteration_ident
 	| IKKeyValue of iteration_ident * iteration_ident
 
-let type_for_loop ctx handle_display it e2 p =
-	let rec loop_ident dko e1 = match e1 with
-		| EConst(Ident i),p -> i,p,dko
-		| EDisplay(e1,dk),_ -> loop_ident (Some dk) e1
-		| _ -> raise_typing_error "Identifier expected" (pos e1)
-	in
-	let rec loop dko e1 = match fst e1 with
-		| EBinop(OpIn,e1,e2) ->
-			begin match fst e1 with
-			| EBinop(OpArrow,ei1,ei2) -> IKKeyValue(loop_ident None ei1,loop_ident None ei2),e2
-			| _ -> IKNormal (loop_ident dko e1),e2
-			end
-		| EDisplay(e1,dk) -> loop (Some dk) e1
-		| EBinop(OpArrow,ei1,(EBinop(OpIn,ei2,e2),_)) -> IKKeyValue(loop_ident None ei1,loop_ident None ei2),e2
-		| _ ->
-			begin match dko with
-			| Some dk -> ignore(handle_display ctx e1 dk MGet WithType.value);
-			| None -> ()
-			end;
-			raise_typing_error "For expression should be 'v in expr'" (snd it)
-	in
-	let ik,e1 = loop None it in
-	let e1 = type_expr ctx e1 WithType.value in
+let type_for_loop ctx handle_display ik e1 e2 p =
 	let old_loop = ctx.in_loop in
 	let old_locals = save_locals ctx in
 	ctx.in_loop <- true;
@@ -535,4 +513,27 @@ let type_for_loop ctx handle_display it e2 p =
 		old_locals();
 		e
 
-
+let type_for_loop ctx handle_display it e2 p =
+	let rec loop_ident dko e1 = match e1 with
+		| EConst(Ident i),p -> i,p,dko
+		| EDisplay(e1,dk),_ -> loop_ident (Some dk) e1
+		| _ -> raise_typing_error "Identifier expected" (pos e1)
+	in
+	let rec loop dko e1 = match fst e1 with
+		| EBinop(OpIn,e1,e2) ->
+			begin match fst e1 with
+			| EBinop(OpArrow,ei1,ei2) -> IKKeyValue(loop_ident None ei1,loop_ident None ei2),e2
+			| _ -> IKNormal (loop_ident dko e1),e2
+			end
+		| EDisplay(e1,dk) -> loop (Some dk) e1
+		| EBinop(OpArrow,ei1,(EBinop(OpIn,ei2,e2),_)) -> IKKeyValue(loop_ident None ei1,loop_ident None ei2),e2
+		| _ ->
+			begin match dko with
+			| Some dk -> ignore(handle_display ctx e1 dk MGet WithType.value);
+			| None -> ()
+			end;
+			raise_typing_error "For expression should be 'v in expr'" (snd it)
+	in
+	let ik,e1 = loop None it in
+	let e1 = type_expr ctx e1 WithType.value in
+	type_for_loop ctx handle_display ik e1 e2 p

+ 2 - 1
src/typing/functionArguments.ml

@@ -89,7 +89,8 @@ object(self)
 		| None ->
 			let make_local name kind t meta pn =
 				let v = alloc_var kind name t pn in
-				v.v_meta <- v.v_meta @ meta;
+				let meta = (StrictMeta.check_strict_meta ctx meta) @ meta in
+				v.v_meta <- meta;
 				v
 			in
 			let rec loop acc is_abstract_this syntax typed = match syntax,typed with

+ 2 - 2
src/typing/generic.ml

@@ -169,7 +169,7 @@ let static_method_container gctx c cf p =
 	let pack = fst c.cl_path in
 	let name = (snd c.cl_path) ^ "_" ^ cf.cf_name ^ "_" ^ gctx.name in
 	try
-		let t = Typeload.load_instance ctx (mk_type_path (pack,name),p) ParamSpawnMonos in
+		let t = Typeload.load_instance ctx (make_ptp (mk_type_path (pack,name)) p) ParamSpawnMonos in
 		match t with
 		| TInst(cg,_) -> cg
 		| _ -> raise_typing_error ("Cannot specialize @:generic static method because the generated type name is already used: " ^ name) p
@@ -254,7 +254,7 @@ let build_generic_class ctx c p tl =
 	let gctx = make_generic ctx c.cl_params tl (Meta.has (Meta.Custom ":debug.generic") c.cl_meta) p in
 	let name = (snd c.cl_path) ^ "_" ^ gctx.name in
 	try
-		let t = Typeload.load_instance ctx (mk_type_path (pack,name),p) ParamNormal in
+		let t = Typeload.load_instance ctx (make_ptp (mk_type_path (pack,name)) p) ParamNormal in
 		match t with
 		| 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

+ 4 - 4
src/typing/instanceBuilder.ml

@@ -39,8 +39,8 @@ let build_macro_type ctx pl p =
 	) in
 	let old = ctx.ret in
 	let t = (match ctx.g.do_macro ctx MMacroType path field args p with
-		| None -> spawn_monomorph ctx p
-		| Some _ -> ctx.ret
+		| MError | MMacroInMacro -> spawn_monomorph ctx p
+		| MSuccess _ -> ctx.ret
 	) in
 	ctx.ret <- old;
 	t
@@ -58,8 +58,8 @@ let build_macro_build ctx c pl cfl p =
 	let old = ctx.ret,ctx.get_build_infos in
 	ctx.get_build_infos <- (fun() -> Some (TClassDecl c, pl, cfl));
 	let t = (match ctx.g.do_macro ctx MMacroType path field args p with
-		| None -> spawn_monomorph ctx p
-		| Some _ -> ctx.ret
+		| MError | MMacroInMacro -> spawn_monomorph ctx p
+		| MSuccess _ -> ctx.ret
 	) in
 	ctx.ret <- fst old;
 	ctx.get_build_infos <- snd old;

+ 31 - 25
src/typing/macroContext.ml

@@ -93,8 +93,7 @@ let typing_timer ctx need_type f =
 	ctx.com.error_ext <- (fun err -> raise_error { err with err_from_macro = true });
 
 	if need_type && ctx.pass < PTypeField then begin
-		ctx.pass <- PTypeField;
-		flush_pass ctx PBuildClass ("typing_timer",[] (* TODO: ? *));
+		enter_field_typing_pass ctx ("typing_timer",[] (* TODO: ? *));
 	end;
 	let exit() =
 		t();
@@ -198,7 +197,8 @@ let make_macro_com_api com mcom p =
 				let r = match ParserEntry.parse_expr_string com.defines s p raise_typing_error inl with
 					| ParseSuccess(data,true,_) when inl -> data (* ignore errors when inline-parsing in display file *)
 					| ParseSuccess(data,_,_) -> data
-					| ParseError _ -> raise MacroApi.Invalid_expr in
+					| ParseError _ -> Interp.exc_string "Invalid expression"
+				in
 				exit();
 				r
 			with Error err ->
@@ -316,6 +316,7 @@ let make_macro_com_api com mcom p =
 		warning = (fun ?(depth=0) w msg p ->
 			com.warning ~depth w [] msg p
 		);
+		exc_string = Interp.exc_string;
 	}
 
 let make_macro_api ctx mctx p =
@@ -328,6 +329,10 @@ let make_macro_api ctx mctx p =
 			raise_typing_error "Malformed metadata string" p
 	in
 	let com_api = make_macro_com_api ctx.com mctx.com p in
+	let mk_type_path ?sub path =
+		try mk_type_path ?sub path
+		with Invalid_argument s -> com_api.exc_string s
+	in
 	{
 		com_api with
 		MacroApi.get_type = (fun s ->
@@ -340,7 +345,7 @@ let make_macro_api ctx mctx p =
 						mk_type_path path
 				in
 				try
-					let m = Some (Typeload.load_instance ctx (tp,p) ParamSpawnMonos) in
+					let m = Some (Typeload.load_instance ctx (make_ptp tp p) ParamSpawnMonos) in
 					m
 				with Error { err_message = Module_not_found _; err_pos = p2 } when p == p2 ->
 					None
@@ -351,10 +356,10 @@ let make_macro_api ctx mctx p =
 		);
 		MacroApi.resolve_complex_type = (fun t ->
 			typing_timer ctx false (fun() ->
-				let rec load (t,pos) =
+				let rec load (t,_) =
 					((match t with
-					| CTPath p ->
-						CTPath (load_path p pos)
+					| CTPath ptp ->
+						CTPath (load_path ptp)
 					| CTFunction (args,ret) ->
 						CTFunction (List.map load args, load ret)
 					| CTAnonymous fl ->
@@ -362,7 +367,7 @@ let make_macro_api ctx mctx p =
 					| CTParent t ->
 						CTParent (load t)
 					| CTExtend (pl, fl) ->
-						CTExtend (List.map (fun (p,pos) -> load_path p pos, pos) pl,List.map load_cf fl)
+						CTExtend (List.map (fun ptp -> load_path ptp) pl,List.map load_cf fl)
 					| CTOptional t ->
 						CTOptional t
 					| CTNamed (n,t) ->
@@ -389,15 +394,15 @@ let make_macro_api ctx mctx p =
 						tp_constraints = (match ft.tp_constraints with None -> None | Some t -> Some (load t));
 						tp_default = (match ft.tp_default with None -> None | Some t -> Some (load t));
 					}
-				and load_path p pos =
-					let t = t_infos (Typeload.load_type_def ctx pos p) in
+				and load_path ptp =
+					let t = t_infos (Typeload.load_type_def ctx ptp.pos_path ptp.path) in
 					let is_sub = t.mt_module.m_path <> t.mt_path in
-					{
+					make_ptp {
 						tpackage = fst t.mt_path;
 						tname = (if is_sub then snd t.mt_module.m_path else snd t.mt_path);
-						tparams = List.map (fun ct -> match ct with TPType t -> TPType (load t) | TPExpr _ -> ct) p.tparams;
+						tparams = List.map (fun ct -> match ct with TPType t -> TPType (load t) | TPExpr _ -> ct) ptp.path.tparams;
 						tsub = (if is_sub then Some (snd t.mt_path) else None);
-					}
+					} ptp.pos_full
 				in
 				load t
 			)
@@ -478,7 +483,7 @@ let make_macro_api ctx mctx p =
 		MacroApi.define_type = (fun v mdep ->
 			let cttype = mk_type_path ~sub:"TypeDefinition" (["haxe";"macro"],"Expr") in
 			let mctx = (match ctx.g.macros with None -> die "" __LOC__ | Some (_,mctx) -> mctx) in
-			let ttype = Typeload.load_instance mctx (cttype,p) ParamNormal in
+			let ttype = Typeload.load_instance mctx (make_ptp cttype p) ParamNormal in
 			let f () = Interp.decode_type_def v in
 			let m, tdef, pos = safe_decode ctx.com v "TypeDefinition" ttype p f in
 			let has_native_meta = match tdef with
@@ -844,27 +849,27 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 	in
 	let mpos = mfield.cf_pos in
 	let ctexpr = mk_type_path (["haxe";"macro"],"Expr") in
-	let expr = Typeload.load_instance mctx (ctexpr,p) ParamNormal in
+	let expr = Typeload.load_instance mctx (make_ptp ctexpr p) ParamNormal in
 	(match mode with
 	| MDisplay ->
 		raise Exit (* We don't have to actually call the macro. *)
 	| MExpr ->
 		unify mctx mret expr mpos;
 	| MBuild ->
-		let params = [TPType (CTPath (mk_type_path ~sub:"Field" (["haxe";"macro"],"Expr")),null_pos)] in
+		let params = [TPType (make_ptp_th (mk_type_path ~sub:"Field" (["haxe";"macro"],"Expr")) null_pos)] in
 		let ctfields = mk_type_path ~params ([],"Array") in
-		let tfields = Typeload.load_instance mctx (ctfields,p) ParamNormal in
+		let tfields = Typeload.load_instance mctx (make_ptp ctfields p) ParamNormal in
 		unify mctx mret tfields mpos
 	| MMacroType ->
 		let cttype = mk_type_path (["haxe";"macro"],"Type") in
-		let ttype = Typeload.load_instance mctx (cttype,p) ParamNormal in
+		let ttype = Typeload.load_instance mctx (make_ptp cttype p) ParamNormal in
 		try
 			unify_raise mret ttype mpos;
 			(* TODO: enable this again in the future *)
 			(* warning ctx WDeprecated "Returning Type from @:genericBuild macros is deprecated, consider returning ComplexType instead" p; *)
 		with Error { err_message = Unify _ } ->
 			let cttype = mk_type_path ~sub:"ComplexType" (["haxe";"macro"],"Expr") in
-			let ttype = Typeload.load_instance mctx (cttype,p) ParamNormal in
+			let ttype = Typeload.load_instance mctx (make_ptp cttype p) ParamNormal in
 			unify_raise mret ttype mpos;
 	);
 	(*
@@ -930,7 +935,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 					(EConst (Ident "null"),p)
 				else
 					(* if it's not a constant, let's make something that is typed as haxe.macro.Expr - for nice error reporting *)
-					(ECheckType ((EConst (Ident "null"),p), (CTPath ctexpr,p)), p)
+					(ECheckType ((EConst (Ident "null"),p), (make_ptp_th ctexpr p)), p)
 			in
 			(* let's track the index by doing [e][index] (we will keep the expression type this way) *)
 			incr index;
@@ -967,11 +972,12 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 	in
 	let call() =
 		match call_macro args with
-		| None -> None
+		| None ->
+			MError
 		| Some v ->
 			let expected,process = match mode with
 				| MExpr | MDisplay ->
-					"Expr",(fun () -> Some (Interp.decode_expr v))
+					"Expr",(fun () -> MSuccess (Interp.decode_expr v))
 				| MBuild ->
 					"Array<Field>",(fun () ->
 						let fields = if v = Interp.vnull then
@@ -981,7 +987,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 							else
 								List.map Interp.decode_field (Interp.decode_array v)
 						in
-						Some (EVars [mk_evar ~t:(CTAnonymous fields,p) ("fields",null_pos)],p)
+						MSuccess (EVars [mk_evar ~t:(CTAnonymous fields,p) ("fields",null_pos)],p)
 					)
 				| MMacroType ->
 					"ComplexType",(fun () ->
@@ -994,13 +1000,13 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 							Interp.decode_type v
 						in
 						ctx.ret <- t;
-						Some (EBlock [],p)
+						MSuccess (EBlock [],p)
 					)
 			in
 			safe_decode ctx.com v expected mret p process
 	in
 	let e = if ctx.com.is_macro_context then
-		Some (EThrow((EConst(String("macro-in-macro",SDoubleQuotes))),p),p)
+		MMacroInMacro
 	else
 		call()
 	in

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

@@ -58,7 +58,7 @@ let get_general_module_type ctx mt p =
 			end
 		| _ -> raise_typing_error "Cannot use this type as a value" p
 	in
-	Typeload.load_instance ctx ({tname=loop mt;tpackage=[];tsub=None;tparams=[]},p) ParamSpawnMonos
+	Typeload.load_instance ctx (make_ptp {tname=loop mt;tpackage=[];tsub=None;tparams=[]} p) ParamSpawnMonos
 
 let unify_type_pattern ctx mt t p =
 	let tcl = get_general_module_type ctx mt p in
@@ -216,7 +216,7 @@ let rec make pctx toplevel t e =
 	let rec loop e = match fst e with
 		| EParenthesis e1 | ECast(e1,None) ->
 			loop e1
-		| ECheckType(e, (CTPath({tpackage=["haxe";"macro"]; tname="Expr"}),_)) ->
+		| ECheckType(e, (CTPath({path = {tpackage=["haxe";"macro"]; tname="Expr"}}),_)) ->
 			let old = pctx.in_reification in
 			pctx.in_reification <- true;
 			let e = loop e in

+ 2 - 2
src/typing/matcher/texprConverter.ml

@@ -372,9 +372,9 @@ let to_texpr ctx t_switch with_type dt =
 						begin match bind.Bind.b_status with
 							| BindUsed ->
 								v_lookup := IntMap.add bind.b_var.v_id bind.b_expr !v_lookup;
-								Some (mk (TVar(bind.b_var,Some bind.b_expr)) com.basic.tvoid p)
+								Some (mk (TVar(bind.b_var,Some bind.b_expr)) com.basic.tvoid bind.b_pos)
 							| BindDeferred ->
-								Some (mk (TVar(bind.b_var,None)) com.basic.tvoid p)
+								Some (mk (TVar(bind.b_var,None)) com.basic.tvoid bind.b_pos)
 							| BindUnused ->
 								None
 						end

+ 26 - 20
src/typing/operators.ml

@@ -88,7 +88,7 @@ module BinopResult = struct
 		| BinopSpecial(_,needs_assign) -> needs_assign
 end
 
-let rec check_assign ctx e =
+let check_assign ctx e =
 	match e.eexpr with
 	| TLocal v when has_var_flag v VFinal && not (Common.ignore_error ctx.com) ->
 		raise_typing_error "Cannot assign to final" e.epos
@@ -96,8 +96,6 @@ let rec check_assign ctx e =
 		()
 	| TConst TThis | TTypeExpr _ when ctx.untyped ->
 		()
-	| TMeta ((Meta.CompilerGenerated,_,_),e1) ->
-		check_assign ctx e1
 	| _ ->
 		if not (Common.ignore_error ctx.com) then
 			invalid_assign e.epos
@@ -193,7 +191,7 @@ let unify_int ctx e k =
 		unify ctx e.etype ctx.t.tint e.epos;
 		true
 
-let make_binop ctx op e1 e2 is_assign_op with_type p =
+let make_binop ctx op e1 e2 is_assign_op p =
 	let tint = ctx.t.tint in
 	let tfloat = ctx.t.tfloat in
 	let tstring = ctx.t.tstring in
@@ -204,7 +202,7 @@ let make_binop ctx op e1 e2 is_assign_op with_type p =
 			| KInt | KFloat | KString -> e
 			| KUnk | KDyn | KNumParam _ | KStrParam _ | KOther ->
 				let std = type_type ctx ([],"Std") e.epos in
-				let acc = acc_get ctx (type_field_default_cfg ctx std "string" e.epos (MCall []) with_type) in
+				let acc = acc_get ctx (type_field_default_cfg ctx std "string" e.epos (MCall []) WithType.value) in
 				ignore(follow acc.etype);
 				let acc = (match acc.eexpr with TField (e,FClosure (Some (c,tl),f)) -> { acc with eexpr = TField (e,FInstance (c,tl,f)) } | _ -> acc) in
 				make_call ctx acc [e] ctx.t.tstring e.epos
@@ -392,7 +390,7 @@ let make_binop ctx op e1 e2 is_assign_op with_type p =
 		unify ctx e2.etype b p;
 		mk_op e1 e2 b
 	| OpInterval ->
-		let t = Typeload.load_instance ctx (mk_type_path (["std"],"IntIterator"),null_pos) ParamNormal in
+		let t = Typeload.load_instance ctx (make_ptp (mk_type_path (["std"],"IntIterator")) null_pos) ParamNormal in
 		let e1 = AbstractCast.cast_or_unify_raise ctx tint e1 e1.epos in
 		let e2 = AbstractCast.cast_or_unify_raise ctx tint e2 e2.epos in
 		BinopSpecial (mk (TNew ((match t with TInst (c,[]) -> c | _ -> die "" __LOC__),[],[e1;e2])) t p,false)
@@ -405,14 +403,14 @@ let make_binop ctx op e1 e2 is_assign_op with_type p =
 	| OpAssignOp _ ->
 		die "" __LOC__
 
-let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op with_type p =
+let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op p =
 	let map = apply_params a.a_params tl in
 	let make op_cf cf e1 e2 tret needs_assign swapped =
 		if cf.cf_expr = None && not (has_class_field_flag cf CfExtern) then begin
 			if not (Meta.has Meta.NoExpr cf.cf_meta) then Common.display_error ctx.com "Recursive operator method" p;
 			if not (Meta.has Meta.CoreType a.a_meta) then begin
 				(* for non core-types we require that the return type is compatible to the native result type *)
-				let result = make_binop ctx op {e1 with etype = Abstract.follow_with_abstracts e1.etype} {e1 with etype = Abstract.follow_with_abstracts e2.etype} is_assign_op with_type p in
+				let result = make_binop ctx op {e1 with etype = Abstract.follow_with_abstracts e1.etype} {e1 with etype = Abstract.follow_with_abstracts e2.etype} is_assign_op p in
 				let t_expected = BinopResult.get_type result in
 				begin try
 					unify_raise tret t_expected p
@@ -525,15 +523,15 @@ let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op with_type
 	else
 		find (loop op)
 
-let try_abstract_binop_overloads ctx op e1 e2 is_assign_op with_type p =
+let try_abstract_binop_overloads ctx op e1 e2 is_assign_op p =
 	try
 		begin match follow e1.etype with
-			| TAbstract({a_impl = Some c} as a,tl) -> find_abstract_binop_overload ctx op e1 e2 a c tl true is_assign_op with_type p
+			| TAbstract({a_impl = Some c} as a,tl) -> find_abstract_binop_overload ctx op e1 e2 a c tl true is_assign_op p
 			| _ -> raise Not_found
 		end
 	with Not_found ->
 		begin match follow e2.etype with
-			| TAbstract({a_impl = Some c} as a,tl) -> find_abstract_binop_overload ctx op e1 e2 a c tl false is_assign_op with_type p
+			| TAbstract({a_impl = Some c} as a,tl) -> find_abstract_binop_overload ctx op e1 e2 a c tl false is_assign_op p
 			| _ -> raise Not_found
 		end
 
@@ -542,17 +540,23 @@ let type_binop_rhs ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op wt p =
 		| OpEq | OpNotEq | OpLt | OpLte | OpGt | OpGte -> WithType.with_type e1.etype
 		| _ -> wt
 	in
-	type_expr ctx e2 with_type,with_type
+	type_expr ctx e2 with_type
 
-let type_binop2 ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op with_type p =
-	let e2,with_type = type_binop_rhs ctx op e1 e2 is_assign_op with_type p in
+let type_binop2 ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op with_type_rhs p =
+	let e2 = type_binop_rhs ctx op e1 e2 is_assign_op with_type_rhs p in
 	try
-		try_abstract_binop_overloads ctx op e1 e2 is_assign_op with_type p
+		try_abstract_binop_overloads ctx op e1 e2 is_assign_op p
 	with Not_found ->
-		make_binop ctx op e1 e2 is_assign_op with_type p
+		make_binop ctx op e1 e2 is_assign_op p
+
+let with_type_or_value with_type = match with_type with
+| WithType.NoValue ->
+	(* Even if we expect no value, we still want to type the lhs expression as a value. *)
+	WithType.value
+| _ ->
+	with_type
 
 let type_assign ctx e1 e2 with_type p =
-	let e1 = !type_access_ref ctx (fst e1) (snd e1) (MSet (Some e2)) with_type in
 	let type_rhs with_type = try
 		type_expr ctx e2 with_type
 	with Error e ->
@@ -604,6 +608,8 @@ let type_assign ctx e1 e2 with_type p =
 			let dispatcher = new call_dispatcher ctx (MCall [e2]) with_type p in
 			dispatcher#field_call fa_set [sea.se_this] [e2]
 	in
+	let with_type = with_type_or_value with_type in
+	let e1 = !type_access_ref ctx (fst e1) (snd e1) (MSet (Some e2)) with_type in
 	check_acc e1
 
 let type_non_assign_op ctx op e1 e2 is_assign_op abstract_overload_only with_type p =
@@ -625,8 +631,8 @@ let type_non_assign_op ctx op e1 e2 is_assign_op abstract_overload_only with_typ
 	in
 	let e1 = type_expr ctx e1 wt in
 	let result = if abstract_overload_only then begin
-		let e2,with_type = 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 with_type p
+		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
 	end else
 		type_binop2 ctx op e1 e2 is_assign_op wt p
 	in
@@ -745,6 +751,7 @@ let type_assign_op ctx op e1 e2 with_type p =
 			let e = BinopResult.to_texpr vr r_rhs assign in
 			vr#to_texpr e
 	in
+	let with_type = with_type_or_value with_type in
 	loop (!type_access_ref ctx (fst e1) (snd e1) (MSet (Some e2)) with_type)
 
 
@@ -763,7 +770,6 @@ let type_binop ctx op e1 e2 is_assign_op with_type p =
 			let op = if is_assign_op then OpAssignOp op else op in
 			die ~p ("Failed to type binary operation " ^ (s_binop op)) __LOC__
 
-
 let type_unop ctx op flag e with_type p =
 	let try_abstract_unop_overloads e = match follow e.etype with
 		| TAbstract ({a_impl = Some c} as a,tl) ->

+ 72 - 26
src/typing/strictMeta.ml

@@ -52,23 +52,56 @@ let rec process_meta_argument ?(toplevel=true) ctx expr = match expr.eexpr with
 		(efield(get_native_repr md expr.epos, "class"), p)
 	| TTypeExpr md ->
 		get_native_repr md expr.epos
+	| TArrayDecl el ->
+		let el = List.map (process_meta_argument ctx) el in
+		(EArrayDecl el,expr.epos)
 	| _ ->
 		display_error ctx.com "This expression is too complex to be a strict metadata argument" expr.epos;
 		(EConst(Ident "null"), expr.epos)
 
+let rec kind_of_type_against ctx t_want e_have =
+	match follow t_want with
+	| TInst({cl_path = (["java";"lang"],"Class")},[t1]) ->
+		let e = type_expr ctx e_have (WithType.with_type t_want) in
+		begin match follow e.etype with
+			| TAbstract({a_path = ([],"Class")},[t2]) ->
+				unify ctx t2 t1 e.epos
+			| TAnon an ->
+				begin match !(an.a_status) with
+					| ClassStatics c ->
+						unify ctx (TInst(c,extract_param_types c.cl_params)) t1 e.epos
+					| AbstractStatics a ->
+						unify ctx (TAbstract(a,extract_param_types a.a_params)) t1 e.epos
+					| _ ->
+						unify ctx e.etype t_want e.epos
+				end
+			| _ ->
+				unify ctx e.etype t_want e.epos
+		end;
+		e
+	| TInst({cl_path = (["java"],"NativeArray")},[t1]) ->
+		begin match fst e_have with
+			| EArrayDecl el ->
+				let el = List.map (kind_of_type_against ctx t1) el in
+				mk (TArrayDecl el) t1 (snd e_have)
+			| _ ->
+				let e = type_expr ctx e_have (WithType.with_type t_want) in
+				unify ctx e.etype t_want e.epos;
+				e
+		end
+	| t1 ->
+		let e = type_expr ctx e_have (WithType.with_type t1) in
+		unify ctx e.etype t1 e.epos;
+		e
+
 let handle_fields ctx fields_to_check with_type_expr =
 	List.map (fun ((name,_,_),expr) ->
 		let pos = snd expr in
 		let field = (efield(with_type_expr,name), pos) in
 		let fieldexpr = (EConst(Ident name),pos) in
-		let left_side = match ctx.com.platform with
-			| Jvm -> (ECall(field,[]),pos)
-			| _ -> die "" __LOC__
-		in
-
+		let left_side = (ECall(field,[]),pos) in
 		let left = type_expr ctx left_side NoValue in
-		let right = type_expr ctx expr (WithType.with_type left.etype) in
-		unify ctx left.etype right.etype (snd expr);
+		let right = kind_of_type_against ctx left.etype expr in
 		(EBinop(Ast.OpAssign,fieldexpr,process_meta_argument ctx right), pos)
 	) fields_to_check
 
@@ -82,39 +115,52 @@ let make_meta ctx texpr extra =
 			display_error ctx.com "Unexpected expression" texpr.epos; die "" __LOC__
 
 let get_strict_meta ctx meta params pos =
-	let pf = ctx.com.platform in
 	let changed_expr, fields_to_check, ctype = match params with
 		| [ECall(ef, el),p] ->
 			let tpath = field_to_type_path ctx.com ef in
-			begin match pf with
-			| Jvm ->
-				let fields = match el with
-				| [EObjectDecl(fields),_] ->
-					fields
-				| [] ->
-					[]
-				| (_,p) :: _ ->
-					display_error ctx.com "Object declaration expected" p;
-					[]
-				in
-				ef, fields, CTPath tpath
-			| _ ->
-				Error.raise_typing_error "@:strict is not supported on this target" p
-			end
+			let fields = match el with
+			| [EObjectDecl(fields),_] ->
+				fields
+			| [] ->
+				[]
+			| (_,p) :: _ ->
+				display_error ctx.com "Object declaration expected" p;
+				[]
+			in
+			ef, fields, CTPath (make_ptp tpath (snd ef))
 		| [EConst(Ident i),p as expr] ->
 			let tpath = { tpackage=[]; tname=i; tparams=[]; tsub=None } in
-			expr, [], CTPath tpath
+			let ptp = make_ptp tpath p in
+			expr, [], CTPath ptp
 		| [ (EField(_),p as field) ] ->
 			let tpath = field_to_type_path ctx.com field in
-			field, [], CTPath tpath
+			let ptp = make_ptp tpath p in
+			field, [], CTPath ptp
 		| _ ->
 			display_error ctx.com "A @:strict metadata must contain exactly one parameter. Please check the documentation for more information" pos;
 			raise Exit
 	in
+	let t = Typeload.load_complex_type ctx false (ctype,pos) in
+	flush_pass ctx PBuildClass "get_strict_meta";
 	let texpr = type_expr ctx changed_expr NoValue in
 	let with_type_expr = (ECheckType( (EConst (Ident "null"), pos), (ctype,null_pos) ), pos) in
 	let extra = handle_fields ctx fields_to_check with_type_expr in
-	meta, [make_meta ctx texpr extra], pos
+	let args = [make_meta ctx texpr extra] in
+	let args = match t with
+		| TInst(c,_) ->
+			let v = get_meta_string c.cl_meta Meta.Annotation in
+			begin match v with
+			| None ->
+				(* We explicitly set this to the default retention policy CLASS. This allows us to treat
+				   @:strict as default CLASS and @:meta as default RUNTIME. *)
+				args @ [EConst (String("CLASS",SDoubleQuotes)),pos]
+			| Some v ->
+				args @ [EConst (String(v,SDoubleQuotes)),pos]
+			end;
+		| _ ->
+			args
+	in
+	meta, args, pos
 
 let check_strict_meta ctx metas =
 	let pf = ctx.com.platform in

+ 28 - 54
src/typing/typeload.ml

@@ -421,19 +421,20 @@ let rec load_params ctx info params p =
 	params
 
 (* build an instance from a full type *)
-and load_instance' ctx (t,p) get_params =
+and load_instance' ctx ptp get_params =
+	let t = ptp.path in
 	try
 		if t.tpackage <> [] || t.tsub <> None then raise Not_found;
 		let pt = lookup_param t.tname ctx.type_params in
-		if t.tparams <> [] then raise_typing_error ("Class type parameter " ^ t.tname ^ " can't have parameters") p;
+		if t.tparams <> [] then raise_typing_error ("Class type parameter " ^ t.tname ^ " can't have parameters") ptp.pos_full;
 		pt
 	with Not_found ->
-		let mt = load_type_def ctx p t in
-		let info = ctx.g.get_build_info ctx mt p in
+		let mt = load_type_def ctx ptp.pos_path t in
+		let info = ctx.g.get_build_info ctx mt ptp.pos_full in
 		if info.build_path = ([],"Dynamic") then match t.tparams with
 			| [] -> t_dynamic
 			| [TPType t] -> TDynamic (Some (load_complex_type ctx true t))
-			| _ -> raise_typing_error "Too many parameters for Dynamic" p
+			| _ -> raise_typing_error "Too many parameters for Dynamic" ptp.pos_full
 		else if info.build_params = [] then begin match t.tparams with
 			| [] ->
 				info.build_apply []
@@ -448,26 +449,26 @@ and load_instance' ctx (t,p) get_params =
 			let is_rest = info.build_kind = BuildGenericBuild && (match info.build_params with [{ttp_name="Rest"}] -> true | _ -> false) in
 			let tl = if t.tparams = [] && not is_rest then begin match get_params with
 				| ParamNormal ->
-					load_params ctx info t.tparams p
+					load_params ctx info t.tparams ptp.pos_full
 				| ParamSpawnMonos ->
 					Monomorph.spawn_constrained_monos (fun t -> t) info.build_params
 				| ParamCustom f ->
 					f info None
 			end else
-				load_params ctx info t.tparams p
+				load_params ctx info t.tparams ptp.pos_full
 			in
 			let t = info.build_apply tl in
-			maybe_build_instance ctx t get_params p
+			maybe_build_instance ctx t get_params ptp.pos_full
 		end
 
-and load_instance ctx ?(allow_display=false) ((_,pn) as tp) get_params =
+and load_instance ctx ?(allow_display=false) ptp get_params =
 	try
-		let t = load_instance' ctx tp get_params in
-		if allow_display then DisplayEmitter.check_display_type ctx t tp;
+		let t = load_instance' ctx ptp get_params in
+		if allow_display then DisplayEmitter.check_display_type ctx t ptp;
 		t
-	with Error { err_message = Module_not_found path } when ctx.macro_depth <= 0 && (ctx.com.display.dms_kind = DMDefault) && DisplayPosition.display_position#enclosed_in pn ->
+	with Error { err_message = Module_not_found path } when ctx.macro_depth <= 0 && (ctx.com.display.dms_kind = DMDefault) && DisplayPosition.display_position#enclosed_in ptp.pos_path ->
 		let s = s_type_path path in
-		DisplayToplevel.collect_and_raise ctx TKType NoValue CRTypeHint (s,pn) (patch_string_pos pn s)
+		DisplayToplevel.collect_and_raise ctx TKType NoValue CRTypeHint (s,ptp.pos_full) ptp.pos_path
 
 (*
 	build an instance from a complex type
@@ -475,8 +476,8 @@ and load_instance ctx ?(allow_display=false) ((_,pn) as tp) get_params =
 and load_complex_type' ctx allow_display (t,p) =
 	match t with
 	| CTParent t -> load_complex_type ctx allow_display t
-	| CTPath { tpackage = ["$"]; tname = "_hx_mono" } -> spawn_monomorph ctx p
-	| CTPath t -> load_instance ~allow_display ctx (t,p) ParamNormal
+	| CTPath { path = {tpackage = ["$"]; tname = "_hx_mono" }} -> spawn_monomorph ctx p
+	| CTPath ptp -> load_instance ~allow_display ctx ptp ParamNormal
 	| CTOptional _ -> raise_typing_error "Optional type not allowed here" p
 	| CTNamed _ -> raise_typing_error "Named type not allowed here" p
 	| CTIntersection tl ->
@@ -521,9 +522,9 @@ and load_complex_type' ctx allow_display (t,p) =
 				| _ ->
 					raise_typing_error "Can only extend structures" p
 			in
-			let il = List.map (fun (t,pn) ->
+			let il = List.map (fun ptp ->
 				try
-					(load_instance ctx ~allow_display (t,pn) ParamNormal,pn)
+					(load_instance ctx ~allow_display ptp ParamNormal,ptp.pos_full)
 				with DisplayException(DisplayFields ({fkind = CRTypeHint} as r)) ->
 					let l = List.filter (fun item -> match item.ci_kind with
 						| ITType({kind = Struct},_) -> true
@@ -584,7 +585,7 @@ and load_complex_type' ctx allow_display (t,p) =
 					no_expr e;
 					let t = (match t with None -> raise_typing_error "Type required for structure property" p | Some t -> t) in
 					load_complex_type ctx allow_display t, Var { v_read = AccNormal; v_write = AccNever }
-				| FVar (Some (CTPath({tpackage=[];tname="Void"}),_), _)  | FProp (_,_,Some (CTPath({tpackage=[];tname="Void"}),_),_) ->
+				| FVar (Some (CTPath({path = {tpackage=[];tname="Void"}}),_), _)  | FProp (_,_,Some (CTPath({path = {tpackage=[];tname="Void"}}),_),_) ->
 					raise_typing_error "Fields of type Void are not allowed in structures" p
 				| FVar (t, e) ->
 					no_expr e;
@@ -642,7 +643,7 @@ and load_complex_type' ctx allow_display (t,p) =
 		TAnon a
 	| CTFunction (args,r) ->
 		match args with
-		| [CTPath { tpackage = []; tparams = []; tname = "Void" },_] ->
+		| [CTPath { path = {tpackage = []; tparams = []; tname = "Void" }},_] ->
 			TFun ([],load_complex_type ctx allow_display r)
 		| _ ->
 			TFun (List.map (fun t ->
@@ -720,34 +721,11 @@ and init_meta_overloads ctx co cf =
 	) cf.cf_meta;
 	cf.cf_overloads <- (List.rev !overloads)
 
-let hide_params ctx =
-	let old_m = ctx.m in
-	let old_type_params = ctx.type_params in
-	let old_deps = ctx.g.std.m_extra.m_deps in
-	ctx.m <- {
-		curmod = ctx.g.std;
-		import_resolution = new Resolution.resolution_list ["hide_params"];
-		own_resolution = None;
-		enum_with_type = None;
-		module_using = [];
-		import_statements = [];
-	};
-	ctx.type_params <- [];
-	(fun() ->
-		ctx.m <- old_m;
-		ctx.type_params <- old_type_params;
-		(* restore dependencies that might be have been wronly inserted *)
-		ctx.g.std.m_extra.m_deps <- old_deps;
-	)
-
-let t_iterator ctx =
-	let show = hide_params ctx in
-	match load_type_def ctx null_pos (mk_type_path ([],"Iterator")) with
+let t_iterator ctx p =
+	match load_qualified_type_def ctx [] "StdTypes" "Iterator" p with
 	| TTypeDecl t ->
-		show();
 		add_dependency ctx.m.curmod t.t_module;
-		if List.length t.t_params <> 1 then die "" __LOC__;
-		let pt = mk_mono() in
+		let pt = spawn_monomorph ctx p in
 		apply_typedef t [pt], pt
 	| _ ->
 		die "" __LOC__
@@ -853,13 +831,13 @@ let load_core_class ctx c =
 			c
 	) in
 	let tpath = match c.cl_kind with
-		| KAbstractImpl a -> mk_type_path a.a_path
-		| _ -> mk_type_path c.cl_path
+		| KAbstractImpl a -> a.a_path
+		| _ -> c.cl_path
 	in
-	let t = load_instance ctx2 (tpath,c.cl_pos) ParamSpawnMonos in
+	let t = load_type_def' ctx2 (fst c.cl_module.m_path) (snd c.cl_module.m_path) (snd tpath) null_pos in
 	flush_pass ctx2 PFinal ("core_final",(fst c.cl_path @ [snd c.cl_path]));
 	match t with
-	| TInst (ccore,_) | TAbstract({a_impl = Some ccore}, _) ->
+	| TClassDecl ccore | TAbstractDecl {a_impl = Some ccore} ->
 		ccore
 	| _ ->
 		die "" __LOC__
@@ -934,8 +912,4 @@ let init_core_api ctx c =
 	| Some cf, _ when not (has_class_field_flag cf CfPublic) -> ()
 	| Some f, Some f2 -> compare_fields f f2
 	| None, Some cf when not (has_class_field_flag cf CfPublic) -> ()
-	| _ -> raise_typing_error "Constructor differs from core type" c.cl_pos)
-
-let string_list_of_expr_path (e,p) =
-	try string_list_of_expr_path_raise (e,p)
-	with Exit -> raise_typing_error "Invalid path" p
+	| _ -> raise_typing_error "Constructor differs from core type" c.cl_pos)

+ 105 - 69
src/typing/typeloadCheck.ml

@@ -165,70 +165,100 @@ let check_native_name_override ctx child base =
 			error base.cf_name_pos child_pos
 	with Not_found -> ()
 
+type redefinition_context = {
+	c_new : tclass;
+	cf_new : tclass_field;
+	c_old : tclass;
+	cf_old : tclass_field;
+	map : Type.t -> Type.t;
+	t_old : Type.t;
+}
+
+let check_override_field ctx p rctx =
+	let i = rctx.cf_new.cf_name in
+	let f_has_override = has_class_field_flag rctx.cf_new CfOverride in
+	check_native_name_override ctx rctx.cf_new rctx.cf_old;
+	(* allow to define fields that are not defined for this platform version in superclass *)
+	(match rctx.cf_new.cf_kind with
+	| Var { v_read = AccRequire _ } -> raise Not_found;
+	| _ -> ());
+	if has_class_field_flag rctx.cf_old CfAbstract then begin
+		if f_has_override then
+			display_error ctx.com ("Field " ^ i ^ " is declared 'override' but parent field " ^ i ^ " is 'abstract' and does not provide any implementation to override") p
+		else
+			add_class_field_flag rctx.cf_new CfOverride (* our spec requires users to not "override" abstract functions, but our implementation depends on implementations to be declared with "override" ¯\_(ツ)_/¯ *)
+	end;
+	if (has_class_field_flag rctx.cf_old CfOverload && not (has_class_field_flag rctx.cf_new CfOverload)) then
+		display_error ctx.com ("Field " ^ i ^ " should be declared with overload since it was already declared as overload in superclass") p
+	else if not f_has_override && not (has_class_field_flag rctx.cf_old CfAbstract) then begin
+		if has_class_flag rctx.c_new CExtern then add_class_field_flag rctx.cf_new CfOverride
+		else display_error ctx.com ("Field " ^ i ^ " should be declared with 'override' since it is inherited from superclass " ^ s_type_path rctx.c_old.cl_path) p
+	end else if not (has_class_field_flag rctx.cf_new CfPublic) && (has_class_field_flag rctx.cf_old CfPublic) then
+		display_error ctx.com ("Field " ^ i ^ " has less visibility (public/private) than superclass one") p
+	else (match rctx.cf_new.cf_kind, rctx.cf_old.cf_kind with
+	| _, Method MethInline ->
+		display_error ctx.com ("Field " ^ i ^ " is inlined and cannot be overridden") p
+	| a, b when a = b -> ()
+	| Method MethInline, Method MethNormal ->
+		() (* allow to redefine a method as inlined *)
+	| _ ->
+		display_error ctx.com ("Field " ^ i ^ " has different property access than in superclass") p);
+	if (has_class_field_flag rctx.cf_old CfFinal) then display_error ctx.com ("Cannot override final method " ^ i) p;
+	try
+		valid_redefinition ctx rctx.map rctx.map rctx.cf_new rctx.cf_new.cf_type rctx.cf_old rctx.t_old;
+	with
+		Unify_error l ->
+			(* TODO construct error with sub *)
+			display_error ctx.com ("Field " ^ i ^ " overrides parent class with different or incomplete type") p;
+			display_error ~depth:1 ctx.com (compl_msg "Base field is defined here") rctx.cf_old.cf_name_pos;
+			display_error ~depth:1 ctx.com (compl_msg (error_msg (Unify l))) p
+
+let find_override_field ctx c_new cf_new c_old tl get_super_field is_overload p =
+	let i = cf_new.cf_name in
+	try
+		if is_overload && not (has_class_field_flag cf_new CfOverload) then
+			display_error ctx.com ("Missing overload declaration for field " ^ i) p;
+		let t, f2 = get_super_field c_old i in
+		let map = TClass.get_map_function c_old tl in
+		let rctx = {
+			c_new = c_new;
+			cf_new = cf_new;
+			c_old = c_old;
+			cf_old = f2;
+			map = map;
+			t_old = map t;
+		} in
+		Some rctx
+	with Not_found ->
+		if has_class_field_flag cf_new CfOverride then begin
+			let msg = if is_overload then
+				("Field " ^ i ^ " is declared 'override' but no compatible overload was found")
+			else begin
+				let fields = TClass.get_all_super_fields c_new in
+				let fields = PMap.fold (fun (_,cf) acc -> match cf.cf_kind with
+					| Method MethNormal when not (has_class_field_flag cf CfFinal) -> cf.cf_name :: acc
+					| _ -> acc
+				) fields [] in
+				StringError.string_error i fields ("Field " ^ i ^ " is declared 'override' but doesn't override any field")
+			end in
+			display_error ctx.com msg p;
+		end;
+		None
+
+type check_override_kind =
+	| NothingToDo
+	| NormalOverride of redefinition_context
+	| OverloadOverride of (unit -> unit)
+
 let check_overriding ctx c f =
 	match c.cl_super with
 	| None ->
-		if has_class_field_flag f CfOverride then display_error ctx.com ("Field " ^ f.cf_name ^ " is declared 'override' but doesn't override any field") f.cf_pos
+		if has_class_field_flag f CfOverride then
+			display_error ctx.com ("Field " ^ f.cf_name ^ " is declared 'override' but doesn't override any field") f.cf_pos;
+		NothingToDo
 	| Some (csup,params) ->
 		let p = f.cf_name_pos in
 		let i = f.cf_name in
-		let check_field f get_super_field is_overload = try
-			(if is_overload && not (has_class_field_flag f CfOverload) then
-				display_error ctx.com ("Missing overload declaration for field " ^ i) p);
-			let f_has_override = has_class_field_flag f CfOverride in
-			let t, f2 = get_super_field csup i in
-			check_native_name_override ctx f f2;
-			(* allow to define fields that are not defined for this platform version in superclass *)
-			(match f2.cf_kind with
-			| Var { v_read = AccRequire _ } -> raise Not_found;
-			| _ -> ());
-			if has_class_field_flag f2 CfAbstract then begin
-				if f_has_override then
-					display_error ctx.com ("Field " ^ i ^ " is declared 'override' but parent field " ^ i ^ " is 'abstract' and does not provide any implementation to override") p
-				else
-					add_class_field_flag f CfOverride (* our spec requires users to not "override" abstract functions, but our implementation depends on implementations to be declared with "override" ¯\_(ツ)_/¯ *)
-			end;
-			if (has_class_field_flag f2 CfOverload && not (has_class_field_flag f CfOverload)) then
-				display_error ctx.com ("Field " ^ i ^ " should be declared with overload since it was already declared as overload in superclass") p
-			else if not f_has_override && not (has_class_field_flag f2 CfAbstract) then begin
-				if has_class_flag c CExtern then add_class_field_flag f CfOverride
-				else display_error ctx.com ("Field " ^ i ^ " should be declared with 'override' since it is inherited from superclass " ^ s_type_path csup.cl_path) p
-			end else if not (has_class_field_flag f CfPublic) && (has_class_field_flag f2 CfPublic) then
-				display_error ctx.com ("Field " ^ i ^ " has less visibility (public/private) than superclass one") p
-			else (match f.cf_kind, f2.cf_kind with
-			| _, Method MethInline ->
-				display_error ctx.com ("Field " ^ i ^ " is inlined and cannot be overridden") p
-			| a, b when a = b -> ()
-			| Method MethInline, Method MethNormal ->
-				() (* allow to redefine a method as inlined *)
-			| _ ->
-				display_error ctx.com ("Field " ^ i ^ " has different property access than in superclass") p);
-			if (has_class_field_flag f2 CfFinal) then display_error ctx.com ("Cannot override final method " ^ i) p;
-			try
-				let t = apply_params csup.cl_params params t in
-				let map = TClass.get_map_function csup params in
-				valid_redefinition ctx map map f f.cf_type f2 t;
-			with
-				Unify_error l ->
-					(* TODO construct error with sub *)
-					display_error ctx.com ("Field " ^ i ^ " overrides parent class with different or incomplete type") p;
-					display_error ~depth:1 ctx.com (compl_msg "Base field is defined here") f2.cf_name_pos;
-					display_error ~depth:1 ctx.com (compl_msg (error_msg (Unify l))) p;
-		with
-			Not_found ->
-				if has_class_field_flag f CfOverride then
-					let msg = if is_overload then
-						("Field " ^ i ^ " is declared 'override' but no compatible overload was found")
-					else begin
-						let fields = TClass.get_all_super_fields c in
-						let fields = PMap.fold (fun (_,cf) acc -> match cf.cf_kind with
-							| Method MethNormal when not (has_class_field_flag cf CfFinal) -> cf.cf_name :: acc
-							| _ -> acc
-						) fields [] in
-						StringError.string_error i fields ("Field " ^ i ^ " is declared 'override' but doesn't override any field")
-					end in
-					display_error ctx.com msg p
-		in
 		if has_class_field_flag f CfOverload then begin
 			let overloads = Overloads.get_overloads ctx.com csup i in
 			List.iter (fun (t,f2) ->
@@ -236,20 +266,27 @@ let check_overriding ctx c f =
 				match f2.cf_kind with
 				| Var _ ->
 					display_error ctx.com ("A variable named '" ^ f2.cf_name ^ "' was already declared in a superclass") f.cf_pos
-				| _ -> ()
+				| _ ->
+					()
 			) overloads;
-			List.iter (fun f ->
+			OverloadOverride (fun () ->
 				(* find the exact field being overridden *)
-				check_field f (fun csup i ->
+				Option.may (check_override_field ctx p) (find_override_field ctx c f csup params (fun csup i ->
 					List.find (fun (t,f2) ->
 						Overloads.same_overload_args f.cf_type (apply_params csup.cl_params params t) f f2
 					) overloads
-				) true
-			) (f :: f.cf_overloads)
+				) true p)
+			)
 		end else
-			check_field f (fun csup i ->
+			let rctx = find_override_field ctx c f csup params (fun csup i ->
 				let _, t, f2 = raw_class_field (fun f -> f.cf_type) csup params i in
-				t, f2) false
+				t, f2
+			) false p in
+			match rctx with
+			| None ->
+				NothingToDo
+			| Some rctx ->
+				NormalOverride rctx
 
 let class_field_no_interf c i =
 	try
@@ -435,7 +472,6 @@ module Inheritance = struct
 
 	let check_interfaces ctx c =
 		match c.cl_path with
-		| "Proxy" :: _ , _ -> ()
 		| _ ->
 		List.iter (fun (intf,params) ->
 			let missing = DynArray.create () in
@@ -590,10 +626,10 @@ module Inheritance = struct
 					raise_typing_error "Should implement by using an interface" p
 			end
 		in
-		let fl = ExtList.List.filter_map (fun (is_extends,(ct,p)) ->
+		let fl = ExtList.List.filter_map (fun (is_extends,ptp) ->
 			try
 				let t = try
-					Typeload.load_instance ~allow_display:true ctx (ct,p) ParamNormal
+					Typeload.load_instance ~allow_display:true ctx ptp ParamNormal
 				with DisplayException(DisplayFields ({fkind = CRTypeHint} as r)) ->
 					(* We don't allow `implements` on interfaces. Just raise fields completion with no fields. *)
 					if not is_extends && (has_class_flag c CInterface) then raise_fields [] CRImplements r.fsubject;
@@ -607,7 +643,7 @@ module Inheritance = struct
 					) r.fitems in
 					raise_fields l (if is_extends then CRExtends else CRImplements) r.fsubject
 				in
-				Some (check_herit t is_extends p)
+				Some (check_herit t is_extends ptp.pos_full)
 			with Error { err_message = Module_not_found(([],name)); err_pos = p } when ctx.com.display.dms_kind <> DMNone ->
 				if Diagnostics.error_in_diagnostics_run ctx.com p then DisplayToplevel.handle_unresolved_identifier ctx name p true;
 				None

+ 26 - 39
src/typing/typeloadFields.ml

@@ -479,8 +479,8 @@ let build_module_def ctx mt meta fvars fbuild =
 				let r = try ctx.g.do_macro ctx MBuild cpath meth el p with e -> ctx.get_build_infos <- old; raise e in
 				ctx.get_build_infos <- old;
 				(match r with
-				| None -> raise_typing_error "Build failure" p
-				| Some e -> fbuild e)
+				| MError | MMacroInMacro -> raise_typing_error "Build failure" p
+				| MSuccess e -> fbuild e)
 			) :: f_build
 		| Meta.Using,el,p -> (fun () ->
 			List.iter (fun e ->
@@ -790,7 +790,6 @@ module TypeBinding = struct
 				force_macro false
 			else begin
 				cf.cf_type <- TLazy r;
-				(* is_lib ? *)
 				cctx.delayed_expr <- (ctx,Some r) :: cctx.delayed_expr;
 			end
 		end else if ctx.com.display.dms_force_macro_typing && fctx.is_macro && not ctx.com.is_macro_context then
@@ -853,6 +852,7 @@ module TypeBinding = struct
 		let r = make_lazy ~force:false ctx t (fun r ->
 			(* type constant init fields (issue #1956) *)
 			if not !return_partial_type || (match fst e with EConst _ -> true | _ -> false) then begin
+				enter_field_typing_pass ctx ("bind_var_expression",fst ctx.curclass.cl_path @ [snd ctx.curclass.cl_path;ctx.curfield.cf_name]);
 				if (Meta.has (Meta.Custom ":debug.typing") (c.cl_meta @ cf.cf_meta)) then ctx.com.print (Printf.sprintf "Typing field %s.%s\n" (s_type_path c.cl_path) cf.cf_name);
 				let e = type_var_field ctx t e fctx.is_static fctx.is_display_field p in
 				let maybe_run_analyzer e = match e.eexpr with
@@ -944,11 +944,23 @@ module TypeBinding = struct
 					cf.cf_type <- t
 				| _ ->
 					if Meta.has Meta.DisplayOverride cf.cf_meta then DisplayEmitter.check_field_modifiers ctx c cf fctx.override fctx.display_modifier;
+					let f_check = match fctx.field_kind with
+						| FKNormal when not fctx.is_static ->
+							begin match TypeloadCheck.check_overriding ctx c cf with
+							| NothingToDo ->
+								(fun () -> ())
+							| NormalOverride rctx ->
+								(fun () -> 
+									TypeloadCheck.check_override_field ctx cf.cf_name_pos rctx
+								)
+							| OverloadOverride f ->
+								f
+							end
+						| _ ->
+							(fun () -> ())
+					in					
 					let e = TypeloadFunction.type_function ctx args ret fmode e fctx.is_display_field p in
-					begin match fctx.field_kind with
-					| FKNormal when not fctx.is_static -> TypeloadCheck.check_overriding ctx c cf
-					| _ -> ()
-					end;
+					f_check();
 					(* Disabled for now, see https://github.com/HaxeFoundation/haxe/issues/3033 *)
 					(* List.iter (fun (v,_) ->
 						if v.v_name <> "_" && has_mono v.v_type then warning ctx WTemp "Uninferred function argument, please add a type-hint" v.v_pos;
@@ -1292,11 +1304,11 @@ let create_method (ctx,cctx,fctx) c f fd p =
 		if ctx.com.is_macro_context then begin
 			(* a class with a macro cannot be extern in macro context (issue #2015) *)
 			remove_class_flag c CExtern;
-			let texpr = CTPath (mk_type_path (["haxe";"macro"],"Expr")) in
+			let texpr = make_ptp_ct (mk_type_path (["haxe";"macro"],"Expr")) null_pos in
 			(* ExprOf type parameter might contain platform-specific type, let's replace it by Expr *)
 			let no_expr_of (t,p) = match t with
-				| CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some ("ExprOf"); tparams = [TPType _] }
-				| CTPath { tpackage = []; tname = ("ExprOf"); tsub = None; tparams = [TPType _] } -> Some (texpr,p)
+				| CTPath { path = {tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some ("ExprOf"); tparams = [TPType _] }}
+				| CTPath { path = {tpackage = []; tname = ("ExprOf"); tsub = None; tparams = [TPType _] }} -> Some (texpr,p)
 				| t -> Some (t,p)
 			in
 			{
@@ -1306,8 +1318,8 @@ let create_method (ctx,cctx,fctx) c f fd p =
 				f_expr = fd.f_expr;
 			}
 		end else
-			let tdyn = Some (CTPath (mk_type_path ([],"Dynamic")),null_pos) in
-			let to_dyn p t = match t with
+			let tdyn = Some (make_ptp_th (mk_type_path ([],"Dynamic")) null_pos) in
+			let to_dyn p ptp = match ptp.path with
 				| { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some ("ExprOf"); tparams = [TPType t] } -> Some t
 				| { tpackage = []; tname = ("ExprOf"); tsub = None; tparams = [TPType t] } -> Some t
 				| { tpackage = ["haxe"]; tname = ("PosInfos"); tsub = None; tparams = [] } -> raise_typing_error "haxe.PosInfos is not allowed on macro functions, use Context.currentPos() instead" p
@@ -1330,9 +1342,9 @@ let create_method (ctx,cctx,fctx) c f fd p =
 			if fctx.is_static then invalid_modifier ctx.com fctx "static" "constructor" p;
 			begin match fd.f_type with
 				| None -> ()
-				| Some (CTPath ({ tpackage = []; tname = "Void" } as tp),p) ->
+				| Some (CTPath ({ path = {tpackage = []; tname = "Void" } as tp}),p) ->
 					if ctx.is_display_file && DisplayPosition.display_position#enclosed_in p then
-						ignore(load_instance ~allow_display:true ctx (tp,p) ParamNormal);
+						ignore(load_instance ~allow_display:true ctx (make_ptp tp p) ParamNormal);
 				| _ -> raise_typing_error "A class constructor can't have a return type" p;
 			end
 		| false,_ ->
@@ -1349,7 +1361,6 @@ let create_method (ctx,cctx,fctx) c f fd p =
 	if (is_override && fctx.is_static) then invalid_modifier_combination fctx ctx.com fctx "override" "static" p;
 
 	ctx.type_params <- if fctx.is_static && not fctx.is_abstract_member then params else params @ ctx.type_params;
-	(* TODO is_lib: avoid forcing the return type to be typed *)
 	let args,ret = setup_args_ret ctx cctx fctx (fst f.cff_name) fd p in
 	let t = TFun (args#for_type,ret) in
 	let cf = {
@@ -1440,7 +1451,6 @@ let create_method (ctx,cctx,fctx) c f fd p =
 
 let create_property (ctx,cctx,fctx) c f (get,set,t,eo) p =
 	let name = fst f.cff_name in
-	(* TODO is_lib: lazify load_complex_type *)
 	let ret = (match t, eo with
 		| None, None -> raise_typing_error "Property requires type-hint or initialization" p;
 		| None, _ -> mk_mono()
@@ -1865,29 +1875,6 @@ let init_class ctx c p herits fields =
 	end;
 	c.cl_ordered_statics <- List.rev c.cl_ordered_statics;
 	c.cl_ordered_fields <- List.rev c.cl_ordered_fields;
-	(* if ctx.is_display_file && not cctx.has_display_field && Display.is_display_position c.cl_pos && ctx.com.display.dms_kind = DMToplevel then begin
-		let rec loop acc c tl =
-			let maybe_add acc cf = match cf.cf_kind with
-				| Method MethNormal when not (PMap.mem cf.cf_name acc) -> PMap.add cf.cf_name cf acc
-				| _ -> acc
-			in
-			let acc = List.fold_left maybe_add PMap.empty c.cl_ordered_fields in
-			match c.cl_super with
-			| Some(c,tl) -> loop acc c tl
-			| None -> acc
-		in
-		let fields = match c.cl_super with
-			| Some(c,tl) -> loop PMap.empty c tl
-			| None -> PMap.empty
-		in
-		let open Display in
-		let l = PMap.fold (fun cf acc ->
-			if not (List.exists (fun cf' -> cf'.cf_name = cf.cf_name) c.cl_overrides) then
-				(IdentifierType.ITClassMember cf) :: acc
-			else acc
-		) fields [] in
-		raise (Display.DisplayToplevel l)
-	end; *)
 	(*
 		make sure a default contructor with same access as super one will be added to the class structure at some point.
 	*)

+ 2 - 1
src/typing/typeloadFunction.ml

@@ -54,6 +54,7 @@ let type_function ctx (args : function_arguments) ret fmode e do_display p =
 	ctx.ret <- ret;
 	ctx.opened <- [];
 	ctx.monomorphs.perfunction <- [];
+	enter_field_typing_pass ctx ("type_function",fst ctx.curclass.cl_path @ [snd ctx.curclass.cl_path;ctx.curfield.cf_name]);
 	args#bring_into_context;
 	let e = match e with
 		| None ->
@@ -191,7 +192,7 @@ let add_constructor ctx c force_constructor p =
 		let r = make_lazy ctx t (fun r ->
 			let ctx = { ctx with
 				curfield = cf;
-				pass = PTypeField;
+				pass = PConnectField;
 			} in
 			ignore (follow cfsup.cf_type); (* make sure it's typed *)
 			List.iter (fun cf -> ignore (follow cf.cf_type)) cf.cf_overloads;

+ 5 - 7
src/typing/typeloadModule.ml

@@ -214,8 +214,8 @@ module ModuleLevel = struct
 					acc
 				| fields ->
 					let a_t =
-						let params = List.map (fun t -> TPType (CTPath (mk_type_path ([],fst t.tp_name)),null_pos)) d.d_params in
-						CTPath (mk_type_path ~params ([],fst d.d_name)),null_pos
+						let params = List.map (fun t -> TPType (make_ptp_th (mk_type_path ([],fst t.tp_name)) null_pos)) d.d_params in
+						make_ptp_ct_null (mk_type_path ~params ([],fst d.d_name)),null_pos
 					in
 					let rec loop = function
 						| [] -> a_t
@@ -372,7 +372,7 @@ module TypeLevel = struct
 				is_flat := false;
 				let pnames = ref PMap.empty in
 				TFun (List.map (fun (s,opt,(t,tp)) ->
-					(match t with CTPath({tpackage=[];tname="Void"}) -> raise_typing_error "Arguments of type Void are not allowed in enum constructors" tp | _ -> ());
+					(match t with CTPath({path = {tpackage=[];tname="Void"}}) -> raise_typing_error "Arguments of type Void are not allowed in enum constructors" tp | _ -> ());
 					if PMap.mem s (!pnames) then raise_typing_error ("Duplicate argument `" ^ s ^ "` in enum constructor " ^ fst c.ec_name) p;
 					pnames := PMap.add s () (!pnames);
 					s, opt, load_type_hint ~opt ctx p (Some (t,tp))
@@ -446,10 +446,8 @@ module TypeLevel = struct
 			in
 			build()
 		in
-		ctx.pass <- PBuildClass;
 		ctx.curclass <- c;
 		c.cl_build <- make_pass ctx build;
-		ctx.pass <- PBuildModule;
 		ctx.curclass <- null_class;
 		delay ctx PBuildClass (fun() -> ignore(c.cl_build()));
 		if Meta.has Meta.InheritDoc c.cl_meta then
@@ -560,7 +558,7 @@ module TypeLevel = struct
 		let tt = load_complex_type ctx true d.d_data in
 		let tt = (match fst d.d_data with
 		| CTExtend _ -> tt
-		| CTPath { tpackage = ["haxe";"macro"]; tname = "MacroType" } ->
+		| CTPath { path = {tpackage = ["haxe";"macro"]; tname = "MacroType" }} ->
 			(* we need to follow MacroType immediately since it might define other module types that we will load afterwards *)
 			if t.t_type == follow tt then raise_typing_error "Recursive typedef is not allowed" p;
 			tt
@@ -764,7 +762,7 @@ let type_types_into_module ctx m tdecls p =
 	if ctx.g.std != null_module then begin
 		add_dependency m ctx.g.std;
 		(* this will ensure both String and (indirectly) Array which are basic types which might be referenced *)
-		ignore(load_instance ctx (mk_type_path (["std"],"String"),null_pos) ParamNormal)
+		ignore(load_instance ctx (make_ptp (mk_type_path (["std"],"String")) null_pos) ParamNormal)
 	end;
 	ModuleLevel.init_type_params ctx decls;
 	(* setup module types *)

+ 17 - 17
src/typing/typeloadParse.ml

@@ -58,23 +58,23 @@ let parse_file_from_lexbuf com file p lexbuf =
 let parse_file_from_string com file p string =
 	parse_file_from_lexbuf com file p (Sedlexing.Utf8.from_string string)
 
-let current_stdin = ref None (* TODO: we're supposed to clear this at some point *)
-
 let parse_file com file p =
-	let use_stdin = (Common.defined com Define.DisplayStdin) && DisplayPosition.display_position#is_in_file (com.file_keys#get file) in
-	if use_stdin then
-		let s =
-			match !current_stdin with
-			| Some s ->
-				s
-			| None ->
-				let s = Std.input_all stdin in
-				close_in stdin;
-				current_stdin := Some s;
-				s
-		in
+	let file_key = com.file_keys#get file in
+	let contents = match com.file_contents with
+		| [] when (Common.defined com Define.DisplayStdin) && DisplayPosition.display_position#is_in_file file_key ->
+			let s = Std.input_all stdin in
+			close_in stdin;
+			com.file_contents <- [file_key, Some s];
+			Some s
+		| [] -> None
+		| files ->
+			(try List.assoc file_key files with Not_found -> None)
+	in
+
+	match contents with
+	| Some s ->
 		parse_file_from_string com file p s
-	else
+	| _ ->
 		let ch = try open_in_bin file with _ -> raise_typing_error ("Could not open " ^ file) p in
 		Std.finally (fun() -> close_in ch) (parse_file_from_lexbuf com file p) (Sedlexing.Utf8.from_channel ch)
 
@@ -323,12 +323,12 @@ let parse_module ctx m p =
 							else
 								let params =
 									List.map (fun tp ->
-										TPType (CTPath (mk_type_path ([],fst tp.tp_name)),null_pos)
+										TPType (make_ptp_th_null (mk_type_path ([],fst tp.tp_name)))
 									) d.d_params
 								in
 								mk_type_path ~params (!remap,fst d.d_name)
 						in
-						CTPath (tp),null_pos;
+						make_ptp_th_null tp
 					end
 				},p) :: acc
 			in

+ 39 - 35
src/typing/typer.ml

@@ -417,6 +417,7 @@ let rec type_ident_raise ctx i p mode with_type =
 	| _ ->
 	try
 		let v = PMap.find i ctx.locals in
+		add_var_flag v VUsedByTyper;
 		(match v.v_extra with
 		| Some ve ->
 			let (params,e) = (ve.v_params,ve.v_expr) in
@@ -940,25 +941,28 @@ and type_object_decl ctx fl with_type p =
 		mk (TBlock (List.rev (e :: (List.rev evars)))) e.etype e.epos
 	)
 
-and type_new ctx (path,p_path) el with_type force_inline p =
-	let p_path =
-		if p_path <> null_pos then
-			p_path
+and type_new ctx ptp el with_type force_inline p =
+	let ptp =
+		if ptp.pos_full <> null_pos then
+			ptp
 		(*
 			Since macros don't have placed_type_path structure on Haxe side any ENew will have null_pos in `path`.
 			Try to calculate a better pos.
 		*)
 		else begin
-			match el with
-			| (_,p1) :: _ when p1.pfile = p.pfile && p.pmin < p1.pmin ->
-				let pmin = p.pmin + (String.length "new ")
-				and pmax = p1.pmin - 2 (* Additional "1" for an opening bracket *)
-				in
-				{ p with
-					pmin = if pmin < pmax then pmin else p.pmin;
-					pmax = pmax;
-				}
-			| _ -> p
+			let p = match el with
+				| (_,p1) :: _ when p1.pfile = p.pfile && p.pmin < p1.pmin ->
+					let pmin = p.pmin + (String.length "new ")
+					and pmax = p1.pmin - 2 (* Additional "1" for an opening bracket *)
+					in
+					{ p with
+						pmin = if pmin < pmax then pmin else p.pmin;
+						pmax = pmax;
+					}
+				| _ ->
+					p
+			in
+			make_ptp ptp.path p
 		end
 	in
 	let display_position_in_el () =
@@ -1016,14 +1020,14 @@ and type_new ctx (path,p_path) el with_type force_inline p =
 		)
 	in
 	let t = try
-		Typeload.load_instance ctx (path,p_path) (ParamCustom get_params)
+		Typeload.load_instance ctx ptp (ParamCustom get_params)
 	with exc ->
 		restore();
 		(* If we fail for some reason, process the arguments in case we want to display them (#7650). *)
 		if display_position_in_el () then List.iter (fun e -> ignore(type_expr ctx e WithType.value)) el;
 		raise exc
 	in
-	DisplayEmitter.check_display_type ctx t (path,p_path);
+	DisplayEmitter.check_display_type ctx t ptp;
 	let t = follow t in
 	let build_constructor_call ao c tl =
 		let fa = FieldAccess.get_constructor_access c tl p in
@@ -1057,7 +1061,7 @@ and type_new ctx (path,p_path) el with_type force_inline p =
 		raise_typing_error (s_type (print_context()) t ^ " cannot be constructed") p
 	end with Error ({ err_message = No_constructor _ } as err) when ctx.com.display.dms_kind <> DMNone ->
 		display_error_ext ctx.com err;
-		Diagnostics.secure_generated_code ctx.com (mk (TConst TNull) t p)
+		mk (TConst TNull) t p
 
 and type_try ctx e1 catches with_type p =
 	let e1 = type_expr ctx (Expr.ensure_block e1) with_type in
@@ -1093,7 +1097,7 @@ and type_try ctx e1 catches with_type p =
 		) params
 	in
 	let catches,el = List.fold_left (fun (acc1,acc2) ((v,pv),t,e_ast,pc) ->
-		let th = Option.default (CTPath { tpackage = ["haxe"]; tname = "Exception"; tsub = None; tparams = [] },null_pos) t in
+		let th = Option.default (make_ptp_th { tpackage = ["haxe"]; tname = "Exception"; tsub = None; tparams = [] } null_pos) t in
 		let t = Typeload.load_complex_type ctx true th in
 		let rec loop t = match follow t with
 			| TInst ({ cl_kind = KTypeParameter _} as c,_) when not (TypeloadCheck.is_generic_parameter ctx c) ->
@@ -1454,7 +1458,7 @@ and type_array_comprehension ctx e with_type p =
 			end
 		| EParenthesis e2 -> (EParenthesis (map_compr e2),p)
 		| EBinop(OpArrow,a,b) ->
-			et := (ENew(({tpackage=["haxe";"ds"];tname="Map";tparams=[];tsub=None},null_pos),[]),comprehension_pos);
+			et := (ENew(make_ptp {tpackage=["haxe";"ds"];tname="Map";tparams=[];tsub=None} null_pos,[]),comprehension_pos);
 			(ECall ((efield (e_ref,"set"),p),[a;b]),p)
 		| _ ->
 			et := (EArrayDecl [],comprehension_pos);
@@ -1729,17 +1733,17 @@ and type_call_builtin ctx e el mode with_type p =
 		(match follow e.etype with
 			| TFun signature -> type_bind ctx e signature args p
 			| _ -> raise Exit)
-	| (EConst (Ident "$type"),_) , [e] ->
-		begin match fst e with
-		| EConst (Ident "_") ->
-			warning ctx WInfo (WithType.to_string with_type) p;
-			mk (TConst TNull) t_dynamic p
-		| _ ->
-			let e = type_expr ctx e WithType.value in
-			warning ctx WInfo (s_type (print_context()) e.etype) e.epos;
-			let e = Diagnostics.secure_generated_code ctx.com e in
-			e
-		end
+	| (EConst (Ident "$type"),_) , e1 :: el ->
+		let e1 = type_expr ctx e1 with_type in
+		let s = s_type (print_context()) e1.etype in
+		let s = match el with
+			| [EConst (Ident "_"),_] ->
+				Printf.sprintf "%s (expected: %s)" s (WithType.to_string with_type)
+			| _ ->
+				s
+		in
+		warning ctx WInfo s e1.epos;
+		e1
 	| (EField(e,"match",efk_todo),p), [epat] ->
 		let et = type_expr ctx e WithType.value in
 		let rec has_enum_match t = match follow t with
@@ -1801,7 +1805,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 	| EConst (Regexp (r,opt)) ->
 		let str = mk (TConst (TString r)) ctx.t.tstring p in
 		let opt = mk (TConst (TString opt)) ctx.t.tstring p in
-		let t = Typeload.load_instance ctx (mk_type_path (["std"],"EReg"),null_pos) ParamNormal in
+		let t = Typeload.load_instance ctx (make_ptp (mk_type_path (["std"],"EReg")) null_pos) ParamNormal in
 		mk (TNew ((match t with TInst (c,[]) -> c | _ -> die "" __LOC__),[],[str;opt])) t p
 	| EConst (String(s,SSingleQuotes)) when s <> "" ->
 		type_expr ctx (format_string ctx s p) with_type
@@ -1825,7 +1829,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 			let call     = ECall (field, [ arg_high; arg_low ]), p in
 			type_expr ctx call with_type
 		| "u32" ->
-			let check = ECheckType ((EConst (Int (s, None)), p), (CTPath (mk_type_path ([],"UInt")), p)), p in
+			let check = ECheckType ((EConst (Int (s, None)), p), (make_ptp_th (mk_type_path ([],"UInt")) p)), p in
 			type_expr ctx check with_type
 		| other -> raise_typing_error (other ^ " is not a valid integer suffix") p)
 	| EConst (Float (s, Some suffix) as c) ->
@@ -1896,7 +1900,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 			| TAbstract({a_path = (["haxe";"ds"],"Map")},[tk;tv]) ->
 				begin match el with
 				| [] ->
-					type_expr ctx (ENew(({tpackage=["haxe";"ds"];tname="Map";tparams=[];tsub=None},null_pos),[]),p) with_type
+					type_expr ctx (ENew(make_ptp {tpackage=["haxe";"ds"];tname="Map";tparams=[];tsub=None} null_pos,[]),p) with_type
 				| [(EDisplay _,_) as e1] ->
 					(* This must mean we're just typing the first key of a map declaration (issue #9133). *)
 					type_expr ctx e1 (WithType.with_type tk)
@@ -2002,9 +2006,9 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 	| EIs (e,(t,p_t)) ->
 		match t with
 		| CTPath tp ->
-			if tp.tparams <> [] then display_error ctx.com "Type parameters are not supported for the `is` operator" p_t;
+			if tp.path.tparams <> [] then display_error ctx.com "Type parameters are not supported for the `is` operator" p_t;
 			let e = type_expr ctx e WithType.value in
-			let mt = Typeload.load_type_def ctx p_t tp in
+			let mt = Typeload.load_type_def ctx p_t tp.path in
 			if ctx.in_display && DisplayPosition.display_position#enclosed_in p_t then
 				DisplayEmitter.display_module_type ctx mt p_t;
 			let e_t = type_module_type ctx mt p_t in

+ 5 - 3
src/typing/typerBase.ml

@@ -155,9 +155,11 @@ let get_this ctx p =
 	| FunMemberClassLocal | FunMemberAbstractLocal ->
 		let v = match ctx.vthis with
 			| None ->
-				let v = if ctx.curfun = FunMemberAbstractLocal then
-					PMap.find "this" ctx.locals
-				else
+				let v = if ctx.curfun = FunMemberAbstractLocal then begin
+					let v = PMap.find "this" ctx.locals in
+					add_var_flag v VUsedByTyper;
+					v
+				end else
 					add_local ctx VGenerated (Printf.sprintf "%sthis" gen_local_prefix) ctx.tthis p
 				in
 				ctx.vthis <- Some v;

+ 23 - 5
src/typing/typerDisplay.ml

@@ -309,9 +309,9 @@ let rec handle_signature_display ctx e_ast with_type =
 				| _ -> [e1.etype,None,PMap.empty]
 			in
 			handle_call tl el e1.epos
-		| ENew(tpath,el) ->
-			let t = Abstract.follow_with_forward_ctor (Typeload.load_instance ctx tpath ParamSpawnMonos) in
-			handle_call (find_constructor_types t) el (pos tpath)
+		| ENew(ptp,el) ->
+			let t = Abstract.follow_with_forward_ctor (Typeload.load_instance ctx ptp ParamSpawnMonos) in
+			handle_call (find_constructor_types t) el ptp.pos_full
 		| EArray(e1,e2) ->
 			let e1 = type_expr ctx e1 WithType.value in
 			begin match follow e1.etype with
@@ -354,9 +354,23 @@ and display_expr ctx e_ast e dk mode with_type p =
 		| _ ->
 			e
 	in
-	let e,el_typed = match e.eexpr with
-		| TMeta((Meta.StaticExtension,[e_self],_),e1) ->
+	let e,el_typed = match fst e_ast,e.eexpr with
+		| _,TMeta((Meta.StaticExtension,[e_self],_),e1) ->
 			e1,[type_stored_expr ctx e_self]
+		| EField((_,_,EFSafe)),e1 ->
+			(* For ?. we want to extract the then-expression of the TIf. *)
+			let rec loop e1 = match e1.eexpr with
+				| TIf({eexpr = TBinop(OpNotEq,_,{eexpr = TConst TNull})},e1,Some _) ->
+					e1
+				| TBlock el ->
+					begin match List.rev el with
+						| e :: _ -> loop e
+						| _ -> e
+					end
+				| _ ->
+					e
+			in
+			loop e,[]
 		| _ ->
 			e,[]
 	in
@@ -411,6 +425,8 @@ and display_expr ctx e_ast e dk mode with_type p =
 			end
 		| TCall(e1,_) ->
 			loop e1
+		| TCast(e1,_) ->
+			loop e1
 		| _ ->
 			()
 		in
@@ -466,6 +482,8 @@ and display_expr ctx e_ast e dk mode with_type p =
 			end
 		| TCall(e1,_) ->
 			loop e1
+		| TCast(e1,_) ->
+			loop e1
 		| _ ->
 			[]
 		in

+ 0 - 228
std/cpp/_std/sys/db/Mysql.hx

@@ -1,228 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-@:keep
-private class D {
-	@:native("_hx_mysql_connect")
-	extern public static function connect(params:Dynamic):Dynamic;
-
-	@:native("_hx_mysql_select_db")
-	extern public static function select_db(handle:Dynamic, db:String):Void;
-
-	@:native("_hx_mysql_request")
-	extern public static function request(handle:Dynamic, req:String):Dynamic;
-
-	@:native("_hx_mysql_close")
-	extern public static function close(handle:Dynamic):Dynamic;
-
-	@:native("_hx_mysql_escape")
-	extern public static function escape(handle:Dynamic, str:String):String;
-
-	@:native("_hx_mysql_result_get_length")
-	extern public static function result_get_length(handle:Dynamic):Int;
-
-	@:native("_hx_mysql_result_get_nfields")
-	extern public static function result_get_nfields(handle:Dynamic):Int;
-
-	@:native("_hx_mysql_result_next")
-	extern public static function result_next(handle:Dynamic):Dynamic;
-
-	@:native("_hx_mysql_result_get")
-	extern public static function result_get(handle:Dynamic, i:Int):String;
-
-	@:native("_hx_mysql_result_get_int")
-	extern public static function result_get_int(handle:Dynamic, i:Int):Int;
-
-	@:native("_hx_mysql_result_get_float")
-	extern public static function result_get_float(handle:Dynamic, i:Int):Float;
-
-	@:native("_hx_mysql_result_get_fields_names")
-	extern public static function result_fields_names(handle:Dynamic):Array<String>;
-
-	@:native("_hx_mysql_set_conversion")
-	extern public static function set_conv_funs(charsToBytes:cpp.Callable<Dynamic->Dynamic>, intToDate:cpp.Callable<Float->Dynamic>):Void;
-
-	public static function charsToBytes(data:Dynamic):Dynamic
-		return haxe.io.Bytes.ofData(data);
-
-	public static function secondsToDate(seconds:Float):Dynamic
-		return Date.fromTime(seconds * 1000);
-}
-
-private class MysqlResultSet implements sys.db.ResultSet {
-	public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	private var __r:Dynamic;
-	private var cache:Dynamic;
-
-	public function new(r:Dynamic) {
-		__r = r;
-	}
-
-	private function get_length() {
-		return D.result_get_length(__r);
-	}
-
-	private function get_nfields() {
-		return D.result_get_nfields(__r);
-	}
-
-	public function hasNext() {
-		if (cache == null)
-			cache = next();
-		return (cache != null);
-	}
-
-	public function next():Dynamic {
-		var c = cache;
-		if (c != null) {
-			cache = null;
-			return c;
-		}
-		c = D.result_next(__r);
-		return c;
-	}
-
-	public function results():List<Dynamic> {
-		var l = new List();
-		while (hasNext())
-			l.add(next());
-		return l;
-	}
-
-	public function getResult(n:Int) {
-		return D.result_get(__r, n);
-	}
-
-	public function getIntResult(n:Int):Int {
-		return D.result_get_int(__r, n);
-	}
-
-	public function getFloatResult(n:Int):Float {
-		return D.result_get_float(__r, n);
-	}
-
-	public function getFieldsNames():Array<String> {
-		var a = D.result_fields_names(__r);
-		return a;
-	}
-}
-
-private class MysqlConnection implements sys.db.Connection {
-	private var __c:Dynamic;
-
-	public function new(c:Dynamic) {
-		__c = c;
-		D.set_conv_funs(cpp.Function.fromStaticFunction(D.charsToBytes), cpp.Function.fromStaticFunction(D.secondsToDate));
-	}
-
-	public function request(s:String):sys.db.ResultSet {
-		var r = D.request(this.__c, s);
-		return new MysqlResultSet(r);
-	}
-
-	public function close() {
-		D.close(__c);
-	}
-
-	public function escape(s:String) {
-		return D.escape(__c, s);
-	}
-
-	public function quote(s:String) {
-		return "'" + escape(s) + "'";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic) {
-		if (v == null) {
-			s.add(v);
-		} else if (Std.isOfType(v, Bool)) {
-			s.add(v ? 1 : 0);
-		} else {
-			var t:Int = untyped v.__GetType();
-			if (t == 0xff)
-				s.add(v);
-			else if (t == 2)
-				s.add(untyped v.__GetInt() ? "1".code : "0".code);
-			else {
-				s.addChar("'".code);
-				s.add(escape(Std.string(v)));
-				s.addChar("'".code);
-			}
-		}
-	}
-
-	public function lastInsertId() {
-		return request("SELECT LAST_INSERT_ID()").getIntResult(0);
-	}
-
-	public function dbName() {
-		return "MySQL";
-	}
-
-	public function startTransaction() {
-		request("START TRANSACTION");
-	}
-
-	public function commit() {
-		request("COMMIT");
-	}
-
-	public function rollback() {
-		request("ROLLBACK");
-	}
-
-	private static var __use_date = Date;
-}
-
-@:buildXml('<include name="${HXCPP}/src/hx/libs/mysql/Build.xml"/>')
-@:coreApi class Mysql {
-	public static function connect(params:{
-		host:String,
-		?port:Int,
-		user:String,
-		pass:String,
-		?socket:String,
-		?database:String
-	}):sys.db.Connection {
-		var o = {
-			host: params.host,
-			port: if (params.port == null) 3306 else params.port,
-			user: params.user,
-			pass: params.pass,
-			socket: if (params.socket == null) null else params.socket
-		};
-		var c = D.connect(o);
-		if (params.database != null) {
-			try {
-				D.select_db(c, params.database);
-			} catch (e:Dynamic) {
-				D.close(c);
-				cpp.Lib.rethrow(e);
-			}
-		}
-		return new MysqlConnection(c);
-	}
-}

+ 0 - 203
std/cpp/_std/sys/db/Sqlite.hx

@@ -1,203 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-private class SqliteConnection implements Connection {
-	var c:Dynamic;
-
-	public function new(file:String) {
-		c = _connect(file);
-	}
-
-	public function close() {
-		_close(c);
-	}
-
-	public function request(s:String):ResultSet {
-		try {
-			return new SqliteResultSet(_request(c, s));
-		} catch (e:String) {
-			throw "Error while executing " + s + " (" + e + ")";
-		}
-	}
-
-	public function escape(s:String) {
-		return s.split("'").join("''");
-	}
-
-	public function quote(s:String) {
-		if (s.indexOf("\000") >= 0) {
-			var hexChars = new Array<String>();
-			for (i in 0...s.length)
-				hexChars.push(StringTools.hex(StringTools.fastCodeAt(s, i), 2));
-			return "x'" + hexChars.join("") + "'";
-		}
-		return "'" + s.split("'").join("''") + "'";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic) {
-		if (v == null) {
-			s.add(v);
-		} else if (Std.isOfType(v, Bool)) {
-			s.add(v ? 1 : 0);
-		} else {
-			var t:Int = untyped v.__GetType();
-			if (t == 0xff)
-				s.add(v);
-			else if (t == 2)
-				s.add(untyped v.__GetInt());
-			else
-				s.add(quote(Std.string(v)));
-		}
-	}
-
-	public function lastInsertId():Int {
-		return _last_id(c);
-	}
-
-	public function dbName() {
-		return "SQLite";
-	}
-
-	public function startTransaction() {
-		request("BEGIN TRANSACTION");
-	}
-
-	public function commit() {
-		request("COMMIT");
-	}
-
-	public function rollback() {
-		request("ROLLBACK");
-	}
-
-	@:native("_hx_sqlite_connect")
-	extern public static function _connect(filename:String):Dynamic;
-
-	@:native("_hx_sqlite_request")
-	extern public static function _request(handle:Dynamic, req:String):Dynamic;
-
-	@:native("_hx_sqlite_close")
-	extern public static function _close(handle:Dynamic):Void;
-
-	@:native("_hx_sqlite_last_insert_id")
-	extern public static function _last_id(handle:Dynamic):Int;
-}
-
-private class SqliteResultSet implements ResultSet {
-	public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	var r:Dynamic;
-	var cache:List<Dynamic>;
-
-	public function new(r:Dynamic) {
-		cache = new List();
-		this.r = r;
-		hasNext(); // execute the request
-	}
-
-	function get_length() {
-		if (nfields != 0) {
-			while (true) {
-				var c = result_next(r);
-				if (c == null)
-					break;
-				cache.add(c);
-			}
-			return cache.length;
-		}
-		return result_get_length(r);
-	}
-
-	function get_nfields() {
-		return result_get_nfields(r);
-	}
-
-	public function hasNext() {
-		var c = next();
-		if (c == null)
-			return false;
-		cache.push(c);
-		return true;
-	}
-
-	public function next():Dynamic {
-		var c = cache.pop();
-		if (c != null)
-			return c;
-		return result_next(r);
-	}
-
-	public function results():List<Dynamic> {
-		var l = new List();
-		while (true) {
-			var c = next();
-			if (c == null)
-				break;
-			l.add(c);
-		}
-		return l;
-	}
-
-	public function getResult(n:Int) {
-		return new String(result_get(r, n));
-	}
-
-	public function getIntResult(n:Int):Int {
-		return result_get_int(r, n);
-	}
-
-	public function getFloatResult(n:Int):Float {
-		return result_get_float(r, n);
-	}
-
-	public function getFieldsNames():Array<String> {
-		throw new haxe.exceptions.NotImplementedException();
-	}
-
-	@:native("_hx_sqlite_result_next")
-	extern public static function result_next(handle:Dynamic):Dynamic;
-
-	@:native("_hx_sqlite_result_get_length")
-	extern public static function result_get_length(handle:Dynamic):Int;
-
-	@:native("_hx_sqlite_result_get_nfields")
-	extern public static function result_get_nfields(handle:Dynamic):Int;
-
-	@:native("_hx_sqlite_result_get")
-	extern public static function result_get(handle:Dynamic, i:Int):String;
-
-	@:native("_hx_sqlite_result_get_int")
-	extern public static function result_get_int(handle:Dynamic, i:Int):Int;
-
-	@:native("_hx_sqlite_result_get_float")
-	extern public static function result_get_float(handle:Dynamic, i:Int):Float;
-}
-
-@:buildXml('<include name="${HXCPP}/src/hx/libs/sqlite/Build.xml"/>')
-@:coreApi class Sqlite {
-	public static function open(file:String):Connection {
-		return new SqliteConnection(file);
-	}
-}

+ 0 - 6
std/cpp/cppia/HostClasses.hx

@@ -59,8 +59,6 @@ class HostClasses {
 		"cpp.Finalizable",
 		"Std",
 		"StringBuf",
-		"sys.db.Mysql",
-		"sys.db.Sqlite",
 		"sys.FileSystem",
 		"sys.io.File",
 		"sys.io.FileInput",
@@ -180,10 +178,6 @@ class HostClasses {
 		externs.set("haxe._Int32.___Int32", true);
 		// Hidded in implementation classes
 		// externs.set("sys.db.RecordType",true);
-		externs.set("sys.db._Sqlite.SqliteConnection", true);
-		externs.set("sys.db._Sqlite.SqliteResultSet", true);
-		externs.set("sys.db._Mysql.MysqlConnection", true);
-		externs.set("sys.db._Mysql.MysqlResultSet", true);
 		externs.set("sys.net._Socket.SocketInput", true);
 		externs.set("sys.net._Socket.SocketOutput", true);
 		externs.set("sys.ssl._Socket.SocketInput", true);

+ 9 - 1
tests/display/src/Diagnostic.hx → std/haxe/display/Diagnostic.hx

@@ -1,4 +1,6 @@
 // from vshaxe
+package haxe.display;
+
 import haxe.display.Position.Location;
 import haxe.display.Position.Range;
 import haxe.display.JsonModuleTypes;
@@ -44,11 +46,17 @@ typedef MissingFieldDiagnostics = {
 	var entries:Array<MissingFieldDiagnostic>;
 }
 
+typedef ReplacableCode = {
+	var description:String;
+	var range:Range;
+	var ?newCode:String;
+}
+
 enum abstract DiagnosticKind<T>(Int) from Int to Int {
 	final DKUnusedImport:DiagnosticKind<Void>;
 	final DKUnresolvedIdentifier:DiagnosticKind<Array<{kind:UnresolvedIdentifierSuggestion, name:String}>>;
 	final DKCompilerError:DiagnosticKind<String>;
-	final DKRemovableCode:DiagnosticKind<{description:String, range:Range}>;
+	final ReplacableCode:DiagnosticKind<ReplacableCode>;
 	final DKParserError:DiagnosticKind<String>;
 	final DeprecationWarning:DiagnosticKind<String>;
 	final InactiveBlock:DiagnosticKind<Void>;

+ 43 - 0
std/haxe/display/Display.hx

@@ -25,6 +25,7 @@ package haxe.display;
 import haxe.display.JsonModuleTypes;
 import haxe.display.Position;
 import haxe.display.Protocol;
+import haxe.ds.ReadOnlyArray;
 
 /**
 	Methods of the JSON-RPC-based `--display` protocol in Haxe 4.
@@ -32,6 +33,11 @@ import haxe.display.Protocol;
 **/
 @:publicFields
 class DisplayMethods {
+	/**
+		TODO documentation
+	**/
+	static inline var Diagnostics = new HaxeRequestMethod<DiagnosticsParams, DiagnosticsResult>("display/diagnostics");
+
 	/**
 		The completion request is sent from the client to Haxe to request code completion.
 		Haxe automatically determines the type of completion to use based on the passed position, see `CompletionResultKind`.
@@ -78,6 +84,16 @@ class DisplayMethods {
 	**/
 	static inline var SignatureHelp = new HaxeRequestMethod<SignatureHelpParams, SignatureHelpResult>("display/signatureHelp");
 
+	/**
+		The metadata request is sent from the client to Haxe to get a list of all registered metadata and their documentation.
+	**/
+	static inline var Metadata = new HaxeRequestMethod<MetadataParams, MetadataResult>("display/metadata");
+
+	/**
+		The defines request is sent from the client to Haxe to get a list of all registered defines and their documentation.
+	**/
+	static inline var Defines = new HaxeRequestMethod<DefinesParams, DefinesResult>("display/defines");
+
 	/*
 		TODO:
 
@@ -306,6 +322,8 @@ typedef Define = {
 	var parameters:Array<String>;
 	var platforms:Array<Platform>;
 	var links:Array<String>;
+	var ?origin:String;
+	var ?deprecated:String;
 }
 
 typedef Keyword = {
@@ -426,6 +444,17 @@ typedef PatternCompletion<T> = ToplevelCompletion<T> & {
 	var isOutermostPattern:Bool;
 }
 
+typedef DiagnosticsParams = {
+	var ?file:FsPath;
+	var ?contents:String;
+	var ?fileContents:Array<{file:FsPath, ?contents:String}>;
+}
+
+typedef DiagnosticsResult = Response<ReadOnlyArray<{
+	var file:FsPath;
+	var diagnostics:ReadOnlyArray<Diagnostic<Any>>;
+}>>
+
 enum abstract CompletionModeKind<T>(Int) {
 	var Field:CompletionModeKind<FieldCompletionSubject<Dynamic>>;
 	var StructureField;
@@ -543,6 +572,20 @@ typedef SignatureItem = {
 
 typedef SignatureHelpResult = Response<Null<SignatureItem>>;
 
+typedef MetadataParams = {
+	var compiler:Bool;
+	var user:Bool;
+}
+
+typedef MetadataResult = Response<Array<Metadata>>;
+
+typedef DefinesParams = {
+	var compiler:Bool;
+	var user:Bool;
+}
+
+typedef DefinesResult = Response<Array<Define>>;
+
 /** General types **/
 typedef PositionParams = FileParams & {
 	/** Unicode character offset in the file. **/

+ 0 - 36
std/hl/_std/sys/db/Connection.hx

@@ -1,36 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-interface Connection {
-	function request(s:String):ResultSet;
-	function close():Void;
-	function escape(s:String):String;
-	function quote(s:String):String;
-	function addValue(s:StringBuf, v:Dynamic):Void;
-	function lastInsertId():Int;
-	function dbName():String;
-	function startTransaction():Void;
-	function commit():Void;
-	function rollback():Void;
-}

+ 0 - 250
std/hl/_std/sys/db/Mysql.hx

@@ -1,250 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-private class MysqlParams {
-	public var host:hl.Bytes;
-	public var user:hl.Bytes;
-	public var pass:hl.Bytes;
-	public var socket:hl.Bytes;
-	public var port:Int;
-
-	public function new() {}
-}
-
-private typedef ConnectionHandler = hl.Abstract<"mysql_cnx">;
-private typedef ResultHandler = hl.Abstract<"mysql_result">;
-
-@:hlNative("mysql")
-private class MysqlResultSet implements sys.db.ResultSet {
-	public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	private var r:ResultHandler;
-	private var cache:Dynamic;
-
-	function new(r) {
-		this.r = r;
-	}
-
-	private function get_length() {
-		return result_get_length(r);
-	}
-
-	private function get_nfields() {
-		return result_get_nfields(r);
-	}
-
-	public function hasNext() {
-		if (cache == null)
-			cache = next();
-		return (cache != null);
-	}
-
-	public function next():Dynamic {
-		var c = cache;
-		if (c != null) {
-			cache = null;
-			return c;
-		}
-		c = result_next(r);
-		return c;
-	}
-
-	public function results():List<Dynamic> {
-		var l = new List();
-		while (hasNext())
-			l.add(next());
-		return l;
-	}
-
-	public function getResult(n:Int) {
-		var v = result_get(r, n);
-		if (v == null)
-			return null;
-		return @:privateAccess String.fromUTF8(v);
-	}
-
-	public function getIntResult(n:Int):Int {
-		return result_get_int(r, n);
-	}
-
-	public function getFloatResult(n:Int):Float {
-		return result_get_float(r, n);
-	}
-
-	public function getFieldsNames():Array<String> {
-		var a = result_get_fields_names(r);
-		return [for (v in a) @:privateAccess String.fromUTF8(v)];
-	}
-
-	static function result_get_length(r:ResultHandler):Int {
-		return 0;
-	}
-
-	static function result_get_nfields(r:ResultHandler):Int {
-		return 0;
-	}
-
-	static function result_next(r:ResultHandler):Dynamic {
-		return null;
-	}
-
-	static function result_get(r:ResultHandler, n:Int):hl.Bytes {
-		return null;
-	}
-
-	static function result_get_int(r:ResultHandler, n:Int):Int {
-		return 0;
-	}
-
-	static function result_get_float(r:ResultHandler, n:Int):Float {
-		return 0.;
-	}
-
-	static function result_get_fields_names(r:ResultHandler):hl.NativeArray<hl.Bytes> {
-		return null;
-	}
-}
-
-@:hlNative("mysql")
-private class MysqlConnection implements Connection {
-	var h:ConnectionHandler;
-
-	function new(h) {
-		this.h = h;
-	}
-
-	public function close() {
-		if (h != null)
-			close_wrap(h);
-		h = null;
-	}
-
-	public function request(s:String) @:privateAccess {
-		var len = 0;
-		var b = s.bytes.utf16ToUtf8(0, len);
-		return new MysqlResultSet(request_wrap(h, b, len));
-	}
-
-	public function escape(s:String) @:privateAccess {
-		var len = 0;
-		var utf = s.bytes.utf16ToUtf8(0, len);
-		return String.fromUTF8(escape_wrap(h, utf, len));
-	}
-
-	public function quote(s:String) {
-		return "'" + escape(s) + "'";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic) {
-		if (v == null) {
-			s.add(null);
-			return;
-		}
-		var t = hl.Type.getDynamic(v).kind;
-		if (t == HI32 || t == HF64)
-			s.add(v);
-		else if (t == HBool)
-			s.addChar(if (v) "1".code else "0".code);
-		else {
-			s.addChar("'".code);
-			s.add(escape(Std.string(v)));
-			s.addChar("'".code);
-		}
-	}
-
-	public function lastInsertId() {
-		return request("SELECT LAST_INSERT_ID()").getIntResult(0);
-	}
-
-	public function dbName() {
-		return "MySQL";
-	}
-
-	public function startTransaction() {
-		request("START TRANSACTION");
-	}
-
-	public function commit() {
-		request("COMMIT");
-	}
-
-	public function rollback() {
-		request("ROLLBACK");
-	}
-
-	static function close_wrap(h:ConnectionHandler) {}
-
-	static function connect_wrap(p:MysqlParams):ConnectionHandler {
-		return null;
-	}
-
-	static function select_db_wrap(h:ConnectionHandler, db:hl.Bytes):Bool {
-		return false;
-	}
-
-	@:hlNative("mysql", "request")
-	static function request_wrap(h:ConnectionHandler, rq:hl.Bytes, rqLen:Int):ResultHandler {
-		return null;
-	}
-
-	@:hlNative("mysql", "escape")
-	static function escape_wrap(h:ConnectionHandler, str:hl.Bytes, len:Int):hl.Bytes {
-		return null;
-	}
-
-	static function setConvFuns(fstring:Dynamic, fbytes:Dynamic, fdate:Dynamic, fjson:Dynamic) {};
-}
-
-class Mysql {
-	static var INIT_DONE = false;
-
-	public static function connect(params:{
-		host:String,
-		?port:Int,
-		user:String,
-		pass:String,
-		?socket:String,
-		?database:String
-	}):sys.db.Connection@:privateAccess {
-		if (!INIT_DONE) {
-			INIT_DONE = true;
-			MysqlConnection.setConvFuns(function(v:hl.Bytes) return @:privateAccess String.fromUTF8(v),
-			function(v:hl.Bytes, len:Int) return new haxe.io.Bytes(v, len), function(t) return Date.fromTime(1000. * t),
-			function(v:hl.Bytes) return haxe.Json.parse(@:privateAccess String.fromUTF8(v)));
-		}
-		var p = new MysqlParams();
-		p.host = params.host == null ? null : params.host.toUtf8();
-		p.user = params.user.toUtf8();
-		p.pass = params.pass.toUtf8();
-		p.socket = params.socket == null ? null : params.socket.toUtf8();
-		p.port = params.port == null ? 3306 : params.port;
-		var cnx = new MysqlConnection(MysqlConnection.connect_wrap(p));
-		if (params.database != null && !MysqlConnection.select_db_wrap(cnx.h, params.database.toUtf8())) {
-			cnx.close();
-			throw "Failed to select database " + params.database;
-		}
-		return cnx;
-	}
-}

+ 0 - 36
std/hl/_std/sys/db/ResultSet.hx

@@ -1,36 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-interface ResultSet {
-	var length(get, null):Int;
-	var nfields(get, null):Int;
-
-	function hasNext():Bool;
-	function next():Dynamic;
-	function results():List<Dynamic>;
-	function getResult(n:Int):String;
-	function getIntResult(n:Int):Int;
-	function getFloatResult(n:Int):Float;
-	function getFieldsNames():Null<Array<String>>;
-}

+ 0 - 283
std/hl/_std/sys/db/Sqlite.hx

@@ -1,283 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-import haxe.crypto.BaseCode;
-
-private typedef SqliteConnectionHandle = hl.Abstract<"sqlite_database">;
-private typedef SqliteResultHandle = hl.Abstract<"sqlite_result">;
-
-@:hlNative("sqlite")
-private class SqliteLib {
-	public static function connect(path:hl.Bytes):SqliteConnectionHandle {
-		return null;
-	}
-
-	public static function close(c:SqliteConnectionHandle):Void {}
-
-	public static function request(c:SqliteConnectionHandle, sql:hl.Bytes):SqliteResultHandle {
-		return null;
-	}
-
-	public static function last_id(c:SqliteConnectionHandle):Int {
-		return 0;
-	}
-
-	public static function result_next(c:SqliteResultHandle):hl.NativeArray<Dynamic> {
-		return null;
-	}
-
-	public static function result_get(c:SqliteResultHandle, n:Int):Null<hl.Bytes> {
-		return null;
-	}
-
-	public static function result_get_int(c:SqliteResultHandle, n:Int):Null<Int> {
-		return 0;
-	}
-
-	public static function result_get_float(c:SqliteResultHandle, n:Int):Null<Float> {
-		return .0;
-	}
-
-	public static function result_get_length(c:SqliteResultHandle):Null<Int> {
-		return 0;
-	}
-
-	public static function result_get_nfields(c:SqliteResultHandle):Int {
-		return 0;
-	}
-
-	public static function result_get_fields(c:SqliteResultHandle):hl.NativeArray<hl.Bytes> {
-		return null;
-	}
-}
-
-@:access(Sys)
-@:access(String)
-private class SqliteConnection implements Connection {
-	var c:SqliteConnectionHandle;
-
-	public function new(file:String) {
-		c = SqliteLib.connect(file.bytes);
-	}
-
-	public function close():Void {
-		SqliteLib.close(c);
-	}
-
-	public function request(s:String):ResultSet {
-		try {
-			var r:SqliteResultHandle = SqliteLib.request(c, s.bytes);
-
-			return new SqliteResultSet(r);
-		} catch (e:String) {
-			throw 'Error while executing $s ($e)';
-		}
-
-		return null;
-	}
-
-	public function escape(s:String):String {
-		return s.split("'").join("''");
-	}
-
-	public function quote(s:String):String {
-		if (s.indexOf("\000") >= 0)
-			return "x'" + BaseCode.encode(s, "0123456789ABCDEF") + "'";
-
-		return "'" + s.split("'").join("''") + "'";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic):Void {
-		switch (Type.typeof(v)) {
-			case TNull, TInt:
-				s.add(v);
-			case TBool:
-				s.add(v ? 1 : 0);
-			case TClass(haxe.io.Bytes):
-				s.add("x'");
-				s.add((v : haxe.io.Bytes).toHex());
-				s.add("'");
-			case _:
-				s.add(quote(Std.string(v)));
-		}
-	}
-
-	public function lastInsertId():Int {
-		return SqliteLib.last_id(c);
-	}
-
-	public function dbName():String {
-		return "SQLite";
-	}
-
-	public function startTransaction():Void {
-		request("BEGIN TRANSACTION");
-	}
-
-	public function commit():Void {
-		request("COMMIT");
-	}
-
-	public function rollback():Void {
-		request("ROLLBACK");
-	}
-}
-
-@:access(String)
-private class SqliteResultSet implements ResultSet {
-	public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	var names:Array<String>;
-	var cache:List<Dynamic>;
-
-	var r:SqliteResultHandle;
-
-	public function new(r:SqliteResultHandle) {
-		cache = new List();
-		this.r = r;
-		hasNext(); // execute the request
-	}
-
-	function get_length():Int {
-		if (nfields != 0) {
-			while (true) {
-				var c = doNext();
-				if (c == null)
-					break;
-
-				cache.add(c);
-			}
-
-			return cache.length;
-		}
-
-		return SqliteLib.result_get_length(r);
-	}
-
-	function get_nfields():Int {
-		return SqliteLib.result_get_nfields(r);
-	}
-
-	public function hasNext():Bool {
-		var c = next();
-		if (c == null)
-			return false;
-
-		cache.push(c);
-
-		return true;
-	}
-
-	public function next():Dynamic {
-		var c = cache.pop();
-		if (c != null)
-			return c;
-
-		return doNext();
-	}
-
-	private function doNext():Dynamic {
-		var o:Dynamic = {};
-		var a = SqliteLib.result_next(r);
-		if (a == null)
-			return null;
-
-		var names = getFieldsNames();
-		var i = 0;
-		var l = names.length;
-		while (i < l) {
-			var n:String = names[i];
-			var v:Dynamic = a[i];
-			switch (hl.Type.getDynamic(v).kind) {
-				case hl.Type.TypeKind.HArray:
-					var pair:hl.NativeArray<Dynamic> = v;
-					var bytes:hl.Bytes = pair[0];
-					var len:Int = pair[1];
-					var data = new haxe.io.BytesData(bytes, len);
-					Reflect.setField(o, n, haxe.io.Bytes.ofData(data));
-
-				case hl.Type.TypeKind.HBytes:
-					Reflect.setField(o, n, String.fromUCS2(v));
-
-				default:
-					Reflect.setField(o, n, v);
-			}
-			i++;
-		}
-		return o;
-	}
-
-	public function results():List<Dynamic> {
-		var l = new List();
-		while (true) {
-			var c = next();
-			if (c == null)
-				break;
-
-			l.add(c);
-		}
-
-		return l;
-	}
-
-	public function getResult(n:Int):String {
-		var bytes = SqliteLib.result_get(r, n);
-		if (bytes == null)
-			return null;
-
-		return String.fromUCS2(bytes);
-	}
-
-	public function getIntResult(n:Int):Int {
-		return SqliteLib.result_get_int(r, n);
-	}
-
-	public function getFloatResult(n:Int):Float {
-		return SqliteLib.result_get_float(r, n);
-	}
-
-	public function getFieldsNames():Array<String> {
-		if (this.names != null)
-			return this.names;
-
-		this.names = [];
-		var names = SqliteLib.result_get_fields(r);
-		var i = 0;
-		var l = names.length;
-		while (i < l) {
-			var name = String.fromUCS2(names[i]);
-			this.names.push(name);
-			i++;
-		}
-
-		return this.names;
-	}
-}
-
-@:coreApi class Sqlite {
-	public static function open(file:String):Connection {
-		return new SqliteConnection(file);
-	}
-}

+ 0 - 56
std/java/_std/sys/db/Mysql.hx

@@ -1,56 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-class Mysql {
-	static var init = false;
-
-	public static function connect(params:{
-		host:String,
-		?port:Int,
-		user:String,
-		pass:String,
-		?socket:String,
-		?database:String
-	}):sys.db.Connection {
-		if (!init) {
-			java.lang.Class.forName("com.mysql.jdbc.Driver");
-			init = true;
-		}
-		var url = new StringBuf();
-		url.add('jdbc:mysql:');
-		if (params.socket != null) {
-			url.add(params.socket);
-		} else {
-			url.add('//');
-			url.add(params.host);
-			if (params.port != null)
-				url.add(':${params.port}');
-		}
-		if (params.database != null) {
-			url.add('/${params.database}');
-		}
-		var cnx = java.sql.DriverManager.getConnection(url.toString(), params.user, params.pass);
-		return java.db.Jdbc.create(cnx);
-	}
-}

+ 0 - 42
std/java/_std/sys/db/Sqlite.hx

@@ -1,42 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-class Sqlite {
-	static var init = false;
-
-	public static function open(file:String):sys.db.Connection {
-		if (!init) {
-			try
-				java.lang.Class.forName("org.sqlite.JDBC")
-			catch (e:Dynamic)
-				throw e;
-			init = true;
-		}
-		try {
-			var cnx = java.sql.DriverManager.getConnection("jdbc:sqlite:" + file);
-			return java.db.Jdbc.create(cnx);
-		} catch (e:Dynamic)
-			throw e;
-	}
-}

+ 0 - 318
std/java/db/Jdbc.hx

@@ -1,318 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 java.db;
-
-import haxe.io.Bytes;
-import java.sql.Types;
-import java.util.concurrent.atomic.AtomicInteger;
-
-@:native('haxe.java.db.Jdbc')
-class Jdbc {
-	public static function create(cnx:java.sql.Connection):sys.db.Connection {
-		return new JdbcConnection(cnx);
-	}
-}
-
-@:native('haxe.java.db.JdbcConnection')
-private class JdbcConnection implements sys.db.Connection {
-	private static var ids = new AtomicInteger(0);
-
-	private var id:Int;
-
-	private var cnx:java.sql.Connection;
-	private var _lastInsertId:Int;
-	// escape handling
-	private var escapeRegex:EReg;
-	private var escapes:Array<Dynamic>;
-
-	public function new(cnx) {
-		this.id = ids.getAndIncrement();
-		this.cnx = cnx;
-		this.escapes = [];
-		this.escapeRegex = ~/@@HX_ESCAPE(\d+)_(\d+)@@/;
-	}
-
-	public function close() {
-		try
-			this.cnx.close()
-		catch (e:Dynamic)
-			throw e;
-	}
-
-	public function escape(s:String):String {
-		return "@@HX_ESCAPE" + id + "_" + escapes.push(s) + "@@";
-	}
-
-	public function quote(s:String):String {
-		return "@@HX_ESCAPE" + id + "_" + escapes.push(s) + "@@";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic) {
-		if (Std.isOfType(v, Date)) {
-			v = Std.string(v);
-		} else if (Std.isOfType(v, Bytes)) {
-			var bt:Bytes = v;
-			v = bt.getData();
-		}
-		s.add("@@HX_ESCAPE");
-		s.add(id);
-		s.add("_");
-		s.add(escapes.push(v));
-		s.add("@@");
-	}
-
-	public function lastInsertId():Int {
-		return _lastInsertId;
-	}
-
-	public function dbName():String {
-		try {
-			var ret = cnx.getMetaData().getDriverName();
-			var retc = ret.toLowerCase();
-			if (retc.indexOf("mysql") != -1)
-				return "MySQL";
-			else if (retc.indexOf("sqlite") != -1)
-				return "SQLite";
-			return ret;
-		} catch (e:Dynamic) {
-			throw e;
-		}
-	}
-
-	public function startTransaction() {
-		try {
-			cnx.setAutoCommit(false);
-		} catch (e:Dynamic)
-			throw e;
-	}
-
-	public function commit() {
-		try {
-			cnx.commit();
-		} catch (e:Dynamic) {
-			throw e;
-		}
-	}
-
-	public function rollback() {
-		try
-			cnx.rollback()
-		catch (e:Dynamic)
-			throw e;
-	}
-
-	public function request(s:String):sys.db.ResultSet {
-		var newst = new StringBuf();
-		var sentArray = [];
-
-		// cycle through the request string, adding any @@HX_ESCAPE@@ reference to the sentArray
-		var r = escapeRegex;
-		var myid = id + "", escapes = escapes, elen = escapes.length;
-		try {
-			while (r.match(s)) {
-				var id = r.matched(1);
-				if (id != myid)
-					throw "Request quotes are only valid for one single request; They can't be cached.";
-
-				newst.add(r.matchedLeft());
-				var eid = Std.parseInt(r.matched(2));
-				if (eid == null || eid > elen)
-					throw "Invalid request quote ID " + eid;
-				sentArray.push(escapes[eid - 1]);
-				newst.add("?");
-				s = r.matchedRight();
-			}
-			newst.add(s);
-			var stmt = cnx.prepareStatement(newst.toString(),
-				#if jvm java.sql.Statement.RETURN_GENERATED_KEYS #else java.sql.Statement.Statement_Statics.RETURN_GENERATED_KEYS #end);
-			for (i in 0...sentArray.length) {
-				stmt.setObject(i + 1, sentArray[i]);
-			}
-
-			var ret = null, dbName = dbName();
-			if (stmt.execute()) {
-				// is a result set
-				var rs = stmt.getResultSet();
-				ret = new JdbcResultSet(rs, dbName, stmt.getMetaData());
-			} else {
-				// is an update
-				var affected = stmt.getUpdateCount();
-				if (affected == 1) {
-					var autogen = stmt.getGeneratedKeys();
-					if (autogen.next()) {
-						this._lastInsertId = autogen.getInt(1);
-					}
-				}
-				ret = new JdbcResultSet(null, dbName, null);
-			}
-
-			if (escapes.length != 0)
-				escapes = [];
-			this.id = ids.getAndIncrement();
-			return ret;
-		} catch (e:Dynamic) {
-			if (escapes.length != 0)
-				escapes = [];
-			this.id = ids.getAndIncrement();
-			throw e;
-		}
-	}
-}
-
-@:native('haxe.java.db.JdbcResultSet')
-private class JdbcResultSet implements sys.db.ResultSet {
-	@:isVar public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	private var rs:java.sql.ResultSet;
-	private var names:Array<String>;
-	private var types:java.NativeArray<Int>;
-	private var dbName:String;
-	private var didNext:Bool;
-
-	public function new(rs, dbName, meta:java.sql.ResultSetMetaData) {
-		this.dbName = dbName;
-		this.rs = rs;
-		if (meta != null) {
-			try {
-				var count = meta.getColumnCount();
-				var names = [], types = new NativeArray(count);
-				for (i in 0...count) {
-					names.push(meta.getColumnName(i + 1));
-					types[i] = meta.getColumnType(i + 1);
-				}
-				this.types = types;
-				this.names = names;
-			} catch (e:Dynamic)
-				throw e;
-		}
-	}
-
-	private function get_length():Int {
-		if (length == 0) {
-			try {
-				var cur = rs.getRow();
-				rs.last();
-				this.length = rs.getRow();
-				rs.absolute(cur);
-			} catch (e:Dynamic)
-				throw e;
-		}
-		return length;
-	}
-
-	private function get_nfields():Int {
-		return names == null ? 0 : names.length;
-	}
-
-	public function hasNext():Bool {
-		try {
-			didNext = true;
-			return rs != null && rs.next();
-		} catch (e:Dynamic) {
-			return throw e;
-		}
-	}
-
-	public function next():Dynamic {
-		try {
-			if (rs == null)
-				return null;
-			if (didNext) {
-				didNext = false;
-			} else {
-				if (!rs.next()) {
-					return null;
-				}
-			}
-			var ret = {}, names = names, types = types;
-			for (i in 0...names.length) {
-				var name = names[i], t = types[i], val:Dynamic = null;
-				if (t == Types.FLOAT) {
-					val = rs.getDouble(i + 1);
-				} else if (t == Types.DATE || t == Types.TIME) {
-					if (dbName == "SQLite") {
-						var str = rs.getString(i + 1);
-						if (str != null) {
-							var d:Date = Date.fromString(str);
-							val = d;
-						}
-					} else {
-						var d:java.sql.Date = rs.getDate(i + 1);
-						if (d != null)
-							val = Date.fromTime(cast d.getTime());
-					}
-				} else if (t == Types.LONGVARBINARY || t == Types.VARBINARY || t == Types.BINARY || t == Types.BLOB) {
-					var b = rs.getBytes(i + 1);
-					if (b != null)
-						val = Bytes.ofData(b);
-				} else {
-					val = rs.getObject(i + 1);
-				}
-				Reflect.setField(ret, name, val);
-			}
-			return ret;
-		} catch (e:Dynamic)
-			throw e;
-	}
-
-	public function results():List<Dynamic> {
-		var l = new List();
-		if (rs == null)
-			return l;
-
-		try {
-			while (hasNext())
-				l.add(next());
-		} catch (e:Dynamic)
-			throw e;
-		return l;
-	}
-
-	public function getResult(n:Int):String {
-		try {
-			return rs.getString(n);
-		} catch (e:Dynamic)
-			throw e;
-	}
-
-	public function getIntResult(n:Int):Int {
-		try {
-			return rs.getInt(n);
-		} catch (e:Dynamic) {
-			return throw e;
-		};
-	}
-
-	public function getFloatResult(n:Int):Float {
-		try {
-			return rs.getFloat(n);
-		} catch (e:Dynamic) {
-			return throw e;
-		};
-	}
-
-	public function getFieldsNames():Null<Array<String>> {
-		return this.names;
-	}
-}

+ 1 - 1
std/jvm/annotation/ClassReflectionInformation.hx

@@ -22,7 +22,7 @@
 
 package jvm.annotation;
 
-@:annotation
+@:annotation("RUNTIME")
 @:native("haxe.jvm.annotation.ClassReflectionInformation")
 @:keep
 interface ClassReflectionInformation extends java.lang.annotation.Annotation {

+ 1 - 1
std/jvm/annotation/EnumReflectionInformation.hx

@@ -22,7 +22,7 @@
 
 package jvm.annotation;
 
-@:annotation
+@:annotation("RUNTIME")
 @:native("haxe.jvm.annotation.EnumReflectionInformation")
 @:keep
 interface EnumReflectionInformation extends java.lang.annotation.Annotation {

+ 1 - 1
std/jvm/annotation/EnumValueReflectionInformation.hx

@@ -22,7 +22,7 @@
 
 package jvm.annotation;
 
-@:annotation
+@:annotation("RUNTIME")
 @:native("haxe.jvm.annotation.EnumValueReflectionInformation")
 @:keep
 interface EnumValueReflectionInformation extends java.lang.annotation.Annotation {

+ 0 - 409
std/neko/Web.hx

@@ -1,409 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 neko;
-
-import haxe.ds.List;
-
-/**
-	This class is used for accessing the local Web server and the current
-	client request and information.
-**/
-class Web {
-	/**
-		Returns the GET and POST parameters.
-	**/
-	public static function getParams() {
-		var p = _get_params();
-		var h = new haxe.ds.StringMap<String>();
-		var k = "";
-		while (p != null) {
-			untyped k.__s = p[0];
-			h.set(k, new String(p[1]));
-			p = untyped p[2];
-		}
-		return h;
-	}
-
-	/**
-		Returns an Array of Strings built using GET / POST values.
-		If the URL contains the parameters `[a[]=foo;a[]=hello;a[5]=bar;a[3]=baz]` then
-		`neko.Web.getParamValues("a")` will return `["foo","hello",null,"baz",null,"bar"]`
-	**/
-	public static function getParamValues(param:String):Array<String> {
-		var reg = new EReg("^" + param + "(\\[|%5B)([0-9]*?)(\\]|%5D)=(.*?)$", "");
-		var res = new Array<String>();
-		var explore = function(data:String) {
-			if (data == null || data.length == 0)
-				return;
-			for (part in data.split("&")) {
-				if (reg.match(part)) {
-					var idx = reg.matched(2);
-					var val = StringTools.urlDecode(reg.matched(4));
-					if (idx == "")
-						res.push(val);
-					else
-						res[Std.parseInt(idx)] = val;
-				}
-			}
-		}
-		explore(StringTools.replace(getParamsString(), ";", "&"));
-		explore(getPostData());
-		if (res.length == 0)
-			return null;
-		return res;
-	}
-
-	/**
-		Returns the local server host name.
-	**/
-	public static function getHostName() {
-		return new String(_get_host_name());
-	}
-
-	/**
-		Surprisingly returns the client IP address.
-	**/
-	public static function getClientIP() {
-		return new String(_get_client_ip());
-	}
-
-	/**
-		Returns the original request URL (before any server internal redirections)
-	**/
-	public static function getURI() {
-		return new String(_get_uri());
-	}
-
-	/**
-		Tell the client to redirect to the given url ("Location" header)
-	**/
-	public static function redirect(url:String) {
-		_cgi_redirect(untyped url.__s);
-	}
-
-	/**
-		Set an output header value. If some data have been printed, the headers have
-		already been sent so this will raise an exception.
-	**/
-	public static function setHeader(h:String, v:String) {
-		_cgi_set_header(untyped h.__s, untyped v.__s);
-	}
-
-	/**
-		Set the HTTP return code. Same remark as setHeader.
-	**/
-	public static function setReturnCode(r:Int) {
-		_set_return_code(r);
-	}
-
-	/**
-		Retrieve a client header value sent with the request.
-	**/
-	public static function getClientHeader(k:String) {
-		var v = _get_client_header(untyped k.__s);
-		if (v == null)
-			return null;
-		return new String(v);
-	}
-
-	/**
-		Retrieve all the client headers.
-	**/
-	public static function getClientHeaders() {
-		var v = _get_client_headers();
-		var a = new List();
-		while (v != null) {
-			a.add({header: new String(v[0]), value: new String(v[1])});
-			v = cast v[2];
-		}
-		return a;
-	}
-
-	/**
-		Returns all the GET parameters String.
-	**/
-	public static function getParamsString() {
-		var p = _get_params_string();
-		return if (p == null) "" else new String(p);
-	}
-
-	/**
-		Returns all the POST data. POST Data is always parsed as
-		being `application/x-www-form-urlencoded` and is stored into
-		the getParams hashtable. POST Data is maximimized to 256K
-		unless the content type is `multipart/form-data`. In that
-		case, you will have to use `getMultipart` or `parseMultipart`
-		methods.
-	**/
-	public static function getPostData() {
-		var v = _get_post_data();
-		if (v == null)
-			return null;
-		return new String(v);
-	}
-
-	/**
-		Returns an hashtable of all Cookies sent by the client.
-		Modifying the hashtable will not modify the cookie, use `setCookie` instead.
-	**/
-	public static function getCookies():Map<String, String> {
-		var p = _get_cookies();
-		var h = new haxe.ds.StringMap<String>();
-		var k = "";
-		while (p != null) {
-			untyped k.__s = p[0];
-			h.set(k, new String(p[1]));
-			p = untyped p[2];
-		}
-		return h;
-	}
-
-	/**
-		Set a Cookie value in the HTTP headers. Same remark as `setHeader`.
-	**/
-	public static function setCookie(key:String, value:String, ?expire:Date, ?domain:String, ?path:String, ?secure:Bool, ?httpOnly:Bool) {
-		var buf = new StringBuf();
-		buf.add(value);
-		if (expire != null)
-			addPair(buf, "expires=", DateTools.format(expire, "%a, %d-%b-%Y %H:%M:%S GMT"));
-		addPair(buf, "domain=", domain);
-		addPair(buf, "path=", path);
-		if (secure)
-			addPair(buf, "secure", "");
-		if (httpOnly)
-			addPair(buf, "HttpOnly", "");
-		var v = buf.toString();
-		_set_cookie(untyped key.__s, untyped v.__s);
-	}
-
-	static function addPair(buf:StringBuf, name:String, value:String) {
-		if (value == null)
-			return;
-		buf.add("; ");
-		buf.add(name);
-		buf.add(value);
-	}
-
-	/**
-		Returns an object with the authorization sent by the client (Basic scheme only).
-	**/
-	public static function getAuthorization():{user:String, pass:String} {
-		var h = getClientHeader("Authorization");
-		var reg = ~/^Basic ([^=]+)=*$/;
-		if (h != null && reg.match(h)) {
-			var val = reg.matched(1);
-			untyped val = new String(_base_decode(val.__s, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".__s));
-			var a = val.split(":");
-			if (a.length != 2) {
-				throw "Unable to decode authorization.";
-			}
-			return {user: a[0], pass: a[1]};
-		}
-		return null;
-	}
-
-	/**
-		Get the current script directory in the local filesystem.
-	**/
-	public static function getCwd() {
-		return new String(_get_cwd());
-	}
-
-	/**
-		Set the main entry point function used to handle requests.
-		Setting it back to null will disable code caching.
-	**/
-	public static function cacheModule(f:Void->Void) {
-		_set_main(f);
-	}
-
-	/**
-		Get the multipart parameters as an hashtable. The data
-		cannot exceed the maximum size specified.
-	**/
-	public static function getMultipart(maxSize:Int):Map<String, String> {
-		var h = new haxe.ds.StringMap();
-		var buf:haxe.io.BytesBuffer = null;
-		var curname = null;
-		parseMultipart(function(p, _) {
-			if (curname != null)
-				h.set(curname, neko.Lib.stringReference(buf.getBytes()));
-			curname = p;
-			buf = new haxe.io.BytesBuffer();
-			maxSize -= p.length;
-			if (maxSize < 0)
-				throw "Maximum size reached";
-		}, function(str, pos, len) {
-			maxSize -= len;
-			if (maxSize < 0)
-				throw "Maximum size reached";
-			buf.addBytes(str, pos, len);
-		});
-		if (curname != null)
-			h.set(curname, neko.Lib.stringReference(buf.getBytes()));
-		return h;
-	}
-
-	/**
-		Parse the multipart data. Call `onPart` when a new part is found
-		with the part name and the filename if present
-		and `onData` when some part data is read. You can this way
-		directly save the data on hard drive in the case of a file upload.
-	**/
-	public static function parseMultipart(onPart:String->String->Void, onData:haxe.io.Bytes->Int->Int->Void):Void {
-		_parse_multipart(function(p, f) {
-			onPart(new String(p), if (f == null) null else new String(f));
-		}, function(buf, pos, len) {
-			onData(untyped new haxe.io.Bytes(__dollar__ssize(buf), buf), pos, len);
-		});
-	}
-
-	/**
-		Flush the data sent to the client. By default on Apache, outgoing data is buffered so
-		this can be useful for displaying some long operation progress.
-	**/
-	public static function flush():Void {
-		_flush();
-	}
-
-	/**
-		Get the HTTP method used by the client. This API requires Neko 1.7.1+.
-	**/
-	public static function getMethod():String {
-		return new String(_get_http_method());
-	}
-
-	/**
-		Write a message into the web server log file. This API requires Neko 1.7.1+.
-	**/
-	public static function logMessage(msg:String) {
-		_log_message(untyped msg.__s);
-	}
-
-	public static var isModNeko(default, null):Bool;
-	public static var isTora(default, null):Bool;
-
-	static var _set_main:Dynamic;
-	static var _get_host_name:Dynamic;
-	static var _get_client_ip:Dynamic;
-	static var _get_uri:Dynamic;
-	static var _cgi_redirect:Dynamic;
-	static var _cgi_set_header:Dynamic;
-	static var _set_return_code:Dynamic;
-	static var _get_client_header:Dynamic;
-	static var _get_params_string:Dynamic;
-	static var _get_post_data:Dynamic;
-	static var _get_params:Dynamic;
-	static var _get_cookies:Dynamic;
-	static var _set_cookie:Dynamic;
-	static var _get_cwd:Dynamic;
-	static var _parse_multipart:Dynamic;
-	static var _flush:Dynamic;
-	static var _get_client_headers:Dynamic;
-	static var _get_http_method:Dynamic;
-	static var _base_decode = Lib.load("std", "base_decode", 2);
-	static var _log_message:Dynamic;
-
-	static function __init__() {
-		var get_env = Lib.load("std", "get_env", 1);
-		var ver = untyped get_env("MOD_NEKO".__s);
-		untyped isModNeko = (ver != null);
-		if (isModNeko) {
-			var lib = "mod_neko" + if (ver == untyped "1".__s) "" else ver;
-			_set_main = Lib.load(lib, "cgi_set_main", 1);
-			_get_host_name = Lib.load(lib, "get_host_name", 0);
-			_get_client_ip = Lib.load(lib, "get_client_ip", 0);
-			_get_uri = Lib.load(lib, "get_uri", 0);
-			_cgi_redirect = Lib.load(lib, "redirect", 1);
-			_cgi_set_header = Lib.load(lib, "set_header", 2);
-			_set_return_code = Lib.load(lib, "set_return_code", 1);
-			_get_client_header = Lib.load(lib, "get_client_header", 1);
-			_get_params_string = Lib.load(lib, "get_params_string", 0);
-			_get_post_data = Lib.load(lib, "get_post_data", 0);
-			_get_params = Lib.load(lib, "get_params", 0);
-			_get_cookies = Lib.load(lib, "get_cookies", 0);
-			_set_cookie = Lib.load(lib, "set_cookie", 2);
-			_get_cwd = Lib.load(lib, "cgi_get_cwd", 0);
-			_get_http_method = Lib.loadLazy(lib, "get_http_method", 0);
-			_parse_multipart = Lib.loadLazy(lib, "parse_multipart_data", 2);
-			_flush = Lib.loadLazy(lib, "cgi_flush", 0);
-			_get_client_headers = Lib.loadLazy(lib, "get_client_headers", 0);
-			_log_message = Lib.loadLazy(lib, "log_message", 1);
-			isTora = try Lib.load(lib, "tora_infos", 0) != null catch (e:Dynamic) false;
-		} else {
-			var a0 = untyped __dollar__loader.args[0];
-			if (a0 != null)
-				a0 = new String(a0);
-			_set_main = function(f) {};
-			_get_host_name = function() {
-				return untyped "localhost".__s;
-			};
-			_get_client_ip = function() {
-				return untyped "127.0.0.1".__s;
-			};
-			_get_uri = function() {
-				return untyped (if (a0 == null) "/" else a0).__s;
-			};
-			_cgi_redirect = function(v) {
-				Lib.print("Location: " + v + "\n");
-			};
-			_cgi_set_header = function(h, v) {};
-			_set_return_code = function(i) {};
-			_get_client_header = function(h) {
-				return null;
-			};
-			_get_client_headers = function() {
-				return null;
-			};
-			_get_params_string = function() {
-				return untyped (if (a0 == null) "" else a0).__s;
-			};
-			_get_post_data = function() {
-				return null;
-			};
-			_get_params = function() {
-				var l = null;
-				if (a0 == null)
-					return null;
-				for (p in a0.split(";")) {
-					var k = p.split("=");
-					if (k.length == 2)
-						l = untyped [k[0].__s, k[1].__s, l];
-				}
-				return l;
-			};
-			_get_cookies = function() {
-				return null;
-			}
-			_set_cookie = function(k, v) {};
-			_get_cwd = Lib.load("std", "get_cwd", 0);
-			_get_http_method = function() return untyped "GET".__s;
-			_parse_multipart = function(a, b) {
-				throw "Not supported";
-			};
-			_flush = function() {};
-			_log_message = function(s) {};
-			isTora = false;
-		}
-	}
-}

+ 0 - 213
std/neko/_std/sys/db/Mysql.hx

@@ -1,213 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-private class D {
-	static function load(fun, args):Dynamic {
-		return neko.Lib.load(lib, fun, args);
-	}
-
-	static var lib = try {
-		neko.Lib.load("mysql5", "connect", 1);
-		"mysql5";
-	} catch (e:Dynamic) "mysql";
-	public static var connect = load("connect", 1);
-	public static var select_db = load("select_db", 2);
-	public static var request = load("request", 2);
-	public static var close = load("close", 1);
-	public static var escape = load("escape", 2);
-	public static var set_conv_funs = load("set_conv_funs", 4);
-	public static var result_get_length = load("result_get_length", 1);
-	public static var result_get_nfields = load("result_get_nfields", 1);
-	public static var result_next = load("result_next", 1);
-	public static var result_get = load("result_get", 2);
-	public static var result_get_int = load("result_get_int", 2);
-	public static var result_get_float = load("result_get_float", 2);
-	public static var result_fields_names = neko.Lib.loadLazy(lib, "result_get_fields_names", 1);
-}
-
-private class MysqlResultSet implements sys.db.ResultSet {
-	public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	private var __r:Dynamic;
-	private var cache:Dynamic;
-
-	public function new(r) {
-		__r = r;
-	}
-
-	private function get_length() {
-		return D.result_get_length(__r);
-	}
-
-	private function get_nfields() {
-		return D.result_get_nfields(__r);
-	}
-
-	public function hasNext() {
-		if (cache == null)
-			cache = next();
-		return (cache != null);
-	}
-
-	public function next():Dynamic {
-		var c = cache;
-		if (c != null) {
-			cache = null;
-			return c;
-		}
-		c = D.result_next(__r);
-		return c;
-	}
-
-	public function results():List<Dynamic> {
-		var l = new List();
-		while (hasNext())
-			l.add(next());
-		return l;
-	}
-
-	public function getResult(n:Int) {
-		return new String(D.result_get(__r, n));
-	}
-
-	public function getIntResult(n:Int):Int {
-		return D.result_get_int(__r, n);
-	}
-
-	public function getFloatResult(n:Int):Float {
-		return D.result_get_float(__r, n);
-	}
-
-	public function getFieldsNames():Array<String> {
-		var a = D.result_fields_names(__r);
-		untyped {
-			var i = 0;
-			var l = __dollar__asize(a);
-			while (i < l) {
-				a[i] = new String(a[i]);
-				i += 1;
-			}
-			a = Array.new1(cast a, l);
-		}
-		return a;
-	}
-}
-
-private class MysqlConnection implements sys.db.Connection {
-	private var __c:Dynamic;
-
-	public function new(c) {
-		__c = c;
-		D.set_conv_funs(c, function(s) return new String(s), function(d) return untyped Date.new1(d), function(b) return haxe.io.Bytes.ofData(b));
-	}
-
-	public function request(s:String):sys.db.ResultSet {
-		try {
-			var r = D.request(this.__c, untyped s.__s);
-			return new MysqlResultSet(r);
-		} catch (e:Dynamic) {
-			untyped if (__dollar__typeof(e) == __dollar__tobject && __dollar__typeof(e.msg) == __dollar__tstring)
-				e = e.msg;
-			untyped __dollar__rethrow(e);
-			return null;
-		}
-	}
-
-	public function close() {
-		D.close(__c);
-	}
-
-	public function escape(s:String) {
-		return new String(D.escape(__c, untyped s.__s));
-	}
-
-	public function quote(s:String) {
-		return "'" + escape(s) + "'";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic) {
-		var t = untyped __dollar__typeof(v);
-		if (untyped (t == __dollar__tint || t == __dollar__tnull))
-			s.add(v);
-		else if (untyped t == __dollar__tbool)
-			s.addChar(if (v) "1".code else "0".code);
-		else {
-			s.addChar("'".code);
-			s.add(escape(Std.string(v)));
-			s.addChar("'".code);
-		}
-	}
-
-	public function lastInsertId() {
-		return request("SELECT LAST_INSERT_ID()").getIntResult(0);
-	}
-
-	public function dbName() {
-		return "MySQL";
-	}
-
-	public function startTransaction() {
-		request("START TRANSACTION");
-	}
-
-	public function commit() {
-		request("COMMIT");
-	}
-
-	public function rollback() {
-		request("ROLLBACK");
-	}
-
-	private static var __use_date = Date;
-}
-
-@:coreApi class Mysql {
-	public static function connect(params:{
-		host:String,
-		?port:Int,
-		user:String,
-		pass:String,
-		?socket:String,
-		?database:String
-	}):sys.db.Connection {
-		var o = untyped {
-			host: params.host.__s,
-			port: if (params.port == null) 3306 else params.port,
-			user: params.user.__s,
-			pass: params.pass.__s,
-			socket: if (params.socket == null) null else params.socket.__s
-		};
-		var c = D.connect(o);
-		if (params.database != null) {
-			try {
-				D.select_db(c, untyped params.database.__s);
-			} catch (e:Dynamic) {
-				D.close(c);
-				neko.Lib.rethrow(e);
-			}
-		}
-		return new MysqlConnection(c);
-	}
-}

+ 0 - 199
std/neko/_std/sys/db/Sqlite.hx

@@ -1,199 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-private class SqliteConnection implements Connection {
-	var c:Dynamic;
-
-	public function new(file:String) {
-		c = _connect(untyped file.__s);
-	}
-
-	public function close() {
-		_close(c);
-	}
-
-	public function request(s:String):ResultSet {
-		try {
-			return new SqliteResultSet(_request(c, untyped s.__s));
-		} catch (e:String) {
-			throw "Error while executing " + s + " (" + e + ")";
-		}
-	}
-
-	public function escape(s:String) {
-		return s.split("'").join("''");
-	}
-
-	public function quote(s:String) {
-		if (s.indexOf("\000") >= 0)
-			return "x'" + new String(untyped _encode(s.__s, "0123456789ABCDEF".__s)) + "'";
-		return "'" + s.split("'").join("''") + "'";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic) {
-		var t = untyped __dollar__typeof(v);
-		if (untyped (t == __dollar__tint || t == __dollar__tnull))
-			s.add(v);
-		else if (untyped t == __dollar__tbool)
-			s.add(if (v) 1 else 0);
-		else
-			s.add(quote(Std.string(v)));
-	}
-
-	public function lastInsertId() {
-		return _last_id(c);
-	}
-
-	public function dbName() {
-		return "SQLite";
-	}
-
-	public function startTransaction() {
-		request("BEGIN TRANSACTION");
-	}
-
-	public function commit() {
-		request("COMMIT");
-	}
-
-	public function rollback() {
-		request("ROLLBACK");
-	}
-
-	static var _encode = neko.Lib.load("std", "base_encode", 2);
-	static var _connect = neko.Lib.load("sqlite", "connect", 1);
-	static var _close = neko.Lib.load("sqlite", "close", 1);
-	static var _request = neko.Lib.load("sqlite", "request", 2);
-	static var _last_id = neko.Lib.load("sqlite", "last_insert_id", 1);
-}
-
-private class SqliteResultSet implements ResultSet {
-	public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	var r:Dynamic;
-	var cache:List<Dynamic>;
-
-	public function new(r) {
-		cache = new List();
-		this.r = r;
-		hasNext(); // execute the request
-	}
-
-	function get_length() {
-		if (nfields != 0) {
-			while (true) {
-				var c = doNext();
-				if (c == null)
-					break;
-				cache.add(c);
-			}
-			return cache.length;
-		}
-		return result_get_length(r);
-	}
-
-	function get_nfields() {
-		return result_get_nfields(r);
-	}
-
-	public function hasNext() {
-		var c = next();
-		if (c == null)
-			return false;
-		cache.push(c);
-		return true;
-	}
-
-	public function next():Dynamic {
-		var c = cache.pop();
-		if (c != null)
-			return c;
-		return doNext();
-	}
-
-	private function doNext():Dynamic {
-		var c = result_next(r);
-		if (c == null)
-			return null;
-		untyped {
-			var f = __dollar__objfields(c);
-			var i = 0;
-			var l = __dollar__asize(f);
-			while (i < l) {
-				var v = __dollar__objget(c, f[i]);
-				if (__dollar__typeof(v) == __dollar__tstring)
-					__dollar__objset(c, f[i], new String(v));
-				i = i + 1;
-			}
-		}
-		return c;
-	}
-
-	public function results():List<Dynamic> {
-		var l = new List();
-		while (true) {
-			var c = next();
-			if (c == null)
-				break;
-			l.add(c);
-		}
-		return l;
-	}
-
-	public function getResult(n:Int) {
-		return new String(result_get(r, n));
-	}
-
-	public function getIntResult(n:Int):Int {
-		return result_get_int(r, n);
-	}
-
-	public function getFloatResult(n:Int):Float {
-		return result_get_float(r, n);
-	}
-
-	public function getFieldsNames():Array<String> {
-		if(hasNext()) {
-			return switch cache.first() {
-				case null: null;
-				case row: Reflect.fields(row);
-			}
-		}
-		return null;
-	}
-
-	static var result_next = neko.Lib.load("sqlite", "result_next", 1);
-	static var result_get_length = neko.Lib.load("sqlite", "result_get_length", 1);
-	static var result_get_nfields = neko.Lib.load("sqlite", "result_get_nfields", 1);
-	static var result_get = neko.Lib.load("sqlite", "result_get", 2);
-	static var result_get_int = neko.Lib.load("sqlite", "result_get_int", 2);
-	static var result_get_float = neko.Lib.load("sqlite", "result_get_float", 2);
-}
-
-@:coreApi class Sqlite {
-	public static function open(file:String):Connection {
-		return new SqliteConnection(file);
-	}
-}

+ 0 - 482
std/php/Web.hx

@@ -1,482 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 php;
-
-import haxe.io.Bytes;
-import haxe.ds.Map;
-import php.Syntax.*;
-import php.Global.*;
-import php.SuperGlobal.*;
-
-/**
-	This class is used for accessing the local Web server and the current
-	client request and information.
-**/
-@:deprecated('php.Web is deprecated and will be removed from standard library. See php.SuperGlobal and php.Global for alternatives.')
-class Web {
-	/**
-		Returns the GET and POST parameters.
-	**/
-	public static function getParams():Map<String, String> {
-		#if force_std_separator
-		var h = Lib.hashOfAssociativeArray(_POST);
-		var params = getParamsString();
-		if (params == "")
-			return h;
-		for (p in ~/[;&]/g.split(params)) {
-			var a = p.split("=");
-			var n = a.shift();
-			h.set(StringTools.urlDecode(n), StringTools.urlDecode(a.join("=")));
-		}
-		return h;
-		#else
-		return Lib.hashOfAssociativeArray(array_merge(_GET, _POST));
-		#end
-	}
-
-	/**
-		Returns an Array of Strings built using GET / POST values.
-		If you have in your URL the parameters `a[]=foo;a[]=hello;a[5]=bar;a[3]=baz` then
-		`php.Web.getParamValues("a")` will return `["foo","hello",null,"baz",null,"bar"]`.
-	**/
-	public static function getParamValues(param:String):Array<String> {
-		var reg = new EReg("^" + param + "(\\[|%5B)([0-9]*?)(\\]|%5D)=(.*?)$", "");
-		var res = new Array<String>();
-		var explore = function(data:String) {
-			if (data == null || Global.strlen(data) == 0)
-				return;
-			for (part in data.split("&")) {
-				if (reg.match(part)) {
-					var idx = reg.matched(2);
-					var val = StringTools.urlDecode(reg.matched(4));
-					if (idx == "")
-						res.push(val);
-					else
-						res[Std.parseInt(idx)] = val;
-				}
-			}
-		}
-		explore(StringTools.replace(getParamsString(), ";", "&"));
-		explore(getPostData());
-
-		if (res.length == 0) {
-			var post:haxe.ds.StringMap<Dynamic> = Lib.hashOfAssociativeArray(_POST);
-			var data = post.get(param);
-			if (is_array(data)) {
-				foreach(data, function(key:Int, value:String) {
-					res[key] = value;
-				});
-			}
-		}
-
-		if (res.length == 0)
-			return null;
-		return res;
-	}
-
-	/**
-		Returns the local server host name.
-	**/
-	public static inline function getHostName():String {
-		return _SERVER['SERVER_NAME'];
-	}
-
-	/**
-		Surprisingly returns the client IP address.
-	**/
-	public static inline function getClientIP():String {
-		return _SERVER['REMOTE_ADDR'];
-	}
-
-	/**
-		Returns the original request URL (before any server internal redirections).
-	**/
-	public static function getURI():String {
-		var s:String = _SERVER['REQUEST_URI'];
-		return s.split("?")[0];
-	}
-
-	/**
-		Tell the client to redirect to the given url ("Location" header).
-	**/
-	public static function redirect(url:String) {
-		header("Location: " + url);
-	}
-
-	/**
-		Set an output header value. If some data have been printed, the headers have
-		already been sent so this will raise an exception.
-	**/
-	public static inline function setHeader(h:String, v:String) {
-		header('$h: $v');
-	}
-
-	/**
-		Set the HTTP return code. Same remark as `php.Web.setHeader()`.
-		See status code explanation here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
-	**/
-	public static function setReturnCode(r:Int) {
-		var code:String;
-		switch (r) {
-			case 100:
-				code = "100 Continue";
-			case 101:
-				code = "101 Switching Protocols";
-			case 200:
-				code = "200 OK";
-			case 201:
-				code = "201 Created";
-			case 202:
-				code = "202 Accepted";
-			case 203:
-				code = "203 Non-Authoritative Information";
-			case 204:
-				code = "204 No Content";
-			case 205:
-				code = "205 Reset Content";
-			case 206:
-				code = "206 Partial Content";
-			case 300:
-				code = "300 Multiple Choices";
-			case 301:
-				code = "301 Moved Permanently";
-			case 302:
-				code = "302 Found";
-			case 303:
-				code = "303 See Other";
-			case 304:
-				code = "304 Not Modified";
-			case 305:
-				code = "305 Use Proxy";
-			case 307:
-				code = "307 Temporary Redirect";
-			case 400:
-				code = "400 Bad Request";
-			case 401:
-				code = "401 Unauthorized";
-			case 402:
-				code = "402 Payment Required";
-			case 403:
-				code = "403 Forbidden";
-			case 404:
-				code = "404 Not Found";
-			case 405:
-				code = "405 Method Not Allowed";
-			case 406:
-				code = "406 Not Acceptable";
-			case 407:
-				code = "407 Proxy Authentication Required";
-			case 408:
-				code = "408 Request Timeout";
-			case 409:
-				code = "409 Conflict";
-			case 410:
-				code = "410 Gone";
-			case 411:
-				code = "411 Length Required";
-			case 412:
-				code = "412 Precondition Failed";
-			case 413:
-				code = "413 Request Entity Too Large";
-			case 414:
-				code = "414 Request-URI Too Long";
-			case 415:
-				code = "415 Unsupported Media Type";
-			case 416:
-				code = "416 Requested Range Not Satisfiable";
-			case 417:
-				code = "417 Expectation Failed";
-			case 500:
-				code = "500 Internal Server Error";
-			case 501:
-				code = "501 Not Implemented";
-			case 502:
-				code = "502 Bad Gateway";
-			case 503:
-				code = "503 Service Unavailable";
-			case 504:
-				code = "504 Gateway Timeout";
-			case 505:
-				code = "505 HTTP Version Not Supported";
-			default:
-				code = Std.string(r);
-		}
-		header("HTTP/1.1 " + code, true, r);
-	}
-
-	/**
-		Retrieve a client header value sent with the request.
-	**/
-	public static function getClientHeader(k:String):String {
-		return loadClientHeaders().get(str_replace('-', '_', strtoupper(k)));
-	}
-
-	private static var _clientHeaders:Map<String, String>;
-
-	/**
-		Based on https://github.com/ralouphie/getallheaders
-	**/
-	static function loadClientHeaders():Map<String, String> {
-		if (_clientHeaders != null)
-			return _clientHeaders;
-
-		_clientHeaders = new Map();
-
-		if (function_exists('getallheaders')) {
-			foreach(getallheaders(), function(key:String, value:Dynamic) {
-				_clientHeaders.set(str_replace('-', '_', strtoupper(key)), Std.string(value));
-			});
-			return _clientHeaders;
-		}
-
-		var copyServer = Syntax.assocDecl({
-			CONTENT_TYPE: 'Content-Type',
-			CONTENT_LENGTH: 'Content-Length',
-			CONTENT_MD5: 'Content-Md5'
-		});
-		foreach(_SERVER, function(key:String, value:Dynamic) {
-			if ((substr(key, 0, 5) : String) == 'HTTP_') {
-				key = substr(key, 5);
-				if (!isset(copyServer[key]) || !isset(_SERVER[key])) {
-					_clientHeaders[key] = Std.string(value);
-				}
-			} else if (isset(copyServer[key])) {
-				_clientHeaders[key] = Std.string(value);
-			}
-		});
-		if (!_clientHeaders.exists('AUTHORIZATION')) {
-			if (isset(_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
-				_clientHeaders['AUTHORIZATION'] = Std.string(_SERVER['REDIRECT_HTTP_AUTHORIZATION']);
-			} else if (isset(_SERVER['PHP_AUTH_USER'])) {
-				var basic_pass = isset(_SERVER['PHP_AUTH_PW']) ? Std.string(_SERVER['PHP_AUTH_PW']) : '';
-				_clientHeaders['AUTHORIZATION'] = 'Basic ' + base64_encode(_SERVER['PHP_AUTH_USER'] + ':' + basic_pass);
-			} else if (isset(_SERVER['PHP_AUTH_DIGEST'])) {
-				_clientHeaders['AUTHORIZATION'] = Std.string(_SERVER['PHP_AUTH_DIGEST']);
-			}
-		}
-
-		return _clientHeaders;
-	}
-
-	/**
-		Retrieve all the client headers.
-	**/
-	public static function getClientHeaders():List<{value:String, header:String}> {
-		var headers = loadClientHeaders();
-		var result = new List();
-		for (key in headers.keys()) {
-			result.push({value: headers.get(key), header: key});
-		}
-		return result;
-	}
-
-	/**
-		Retrieve all the client headers as `haxe.ds.Map`.
-	**/
-	public static function getClientHeadersMap():Map<String, String> {
-		return loadClientHeaders().copy();
-	}
-
-	/**
-		Returns all the GET parameters `String`
-	**/
-	public static function getParamsString():String {
-		if (isset(_SERVER['QUERY_STRING']))
-			return _SERVER['QUERY_STRING'];
-		else
-			return "";
-	}
-
-	/**
-		Returns all the POST data. POST Data is always parsed as
-		being application/x-www-form-urlencoded and is stored into
-		the getParams hashtable. POST Data is maximimized to 256K
-		unless the content type is multipart/form-data. In that
-		case, you will have to use `php.Web.getMultipart()` or
-		`php.Web.parseMultipart()` methods.
-	**/
-	public static function getPostData():Null<String> {
-		var h = fopen("php://input", "r");
-		var bsize = 8192;
-		var max = 32;
-		var data:String = null;
-		var counter = 0;
-		while (!feof(h) && counter < max) {
-			data = Syntax.concat(data, fread(h, bsize));
-			counter++;
-		}
-		fclose(h);
-		return data;
-	}
-
-	/**
-		Returns an hashtable of all Cookies sent by the client.
-		Modifying the hashtable will not modify the cookie, use `php.Web.setCookie()`
-		instead.
-	**/
-	public static function getCookies():Map<String, String> {
-		return Lib.hashOfAssociativeArray(_COOKIE);
-	}
-
-	/**
-		Set a Cookie value in the HTTP headers. Same remark as `php.Web.setHeader()`.
-	**/
-	public static function setCookie(key:String, value:String, ?expire:Date, ?domain:String, ?path:String, ?secure:Bool, ?httpOnly:Bool) {
-		var t = expire == null ? 0 : Std.int(expire.getTime() / 1000.0);
-		if (path == null)
-			path = '/';
-		if (domain == null)
-			domain = '';
-		if (secure == null)
-			secure = false;
-		if (httpOnly == null)
-			httpOnly = false;
-		setcookie(key, value, t, path, domain, secure, httpOnly);
-	}
-
-	/**
-		Returns an object with the authorization sent by the client (Basic scheme only).
-	**/
-	public static function getAuthorization():{user:String, pass:String} {
-		if (!isset(_SERVER['PHP_AUTH_USER']))
-			return null;
-		return {user: _SERVER['PHP_AUTH_USER'], pass: _SERVER['PHP_AUTH_PW']};
-	}
-
-	/**
-		Get the current script directory in the local filesystem.
-	**/
-	public static inline function getCwd():String {
-		return dirname(_SERVER['SCRIPT_FILENAME']) + "/";
-	}
-
-	/**
-		Get the multipart parameters as an hashtable. The data
-		cannot exceed the maximum size specified.
-	**/
-	public static function getMultipart(maxSize:Int):Map<String, String> {
-		var h = new haxe.ds.StringMap();
-		var buf:StringBuf = null;
-		var curname = null;
-		parseMultipart(function(p, _) {
-			if (curname != null)
-				h.set(curname, buf.toString());
-			curname = p;
-			buf = new StringBuf();
-			maxSize -= Global.strlen(p);
-			if (maxSize < 0)
-				throw "Maximum size reached";
-		}, function(str, pos, len) {
-			maxSize -= len;
-			if (maxSize < 0)
-				throw "Maximum size reached";
-			buf.addSub(str.toString(), pos, len);
-		});
-		if (curname != null)
-			h.set(curname, buf.toString());
-		return h;
-	}
-
-	/**
-		Parse the multipart data. Call `onPart` when a new part is found
-		with the part name and the filename if present
-		and `onData` when some part data is readed. You can this way
-		directly save the data on hard drive in the case of a file upload.
-	**/
-	public static function parseMultipart(onPart:String->String->Void, onData:Bytes->Int->Int->Void):Void {
-		Syntax.foreach(_POST, function(key:String, value:Dynamic) {
-			onPart(key, "");
-			onData(Bytes.ofString(value), 0, strlen(value));
-		});
-
-		if (!isset(_FILES))
-			return;
-		Syntax.foreach(_FILES, function(part:String, data:NativeAssocArray<Dynamic>) {
-			function handleFile(tmp:String, file:String, err:Int) {
-				var fileUploaded = true;
-				if (err > 0) {
-					switch (err) {
-						case 1:
-							throw "The uploaded file exceeds the max size of " + ini_get('upload_max_filesize');
-						case 2:
-							throw "The uploaded file exceeds the max file size directive specified in the HTML form (max is" + ini_get('post_max_size') + ")";
-						case 3:
-							throw "The uploaded file was only partially uploaded";
-						case 4:
-							fileUploaded = false; // No file was uploaded
-						case 6:
-							throw "Missing a temporary folder";
-						case 7:
-							throw "Failed to write file to disk";
-						case 8:
-							throw "File upload stopped by extension";
-					}
-				}
-				if (fileUploaded) {
-					onPart(part, file);
-					if ("" != file) {
-						var h = fopen(tmp, "r");
-						var bsize = 8192;
-						while (!feof(h)) {
-							var buf:String = fread(h, bsize);
-							var size:Int = strlen(buf);
-							onData(Bytes.ofString(buf), 0, size);
-						}
-						fclose(h);
-					}
-				}
-			}
-			if (is_array(data['name'])) {
-				for (index in array_keys(data['name'])) {
-					handleFile(data['tmp_name'][index], data['name'][index], data['error'][index]);
-				};
-			} else {
-				handleFile(data['tmp_name'], data['name'], data['error']);
-			}
-		});
-	}
-
-	/**
-		Flush the data sent to the client. By default on Apache, outgoing data is buffered so
-		this can be useful for displaying some long operation progress.
-	**/
-	public static inline function flush():Void {
-		Global.flush();
-	}
-
-	/**
-		Get the HTTP method used by the client.
-	**/
-	public static function getMethod():String {
-		if (isset(_SERVER['REQUEST_METHOD']))
-			return _SERVER['REQUEST_METHOD'];
-		else
-			return null;
-	}
-
-	public static var isModNeko(default, null):Bool;
-
-	static function __init__() {
-		isModNeko = !Lib.isCli();
-	}
-}

+ 0 - 268
std/php/_std/sys/db/Mysql.hx

@@ -1,268 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-import php.*;
-import sys.db.*;
-import php.db.*;
-import php.db.Mysqli_result;
-
-@:coreApi class Mysql {
-	public static function connect(params:{
-		host:String,
-		?port:Int,
-		user:String,
-		pass:String,
-		?socket:String,
-		?database:String
-	}):Connection {
-		return new MysqlConnection(params);
-	}
-}
-
-private class MysqlConnection implements Connection {
-	var db:Mysqli;
-
-	public function new(params:{
-		host:String,
-		?port:Int,
-		user:String,
-		pass:String,
-		?socket:String,
-		?database:String
-	}):Void {
-		if (params.port == null)
-			params.port = Std.parseInt(Global.ini_get('mysqli.default_port'));
-		if (params.socket == null)
-			params.socket = Global.ini_get('mysqli.default_socket');
-		if (params.database == null)
-			params.database = "";
-
-		db = new Mysqli(params.host, params.user, params.pass, params.database, params.port, params.socket);
-	}
-
-	public function request(s:String):ResultSet {
-		var result = db.query(s);
-		if (result == false)
-			throw 'Failed to perform db query: ' + db.error;
-		if (result == true) {
-			return new WriteMysqlResultSet(db.affected_rows);
-		}
-
-		return new MysqlResultSet(result);
-	}
-
-	public function close():Void {
-		db.close();
-	}
-
-	public function escape(s:String):String {
-		return db.escape_string(s);
-	}
-
-	public function quote(s:String):String {
-		if (s.indexOf("\000") >= 0)
-			return "x'" + Global.bin2hex(s) + "'";
-		return "'" + db.escape_string(s) + "'";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic):Void {
-		if (Global.is_int(v) || Global.is_null(v)) {
-			s.add(v);
-		} else if (Global.is_bool(v)) {
-			s.add(v ? 1 : 0);
-		} else {
-			s.add(quote(Std.string(v)));
-		}
-	}
-
-	public function lastInsertId():Int {
-		return db.insert_id;
-	}
-
-	public function dbName():String {
-		return 'MySQL';
-	}
-
-	public function startTransaction():Void {
-		var success = db.begin_transaction();
-		if (!success)
-			throw 'Failed to start transaction: ' + db.error;
-	}
-
-	public function commit():Void {
-		var success = db.commit();
-		if (!success)
-			throw 'Failed to commit transaction: ' + db.error;
-	}
-
-	public function rollback():Void {
-		var success = db.rollback();
-		if (!success)
-			throw 'Failed to rollback transaction: ' + db.error;
-	}
-}
-
-private class MysqlResultSet implements ResultSet {
-	static var hxAnonClassName = Boot.getHxAnon().phpClassName;
-
-	public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	var result:Mysqli_result;
-	var fetchedRow:NativeAssocArray<Scalar>;
-	var fieldsInfo:NativeAssocArray<MysqliFieldInfo>;
-
-	public function new(result:Mysqli_result) {
-		this.result = result;
-	}
-
-	public function hasNext():Bool {
-		if (fetchedRow == null)
-			fetchNext();
-		return fetchedRow != null;
-	}
-
-	public function next():Dynamic {
-		if (fetchedRow == null)
-			fetchNext();
-		return withdrawFetched();
-	}
-
-	public function results():List<Dynamic> {
-		var list = new List();
-
-		result.data_seek(0);
-		var row = result.fetch_object(hxAnonClassName);
-		while (row != null) {
-			row = correctObjectTypes(row);
-			list.add(row);
-			row = result.fetch_object(hxAnonClassName);
-		}
-
-		return list;
-	}
-
-	public function getResult(n:Int):String {
-		if (fetchedRow == null)
-			fetchNext();
-		return Global.array_values(fetchedRow)[n];
-	}
-
-	public function getIntResult(n:Int):Int {
-		return Syntax.int(getResult(n));
-	}
-
-	public function getFloatResult(n:Int):Float {
-		return Syntax.float(getResult(n));
-	}
-
-	public function getFieldsNames():Null<Array<String>> {
-		var fields = result.fetch_fields();
-		return [for (field in fields) field.name];
-	}
-
-	function fetchNext() {
-		var row = result.fetch_assoc();
-		if (row != null)
-			fetchedRow = correctArrayTypes(row);
-	}
-
-	function withdrawFetched():Dynamic {
-		if (fetchedRow == null)
-			return null;
-		var row = fetchedRow;
-		fetchedRow = null;
-		return Boot.createAnon(row);
-	}
-
-	function correctArrayTypes(row:NativeAssocArray<String>):NativeAssocArray<Scalar> {
-		var fieldsInfo = getFieldsInfo();
-		Syntax.foreach(row, function(field:String, value:String) {
-			row[field] = correctType(value, fieldsInfo[field].type);
-		});
-		return cast row;
-	}
-
-	function correctObjectTypes(row:{}):{} {
-		var fieldsInfo = getFieldsInfo();
-		Syntax.foreach(row, function(field:String, value:String) {
-			value = correctType(value, fieldsInfo[field].type);
-			Syntax.setField(row, field, value);
-		});
-		return row;
-	}
-
-	inline function getFieldsInfo():NativeAssocArray<MysqliFieldInfo> {
-		if (fieldsInfo == null) {
-			fieldsInfo = cast Syntax.arrayDecl();
-			Syntax.foreach(result.fetch_fields(), function(_, info) {
-				fieldsInfo[info.name] = info;
-			});
-		}
-		return fieldsInfo;
-	}
-
-	function correctType(value:String, type:Int):Scalar {
-		if (value == null)
-			return null;
-		if (type == Const.MYSQLI_TYPE_BIT || type == Const.MYSQLI_TYPE_TINY || type == Const.MYSQLI_TYPE_SHORT || type == Const.MYSQLI_TYPE_LONG
-			|| type == Const.MYSQLI_TYPE_INT24 || type == Const.MYSQLI_TYPE_CHAR) {
-			return Syntax.int(value);
-		}
-		if (type == Const.MYSQLI_TYPE_DECIMAL
-			|| type == Const.MYSQLI_TYPE_NEWDECIMAL
-			|| type == Const.MYSQLI_TYPE_FLOAT
-			|| type == Const.MYSQLI_TYPE_DOUBLE) {
-			return Syntax.float(value);
-		}
-		return value;
-	}
-
-	function get_length()
-		return result.num_rows;
-
-	function get_nfields()
-		return result.field_count;
-}
-
-private class WriteMysqlResultSet extends MysqlResultSet {
-	var affectedRows:Int = 0;
-
-	public function new(affectedRows:Int) {
-		super(null);
-		this.affectedRows = affectedRows;
-	}
-
-	override public function hasNext():Bool {
-		return false;
-	}
-
-	override function fetchNext() {}
-
-	override function get_length()
-		return affectedRows;
-
-	override function get_nfields()
-		return 0;
-}

+ 0 - 218
std/php/_std/sys/db/Sqlite.hx

@@ -1,218 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 sys.db;
-
-import php.*;
-import php.Global.*;
-import php.db.*;
-import sys.db.*;
-
-@:coreApi class Sqlite {
-	public static function open(file:String):Connection {
-		return new SQLiteConnection(file);
-	}
-}
-
-private class SQLiteConnection implements Connection {
-	var db:SQLite3;
-
-	public function new(file:String) {
-		db = new SQLite3(file);
-		db.enableExceptions(true);
-	}
-
-	public function request(s:String):ResultSet {
-		var result = db.query(s);
-		return new SQLiteResultSet(result);
-	}
-
-	public function close():Void {
-		db.close();
-	}
-
-	public function escape(s:String):String {
-		return SQLite3.escapeString(s);
-	}
-
-	public function quote(s:String):String {
-		if (s.indexOf("\000") >= 0)
-			return "x'" + Global.bin2hex(s) + "'";
-		return "'" + SQLite3.escapeString(s) + "'";
-	}
-
-	public function addValue(s:StringBuf, v:Dynamic):Void {
-		if (Global.is_int(v) || Global.is_null(v)) {
-			s.add(v);
-		} else if (Global.is_bool(v)) {
-			s.add(v ? 1 : 0);
-		} else {
-			s.add(quote(Std.string(v)));
-		}
-	}
-
-	public function lastInsertId():Int {
-		return Syntax.int(db.lastInsertRowID());
-	}
-
-	public function dbName():String {
-		return 'SQLite';
-	}
-
-	public function startTransaction():Void {
-		db.query('BEGIN TRANSACTION');
-	}
-
-	public function commit():Void {
-		db.query('COMMIT');
-	}
-
-	public function rollback():Void {
-		db.query('ROLLBACK');
-	}
-}
-
-private class SQLiteResultSet implements ResultSet {
-	public var length(get, null):Int;
-	public var nfields(get, null):Int;
-
-	var cache = new NativeIndexedArray<{}>();
-	var result:SQLite3Result;
-	var resultIsDepleted = false;
-	var fieldsInfo:NativeAssocArray<Int>;
-
-	public function new(result:SQLite3Result) {
-		this.result = result;
-	}
-
-	public function hasNext():Bool {
-		return switch next() {
-			case null: false;
-			case row:
-				array_unshift(cache, row);
-				row;
-		}
-	}
-
-	public function next():Dynamic {
-		return switch array_shift(cache) {
-			case null: fetchNext();
-			case row: row;
-		}
-	}
-
-	function fetchNext():Null<{}> {
-		return resultIsDepleted ? null : switch result.fetchArray(Const.SQLITE3_ASSOC) {
-			case false:
-				resultIsDepleted = true;
-				result.finalize();
-				null;
-			case row:
-				Boot.createAnon(correctArrayTypes(row));
-		}
-	}
-
-	public function cacheAll():NativeIndexedArray<{}> {
-		var row = fetchNext();
-		while(row != null) {
-			cache.push(row);
-			row = fetchNext();
-		}
-		return cache;
-	}
-
-	public function results():List<Dynamic> {
-		var list = new List();
-		for(row in cacheAll()) {
-			list.add(row);
-		}
-		return list;
-	}
-
-	function getColumn(n:Int):Any {
-		return array_values(Syntax.array(current()))[n];
-	}
-
-	public function getResult(n:Int):String {
-		return Syntax.string(getColumn(n));
-	}
-
-	public function getIntResult(n:Int):Int {
-		return Syntax.int(getColumn(n));
-	}
-
-	public function getFloatResult(n:Int):Float {
-		return Syntax.float(getColumn(n));
-	}
-
-	public function getFieldsNames():Null<Array<String>> {
-		var fieldsInfo = getFieldsInfo();
-		return Global.array_keys(fieldsInfo);
-	}
-
-	function current():Null<{}> {
-		return switch reset(cache) {
-			case false:
-				switch next() {
-					case null: null;
-					case row:
-						cache.push(row);
-						row;
-				}
-			case row: row;
-		}
-	}
-
-	function correctArrayTypes(row:NativeAssocArray<String>):NativeAssocArray<Scalar> {
-		var fieldsInfo = getFieldsInfo();
-		Syntax.foreach(row, function(field:String, value:String) {
-			row[field] = correctType(value, fieldsInfo[field]);
-		});
-		return cast row;
-	}
-
-	inline function getFieldsInfo():NativeAssocArray<Int> {
-		if (fieldsInfo == null) {
-			fieldsInfo = cast Syntax.arrayDecl();
-			for (i in 0...nfields) {
-				fieldsInfo[result.columnName(i)] = result.columnType(i);
-			}
-		}
-		return fieldsInfo;
-	}
-
-	function correctType(value:String, type:Int):Scalar {
-		if (value == null)
-			return null;
-		if (type == Const.SQLITE3_INTEGER)
-			return Syntax.int(value);
-		if (type == Const.SQLITE3_FLOAT)
-			return Syntax.float(value);
-		return value;
-	}
-
-	function get_length():Int
-		return count(cacheAll());
-
-	function get_nfields():Int
-		return result.numColumns();
-}

+ 0 - 100
std/php/db/Mysqli.hx

@@ -1,100 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 php.db;
-
-import haxe.extern.*;
-import php.*;
-import haxe.Constraints.Function;
-
-/**
-	@see http://php.net/manual/en/class.mysqli.php
-**/
-@:native('Mysqli')
-extern class Mysqli {
-	var affected_rows(default, null):Int;
-	var client_info(default, null):String;
-	var client_version(default, null):Int;
-	var connect_errno(default, null):Int;
-	var connect_error(default, null):String;
-	var errno(default, null):Int;
-	var error_list(default, null):NativeAssocArray<Scalar>;
-	var error(default, null):String;
-	var field_count(default, null):Int;
-	var host_info(default, null):String;
-	var protocol_version(default, null):String;
-	var server_info(default, null):String;
-	var server_version(default, null):Int;
-	var info(default, null):String;
-	var insert_id(default, null):EitherType<Int, String>;
-	var sqlstate(default, null):String;
-	var thread_id(default, null):Int;
-	var warning_count(default, null):Int;
-
-	static function poll(read:Ref<NativeArray>, error:Ref<NativeArray>, reject:Ref<NativeArray>, sec:Int, ?usec:Int):Int;
-
-	function new(?host:String, ?username:String, ?passwd:String, dbname:String = "", ?port:Int, ?socket:String):Void;
-	function autocommit(mode:Bool):Bool;
-	function begin_transaction(?flags:Int, ?name:String):Bool;
-	function change_user(user:String, password:String, database:String):Bool;
-	function character_set_name():String;
-	function close():Bool;
-	function commit(?flags:Int, ?name:String):Bool;
-	function debug(message:String):Bool;
-	function dump_debug_info():Bool;
-	function get_charset():{
-		charset:String,
-		collation:String,
-		dir:String,
-		min_length:Int,
-		number:Int,
-		state:Int
-	};
-	function get_client_info():String;
-	function get_connection_stats():Bool;
-	function get_warnings():Mysqli_warning;
-	function init():Mysqli;
-	function kill(processid:Int):Bool;
-	function more_results():Bool;
-	function multi_query(query:String):Bool;
-	function next_result():Bool;
-	function options(option:Int, value:Scalar):Bool;
-	function ping():Bool;
-	function prepare(query:String):Mysqli_stmt;
-	function query(query:String, ?resultmode:Int):EitherType<Bool, Mysqli_result>;
-	function real_connect(?host:String, ?username:String, ?passwd:String, ?dbname:String, ?port:Int, ?socket:String, ?flags:Int):Bool;
-	function escape_string(escapestr:String):String;
-	function real_query(query:String):Bool;
-	function reap_async_query():Mysqli_result;
-	function refresh(options:Int):Bool;
-	function rollback(?flags:Int, ?name:String):Bool;
-	function rpl_query_type(query:String):Int;
-	function select_db(dbname:String):Bool;
-	function send_query(query:String):Bool;
-	function set_charset(charset:String):Bool;
-	function set_local_infile_handler(read_func:Function):Bool;
-	function ssl_set(key:String, cert:String, ca:String, capath:String, cipher:String):Bool;
-	function stat():String;
-	function stmt_init():Mysqli_stmt;
-	function store_result(?option:Int):Mysqli_result;
-	function use_result():Mysqli_result;
-}

+ 0 - 38
std/php/db/Mysqli_driver.hx

@@ -1,38 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 php.db;
-
-import php.NativeArray;
-
-@:native('Mysqli_driver')
-extern class Mysqli_driver {
-	var client_info(default, null):String;
-	var client_version(default, null):String;
-	var driver_version(default, null):String;
-	var embedded(default, null):String;
-	var reconnect(default, null):Bool;
-	var report_mode(default, null):Int;
-
-	function embedded_server_end():Void;
-	function embedded_server_start(start:Bool, arguments:NativeArray, groups:NativeArray):Bool;
-}

+ 0 - 62
std/php/db/Mysqli_result.hx

@@ -1,62 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 php.db;
-
-import php.*;
-import haxe.extern.*;
-
-/**
-	@see http://php.net/manual/en/class.mysqli-result.php
-**/
-@:native('Myslqi_result')
-extern class Mysqli_result implements Traversable {
-	var current_field(default, null):Int;
-	var field_count(default, null):Int;
-	var lengths(default, null):EitherType<Bool, NativeIndexedArray<Int>>;
-	var num_rows(default, null):Int;
-
-	function data_seek(offset:Int):Bool;
-	function fetch_all(?resulttype:Int):NativeArray;
-	function fetch_array(?resulttype:Int):NativeArray;
-	function fetch_assoc():NativeAssocArray<String>;
-	function fetch_field_direct(fieldnr:Int):MysqliFieldInfo;
-	function fetch_field():MysqliFieldInfo;
-	function fetch_fields():NativeIndexedArray<MysqliFieldInfo>;
-	function fetch_object(?class_name:String = "stdClass", ?params:NativeArray):{};
-	function fetch_row():NativeIndexedArray<String>;
-	function field_seek(fieldnr:Int):Bool;
-	function free():Void;
-}
-
-typedef MysqliFieldInfo = {
-	name:String,
-	orgname:String,
-	table:String,
-	orgtable:String,
-	max_length:Int,
-	length:Int,
-	charsetnr:Int,
-	flags:Int,
-	type:Int,
-	decimals:Int
-}

+ 0 - 57
std/php/db/Mysqli_stmt.hx

@@ -1,57 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 php.db;
-
-import haxe.extern.*;
-import php.*;
-
-@:native('Mysqli_stmt')
-extern class Mysqli_stmt {
-	var affected_rows(default, null):Int;
-	var errno(default, null):Int;
-	var error_list(default, null):NativeArray;
-	var error(default, null):String;
-	var field_count(default, null):Int;
-	var insert_id(default, null):Int;
-	var num_rows(default, null):Int;
-	var param_count(default, null):Int;
-	var sqlstate(default, null):String;
-
-	function new(link:Mysqli, ?query:String):Void;
-	function attr_get(attr:Int):Int;
-	function attr_set(attr:Int, mode:Int):Bool;
-	function bind_param(types:String, var1:Ref<Dynamic>, args:Rest<Ref<Dynamic>>):Bool;
-	function bind_result(var1:Ref<Dynamic>, args:Rest<Ref<Dynamic>>):Bool;
-	function close():Bool;
-	function data_seek(offset:Int):Void;
-	function execute():Bool;
-	function fetch():Bool;
-	function free_result():Void;
-	function get_result():Mysqli_result;
-	function get_warnings(stmt:Mysqli_stmt):{};
-	function prepare(query:String):Bool;
-	function reset():Bool;
-	function result_metadata():Mysqli_result;
-	function send_long_data(param_nr:Int, data:String):Bool;
-	function store_result():Bool;
-}

+ 0 - 32
std/php/db/Mysqli_warning.hx

@@ -1,32 +0,0 @@
-/*
- * Copyright (C)2005-2019 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 php.db;
-
-@:native('Mysqli_warning')
-extern class Mysqli_warning {
-	var message(default, null):String;
-	var sqlstate(default, null):Dynamic;
-	var errno(default, null):Int;
-
-	function next():Void;
-}

Vissa filer visades inte eftersom för många filer har ändrats