ソースを参照

Merge remote-tracking branch 'upstream/development' into development

dfadev 9 年 前
コミット
128c732f4c
95 ファイル変更2846 行追加1185 行削除
  1. 2 0
      .gitignore
  2. 21 10
      .travis.yml
  3. 3 3
      analyzer.ml
  4. 2 0
      ast.ml
  5. 25 10
      codegen.ml
  6. 5 39
      common.ml
  7. 17 18
      dce.ml
  8. 1 1
      extra/CHANGES.txt
  9. BIN
      extra/haxeci_sec.gpg.enc
  10. BIN
      extra/haxeci_ssh.enc
  11. 62 115
      filters.ml
  12. 1 4
      genas3.ml
  13. 1272 29
      gencpp.ml
  14. 2 2
      genjs.ml
  15. 2 1
      genswf.ml
  16. 5 2
      genswf9.ml
  17. 13 2
      interp.ml
  18. 1 1
      main.ml
  19. 16 25
      matcher.ml
  20. 15 15
      optimizer.ml
  21. 4 5
      parser.ml
  22. 1 1
      std/DateTools.hx
  23. 1 1
      std/Map.hx
  24. 23 23
      std/StdTypes.hx
  25. 7 7
      std/Xml.hx
  26. 3 1
      std/cpp/_std/Reflect.hx
  27. 3 1
      std/cpp/_std/haxe/Int64.hx
  28. 5 0
      std/cpp/cppia/HostClasses.hx
  29. 4 0
      std/flash/Boot.hx
  30. 26 16
      std/haxe/Serializer.hx
  31. 11 10
      std/haxe/ds/Vector.hx
  32. 1 1
      std/haxe/macro/ComplexTypeTools.hx
  33. 17 5
      std/haxe/macro/Context.hx
  34. 1 1
      std/haxe/rtti/CType.hx
  35. 1 1
      std/java/StdTypes.hx
  36. 0 1
      std/js/_std/Type.hx
  37. 2 0
      std/js/html/ArrayBuffer.hx
  38. 2 0
      std/js/html/DataView.hx
  39. 4 2
      std/js/html/Float32Array.hx
  40. 4 2
      std/js/html/Float64Array.hx
  41. 4 2
      std/js/html/Uint8Array.hx
  42. 1 1
      std/js/html/compat/ArrayBuffer.hx
  43. 1 1
      std/js/html/compat/DataView.hx
  44. 1 1
      std/js/html/compat/Float32Array.hx
  45. 1 1
      std/js/html/compat/Float64Array.hx
  46. 1 1
      std/js/html/compat/Uint8Array.hx
  47. 1 1
      std/js/jquery/Helper.hx
  48. 7 3
      std/js/jquery/JQuery.hx
  49. 0 1
      std/js/jquery/jquery-1.11.3.min.js
  50. 1 0
      std/js/jquery/jquery-1.12.1.min.js
  51. 0 1
      std/neko/_std/String.hx
  52. 2 2
      std/neko/_std/Type.hx
  53. 91 24
      tests/RunCi.hx
  54. 11 0
      tests/misc/projects/Issue2148/Main1.hx
  55. 2 0
      tests/misc/projects/Issue2148/compile1-fail.hxml
  56. 1 0
      tests/misc/projects/Issue2148/compile1-fail.hxml.stderr
  57. 8 0
      tests/misc/projects/Issue2232/Main1.hx
  58. 8 0
      tests/misc/projects/Issue2232/Main2.hx
  59. 3 0
      tests/misc/projects/Issue2232/compile1-fail.hxml
  60. 2 0
      tests/misc/projects/Issue2232/compile1-fail.hxml.stderr
  61. 3 0
      tests/misc/projects/Issue2232/compile2-fail.hxml
  62. 1 0
      tests/misc/projects/Issue2232/compile2-fail.hxml.stderr
  63. 0 0
      tests/misc/projects/Issue2278/compile.hxml.disabled
  64. 5 0
      tests/misc/projects/Issue3192/Main1.hx
  65. 2 0
      tests/misc/projects/Issue3192/compile1-fail.hxml
  66. 1 0
      tests/misc/projects/Issue3192/compile1-fail.hxml.stderr
  67. 2 1
      tests/misc/projects/Issue3782/compile-fail.hxml
  68. 21 0
      tests/misc/projects/Issue4448/Main1.hx
  69. 2 0
      tests/misc/projects/Issue4448/compile1-fail.hxml
  70. 3 0
      tests/misc/projects/Issue4448/compile1-fail.hxml.stderr
  71. 6 0
      tests/misc/projects/Issue4671/Main1.hx
  72. 6 0
      tests/misc/projects/Issue4671/Main2.hx
  73. 2 0
      tests/misc/projects/Issue4671/compile1-fail.hxml
  74. 1 0
      tests/misc/projects/Issue4671/compile1-fail.hxml.stderr
  75. 2 0
      tests/misc/projects/Issue4671/compile2-fail.hxml
  76. 1 0
      tests/misc/projects/Issue4671/compile2-fail.hxml.stderr
  77. 6 0
      tests/misc/projects/Issue4816/Main1.hx
  78. 2 0
      tests/misc/projects/Issue4816/compile1-fail.hxml
  79. 1 0
      tests/misc/projects/Issue4816/compile1-fail.hxml.stderr
  80. 12 6
      tests/optimization/src/TestJs.hx
  81. 17 0
      tests/unit/src/unit/issues/Issue3192.hx
  82. 17 0
      tests/unit/src/unit/issues/Issue3499.hx
  83. 21 0
      tests/unit/src/unit/issues/Issue4121.hx
  84. 68 0
      tests/unit/src/unit/issues/Issue4526.hx
  85. 11 0
      tests/unit/src/unit/issues/Issue4777.hx
  86. 13 0
      tests/unit/src/unit/issues/Issue4843.hx
  87. 28 0
      tests/unit/src/unit/issues/Issue4862.hx
  88. 21 0
      tests/unit/src/unit/issues/Issue4867.hx
  89. 14 0
      tests/unit/src/unit/issues/misc/Issue4121Macro.hx
  90. 12 9
      tests/unit/src/unitstd/haxe/ds/Vector.unit.hx
  91. 1 1
      tests/unit/unit-js.html
  92. 4 8
      type.ml
  93. 10 5
      typecore.ml
  94. 246 182
      typeload.ml
  95. 553 579
      typer.ml

+ 2 - 0
.gitignore

@@ -14,6 +14,8 @@
 /extra/bintray.json
 /extra/git-archive-all
 /extra/deploy_key
+/extra/*_sec.gpg
+/extra/*_ssh
 
 /version.ml
 /haxe

+ 21 - 10
.travis.yml

@@ -15,8 +15,10 @@ env:
     - secure: "VBJDQNJ9uvdt0aszo7oU3txuRvjkuLmuHZGOkrd4wE/5B4sX5jzx/+dnrKcNTXJCmQ/rVLuMu9GyxqVjNHlzce678voxdQNOtNkNgpkr1qN9/A9rRnCp77hH27ErdthpWxbmcnE62hAJ83TIKSvn//5lAkx4sMCKS1NXEWQ5qec="
     # HAXECI_GH_TOKEN: haxe-ci Github personal access token
     - secure: "TpEMYTLgNrVD7kR6hs6EwyWNXUxnfV6XO5MGvYQncKXB1N65PG18n4WQFhnKaH8C2QTFE7dq7688ooXGzwWeoT9WAOBey10jP1f7LXEAjMGAUA4vh2zS93qBZ92ZgzCDZnQN7ZOTQGocwU6Xolu+7/6hP2M8041HBixmFuNkXF4="
-    # deploy_key_decrypt
-    - secure: "A75uYqU0Xz6plIgSewEs0QQWe472dCMb9kf3j7Hx0DS7dApXgx8++189sw9Sv0wam5KPtbcIM292MucjGCb5zocVj9xCUVgajhEA0QpTuDMBjk/cg3ClWCGjfybaCl2E5LLdUs7Zy4b4oNWtVikOWLWJ4sC1kaarR9p6kv8yYZg="
+    # PPA configs
+    - PPA="ppa:haxe/snapshots"
+    - DEBFULLNAME="Haxe CI Bot"
+    - DEBEMAIL="[email protected]"
 
 sudo: false
 addons:
@@ -32,7 +34,7 @@ apt_targets:
   - &apt_cpp    [*apt_common, gcc-multilib, g++-multilib]
   - &apt_cs     [*apt_common, mono-devel, mono-mcs]
   - &apt_python [*apt_common, python3]
-  - &apt_flash  [*apt_common, libgd2-xpm, ia32-libs, ia32-libs-multiarch]
+  - &apt_flash  [*apt_common, "libcurl3:i386", "libglib2.0-0:i386", "libx11-6:i386", "libxext6:i386", "libxt6:i386", "libxcursor1:i386", "libnss3:i386", "libgtk2.0-0:i386"]
 
 matrix:
   include:
@@ -48,10 +50,19 @@ matrix:
       env: TEST=macro
       addons: {apt: {packages: [*apt_cs, *apt_python]}}
     - os: linux
+      sudo: required
+      dist: trusty
       env:
         - TEST=neko
-        - BINTRAY=1
         - DEPLOY=1
+        - BINTRAY=1
+        # haxeci_decrypt (Deploy source package to ppa:haxe/snapshots.)
+        - secure: "Mw3p6bDZuqVQ6u7GrwLQfje5hhIOA4+mdqqLXYHP79UKdhgqb91Dn6IbG9vQ1VXVe64W4YZbQAMBMMRX5kEPDl6JvTVGSBhg00Mi69oO5qrCMcBI6f9FntG72YaVvLf+PA7co+vKrnJzaP2M9pe4SH9Ztbhy0YNxULp7NQ8FLsM="
+        # deploy_key_decrypt (Deploy doc to api.haxe.org.)
+        - secure: "A75uYqU0Xz6plIgSewEs0QQWe472dCMb9kf3j7Hx0DS7dApXgx8++189sw9Sv0wam5KPtbcIM292MucjGCb5zocVj9xCUVgajhEA0QpTuDMBjk/cg3ClWCGjfybaCl2E5LLdUs7Zy4b4oNWtVikOWLWJ4sC1kaarR9p6kv8yYZg="
+      before_script:
+        - travis_retry sudo apt-get install mysql-server -y
+        - mysql -u root -e "create user travis@localhost identified by '';"
     - os: linux
       env:
         - TEST=js
@@ -89,6 +100,7 @@ matrix:
     - os: osx
       env:
         - TEST=neko
+        - DEPLOY=1
         - BINTRAY=1
     - os: osx
       env: TEST=js
@@ -126,18 +138,17 @@ install:
       travis_retry brew install neko --HEAD;
     fi
 
-before_script:
+script:
+  # setup database
   - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
-    travis_retry brew install mysql &&
-    mysql.server start;
-    mysql -u root -e "create user if not exists travis@localhost identified by '';";
+      travis_retry brew install mysql &&
+      mysql.server start;
+      mysql -u root -e "create user if not exists travis@localhost identified by '';";
     fi
   - mysql -u root -e "CREATE DATABASE haxe_test;"
   - mysql -u root -e "grant all on haxe_test.* to travis@localhost;"
   # start ssh-agent for deployment to haxe.org
   - eval `ssh-agent -s`
-
-script:
   - make package_src -s
   - make -s
   - make tools -s

+ 3 - 3
analyzer.ml

@@ -93,7 +93,7 @@ let can_throw e =
 	let rec loop e = match e.eexpr with
 		| TConst _ | TLocal _ | TTypeExpr _ | TFunction _ | TBlock _ -> ()
 		| TCall _ | TNew _ | TThrow _ | TCast(_,Some _) -> raise Exit
-		| TField _ -> raise Exit (* sigh *)
+		| TField _ | TArray _ -> raise Exit (* sigh *)
 		| _ -> Type.iter loop e
 	in
 	try
@@ -216,8 +216,6 @@ module Config = struct
 						true
 					else
 						loop ml
-				| (Meta.HasUntyped,_,_) :: _ ->
-					true
 				| _ :: ml ->
 					loop ml
 				| [] ->
@@ -261,6 +259,8 @@ module Config = struct
 					| EConst (Ident s) when s = flag_dot_debug -> {config with dot_debug = true}
 					| _ -> config
 				) config el
+			| (Meta.HasUntyped,_,_) ->
+				{config with optimize = false}
 			| _ ->
 				config
 		) config meta

+ 2 - 0
ast.ml

@@ -24,6 +24,7 @@ type pos = {
 }
 
 module IntMap = Map.Make(struct type t = int let compare a b = a - b end)
+module StringMap = Map.Make(struct type t = string let compare = String.compare end)
 
 module Meta = struct
 	type strict_meta =
@@ -416,6 +417,7 @@ type abstract_flag =
 	| AFromType of complex_type
 	| AToType of complex_type
 	| AIsType of complex_type
+	| AExtern
 
 type enum_constructor = {
 	ec_name : string;

+ 25 - 10
codegen.ml

@@ -481,7 +481,7 @@ let rec build_generic ctx c p tl =
 						apply_params c.cl_params tl (TInst(cs,pl))
 				in
 				let ts = follow (find_class gctx.subst) in
-				let cs,pl = Typeload.check_extends ctx c ts p in
+				let cs,pl = Typeload.Inheritance.check_extends ctx c ts p in
 				match cs.cl_kind with
 				| KGeneric ->
 					(match build_generic ctx cs p pl with
@@ -705,15 +705,17 @@ let build_instance ctx mtype p =
 	| TAbstractDecl a ->
 		a.a_params, a.a_path, (fun tl -> TAbstract(a,tl))
 
-let on_inherit ctx c p h =
-	match h with
-	| HExtends { tpackage = ["haxe";"remoting"]; tname = "Proxy"; tparams = [TPType(CTPath t)] } ->
+let on_inherit ctx c p (is_extends,tp) =
+	if not is_extends then
+		true
+	else match tp with
+	| { tpackage = ["haxe";"remoting"]; tname = "Proxy"; tparams = [TPType(CTPath t)] } ->
 		extend_remoting ctx c t p false true;
 		false
-	| HExtends { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(CTPath t)] } ->
+	| { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(CTPath t)] } ->
 		extend_remoting ctx c t p true true;
 		false
-	| HExtends { tpackage = ["haxe";"xml"]; tname = "Proxy"; tparams = [TPExpr(EConst (String file),p);TPType t] } ->
+	| { tpackage = ["haxe";"xml"]; tname = "Proxy"; tparams = [TPExpr(EConst (String file),p);TPType t] } ->
 		extend_xml_proxy ctx c t file p;
 		true
 	| _ ->
@@ -876,11 +878,24 @@ module AbstractCast = struct
 			| _,[],_ -> pl
 			| _,el,_ ->
 				let relevant = Hashtbl.create 0 in
-				List.iter (fun e -> match fst e with
-					| EConst(Ident s) -> Hashtbl.replace relevant s true
-					| _ -> error "Type parameter expected" (pos e)
+				List.iter (fun e ->
+					let rec loop f e = match fst e with
+						| EConst(Ident s) ->
+							Hashtbl.replace relevant s f
+						| EMeta((Meta.Custom ":followWithAbstracts",_,_),e1) ->
+							loop Abstract.follow_with_abstracts e1;
+						| _ ->
+							error "Type parameter expected" (pos e)
+					in
+					loop (fun t -> t) e
 				) el;
-				let tl = List.map2 (fun (n,_) t -> if Hashtbl.mem relevant n || not (has_mono t) then t else t_dynamic) a.a_params pl in
+				let tl = List.map2 (fun (n,_) t ->
+					try
+						(Hashtbl.find relevant n) t
+					with Not_found ->
+						if not (has_mono t) then t
+						else t_dynamic
+				) a.a_params pl in
 				if com.platform = Js && a.a_path = ([],"Map") then begin match tl with
 					| t1 :: _ ->
 						let rec loop stack t =

+ 5 - 39
common.ml

@@ -74,12 +74,6 @@ type platform_config = {
 	pf_static : bool;
 	(** has access to the "sys" package *)
 	pf_sys : bool;
-	(** local variables are block-scoped *)
-	pf_locals_scope : bool;
-	(** captured local variables are scoped *)
-	pf_captured_scope : bool;
-	(** generated locals must be absolutely unique wrt the current function *)
-	pf_unique_locals : bool;
 	(** captured variables handling (see before) *)
 	pf_capture_policy : capture_policy;
 	(** when calling a method with optional args, do we replace the missing args with "null" constants *)
@@ -131,7 +125,7 @@ type context = {
 	mutable get_macros : unit -> context option;
 	mutable run_command : string -> int;
 	file_lookup_cache : (string,string option) Hashtbl.t;
-	parser_cache : (string,string list * (type_def * pos) list) Hashtbl.t;
+	parser_cache : (string,(type_def * pos) list) Hashtbl.t;
 	mutable stored_typed_exprs : (int, texpr) PMap.t;
 	(* output *)
 	mutable file : string;
@@ -167,7 +161,7 @@ module Define = struct
 	type strict_defined =
 		| AbsolutePath
 		| AdvancedTelemetry
-		| Analyzer
+		(* | Analyzer *)
 		| As3
 		| CheckXmlProxy
 		| CoreApi
@@ -212,6 +206,7 @@ module Define = struct
 		| NetworkSandbox
 		| NetVer
 		| NetTarget
+		| NoAnalyzer
 		| NoCompilation
 		| NoCOpt
 		| NoDeprecationWarnings
@@ -252,7 +247,7 @@ module Define = struct
 	let infos = function
 		| AbsolutePath -> ("absolute_path","Print absolute file path in trace output")
 		| AdvancedTelemetry -> ("advanced-telemetry","Allow the SWF to be measured with Monocle tool")
-		| Analyzer -> ("analyzer","Use static analyzer for optimization (experimental)")
+		(* | Analyzer -> ("analyzer","Use static analyzer for optimization (experimental)") *)
 		| As3 -> ("as3","Defined when outputing flash9 as3 source code")
 		| CheckXmlProxy -> ("check_xml_proxy","Check the used fields of the xml proxy")
 		| CoreApi -> ("core_api","Defined in the core api context")
@@ -298,6 +293,7 @@ module Define = struct
 		| NekoSource -> ("neko_source","Output neko source instead of bytecode")
 		| NekoV1 -> ("neko_v1","Keep Neko 1.x compatibility")
 		| NetworkSandbox -> ("network-sandbox","Use local network sandbox instead of local file access one")
+		| NoAnalyzer -> ("no-analyzer","Disable the static analyzer")
 		| NoCompilation -> ("no-compilation","Disable final compilation for Cs, Cpp and Java")
 		| NoCOpt -> ("no_copt","Disable completion optimization (for debug purposes)")
 		| NoDebug -> ("no_debug","Remove all debug macros from cpp output")
@@ -546,9 +542,6 @@ let default_config =
 	{
 		pf_static = true;
 		pf_sys = true;
-		pf_locals_scope = true;
-		pf_captured_scope = true;
-		pf_unique_locals = false;
 		pf_capture_policy = CPNone;
 		pf_pad_nulls = false;
 		pf_add_final_return = false;
@@ -567,9 +560,6 @@ let get_config com =
 		{
 			pf_static = false;
 			pf_sys = false;
-			pf_locals_scope = false;
-			pf_captured_scope = false;
-			pf_unique_locals = false;
 			pf_capture_policy = CPLoopVars;
 			pf_pad_nulls = false;
 			pf_add_final_return = false;
@@ -582,9 +572,6 @@ let get_config com =
 		{
 			pf_static = false;
 			pf_sys = true;
-			pf_locals_scope = true;
-			pf_captured_scope = true;
-			pf_unique_locals = false;
 			pf_capture_policy = CPNone;
 			pf_pad_nulls = true;
 			pf_add_final_return = false;
@@ -597,9 +584,6 @@ let get_config com =
 		{
 			pf_static = true;
 			pf_sys = false;
-			pf_locals_scope = false;
-			pf_captured_scope = true;
-			pf_unique_locals = true;
 			pf_capture_policy = CPLoopVars;
 			pf_pad_nulls = false;
 			pf_add_final_return = true;
@@ -612,9 +596,6 @@ let get_config com =
 		{
 			pf_static = true;
 			pf_sys = false;
-			pf_locals_scope = true;
-			pf_captured_scope = true; (* handled by genSwf9 *)
-			pf_unique_locals = false;
 			pf_capture_policy = CPLoopVars;
 			pf_pad_nulls = false;
 			pf_add_final_return = false;
@@ -627,9 +608,6 @@ let get_config com =
 		{
 			pf_static = false;
 			pf_sys = true;
-			pf_locals_scope = false; (* some duplicate work is done in genPhp *)
-			pf_captured_scope = false;
-			pf_unique_locals = false;
 			pf_capture_policy = CPNone;
 			pf_pad_nulls = true;
 			pf_add_final_return = false;
@@ -642,9 +620,6 @@ let get_config com =
 		{
 			pf_static = true;
 			pf_sys = true;
-			pf_locals_scope = true;
-			pf_captured_scope = true;
-			pf_unique_locals = false;
 			pf_capture_policy = CPWrapRef;
 			pf_pad_nulls = true;
 			pf_add_final_return = true;
@@ -657,9 +632,6 @@ let get_config com =
 		{
 			pf_static = true;
 			pf_sys = true;
-			pf_locals_scope = false;
-			pf_captured_scope = true;
-			pf_unique_locals = true;
 			pf_capture_policy = CPWrapRef;
 			pf_pad_nulls = true;
 			pf_add_final_return = false;
@@ -672,9 +644,6 @@ let get_config com =
 		{
 			pf_static = true;
 			pf_sys = true;
-			pf_locals_scope = false;
-			pf_captured_scope = true;
-			pf_unique_locals = false;
 			pf_capture_policy = CPWrapRef;
 			pf_pad_nulls = true;
 			pf_add_final_return = false;
@@ -687,9 +656,6 @@ let get_config com =
 		{
 			pf_static = false;
 			pf_sys = true;
-			pf_locals_scope = false;
-			pf_captured_scope = false;
-			pf_unique_locals = false;
 			pf_capture_policy = CPLoopVars;
 			pf_pad_nulls = false;
 			pf_add_final_return = false;

+ 17 - 18
dce.ml

@@ -85,7 +85,7 @@ let rec check_feature dce s =
 
 and check_and_add_feature dce s =
 	check_feature dce s;
-	Common.add_feature dce.com s;
+	Hashtbl.replace dce.curclass.cl_module.m_extra.m_features s true
 
 (* mark a field as kept *)
 and mark_field dce c cf stat =
@@ -98,23 +98,24 @@ and mark_field dce c cf stat =
 		end
 	in
 	if cf.cf_name = "new" then begin
-		let rec loop c = match c.cl_super with
-			| None -> ()
-			| Some (csup,_) ->
-				begin match csup.cl_constructor with
-				| None -> ()
+		let rec loop c =
+			begin match c.cl_constructor with
 				| Some cf -> add cf
-				end;
-				loop csup
+				| None -> ()
+			end;
+			match c.cl_super with
+			| Some(csup,_) -> loop csup
+			| None -> ()
 		in
 		loop c
-	end;
-	if not (PMap.mem cf.cf_name (if stat then c.cl_statics else c.cl_fields)) then begin
-		match c.cl_super with
-		| None -> add cf
-		| Some (c,_) -> mark_field dce c cf stat
-	end else
-		add cf
+	end else begin
+		if not (PMap.mem cf.cf_name (if stat then c.cl_statics else c.cl_fields)) then begin
+			match c.cl_super with
+			| None -> add cf
+			| Some (c,_) -> mark_field dce c cf stat
+		end else
+			add cf
+	end
 
 let rec update_marked_class_fields dce c =
 	(* mark all :?used fields as surely :used now *)
@@ -747,6 +748,4 @@ let run com main full =
 		| x :: l -> x :: remove_meta m l
 	in
 	List.iter (fun cf -> cf.cf_meta <- remove_meta Meta.Used cf.cf_meta) dce.marked_fields;
-	List.iter (fun cf -> cf.cf_meta <- remove_meta Meta.MaybeUsed cf.cf_meta) dce.marked_maybe_fields;
-
-
+	List.iter (fun cf -> cf.cf_meta <- remove_meta Meta.MaybeUsed cf.cf_meta) dce.marked_maybe_fields

+ 1 - 1
extra/CHANGES.txt

@@ -1482,7 +1482,7 @@
 	fixed infinite loop in neko EReg split/replace and epsilon matching
 	added neko native serialization support
 	fixed syntax for multiple constraints in type parameter
-	added recursive type parameters contraints (T : C<T> constraints)
+	added recursive type parameters constraints (T : C<T> constraints)
 	updated Xml handling
 
 2006-04-17: beta 5

BIN
extra/haxeci_sec.gpg.enc


BIN
extra/haxeci_ssh.enc


+ 62 - 115
filters.ml

@@ -522,71 +522,17 @@ let captured_vars com e =
 (* RENAME LOCAL VARS *)
 
 let rename_local_vars ctx e =
-	let cfg = ctx.com.config in
-	let all_scope = (not cfg.pf_captured_scope) || (not cfg.pf_locals_scope) in
-	let vars = ref PMap.empty in
-	let all_vars = ref PMap.empty in
-	let vtemp = alloc_var "~" t_dynamic in
-	let rebuild_vars = ref false in
-	let rebuild m =
-		PMap.fold (fun v acc -> PMap.add v.v_name v acc) m PMap.empty
+	let vars = ref [] in
+	let declare v =
+		vars := v :: !vars
 	in
-	let save() =
-		let old = !vars in
-		if cfg.pf_unique_locals || not cfg.pf_locals_scope then (fun() -> ()) else (fun() -> vars := if !rebuild_vars then rebuild old else old)
+	let reserved = ref StringMap.empty in
+	let reserve name =
+		reserved := StringMap.add name true !reserved
 	in
-	let count = ref 1 in
-	let rename vars v =
-		while PMap.mem (v.v_name ^ string_of_int !count) vars do
-			incr count;
-		done;
-		begin match ctx.com.platform with
-			| Cpp ->
-				if not (Meta.has Meta.RealPath v.v_meta) then
-					v.v_meta <- (Meta.RealPath,[EConst (String v.v_name),e.epos],e.epos) :: v.v_meta
-			| _ ->
-				()
-		end;
-		v.v_name <- v.v_name ^ string_of_int !count;
-	in
-	let declare v p =
-		(match follow v.v_type with
-			| TAbstract ({a_path = [],"Void"},_) -> error "Arguments and variables of type Void are not allowed" p
-			| _ -> ());
-		(* chop escape char for all local variables generated *)
-		if is_gen_local v then v.v_name <- "_g" ^ String.sub v.v_name 1 (String.length v.v_name - 1);
-		let look_vars = (if not cfg.pf_captured_scope && v.v_capture then !all_vars else !vars) in
-		(try
-			let v2 = PMap.find v.v_name look_vars in
-			(*
-				block_vars will create some wrapper-functions that are declaring
-				the same variable twice. In that case do not perform a rename since
-				we are sure it's actually the same variable
-			*)
-			if v == v2 then raise Not_found;
-			rename look_vars v;
-		with Not_found ->
-			());
-		vars := PMap.add v.v_name v !vars;
-		if all_scope then all_vars := PMap.add v.v_name v !all_vars;
-	in
-	(*
-		This is quite a rare case, when a local variable would otherwise prevent
-		accessing a type because it masks the type value or the package name.
-	*)
 	let check t =
 		match (t_infos t).mt_path with
-		| [], name | name :: _, _ ->
-			let vars = if cfg.pf_locals_scope then vars else all_vars in
-			(try
-				let v = PMap.find name !vars in
-				if v == vtemp then raise Not_found; (* ignore *)
-				rename (!vars) v;
-				rebuild_vars := true;
-				vars := PMap.add v.v_name v !vars
-			with Not_found ->
-				());
-			vars := PMap.add name vtemp !vars
+		| [], name | name :: _, _ -> reserve name
 	in
 	let check_type t =
 		match follow t with
@@ -596,70 +542,62 @@ let rename_local_vars ctx e =
 		| TAbstract (a,_) -> check (TAbstractDecl a)
 		| TMono _ | TLazy _ | TAnon _ | TDynamic _ | TFun _ -> ()
 	in
-	let rec loop e =
-		match e.eexpr with
-		| TVar (v,eo) ->
-			if not cfg.pf_locals_scope then declare v e.epos;
-			(match eo with None -> () | Some e -> loop e);
-			if cfg.pf_locals_scope then declare v e.epos;
-		| TFunction tf ->
-			let old = save() in
-			List.iter (fun (v,_) -> declare v e.epos) tf.tf_args;
-			loop tf.tf_expr;
-			old()
-		| TBlock el ->
-			let old = save() in
-			(* we have to look ahead for vars on these targets (issue #3344) *)
-			begin match ctx.com.platform with
-				| Js ->
-					let rec check_var e = match e.eexpr with
-						| TVar (v,eo) ->
-							(match eo with None -> () | Some e -> loop e);
-							declare v e.epos
-						| TBlock _ ->
-							()
-						| _ ->
-							Type.iter check_var e
-					in
-					List.iter check_var el
-				| _ ->
-					()
-			end;
-			List.iter loop el;
-			old()
-		| TFor (v,it,e1) ->
-			loop it;
-			let old = save() in
-			declare v e.epos;
-			loop e1;
-			old()
-		| TTry (e,catchs) ->
-			loop e;
+	let rec collect e = match e.eexpr with
+ 		| TVar(v,eo) ->
+			declare v;
+			(match eo with None -> () | Some e -> collect e)
+		| TFor(v,e1,e2) ->
+			declare v;
+			collect e1;
+			collect e2;
+		| TTry(e1,catches) ->
+			collect e1;
 			List.iter (fun (v,e) ->
-				let old = save() in
-				declare v e.epos;
+				declare v;
 				check_type v.v_type;
-				loop e;
-				old()
-			) catchs;
+				collect e
+			) catches
+		| TFunction tf ->
+			List.iter (fun (v,_) -> declare v) tf.tf_args;
+			collect tf.tf_expr
 		| TTypeExpr t ->
 			check t
 		| TNew (c,_,_) ->
-			Type.iter loop e;
+			Type.iter collect e;
 			check (TClassDecl c);
 		| TCast (e,Some t) ->
-			loop e;
+			collect e;
 			check t;
 		| TConst TSuper ->
 			check_type e.etype
 		| _ ->
-			Type.iter loop e
+			Type.iter collect e
 	in
-	declare (alloc_var "this" t_dynamic) Ast.null_pos; (* force renaming of 'this' vars in abstract *)
+	(* Pass 1: Collect used identifiers and variables. *)
+	reserve "this";
+	if ctx.com.platform = Java then reserve "_";
 	begin match ctx.curclass.cl_path with
-		| s :: _,_ | [],s -> declare (alloc_var s t_dynamic) Ast.null_pos
+		| s :: _,_ | [],s -> reserve s
 	end;
-	loop e;
+	collect e;
+	(* Pass 2: Check and rename variables. *)
+	let count_table = Hashtbl.create 0 in
+	let maybe_rename v =
+		(* chop escape char for all local variables generated *)
+		if is_gen_local v then v.v_name <- "_g" ^ String.sub v.v_name 1 (String.length v.v_name - 1);
+		let name = ref v.v_name in
+		let count = ref (try Hashtbl.find count_table v.v_name with Not_found -> 0) in
+		while StringMap.mem !name !reserved do
+			incr count;
+			name := v.v_name ^ (string_of_int !count);
+		done;
+		reserve !name;
+		Hashtbl.replace count_table v.v_name !count;
+		if not (Meta.has Meta.RealPath v.v_meta) then
+			v.v_meta <- (Meta.RealPath,[EConst (String v.v_name),e.epos],e.epos) :: v.v_meta;
+		v.v_name <- !name;
+	in
+	List.iter maybe_rename (List.rev !vars);
 	e
 
 let check_unification ctx e t =
@@ -910,7 +848,7 @@ let add_field_inits ctx t =
 						eassign;
 			) inits in
 			let el = if !need_this then (mk (TVar((v, Some ethis))) ethis.etype ethis.epos) :: el else el in
-			match c.cl_constructor with
+			let cf = match c.cl_constructor with
 			| None ->
 				let ct = TFun([],ctx.com.basic.tvoid) in
 				let ce = mk (TFunction {
@@ -920,15 +858,24 @@ let add_field_inits ctx t =
 				}) ct c.cl_pos in
 				let ctor = mk_field "new" ct c.cl_pos in
 				ctor.cf_kind <- Method MethNormal;
-				c.cl_constructor <- Some { ctor with cf_expr = Some ce };
+				{ ctor with cf_expr = Some ce }
 			| Some cf ->
 				match cf.cf_expr with
 				| Some { eexpr = TFunction f } ->
 					let bl = match f.tf_expr with {eexpr = TBlock b } -> b | x -> [x] in
 					let ce = mk (TFunction {f with tf_expr = mk (TBlock (el @ bl)) ctx.com.basic.tvoid c.cl_pos }) cf.cf_type cf.cf_pos in
-					c.cl_constructor <- Some {cf with cf_expr = Some ce }
+					{cf with cf_expr = Some ce };
 				| _ ->
 					assert false
+			in
+			let config = Analyzer.Config.get_base_config ctx.com false in
+			Analyzer.Run.run_on_field ctx config c cf;
+			(match cf.cf_expr with
+			| Some e ->
+				cf.cf_expr <- Some (Optimizer.sanitize ctx.com e)
+			| _ ->
+				());
+			c.cl_constructor <- Some cf
 	in
 	match t with
 	| TClassDecl c ->
@@ -1081,7 +1028,7 @@ let run com tctx main =
 	end;
 	if not (Common.defined com Define.NoDeprecationWarnings) then
 		Codegen.DeprecationCheck.run com;
-	let use_static_analyzer = Common.defined com Define.Analyzer in
+	let use_static_analyzer = not (Common.defined com Define.NoAnalyzer) in
 	let new_types = List.filter (fun t -> not (is_cached t)) com.types in
 	(* PASS 1: general expression filters *)
 	let filters = [

+ 1 - 4
genas3.ml

@@ -298,10 +298,7 @@ let rec type_str ctx t p =
 				| TAbstract ({ a_path = [],"UInt" },_)
 				| TAbstract ({ a_path = [],"Int" },_)
 				| TAbstract ({ a_path = [],"Float" },_)
-				| TAbstract ({ a_path = [],"Bool" },_)
-				| TInst ({ cl_path = [],"Int" },_)
-				| TInst ({ cl_path = [],"Float" },_)
-				| TEnum ({ e_path = [],"Bool" },_) -> "*"
+				| TAbstract ({ a_path = [],"Bool" },_) -> "*"
 				| _ -> type_str ctx t p)
 			| _ -> assert false);
 		| _ -> type_str ctx (apply_params t.t_params args t.t_type) p)

ファイルの差分が大きいため隠しています
+ 1272 - 29
gencpp.ml


+ 2 - 2
genjs.ml

@@ -596,7 +596,7 @@ and gen_expr ctx e =
 		spr ctx "if";
 		gen_value ctx cond;
 		spr ctx " ";
-		gen_expr ctx e;
+		gen_expr ctx (mk_block e);
 		(match eelse with
 		| None -> ()
 		| Some e2 ->
@@ -605,7 +605,7 @@ and gen_expr ctx e =
 			| _ -> ());
 			semicolon ctx;
 			spr ctx " else ";
-			gen_expr ctx e2);
+			gen_expr ctx (match e2.eexpr with | TIf _ -> e2 | _ -> mk_block e2));
 	| TUnop (op,Ast.Prefix,e) ->
 		spr ctx (Ast.s_unop op);
 		gen_value ctx e

+ 2 - 1
genswf.ml

@@ -1111,6 +1111,7 @@ let generate swf_header com =
 	let tags = build_swf9 com file swc in
 	let header, bg = (match swf_header with None -> default_header com | Some h -> convert_header com h) in
 	let bg = tag (TSetBgColor { cr = bg lsr 16; cg = (bg lsr 8) land 0xFF; cb = bg land 0xFF }) in
+	let scene = tag ~ext:true (TScenes ([(0,"Scene1")],[])) in
 	let swf_debug_password = try
 		Digest.to_hex(Digest.string (Common.defined_value com Define.SwfDebugPassword))
 	with Not_found ->
@@ -1143,7 +1144,7 @@ let generate swf_header com =
 	with Not_found ->
 		[]
 	in
-	let swf = header, fattr @ meta_data @ bg :: debug @ swf_script_limits @ tags @ [tag TShowFrame] in
+	let swf = header, fattr @ meta_data @ bg :: scene :: debug @ swf_script_limits @ tags @ [tag TShowFrame] in
 	(* merge swf libraries *)
 	let priority = ref (swf_header = None) in
 	let swf = List.fold_left (fun swf (file,lib,cl) ->

+ 5 - 2
genswf9.ml

@@ -213,9 +213,12 @@ let rec type_id ctx t =
 	| TInst ({ cl_path = ["haxe"],"Int32" },_) ->
 		type_path ctx ([],"Int")
 	| TInst ({ cl_path = ["flash"],"Vector" } as c,pl) ->
+		let def() = HMParams (type_path ctx c.cl_path,List.map (type_id ctx) pl) in
 		(match pl with
-		| [TInst({cl_kind = KTypeParameter _},_)] -> type_path ctx ([],"Object")
-		| _ -> HMParams (type_path ctx c.cl_path,List.map (type_id ctx) pl))
+		| [t] -> (match follow t with
+			| TInst({cl_kind = KTypeParameter _},_) -> type_path ctx ([],"Object")
+			| _ -> def())
+		| _ -> def())
 	| TInst (c,_) ->
 		(match c.cl_kind with
 		| KTypeParameter l ->

+ 13 - 2
interp.ml

@@ -103,6 +103,7 @@ type extern_api = {
 	on_type_not_found : (string -> value) -> unit;
 	parse_string : string -> Ast.pos -> bool -> Ast.expr;
 	type_expr : Ast.expr -> Type.texpr;
+	resolve_type  : Ast.complex_type -> Ast.pos -> t;
 	type_macro_expr : Ast.expr -> Type.texpr;
 	store_typed_expr : Type.texpr -> Ast.expr;
 	get_display : string -> string;
@@ -196,6 +197,8 @@ exception Sys_exit of int
 
 let get_ctx_ref = ref (fun() -> assert false)
 let encode_complex_type_ref = ref (fun t -> assert false)
+let decode_complex_type_ref = ref (fun t -> assert false)
+let decode_pos_ref = ref (fun v -> assert false)
 let encode_type_ref = ref (fun t -> assert false)
 let decode_type_ref = ref (fun t -> assert false)
 let encode_expr_ref = ref (fun e -> assert false)
@@ -215,7 +218,10 @@ let eval_expr_ref : (context -> texpr -> value option) ref = ref (fun _ _ -> ass
 let get_ctx() = (!get_ctx_ref)()
 let enc_array (l:value list) : value = (!enc_array_ref) l
 let dec_array (l:value) : value list = (!dec_array_ref) l
+
+let decode_complex_type (v:value) : Ast.complex_type = (!decode_complex_type_ref) v
 let encode_complex_type (t:Ast.complex_type) : value = (!encode_complex_type_ref) t
+let decode_pos (v:value) : Ast.pos = (!decode_pos_ref) v
 let encode_type (t:Type.t) : value = (!encode_type_ref) t
 let decode_type (v:value) : Type.t = (!decode_type_ref) v
 let encode_expr (e:Ast.expr) : value = (!encode_expr_ref) e
@@ -2428,6 +2434,9 @@ let macro_lib =
 		"type_expr", Fun1 (fun v ->
 			encode_texpr ((get_ctx()).curapi.type_expr (decode_expr v))
 		);
+		"resolve_type", Fun2 (fun t p ->
+			encode_type ((get_ctx()).curapi.resolve_type (decode_complex_type t) (decode_pos p));
+		);
 		"s_type", Fun1 (fun v ->
 			VString (Type.s_type (print_context()) (decode_type v))
 		);
@@ -3486,7 +3495,7 @@ and call ctx vthis vfun pl p =
 		| Stack_overflow -> exc (VString "Compiler Stack overflow")
 		| Sys_error msg | Failure msg -> exc (VString msg)
 		| Unix.Unix_error (_,cmd,msg) -> exc (VString ("Error " ^ cmd ^ " " ^ msg))
-		(* | Invalid_expr -> exc (VString "Invalid input value") *)
+		| Invalid_expr -> exc (VString "Invalid input value")
 		| Builtin_error | Invalid_argument _ -> exc (VString "Invalid call")) in
 	ctx.vthis <- oldthis;
 	ctx.venv <- oldenv;
@@ -4569,7 +4578,7 @@ and encode_anon_status s =
 	let tag, pl = (match s with
 		| Closed -> 0, []
 		| Opened -> 1, []
-		| Type.Const -> 2, []
+		(* | Type.Const -> 2, [] *)
 		| Extend tl -> 3, [encode_ref tl (fun tl -> enc_array (List.map encode_type tl)) (fun() -> "<extended types>")]
 		| Statics cl -> 4, [encode_clref cl]
 		| EnumStatics en -> 5, [encode_enref en]
@@ -5036,6 +5045,8 @@ let rec make_const e =
 
 ;;
 encode_complex_type_ref := encode_ctype;
+decode_complex_type_ref := decode_ctype;
+decode_pos_ref := decode_pos;
 enc_array_ref := enc_array;
 dec_array_ref := dec_array;
 encode_type_ref := encode_type;

+ 1 - 1
main.ml

@@ -1448,7 +1448,7 @@ try
 			"n"
 		| Js ->
 			if not (PMap.exists (fst (Define.infos Define.JqueryVer)) com.defines) then
-				Common.define_value com Define.JqueryVer "11103";
+				Common.define_value com Define.JqueryVer "11201";
 			add_std "js";
 			"js"
 		| Php ->

+ 16 - 25
matcher.ml

@@ -416,39 +416,28 @@ let to_pattern ctx e t =
 			end
 		| EConst(Ident s) ->
 			begin try
-				let ec = match follow t with
-					| TEnum(en,pl) ->
-						let ef = try
-							PMap.find s en.e_constrs
-						with Not_found when not (is_lower_ident s) ->
-							error (string_error s en.e_names ("Expected constructor for enum " ^ (s_type_path en.e_path))) p
-						in
-						(match ef.ef_type with
-							| TFun (args,_) ->
-								let msg = Printf.sprintf "Enum constructor %s.%s requires parameters %s"
-									(s_type_path en.e_path)
-									ef.ef_name
-									(String.concat ", " (List.map (fun (n,_,t) -> n ^ ":" ^ (s_type t)) args))
-								in
-								error msg p
-							| _ -> ());
+				let rec loop t = match follow t with
+					| TEnum (en,tl) ->
+						let ef = PMap.find s en.e_constrs in
 						let et = mk (TTypeExpr (TEnumDecl en)) (TAnon { a_fields = PMap.empty; a_status = ref (EnumStatics en) }) p in
-						mk (TField (et,FEnum (en,ef))) (apply_params en.e_params pl ef.ef_type) p
-					| TAbstract({a_impl = Some c} as a,_) when Meta.has Meta.Enum a.a_meta ->
+						mk (TField (et,FEnum (en,ef))) (apply_params en.e_params tl ef.ef_type) p
+					| TAbstract ({a_impl = Some c} as a,_) when has_meta Meta.Enum a.a_meta ->
 						let cf = PMap.find s c.cl_statics in
 						Type.unify (follow cf.cf_type) t;
 						let e = begin match cf.cf_expr with
-						| Some ({eexpr = TConst c | TCast({eexpr = TConst c},None)} as e) -> e
-						| _ -> raise Not_found
+							| Some ({eexpr = TConst c | TCast({eexpr = TConst c},None)} as e) -> e
+							| None when c.cl_extern -> make_static_field_access c cf cf.cf_type p
+							| _ -> raise Not_found
 						end in
 						e
 					| _ ->
-						let old = ctx.untyped in
-						ctx.untyped <- true;
-						let e = try type_expr ctx e (WithType t) with _ -> ctx.untyped <- old; raise Not_found in
-						ctx.untyped <- old;
-						e
+						let old = ctx.in_call_args in
+						ctx.in_call_args <- true; (* Not really, but it does exactly what we want here. *)
+						let ec = try type_expr ctx e (WithType t) with _ -> ctx.in_call_args <- old; raise Not_found in
+						ctx.in_call_args <- old;
+						ec
 				in
+				let ec = loop t in
 				let ec = match Optimizer.make_constant_expression ctx ~concat_strings:true ec with Some e -> e | None -> ec in
 				(match ec.eexpr with
 					| TField (_,FEnum (en,ef)) ->
@@ -465,6 +454,8 @@ let to_pattern ctx e t =
 						mk_con_pat (CConst c) [] t p
 					| TTypeExpr mt ->
 						mk_type_pat ctx mt t p
+					| TField(_,FStatic({cl_extern = true},({cf_kind = Var {v_write = AccNever}} as cf))) ->
+						mk_con_pat (CExpr ec) [] cf.cf_type p
 					| _ ->
 						raise Not_found);
 			with Not_found ->

+ 15 - 15
optimizer.ml

@@ -74,6 +74,7 @@ let api_inline2 com c field params p =
 		Some { e with epos = p }
 	| ([],"String"),"fromCharCode",[{ eexpr = TConst (TInt i) }] when i > 0l && i < 128l ->
 		Some (mk (TConst (TString (String.make 1 (char_of_int (Int32.to_int i))))) com.basic.tstring p)
+	| ([],"Std"),"string",[{ eexpr = TCast ({ eexpr = TConst c } as e, None)}]
 	| ([],"Std"),"string",[{ eexpr = TConst c } as e] ->
 		(match c with
 		| TString s ->
@@ -259,6 +260,8 @@ let create_affection_checker () =
 type in_local = {
 	i_var : tvar;
 	i_subst : tvar;
+	i_outside : bool;
+	i_abstract_this : bool;
 	mutable i_captured : bool;
 	mutable i_write : bool;
 	mutable i_read : int;
@@ -311,6 +314,8 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 			let i = {
 				i_var = v;
 				i_subst = v';
+				i_outside = false;
+				i_abstract_this = Meta.has Meta.This v.v_meta;
 				i_captured = false;
 				i_write = false;
 				i_force_temp = false;
@@ -331,6 +336,8 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 			{
 				i_var = v;
 				i_subst = v;
+				i_outside = true;
+				i_abstract_this = Meta.has Meta.This v.v_meta;
 				i_captured = false;
 				i_write = false;
 				i_force_temp = false;
@@ -417,7 +424,7 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 				to its variables and not the calling method *)
 			if v.v_name = "__dollar__delay_call" then cancel_inlining := true;
 			let e = { e with eexpr = TLocal l.i_subst } in
-			if Meta.has Meta.This v.v_meta then mk (TCast(e,None)) v.v_type e.epos else e
+			if l.i_abstract_this then mk (TCast(e,None)) v.v_type e.epos else e
 		| TConst TThis ->
 			let l = read_local vthis in
 			l.i_read <- l.i_read + (if !in_loop then 2 else 1);
@@ -514,14 +521,6 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 			l.i_write <- true;
 			let e2 = map false e2 in
 			{e with eexpr = TBinop(op,{e1 with eexpr = TLocal l.i_subst},e2)}
-		| TObjectDecl fl ->
-			let fl = List.map (fun (s,e) -> s,map false e) fl in
-			begin match follow e.etype with
-				| TAnon an when (match !(an.a_status) with Const -> true | _ -> false) ->
-					{e with eexpr = TObjectDecl fl; etype = TAnon { an with a_status = ref Closed}}
-				| _ ->
-					{e with eexpr = TObjectDecl fl}
-			end
 		| TFunction f ->
 			(match f.tf_args with [] -> () | _ -> has_vars := true);
 			let old = save_locals ctx and old_fun = !in_local_fun in
@@ -576,16 +575,16 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 	let force = ref force in
 	let vars = List.fold_left (fun acc (i,e) ->
 		let flag = not i.i_force_temp && (match e.eexpr with
-			| TLocal v when Meta.has Meta.This v.v_meta -> true
+			| TLocal _ when i.i_abstract_this -> true
 			| TLocal _ | TConst _ -> not i.i_write
 			| TFunction _ -> if i.i_write then error "Cannot modify a closure parameter inside inline method" p; true
 			| _ -> not i.i_write && i.i_read <= 1
 		) in
 		let flag = flag && (not i.i_captured || is_constant e) in
 		(* force inlining if we modify 'this' *)
-		if i.i_write && (Meta.has Meta.This i.i_var.v_meta) then force := true;
+		if i.i_write && i.i_abstract_this then force := true;
 		(* force inlining of 'this' variable if it is written *)
-		let flag = if not flag && (Meta.has Meta.This i.i_var.v_meta) && i.i_write then begin
+		let flag = if not flag && i.i_abstract_this && i.i_write then begin
 			if not (is_writable e) then error "Cannot modify the abstract value, store it into a local first" p;
 			true
 		end else flag in
@@ -675,7 +674,7 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 			let map_var v =
 				if not (Hashtbl.mem vars v.v_id) then begin
 					Hashtbl.add vars v.v_id ();
-					v.v_type <- map_type v.v_type;
+					if not (read_local v).i_outside then v.v_type <- map_type v.v_type;
 				end;
 				v
 			in
@@ -1304,7 +1303,8 @@ let rec make_constant_expression ctx ?(concat_strings=false) e =
 		end
 	| TTypeExpr _ -> Some e
 	(* try to inline static function calls *)
-	| TCall ({ etype = TFun(_,ret); eexpr = TField (_,FStatic (c,cf)) },el) ->
+	(* Disabled for now, see #4254. *)
+(* 	| TCall ({ etype = TFun(_,ret); eexpr = TField (_,FStatic (c,cf)) },el) ->
 		(try
 			let func = match cf.cf_expr with Some ({eexpr = TFunction func}) -> func | _ -> raise Not_found in
 			let ethis = mk (TConst TThis) t_dynamic e.epos in
@@ -1312,7 +1312,7 @@ let rec make_constant_expression ctx ?(concat_strings=false) e =
 			(match inl with
 			| None -> None
 			| Some e -> make_constant_expression ctx e)
-		with Not_found -> None)
+		with Not_found -> None) *)
 	| _ -> None
 
 (* ---------------------------------------------------------------------- *)

+ 4 - 5
parser.ml

@@ -141,15 +141,14 @@ let rec make_unop op ((v,p2) as e) p1 =
 	match v with
 	| EBinop (bop,e,e2) -> EBinop (bop, make_unop op e p1 , e2) , (punion p1 p2)
 	| ETernary (e1,e2,e3) -> ETernary (make_unop op e1 p1 , e2, e3), punion p1 p2
-	| _ ->
-		EUnop (op,Prefix,e), punion p1 p2
+	| _ -> EUnop (op,Prefix,e), punion p1 p2
 
 let rec make_meta name params ((v,p2) as e) p1 =
 	match v with
+	| EBinop ((OpAssign | OpAssignOp _),_,_) -> EMeta((name,params,p1),e),punion p1 p2
 	| EBinop (bop,e,e2) -> EBinop (bop, make_meta name params e p1 , e2) , (punion p1 p2)
 	| ETernary (e1,e2,e3) -> ETernary (make_meta name params e1 p1 , e2, e3), punion p1 p2
-	| _ ->
-		EMeta((name,params,p1),e),punion p1 p2
+	| _ -> EMeta((name,params,p1),e),punion p1 p2
 
 let make_is e t p =
 	let e_is = EField((EConst(Ident "Std"),p),"is"),p in
@@ -623,7 +622,7 @@ and parse_type_decl s =
 				d_data = t;
 			}, punion p1 p2)
 		| [< '(Kwd Abstract,p1); name = type_name; tl = parse_constraint_params; st = parse_abstract_subtype; sl = plist parse_abstract_relations; '(BrOpen,_); fl, p2 = parse_class_fields false p1 >] ->
-			let flags = List.map (fun (_,c) -> match c with EPrivate -> APrivAbstract | EExtern -> error (Custom "extern abstract not allowed") p1) c in
+			let flags = List.map (fun (_,c) -> match c with EPrivate -> APrivAbstract | EExtern -> AExtern) c in
 			let flags = (match st with None -> flags | Some t -> AIsType t :: flags) in
 			(EAbstract {
 				d_name = name;

+ 1 - 1
std/DateTools.hx

@@ -161,7 +161,7 @@ class DateTools {
 	/**
 		Converts a number of minutes to a timestamp.
 	**/
-	public static inline function minutes( n : Float ) : Float {
+	#if as3 @:extern #end public static inline function minutes( n : Float ) : Float {
 		return n * 60.0 * 1000.0;
 	}
 

+ 1 - 1
std/Map.hx

@@ -42,7 +42,7 @@ import haxe.Constraints.IMap;
 
 	Map is an abstract type, it is not available at runtime.
 **/
-@:multiType(K)
+@:multiType(@:followWithAbstracts K)
 abstract Map<K,V>(IMap<K,V> ) {
 
 	/**

+ 23 - 23
std/StdTypes.hx

@@ -22,22 +22,22 @@
 // standard Haxe types
 
 /**
-	The standard Void type. Only `null` values can be of the type `Void`.
+	The standard `Void` type. Only `null` values can be of the type `Void`.
 **/
 @:coreType abstract Void { }
 
 /**
-	The standard Float type, this is a double-precision IEEE 64bit float.
+	The standard `Float` type, this is a double-precision IEEE 64bit float.
 
-	On static targets, null cannot be assigned to Float. If this is necessary,
+	On static targets, `null` cannot be assigned to Float. If this is necessary,
 	`Null<Float>` can be used instead.
 **/
 @:coreType @:notNull @:runtimeValue abstract Float { }
 
 /**
-	The standard Int type. Its precision depends on the platform.
+	The standard `Int` type. Its precision depends on the platform.
 
-	On static targets, null cannot be assigned to Int. If this is necessary,
+	On static targets, `null` cannot be assigned to `Int`. If this is necessary,
 	`Null<Int>` can be used instead.
 **/
 @:coreType @:notNull @:runtimeValue abstract Int to Float { }
@@ -48,64 +48,64 @@
 
 /**
 	`Null` can be useful in two cases. In order to document some methods
-	that accepts or can return a `null` value, or for the Flash compiler and AS3
-	generator to distinguish between base values that can be null and others that
+	that accept or can return a `null` value, or for the Flash compiler and AS3
+	generator to distinguish between base values that can be `null` and others that
 	can't.
 **/
 typedef Null<T> = T
 
 /**
-	The standard Boolean type, which can either be true or false.
+	The standard Boolean type, which can either be `true` or `false`.
 
-	On static targets, null cannot be assigned to Bool. If this is necessary,
+	On static targets, `null` cannot be assigned to `Bool`. If this is necessary,
 	`Null<Bool>` can be used instead.
 **/
 @:coreType @:notNull @:runtimeValue abstract Bool {
 }
 
 /**
-	Dynamic is a special type which is compatible with all other types.
+	`Dynamic` is a special type which is compatible with all other types.
 
-	Use of Dynamic should be minimized as it prevents several compiler
+	Use of `Dynamic` should be minimized as it prevents several compiler
 	checks and optimizations.
 **/
 @:coreType @:runtimeValue abstract Dynamic<T> {
 }
 
 /**
-	An Iterator is a structure that permits iteration over elements of type T.
+	An `Iterator` is a structure that permits iteration over elements of type `T`.
 
-	Any class with matching hasNext and next fields is considered an Iterator
-	and can then be used e.g. in for-loops. This makes it easy to implement
+	Any class with matching `hasNext()` and `next()` fields is considered an `Iterator`
+	and can then be used e.g. in `for`-loops. This makes it easy to implement
 	custom iterators.
 **/
 typedef Iterator<T> = {
 
 	/**
-		Returns false if the iteration is complete, true otherwise.
+		Returns `false` if the iteration is complete, `true` otherwise.
 
 		Usually iteration is considered to be complete if all elements of the
-		underlying data structure were handled through calls to next(). However,
+		underlying data structure were handled through calls to `next()`. However,
 		in custom iterators any logic may be used to determine the completion
 		state.
 	**/
 	function hasNext() : Bool;
 
 	/**
-		Returns the current item of the Iterator and advances to the next one.
+		Returns the current item of the `Iterator` and advances to the next one.
 
-		This method is not required to check `hasNext` first. A call to this
-		method while `hasNext` is false yields unspecified behavior.
+		This method is not required to check `hasNext()` first. A call to this
+		method while `hasNext()` is `false` yields unspecified behavior.
 
-		On the other hand iterators should not require a call to `hasNext`
-		before the first call to `next` if an element is available.
+		On the other hand, iterators should not require a call to `hasNext()`
+		before the first call to `next()` if an element is available.
 	**/
 	function next() : T;
 
 }
 
 /**
-	An Iterable is a data structure which has an iterator() method.
+	An `Iterable` is a data structure which has an `iterator()` method.
 	See `Lambda` for generic functions on iterable structures.
 **/
 typedef Iterable<T> = {
@@ -113,7 +113,7 @@ typedef Iterable<T> = {
 }
 
 /**
-	ArrayAccess is used to indicate a class that can be accessed using brackets.
+	`ArrayAccess` is used to indicate a class that can be accessed using brackets.
 	The type parameter represents the type of the elements stored.
 
 	This interface should be used for externs only. Haxe does not support custom

+ 7 - 7
std/Xml.hx

@@ -122,28 +122,28 @@ class Xml {
 	var children:Array<Xml>;
 	var attributeMap:Map<String, String>;
 
-	inline function get_nodeName() {
+	#if !cppia inline #end function get_nodeName() {
 		if (nodeType != Element) {
 			throw 'Bad node type, expected Element but found $nodeType';
 		}
 		return nodeName;
 	}
 
-	inline function set_nodeName(v) {
+	#if !cppia inline #end function set_nodeName(v) {
 		if (nodeType != Element) {
 			throw 'Bad node type, expected Element but found $nodeType';
 		}
 		return this.nodeName = v;
 	}
 
-	inline function get_nodeValue() {
+	#if !cppia inline #end function get_nodeValue() {
 		if (nodeType == Document || nodeType == Element) {
 			throw 'Bad node type, unexpected $nodeType';
 		}
 		return nodeValue;
 	}
 
-	inline function set_nodeValue(v) {
+	#if !cppia inline #end function set_nodeValue(v) {
 		if (nodeType == Document || nodeType == Element) {
 			throw 'Bad node type, unexpected $nodeType';
 		}
@@ -269,7 +269,7 @@ class Xml {
 		Returns an iterator of all child nodes.
 		Only works if the current node is an Element or a Document.
 	**/
-	public inline function iterator() : Iterator<Xml> {
+	public #if !cppia inline #end function iterator() : Iterator<Xml> {
 		ensureElementType();
 		return children.iterator();
 	}
@@ -297,7 +297,7 @@ class Xml {
 	/**
 		Returns the first child node.
 	**/
-	public inline function firstChild() : Xml {
+	public #if !cppia inline #end function firstChild() : Xml {
 		ensureElementType();
 		return children[0];
 	}
@@ -361,7 +361,7 @@ class Xml {
 	/**
 		Returns a String representation of the Xml node.
 	**/
-	public inline function toString() : String {
+	public #if !cppia inline #end function toString() : String {
 		return haxe.xml.Printer.print(this);
 	}
 

+ 3 - 1
std/cpp/_std/Reflect.hx

@@ -19,7 +19,9 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-@:coreApi class Reflect {
+@:coreApi
+@:analyzer(ignore)
+class Reflect {
 
 	public  static function hasField( o : Dynamic, field : String ) : Bool untyped {
 		return o!=null && o.__HasField(field);

+ 3 - 1
std/cpp/_std/haxe/Int64.hx

@@ -40,7 +40,9 @@ abstract Int64( __Int64 ) from __Int64 to __Int64
 
 
 	public static #if !cppia inline #end function make( high : Int32, low : Int32 ) : Int64 {
-      return untyped __cpp__("cpp::Int64Struct(( ( (cpp::Int64)((unsigned int){0}) ) << 32 ) | ((unsigned int){1}))",high, low);
+      var tmpHigh = high;
+      var tmpLow = low;
+      return untyped __cpp__("cpp::Int64Struct(( ( (cpp::Int64)((unsigned int){0}) ) << 32 ) | ((unsigned int){1}))",tmpHigh, tmpLow);
 	}
 
 	@:from public static function ofInt( x : Int ) : Int64 {

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

@@ -72,6 +72,7 @@ class HostClasses
    "Type",
    "Xml",
    "Date",
+   "Lambda",
    "DateTools",
    "List",
    "Math",
@@ -82,6 +83,7 @@ class HostClasses
    "haxe.ds.IntMap",
    "haxe.ds.ObjectMap",
    "haxe.ds.StringMap",
+   "haxe.ds.BalancedTree",
    "haxe.CallStack",
    "haxe.Serializer",
    "haxe.Unserializer",
@@ -184,6 +186,9 @@ class HostClasses
       externs.set("haxe._Int64.___Int64",true);
       externs.set("haxe._Int32.Int32_Impl_",true);
       externs.set("haxe._Int32.___Int32",true);
+      // Hidded in implementation classes
+      externs.set("haxe.ds.TreeNode",true);
+      externs.set("haxe.xml.XmlParserException",true);
       for(e in classes)
          externs.set(e,true);
 

+ 4 - 0
std/flash/Boot.hx

@@ -242,7 +242,11 @@ class Boot extends flash.display.MovieClip {
 		aproto.remove = function(obj) {
 			var idx = __this__.indexOf(obj);
 			if( idx == -1 ) return false;
+			#if flash19
+			__this__.removeAt(idx);
+			#else
 			__this__.splice(idx,1);
+			#end
 			return true;
 		}
 		aproto.iterator = function() {

+ 26 - 16
std/haxe/Serializer.hx

@@ -67,6 +67,7 @@ class Serializer {
 	public static var USE_ENUM_INDEX = false;
 
 	static var BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%:";
+	static var BASE64_CODES = null;
 
 	var buf : StringBuf;
 	var cache : Array<Dynamic>;
@@ -333,38 +334,47 @@ class Serializer {
 				var v : haxe.io.Bytes = v;
 				#if neko
 				var chars = new String(base_encode(v.getData(),untyped BASE64.__s));
+				buf.add("s");
+				buf.add(chars.length);
+				buf.add(":");
+				buf.add(chars);
 				#else
+
+				buf.add("s");
+				buf.add(Math.ceil((v.length * 8) / 6));
+				buf.add(":");
+
 				var i = 0;
 				var max = v.length - 2;
-				var charsBuf = new StringBuf();
-				var b64 = BASE64;
+				var b64 = BASE64_CODES;
+				if( b64 == null ) {
+					b64 = new haxe.ds.Vector(BASE64.length);
+					for( i in 0...BASE64.length )
+						b64[i] = BASE64.charCodeAt(i);
+					BASE64_CODES = b64;
+				}
 				while( i < max ) {
 					var b1 = v.get(i++);
 					var b2 = v.get(i++);
 					var b3 = v.get(i++);
 
-					charsBuf.add(b64.charAt(b1 >> 2));
-					charsBuf.add(b64.charAt(((b1 << 4) | (b2 >> 4)) & 63));
-					charsBuf.add(b64.charAt(((b2 << 2) | (b3 >> 6)) & 63));
-					charsBuf.add(b64.charAt(b3 & 63));
+					buf.addChar(b64[b1 >> 2]);
+					buf.addChar(b64[((b1 << 4) | (b2 >> 4)) & 63]);
+					buf.addChar(b64[((b2 << 2) | (b3 >> 6)) & 63]);
+					buf.addChar(b64[b3 & 63]);
 				}
 				if( i == max ) {
 					var b1 = v.get(i++);
 					var b2 = v.get(i++);
-					charsBuf.add(b64.charAt(b1 >> 2));
-					charsBuf.add(b64.charAt(((b1 << 4) | (b2 >> 4)) & 63));
-					charsBuf.add(b64.charAt((b2 << 2) & 63));
+					buf.addChar(b64[b1 >> 2]);
+					buf.addChar(b64[((b1 << 4) | (b2 >> 4)) & 63]);
+					buf.addChar(b64[(b2 << 2) & 63]);
 				} else if( i == max + 1 ) {
 					var b1 = v.get(i++);
-					charsBuf.add(b64.charAt(b1 >> 2));
-					charsBuf.add(b64.charAt((b1 << 4) & 63));
+					buf.addChar(b64[b1 >> 2]);
+					buf.addChar(b64[(b1 << 4) & 63]);
 				}
-				var chars = charsBuf.toString();
 				#end
-				buf.add("s");
-				buf.add(chars.length);
-				buf.add(":");
-				buf.add(chars);
 			default:
 				if( useCache ) cache.pop();
 				if( #if flash try v.hxSerialize != null catch( e : Dynamic ) false #elseif (cs || java || python) Reflect.hasField(v, "hxSerialize") #else v.hxSerialize != null #end  ) {

+ 11 - 10
std/haxe/ds/Vector.hx

@@ -270,16 +270,17 @@ abstract Vector<T>(VectorData<T>) {
 
 		If `f` is null, the result is unspecified.
 	**/
-	//public function map<S>(f:T->S):Vector<S> {
-		//var r = new Vector<S>(length);
-		//var i = 0;
-		//var len = length;
-		//for(i in 0...len) {
-			//var v = f(get(i));
-			//r.set(i, v);
-		//}
-		//return r;
-	//}
+	#if cs @:extern #end public inline function map<S>(f:T->S):Vector<S> {
+		var length = length;
+		var r = new Vector<S>(length);
+		var i = 0;
+		var len = length;
+		for(i in 0...len) {
+			var v = f(get(i));
+			r.set(i, v);
+		}
+		return r;
+	}
 
 	/**
 		Sorts `this` Vector according to the comparison function `f`, where

+ 1 - 1
std/haxe/macro/ComplexTypeTools.hx

@@ -48,7 +48,7 @@ class ComplexTypeTools {
 		If [c] is null, the result is null.
 	**/
 	static public function toType( c : ComplexType ) : Null<Type>
-		return c == null ? null : haxe.macro.Context.typeof( { expr: ECheckType(macro null, c), pos: Context.currentPos() } );
+		return c == null ? null : Context.resolveType(c,Context.currentPos());
 
 	#end
 }

+ 17 - 5
std/haxe/macro/Context.hx

@@ -368,6 +368,18 @@ class Context {
 		return load("type_expr", 1)(e);
 	}
 
+	/**
+		Resolve type `t` and returns the corresponding `Type`.
+
+		Resolving the type may result in a compiler error which can be
+		caught using `try ... catch`.
+		Resolution is performed based on the current context in which the macro is called.
+	**/
+	@:require(haxe_ver >= 3.3)
+	public static function resolveType( t : ComplexType, p : Position ) : Type {
+		return load("resolve_type", 2)(t,p);
+	}
+
 	/**
 		Returns the `ComplexType` corresponding to the given `Type` `t`.
 
@@ -439,7 +451,7 @@ class Context {
 		The resource is then available using the `haxe.macro.Resource` API.
 
 		If a previous resource was bound to `name`, it is overwritten.
-		
+
 		Compilation server : when using the compilation server, the resource is bound
 		to the Haxe module which calls the macro, so it will be included again if
 		that module is reused. If this resource concerns several modules, prefix its
@@ -529,10 +541,10 @@ class Context {
 
 		If `e` is null, the result is unspecified.
 	**/
-	@:require(haxe_ver >= 3.3)
-	public static function eval( e : Expr ) : Dynamic {
-		return load("eval",1)(e);
-	}
+	//@:require(haxe_ver >= 3.3)
+	//public static function eval( e : Expr ) : Dynamic {
+		//return load("eval",1)(e);
+	//}
 
 	/**
 		Manually adds a dependency between module `modulePath` and an external

+ 1 - 1
std/haxe/rtti/CType.hx

@@ -43,7 +43,7 @@ typedef PathParams = {
 	var params : List<CType>;
 }
 
-typedef TypeParams = Array<String> // no contraints
+typedef TypeParams = Array<String> // no constraints
 
 enum Rights {
 	RNormal;

+ 1 - 1
std/java/StdTypes.hx

@@ -24,7 +24,7 @@ package java;
 @:notNull @:runtimeValue @:coreType abstract Int8 from Int {}
 @:notNull @:runtimeValue @:coreType abstract Int16 from Int {}
 @:notNull @:runtimeValue @:coreType abstract Char16 from Int {}
-@:notNull @:runtimeValue @:coreType abstract Int64 from Int from Float
+@:notNull @:runtimeValue @:coreType extern abstract Int64 from Int from Float
 {
 	@:op(A+B) public static function addI(lhs:Int64, rhs:Int):Int64;
 	@:op(A+B) public static function add(lhs:Int64, rhs:Int64):Int64;

+ 0 - 1
std/js/_std/Type.hx

@@ -99,7 +99,6 @@ enum ValueType {
 		default:
 			throw "Too many arguments";
 		}
-		return null;
 	}
 
 	public static function createEmptyInstance<T>( cl : Class<T> ) : T untyped {

+ 2 - 0
std/js/html/ArrayBuffer.hx

@@ -24,6 +24,8 @@
 
 package js.html;
 
+import js.html.compat.ArrayBuffer;
+
 @:native("ArrayBuffer")
 extern class ArrayBuffer
 {

+ 2 - 0
std/js/html/DataView.hx

@@ -24,6 +24,8 @@
 
 package js.html;
 
+import js.html.compat.DataView;
+
 @:native("DataView")
 extern class DataView extends ArrayBufferView
 {

+ 4 - 2
std/js/html/Float32Array.hx

@@ -24,13 +24,15 @@
 
 package js.html;
 
+import js.html.compat.Float32Array;
+
 @:native("Float32Array")
 extern class Float32Array extends ArrayBufferView implements ArrayAccess<Float>
 {
 	static inline var BYTES_PER_ELEMENT : Int = 4;
-	
+
 	var length(default,null) : Int;
-	
+
 	/** @throws DOMError */
 	@:overload( function( length : Int ) : Void {} )
 	@:overload( function( array : Float32Array ) : Void {} )

+ 4 - 2
std/js/html/Float64Array.hx

@@ -24,13 +24,15 @@
 
 package js.html;
 
+import js.html.compat.Float64Array;
+
 @:native("Float64Array")
 extern class Float64Array extends ArrayBufferView implements ArrayAccess<Float>
 {
 	static inline var BYTES_PER_ELEMENT : Int = 8;
-	
+
 	var length(default,null) : Int;
-	
+
 	/** @throws DOMError */
 	@:overload( function( length : Int ) : Void {} )
 	@:overload( function( array : Float64Array ) : Void {} )

+ 4 - 2
std/js/html/Uint8Array.hx

@@ -24,13 +24,15 @@
 
 package js.html;
 
+import js.html.compat.Uint8Array;
+
 @:native("Uint8Array")
 extern class Uint8Array extends ArrayBufferView implements ArrayAccess<Int>
 {
 	static inline var BYTES_PER_ELEMENT : Int = 1;
-	
+
 	var length(default,null) : Int;
-	
+
 	/** @throws DOMError */
 	@:overload( function( length : Int ) : Void {} )
 	@:overload( function( array : Uint8Array ) : Void {} )

+ 1 - 1
std/js/html/compat/ArrayBuffer.hx

@@ -22,7 +22,7 @@
 package js.html.compat;
 
 #if !nodejs
-@:keep
+@:ifFeature("js.html.ArrayBuffer.*")
 class ArrayBuffer {
 
 	public var byteLength : Int;

+ 1 - 1
std/js/html/compat/DataView.hx

@@ -24,7 +24,7 @@ package js.html.compat;
 #if !nodejs
 import haxe.io.Error;
 
-@:ifFeature("haxe.io.Float32Array.*", "haxe.io.Float64Array.*")
+@:ifFeature("js.html.DataView.*")
 @:access(js.html.compat.ArrayBuffer)
 class DataView {
 

+ 1 - 1
std/js/html/compat/Float32Array.hx

@@ -24,7 +24,7 @@ package js.html.compat;
 #if !nodejs
 import js.Lib.nativeThis;
 
-@:keep
+@:ifFeature("js.html.Float32Array.*")
 class Float32Array {
 
 	static var BYTES_PER_ELEMENT = 4;

+ 1 - 1
std/js/html/compat/Float64Array.hx

@@ -24,7 +24,7 @@ package js.html.compat;
 #if !nodejs
 import js.Lib.nativeThis;
 
-@:keep
+@:ifFeature("js.html.Float64Array.*")
 class Float64Array {
 
 	static var BYTES_PER_ELEMENT = 8;

+ 1 - 1
std/js/html/compat/Uint8Array.hx

@@ -24,7 +24,7 @@ package js.html.compat;
 #if !nodejs
 import js.Lib.nativeThis;
 
-@:keep
+@:ifFeature("js.html.Uint8Array.*")
 class Uint8Array {
 
 	static var BYTES_PER_ELEMENT = 1;

+ 1 - 1
std/js/jquery/Helper.hx

@@ -17,7 +17,7 @@ package js.jquery;
 	@:allow(js.jquery.JQuery)
 	macro static function embed() {
 		return if (haxe.macro.Context.defined("embed_js")) {
-			macro haxe.macro.Compiler.includeFile("js/jquery/jquery-1.11.3.min.js");
+			macro haxe.macro.Compiler.includeFile("js/jquery/jquery-1.12.1.min.js");
 		} else {
 			macro {};
 		}

+ 7 - 3
std/js/jquery/JQuery.hx

@@ -104,6 +104,10 @@ package js.jquery;
 		Holds or releases the execution of jQuery's ready event.
 	**/
 	static public function holdReady(hold:Bool):Void;
+	/**
+		Modify and filter HTML strings passed through <a href="/category/manipulation/">jQuery manipulation methods</a>.
+	**/
+	static public function htmlPrefilter(html:String):String;
 	/**
 		Search for a specified value within an array and return its index (or -1 if not found).
 	**/
@@ -121,7 +125,7 @@ package js.jquery;
 	**/
 	static public function isFunction(obj:Dynamic):Bool;
 	/**
-		Determines whether its argument is a number.
+		Determines whether its argument represents a JavaScript number.
 	**/
 	static public function isNumeric(value:Dynamic):Bool;
 	/**
@@ -229,7 +233,7 @@ package js.jquery;
 	**/
 	static public function uniqueSort(array:Array<js.html.Element>):Array<js.html.Element>;
 	/**
-		Provides a way to execute callback functions based on one or more objects, usually <a href="/category/deferred-object/">Deferred</a> objects that represent asynchronous events.
+		Provides a way to execute callback functions based on zero or more objects, usually <a href="/category/deferred-object/">Deferred</a> objects that represent asynchronous events.
 	**/
 	static public function when(deferreds:haxe.extern.Rest<js.jquery.Deferred>):js.jquery.Promise;
 	/**
@@ -771,7 +775,7 @@ package js.jquery;
 	**/
 	public function prependTo(target:haxe.extern.EitherType<js.html.Element, haxe.extern.EitherType<Array<js.html.Element>, haxe.extern.EitherType<String, js.jquery.JQuery>>>):js.jquery.JQuery;
 	/**
-		Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector.
+		Get the immediately preceding sibling of each element in the set of matched elements. If a selector is provided, it retrieves the previous sibling only if it matches that selector.
 	**/
 	public function prev(?selector:String):js.jquery.JQuery;
 	/**

ファイルの差分が大きいため隠しています
+ 0 - 1
std/js/jquery/jquery-1.11.3.min.js


ファイルの差分が大きいため隠しています
+ 1 - 0
std/js/jquery/jquery-1.12.1.min.js


+ 0 - 1
std/neko/_std/String.hx

@@ -77,7 +77,6 @@
 					return last;
 				last = p;
 			}
-			return null;
 		}
 	}
 

+ 2 - 2
std/neko/_std/Type.hx

@@ -68,7 +68,7 @@ enum ValueType {
 
 	public static function resolveClass( name : String ) : Class<Dynamic> untyped {
 		var path = name.split(".");
-		cl = Reflect.field(untyped neko.Boot.__classes,path[0]);
+		var cl = Reflect.field(untyped neko.Boot.__classes,path[0]);
 		var i = 1;
 		while( cl != null && i < path.length ) {
 			cl = Reflect.field(cl,path[i]);
@@ -83,7 +83,7 @@ enum ValueType {
 
 	public static function resolveEnum( name : String ) : Enum<Dynamic> untyped {
 		var path = name.split(".");
-		e = Reflect.field(neko.Boot.__classes,path[0]);
+		var e = Reflect.field(neko.Boot.__classes,path[0]);
 		var i = 1;
 		while( e != null && i < path.length ) {
 			e = Reflect.field(e,path[i]);

+ 91 - 24
tests/RunCi.hx

@@ -168,7 +168,10 @@ class RunCi {
 				Sys.putEnv("DISPLAY", ":99.0");
 				runCommand("sh", ["-e", "/etc/init.d/xvfb", "start"]);
 				Sys.putEnv("AUDIODEV", "null");
-				requireAptPackages(["libgd2-xpm", "ia32-libs", "ia32-libs-multiarch"]);
+				requireAptPackages([
+					"libcurl3:i386", "libglib2.0-0:i386", "libx11-6:i386", "libxext6:i386",
+					"libxt6:i386", "libxcursor1:i386", "libnss3:i386", "libgtk2.0-0:i386"	
+				]);
 				runCommand("wget", ["-nv", "http://fpdownload.macromedia.com/pub/flashplayer/updaters/11/flashplayer_11_sa_debug.i386.tar.gz"], true);
 				runCommand("tar", ["-xf", "flashplayer_11_sa_debug.i386.tar.gz", "-C", Sys.getEnv("HOME")]);
 				File.saveContent(mmcfgPath, "ErrorReportingEnable=1\nTraceOutputFileEnable=1");
@@ -244,7 +247,8 @@ class RunCi {
 				runCommand(exe, args);
 				switch (ci) {
 					case AppVeyor:
-						runCommand("mono", [exe].concat(args));
+						// https://github.com/HaxeFoundation/haxe/issues/4873
+						// runCommand("mono", [exe].concat(args));
 					case _:
 						//pass
 				}
@@ -594,15 +598,36 @@ class RunCi {
 				throw haxe_ver;
 		}
 	}
+	static var haxeVerFull(default, never) = {
+		var ver = haxeVer.split(".");
+		while (ver.length < 3) {
+			ver.push("0");
+		}
+		ver.join(".");
+	}
+
+	static function deploy():Void {
+		if (
+			Sys.getEnv("DEPLOY") != null
+		) {
+			changeDirectory(repoDir);
+
+			// generate doc
+			runCommand("make", ["-s", "install_dox"]);
+			runCommand("make", ["-s", "package_doc"]);
 
-	static function bintray():Void {
+			deployBintray();
+			deployApiDoc();
+			deployPPA();
+		}
+	}
+
+	static function deployBintray():Void {
 		if (
 			Sys.getEnv("BINTRAY") != null &&
 			Sys.getEnv("BINTRAY_USERNAME") != null &&
 			Sys.getEnv("BINTRAY_API_KEY") != null
 		) {
-			changeDirectory(repoDir);
-
 			// generate bintray config
 			var tpl = new Template(File.getContent("extra/bintray.tpl.json"));
 			var compatDate = ~/[^0-9]/g.replace(gitInfo.date, "");
@@ -623,24 +648,66 @@ class RunCi {
 			File.saveContent("extra/bintray.json", json);
 			infoMsg("saved " + FileSystem.absolutePath(path) + " with content:");
 			Sys.println(json);
+		}
+	}
 
-			// generate doc
-			runCommand("make", ["-s", "install_dox"]);
-			runCommand("make", ["-s", "package_doc"]);
+	/**
+		Deploy doc to api.haxe.org.
+	*/
+	static function deployApiDoc():Void {
+		if (
+			gitInfo.branch == "development" &&
+			Sys.getEnv("DEPLOY") != null &&
+			Sys.getEnv("deploy_key_decrypt") != null
+		) {
+			// setup deploy_key
+			runCommand("openssl aes-256-cbc -k \"$deploy_key_decrypt\" -in extra/deploy_key.enc -out extra/deploy_key -d");
+			runCommand("chmod 600 extra/deploy_key");
+			runCommand("ssh-add extra/deploy_key");
 
-			// deploy doc to api.haxe.org
-			if (
-				gitInfo.branch == "development" && 
-				Sys.getEnv("DEPLOY") != null && 
-				Sys.getEnv("deploy_key_decrypt") != null
-			) {
-				//setup deploy_key
-				runCommand("openssl aes-256-cbc -k \"$deploy_key_decrypt\" -in extra/deploy_key.enc -out extra/deploy_key -d");
-				runCommand("chmod 600 extra/deploy_key");
-				runCommand("ssh-add extra/deploy_key");
-
-				runCommand("make", ["-s", "deploy_doc"]);
-			}
+			runCommand("make", ["-s", "deploy_doc"]);
+		}
+	}
+
+	/**
+		Deploy source package to ppa:haxe/snapshots.
+	*/
+	static function deployPPA():Void {
+		if (
+			gitInfo.branch == "development" && 
+			Sys.getEnv("DEPLOY") != null && 
+			Sys.getEnv("haxeci_decrypt") != null
+		) {
+			// setup haxeci_ssh
+			runCommand("openssl aes-256-cbc -k \"$haxeci_decrypt\" -in extra/haxeci_ssh.enc -out extra/haxeci_ssh -d");
+			runCommand("chmod 600 extra/haxeci_ssh");
+			runCommand("ssh-add extra/haxeci_ssh");
+			// setup haxeci_sec.gpg
+			runCommand("openssl aes-256-cbc -k \"$haxeci_decrypt\" -in extra/haxeci_sec.gpg.enc -out extra/haxeci_sec.gpg -d");
+			runCommand("gpg --allow-secret-key-import --import extra/haxeci_sec.gpg");
+			runCommand("sudo apt-get install devscripts git-buildpackage ubuntu-dev-tools dh-make -y");
+			var compatDate = ~/[^0-9]/g.replace(gitInfo.date, "");
+			var SNAPSHOT_VERSION = '${haxeVerFull}+1SNAPSHOT${compatDate}+${gitInfo.commit.substr(0,7)}';
+			runCommand('cp out/haxe*_src.tar.gz "../haxe_${SNAPSHOT_VERSION}.orig.tar.gz"');
+			changeDirectory("..");
+			runCommand("git clone https://github.com/HaxeFoundation/haxe-debian.git");
+			changeDirectory("haxe-debian");
+			runCommand("git checkout upstream");
+			runCommand("git checkout next");
+			runCommand('gbp import-orig "../haxe_${SNAPSHOT_VERSION}.orig.tar.gz" -u "${SNAPSHOT_VERSION}" --debian-branch=next');
+			runCommand('dch -v "1:${SNAPSHOT_VERSION}-1" --urgency low "snapshot build"');
+			runCommand("debuild -S -sa");
+			runCommand("backportpackage -d xenial  --upload ${PPA} --yes ../haxe_*.dsc");
+			runCommand("backportpackage -d wily    --upload ${PPA} --yes ../haxe_*.dsc");
+			runCommand("backportpackage -d vivid   --upload ${PPA} --yes ../haxe_*.dsc");
+			runCommand("backportpackage -d trusty  --upload ${PPA} --yes ../haxe_*.dsc");
+			runCommand("git checkout debian/changelog");
+			runCommand("git config --global user.name \"${DEBFULLNAME}\"");
+			runCommand("git config --global user.email \"${DEBEMAIL}\"");
+			runCommand("git merge -X ours --no-edit origin/backport-precise");
+			runCommand('dch -v "1:${SNAPSHOT_VERSION}-1" --urgency low "snapshot build"');
+			runCommand("debuild -S -sa");
+			runCommand("backportpackage -d precise --upload ${PPA} --yes ../haxe_*.dsc");
 		}
 	}
 
@@ -779,8 +846,6 @@ class RunCi {
 	static function main():Void {
 		Sys.putEnv("OCAMLRUNPARAM", "b");
 
-		bintray();
-
 		var tests:Array<TEST> = switch (Sys.getEnv("TEST")) {
 			case null:
 				[Macro];
@@ -1083,6 +1148,8 @@ class RunCi {
 		) {
 			saveOutput();
 		}
+
+		deploy();
 	}
 
 	static function testHxTemplo() {
@@ -1126,7 +1193,7 @@ class RunCi {
 		haxelibInstallGit("massiveinteractive", "mconsole", "master", "src");
 		haxelibInstallGit("massiveinteractive", "MassiveCover", "master", "src", false, "mcover");
 		haxelibInstallGit("massiveinteractive", "MassiveLib", "master", "src", false, "mlib");
-		haxelibInstallGit("massiveinteractive", "MassiveUnit", "master", "src", false, "munit");
+		haxelibInstallGit("massiveinteractive", "MassiveUnit", "2.1.2", "src", false, "munit");
 		changeDirectory(Path.join([getHaxelibPath("munit"), "..", "tool"]));
 		runCommand("haxe", ["build.hxml"]);
 		haxelibRun(["munit", "test", "-result-exit-code", "-neko"], true);

+ 11 - 0
tests/misc/projects/Issue2148/Main1.hx

@@ -0,0 +1,11 @@
+enum E {
+    CTor(i:Int);
+}
+
+class Main {
+    static public function main() {
+        expectE(CTor(foo));
+    }
+
+    static function expectE(e:E) { }
+}

+ 2 - 0
tests/misc/projects/Issue2148/compile1-fail.hxml

@@ -0,0 +1,2 @@
+-main Main1
+--interp

+ 1 - 0
tests/misc/projects/Issue2148/compile1-fail.hxml.stderr

@@ -0,0 +1 @@
+Main1.hx:7: characters 21-24 : Unknown identifier : foo

+ 8 - 0
tests/misc/projects/Issue2232/Main1.hx

@@ -0,0 +1,8 @@
+class Main1 {
+    static function main() {
+		var v : Float = 0;
+		foo(v,v);
+    }
+
+	static function foo(x=0,y=0) { }
+}

+ 8 - 0
tests/misc/projects/Issue2232/Main2.hx

@@ -0,0 +1,8 @@
+class Main1 {
+    static function main() {
+		var v : Float = 0;
+		foo(v);
+    }
+
+	static function foo(x=0,y:Float) { }
+}

+ 3 - 0
tests/misc/projects/Issue2232/compile1-fail.hxml

@@ -0,0 +1,3 @@
+-main Main1
+-swf swf.swf
+--no-output

+ 2 - 0
tests/misc/projects/Issue2232/compile1-fail.hxml.stderr

@@ -0,0 +1,2 @@
+Main1.hx:4: characters 6-7 : Float should be Int
+Main1.hx:4: characters 6-7 : For optional function argument 'x'

+ 3 - 0
tests/misc/projects/Issue2232/compile2-fail.hxml

@@ -0,0 +1,3 @@
+-main Main2
+-swf swf.swf
+--no-output

+ 1 - 0
tests/misc/projects/Issue2232/compile2-fail.hxml.stderr

@@ -0,0 +1 @@
+Main2.hx:4: characters 2-8 : Cannot skip non-nullable argument x

+ 0 - 0
tests/misc/projects/Issue2278/compile.hxml → tests/misc/projects/Issue2278/compile.hxml.disabled


+ 5 - 0
tests/misc/projects/Issue3192/Main1.hx

@@ -0,0 +1,5 @@
+class Main {
+    static function main() {
+		var a:{a:Int} = { a: 1, b: 2 };
+    }
+}

+ 2 - 0
tests/misc/projects/Issue3192/compile1-fail.hxml

@@ -0,0 +1,2 @@
+-main Main1
+--interp

+ 1 - 0
tests/misc/projects/Issue3192/compile1-fail.hxml.stderr

@@ -0,0 +1 @@
+Main1.hx:3: characters 18-32 : { b : Int, a : Int } has extra field b

+ 2 - 1
tests/misc/projects/Issue3782/compile-fail.hxml

@@ -1,2 +1,3 @@
 -main Main
---interp
+--interp
+-D no-analyzer

+ 21 - 0
tests/misc/projects/Issue4448/Main1.hx

@@ -0,0 +1,21 @@
+abstract A(Int) {
+    function f() {}
+
+    var v(get,never):Int;
+    function get_v() return this;
+
+    var v2(get,never):Int;
+    inline function get_v2() return this;
+
+    static function e() {
+        f(); // Not enough arguments, expected this:Int - should be just unavailable
+        v; // generates _$Main_A_$Impl_$.get_v();
+        v2; // Invalid abstract implementation function
+    }
+}
+
+class Main {
+	static function main() {
+
+	}
+}

+ 2 - 0
tests/misc/projects/Issue4448/compile1-fail.hxml

@@ -0,0 +1,2 @@
+-main Main1
+--interp

+ 3 - 0
tests/misc/projects/Issue4448/compile1-fail.hxml.stderr

@@ -0,0 +1,3 @@
+Main1.hx:11: characters 8-9 : Cannot access non-static field f from static method
+Main1.hx:12: characters 8-9 : Cannot access non-static field v from static method
+Main1.hx:13: characters 8-10 : Cannot access non-static field v2 from static method

+ 6 - 0
tests/misc/projects/Issue4671/Main1.hx

@@ -0,0 +1,6 @@
+interface IFoo extends IBar{}
+interface IBar extends IFoo{}
+
+class Main1 {
+	static function main() { }
+}

+ 6 - 0
tests/misc/projects/Issue4671/Main2.hx

@@ -0,0 +1,6 @@
+class A extends B { }
+class B extends A { }
+
+class Main1 {
+	static function main() { }
+}

+ 2 - 0
tests/misc/projects/Issue4671/compile1-fail.hxml

@@ -0,0 +1,2 @@
+-main Main1
+--interp

+ 1 - 0
tests/misc/projects/Issue4671/compile1-fail.hxml.stderr

@@ -0,0 +1 @@
+Main1.hx:1: characters 0-29 : Recursive class

+ 2 - 0
tests/misc/projects/Issue4671/compile2-fail.hxml

@@ -0,0 +1,2 @@
+-main Main2
+--interp

+ 1 - 0
tests/misc/projects/Issue4671/compile2-fail.hxml.stderr

@@ -0,0 +1 @@
+Main2.hx:1: characters 0-21 : Recursive class

+ 6 - 0
tests/misc/projects/Issue4816/Main1.hx

@@ -0,0 +1,6 @@
+class Main {
+    static function main() {
+        var f = { f : { name : "hello" } };
+        trace( macro $i{f.name} );
+    }
+}

+ 2 - 0
tests/misc/projects/Issue4816/compile1-fail.hxml

@@ -0,0 +1,2 @@
+-main Main1
+--interp

+ 1 - 0
tests/misc/projects/Issue4816/compile1-fail.hxml.stderr

@@ -0,0 +1 @@
+Main1.hx:4: characters 24-30 : { f : { name : String } } has no field name

+ 12 - 6
tests/optimization/src/TestJs.hx

@@ -45,7 +45,7 @@ class TestJs {
 		for (v in a) { }
 	}
 
-	@:js('var a = 1;var v2 = a;if(a + v2 > 0) TestJs["use"](a);')
+	@:js('var a = 1;var v2 = a;if(a + v2 > 0) {TestJs["use"](a);}')
 	@:analyzer(no_const_propagation)
 	@:analyzer(no_copy_propagation)
 	@:analyzer(no_local_dce)
@@ -61,7 +61,7 @@ class TestJs {
 		return v + v2;
 	}
 
-	@:js("var a = [];a;")
+	@:js("var a = [];var tmp;try {tmp = a[0];} catch( e ) {tmp = null;}tmp;")
 	@:analyzer(no_local_dce)
 	static function testInlineWithComplexExpr() {
 		var a = [];
@@ -229,7 +229,7 @@ class TestJs {
 
 	@:js('
 		var map = new haxe_ds_StringMap();
-		if(__map_reserved.some != null) map.setReserved("some",2); else map.h["some"] = 2;
+		if(__map_reserved.some != null) {map.setReserved("some",2);} else {map.h["some"] = 2;}
 		TestJs["use"](2);
 	')
 	static function testIssue4731() {
@@ -281,9 +281,13 @@ class TestJs {
 
 	@:js('
 		var a = 0;
-		if(Math.random() < 0.5) a = 2;
+		if(Math.random() < 0.5) {
+			a = 2;
+		}
 		var b = "";
-		if(Math.random() < 0.5) b = "hello";
+		if(Math.random() < 0.5) {
+			b = "hello";
+		}
 		TestJs["use"](a);
 		TestJs["use"](b);
 	')
@@ -443,7 +447,9 @@ class TestJs {
 
 	@:js('
 		TestJs.getInt();
-		if(TestJs.getInt() != 0) throw new js__$Boot_HaxeError("meh");
+		if(TestJs.getInt() != 0) {
+			throw new js__$Boot_HaxeError("meh");
+		}
 	')
 	static function testIfInvert() {
 		var tmp;

+ 17 - 0
tests/unit/src/unit/issues/Issue3192.hx

@@ -0,0 +1,17 @@
+package unit.issues;
+
+class Issue3192 extends Test {
+	function test() {
+		var x1 = {x:1, y:2};
+		var x2 = ({x:1, y:2}:{x:Int,y:Int});
+		var x3:{x:Int,y:Int} = {x:1, y:2};
+		var y1:{} = x1;
+		var y2:{} = x2;
+		var y3:{} = x3;
+		var z1:{x:Int} = x1;
+		var z2:{x:Int} = x2;
+		var z3:{x:Int} = x3;
+		eq(1, x1.x);
+		eq(2, x1.y);
+	}
+}

+ 17 - 0
tests/unit/src/unit/issues/Issue3499.hx

@@ -0,0 +1,17 @@
+package unit.issues;
+
+#if js
+
+private typedef PathSimple = haxe.extern.EitherType<String,js.RegExp>;
+private typedef Path = haxe.extern.EitherType<PathSimple,Array<PathSimple>>;
+
+#end
+
+class Issue3499 extends Test {
+	#if js
+	function test() {
+		var a:Path = ["", new js.RegExp("")];
+		eq("", a[0]);
+	}
+	#end
+}

+ 21 - 0
tests/unit/src/unit/issues/Issue4121.hx

@@ -0,0 +1,21 @@
+package unit.issues;
+
+import unit.issues.misc.Issue4121Macro.wrap;
+
+private typedef P2 = {
+	var hidden(null, null):Int;
+}
+
+class Issue4121 extends Test {
+	function test() {
+		eq("(@:test ((x) = (1)))", wrap(@:test x = 1));
+		eq("(@:test (@:test2 ((x) = (@:test3 (1)))))", wrap(@:test @:test2 x = @:test3 1));
+
+		var p2:P2 = { hidden: 12 };
+		t(unit.TestType.typeError(p2.hidden));
+		eq(12, @:privateAccess p2.hidden);
+		t(unit.TestType.typeError(p2.hidden = 13));
+		@:privateAccess p2.hidden = 13;
+		eq(13, @:privateAccess p2.hidden);
+	}
+}

+ 68 - 0
tests/unit/src/unit/issues/Issue4526.hx

@@ -0,0 +1,68 @@
+package unit.issues;
+
+@:structInit
+private class Struct1 {
+	var x:Int;
+	var y:Int;
+	public function get() {
+		return x + " " + y;
+	}
+}
+
+@:structInit
+private class Struct2 {
+	@:optional var x:Int;
+	var y:Int;
+	public function get() {
+		return x + " " + y;
+	}
+}
+
+@:structInit
+private class Struct3 {
+	@:optional var x:Int;
+	@:optional var y:Int;
+	public function get() {
+		return x + " " + y;
+	}
+}
+
+@:structInit
+private class Struct4 {
+	var x:Int;
+	var y:Int;
+	var z:Int;
+	public function get() {
+		return x + " " + y + " " + z;
+	}
+}
+
+class Issue4526 extends Test {
+	function test() {
+		var fieldNull = #if (cpp || flash || java || cs) 0 #else null #end;
+
+		var s1:Struct1 = { x: 12, y: 13 };
+		eq("12 13", s1.get());
+		t(unit.TestType.typeError(({x:12} : Struct1)));
+		t(unit.TestType.typeError(({y:12} : Struct1)));
+
+		var s2:Struct2 = { x: 12, y: 13 };
+		eq("12 13", s2.get());
+		var s2:Struct2 = { y: 13 };
+		eq(fieldNull + " 13", s2.get());
+		t(unit.TestType.typeError(({x:12} : Struct2)));
+
+		var s3:Struct3 = { x: 12, y: 13 };
+		eq("12 13", s3.get());
+		var s3:Struct3 = { y: 13 };
+		eq(fieldNull + " 13", s3.get());
+		var s3:Struct3 = { };
+		eq(fieldNull + " " + fieldNull, s3.get());
+	}
+
+	function testOrder() {
+		var i = 0;
+		var s4:Struct4 = { y: i++, x: i++, z: i++ };
+		eq("1 0 2", s4.get());
+	}
+}

+ 11 - 0
tests/unit/src/unit/issues/Issue4777.hx

@@ -0,0 +1,11 @@
+package unit.issues;
+
+private abstract A(String) from String {}
+
+class Issue4777 extends Test {
+	function test() {
+		var map:Map<A, String> = new Map();
+		map["foo"] = "bar";
+		eq("bar", map["foo"]);
+	}
+}

+ 13 - 0
tests/unit/src/unit/issues/Issue4843.hx

@@ -0,0 +1,13 @@
+package unit.issues;
+
+private abstract A({}) from {} {
+	@:from static function fromB(b:{a:Int}):A {
+		return null;
+	}
+}
+
+class Issue4843 extends Test {
+	function test() {
+		var a:A = {};
+	}
+}

+ 28 - 0
tests/unit/src/unit/issues/Issue4862.hx

@@ -0,0 +1,28 @@
+package unit.issues;
+
+#if js
+@:native("__issue4862__http_status")
+@:enum private extern abstract HttpStatus(Int) to Int {
+    var Ok;
+    var NotFound;
+
+    static function __init__():Void {
+        untyped __js__("var __issue4862__http_status = {Ok: 200, NotFound: 404};");
+    }
+}
+#end
+
+class Issue4862 extends Test {
+    #if js
+    function test() {
+        var a = Ok;
+        eq(200, a);
+        var b = HttpStatus.NotFound;
+        eq(404, b);
+        t(switch (a) { case HttpStatus.Ok: true; default: false; });
+        t(switch (b) { case HttpStatus.NotFound: true; default: false; });
+        t(switch (a) { case Ok: true; default: false; });
+        t(switch (b) { case NotFound: true; default: false; });
+    }
+    #end
+}

+ 21 - 0
tests/unit/src/unit/issues/Issue4867.hx

@@ -0,0 +1,21 @@
+package unit.issues;
+
+@:enum
+private abstract EnumAbstract(Int) to Int {
+    var a = 0;
+    var b = 1;
+
+    @:from
+    public static function fromString(s:String):EnumAbstract {
+        if (s == "b")
+            return b;
+        return a;
+    }
+}
+
+class Issue4867 extends Test {
+	function test() {
+		var b:EnumAbstract = "b";
+		eq(1, b);
+	}
+}

+ 14 - 0
tests/unit/src/unit/issues/misc/Issue4121Macro.hx

@@ -0,0 +1,14 @@
+package unit.issues.misc;
+
+import haxe.macro.Expr;
+using haxe.macro.Tools;
+
+class Issue4121Macro {
+	macro static public function wrap(e:Expr) {
+		function addParens(e:Expr) {
+			return macro (${e.map(addParens)});
+		}
+		var e = addParens(e);
+		return macro $v{e.toString()};
+	}
+}

+ 12 - 9
tests/unit/src/unitstd/haxe/ds/Vector.unit.hx

@@ -135,15 +135,18 @@ vec.join(", ") == "foo, bar";
 
 // map
 
-//var vec = new haxe.ds.Vector(0);
-//vec.map(function(i) return throw false);
-//
-//var vec = new haxe.ds.Vector(2);
-//vec[0] = 12;
-//vec[1] = 13;
-//var vec2 = vec.map(function(i) return "value: " +i);
-//vec2[0] == "value: 12";
-//vec2[1] == "value: 13";
+var vec = new haxe.ds.Vector(0);
+vec.map(function(i) {
+	throw false;
+	return null;
+});
+
+var vec = new haxe.ds.Vector(2);
+vec[0] = 12;
+vec[1] = 13;
+var vec2 = vec.map(function(i) return "value: " +i);
+vec2[0] == "value: 12";
+vec2[1] == "value: 13";
 
 // sort
 

+ 1 - 1
tests/unit/unit-js.html

@@ -7,7 +7,7 @@
         <meta name="viewport" content="width=device-width, initial-scale=1">
     </head>
     <body id="haxe:trace">
-        <script type="text/javascript" src="//code.jquery.com/jquery-1.11.3.min.js"></script>
+        <script type="text/javascript" src="//code.jquery.com/jquery-1.12.1.min.js"></script>
         <script type="text/javascript">
             // http://stackoverflow.com/questions/11582512/how-to-get-url-parameters-with-javascript
             function getURLParameter(name) {

+ 4 - 8
type.ml

@@ -89,7 +89,6 @@ and tfunc = {
 and anon_status =
 	| Closed
 	| Opened
-	| Const
 	| Extend of t list
 	| Statics of tclass
 	| EnumStatics of tenum
@@ -1707,7 +1706,7 @@ let rec unify a b =
 			(match !(an.a_status) with
 			| Opened -> an.a_status := Closed;
 			| Statics _ | EnumStatics _ | AbstractStatics _ -> error []
-			| Closed | Extend _ | Const -> ())
+			| Closed | Extend _ -> ())
 		with
 			Unify_error l -> error (cannot_unify a b :: l))
 	| TAnon a1, TAnon a2 ->
@@ -1831,14 +1830,11 @@ and unify_anons a b a1 a2 =
 				| Opened ->
 					if not (link (ref None) a f2.cf_type) then error [];
 					a1.a_fields <- PMap.add n f2 a1.a_fields
-				| Const when Meta.has Meta.Optional f2.cf_meta ->
-					()
 				| _ ->
-					error [has_no_field a n];
+					if not (Meta.has Meta.Optional f2.cf_meta) then
+						error [has_no_field a n];
 		) a2.a_fields;
 		(match !(a1.a_status) with
-		| Const when not (PMap.is_empty a2.a_fields) ->
-			PMap.iter (fun n _ -> if not (PMap.mem n a2.a_fields) then error [has_extra_field a n]) a1.a_fields;
 		| Opened ->
 			a1.a_status := Closed
 		| _ -> ());
@@ -1847,7 +1843,7 @@ and unify_anons a b a1 a2 =
 		| EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
 		| AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
 		| Opened -> a2.a_status := Closed
-		| Const | Extend _ | Closed -> ())
+		| Extend _ | Closed -> ())
 	with
 		Unify_error l -> error (cannot_unify a b :: l))
 

+ 10 - 5
typecore.ml

@@ -78,7 +78,7 @@ type typer_globals = {
 	delayed_macros : (unit -> unit) DynArray.t;
 	mutable global_using : tclass list;
 	(* api *)
-	do_inherit : typer -> Type.tclass -> Ast.pos -> Ast.class_flag -> bool;
+	do_inherit : typer -> Type.tclass -> Ast.pos -> (bool * Ast.type_path) -> bool;
 	do_create : Common.context -> typer;
 	do_macro : typer -> macro_mode -> path -> string -> Ast.expr list -> Ast.pos -> Ast.expr option;
 	do_load_module : typer -> path -> pos -> module_def;
@@ -106,7 +106,6 @@ and typer = {
 	(* per-function *)
 	mutable curfield : tclass_field;
 	mutable untyped : bool;
-	mutable in_super_call : bool;
 	mutable in_loop : bool;
 	mutable in_display : bool;
 	mutable in_macro : bool;
@@ -292,12 +291,18 @@ let unify_min ctx el = (!unify_min_ref) ctx el
 
 let match_expr ctx e cases def with_type p = !match_expr_ref ctx e cases def with_type p
 
-let make_static_call ctx c cf map args t p =
+let make_static_this c p =
 	let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in
-	let ethis = mk (TTypeExpr (TClassDecl c)) ta p in
+	mk (TTypeExpr (TClassDecl c)) ta p
+
+let make_static_field_access c cf t p =
+	let ethis = make_static_this c p in
+	mk (TField (ethis,(FStatic (c,cf)))) t p
+
+let make_static_call ctx c cf map args t p =
 	let monos = List.map (fun _ -> mk_mono()) cf.cf_params in
 	let map t = map (apply_params cf.cf_params monos t) in
-	let ef = mk (TField (ethis,(FStatic (c,cf)))) (map cf.cf_type) p in
+	let ef = make_static_field_access c cf (map cf.cf_type) p in
 	make_call ctx ef args (map t) p
 
 let raise_or_display ctx l p =

+ 246 - 182
typeload.ml

@@ -38,10 +38,14 @@ let transform_abstract_field com this_t a_t a f =
 		let init p = (EVars ["this",Some this_t,None],p) in
 		let cast e = (ECast(e,None)),pos e in
 		let ret p = (EReturn (Some (cast (EConst (Ident "this"),p))),p) in
-		if Meta.has Meta.MultiType a.a_meta then begin
+		let meta = (Meta.Impl,[],p) :: f.cff_meta in
+		let meta = if Meta.has Meta.MultiType a.a_meta then begin
 			if List.mem AInline f.cff_access then error "MultiType constructors cannot be inline" f.cff_pos;
 			if fu.f_expr <> None then error "MultiType constructors cannot have a body" f.cff_pos;
-		end;
+			(Meta.Extern,[],f.cff_pos) :: meta
+		end else
+			meta
+		in
 		let fu = {
 			fu with
 			f_expr = (match fu.f_expr with
@@ -51,7 +55,8 @@ let transform_abstract_field com this_t a_t a f =
 			);
 			f_type = Some a_t;
 		} in
-		{ f with cff_name = "_new"; cff_access = AStatic :: f.cff_access; cff_kind = FFun fu; cff_meta = (Meta.Impl,[],p) :: f.cff_meta }
+
+		{ f with cff_name = "_new"; cff_access = AStatic :: f.cff_access; cff_kind = FFun fu; cff_meta = meta }
 	| FFun fu when not stat ->
 		if Meta.has Meta.From f.cff_meta then error "@:from cast functions must be static" f.cff_pos;
 		let fu = { fu with f_args = (if List.mem AMacro f.cff_access then fu.f_args else ("this",false,Some this_t,None) :: fu.f_args) } in
@@ -191,7 +196,7 @@ let module_pass_1 com m tdecls loadp =
 				(match !decls with
 				| (TClassDecl c,_) :: _ ->
 					List.iter (fun m -> match m with
-						| ((Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.Expose | Meta.Deprecated),_,_) ->
+						| ((Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated),_,_) ->
 							c.cl_meta <- m :: c.cl_meta;
 						| _ ->
 							()
@@ -938,71 +943,6 @@ let class_field_no_interf c i =
 			let _, t , f = raw_class_field (fun f -> f.cf_type) c tl i in
 			apply_params c.cl_params tl t , f
 
-let rec check_interface ctx c intf params =
-	let p = c.cl_pos in
-	let rec check_field i f =
-		(if ctx.com.config.pf_overload then
-			List.iter (function
-				| f2 when f != f2 ->
-						check_field i f2
-				| _ -> ()) f.cf_overloads);
-		let is_overload = ref false in
-		try
-			let t2, f2 = class_field_no_interf c i in
-			let t2, f2 =
-				if ctx.com.config.pf_overload && (f2.cf_overloads <> [] || Meta.has Meta.Overload f2.cf_meta) then
-					let overloads = get_overloads c i in
-					is_overload := true;
-					let t = (apply_params intf.cl_params params f.cf_type) in
-					List.find (fun (t1,f1) -> same_overload_args t t1 f f1) overloads
-				else
-					t2, f2
-			in
-
-			ignore(follow f2.cf_type); (* force evaluation *)
-			let p = (match f2.cf_expr with None -> p | Some e -> e.epos) in
-			let mkind = function
-				| MethNormal | MethInline -> 0
-				| MethDynamic -> 1
-				| MethMacro -> 2
-			in
-			if f.cf_public && not f2.cf_public && not (Meta.has Meta.CompilerGenerated f.cf_meta) then
-				display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
-			else if not (unify_kind f2.cf_kind f.cf_kind) || not (match f.cf_kind, f2.cf_kind with Var _ , Var _ -> true | Method m1, Method m2 -> mkind m1 = mkind m2 | _ -> false) then
-				display_error ctx ("Field " ^ i ^ " has different property access than in " ^ s_type_path intf.cl_path ^ " (" ^ s_kind f2.cf_kind ^ " should be " ^ s_kind f.cf_kind ^ ")") p
-			else try
-				valid_redefinition ctx f2 t2 f (apply_params intf.cl_params params f.cf_type)
-			with
-				Unify_error l ->
-					if not (Meta.has Meta.CsNative c.cl_meta && c.cl_extern) then begin
-						display_error ctx ("Field " ^ i ^ " has different type than in " ^ s_type_path intf.cl_path) p;
-						display_error ctx ("Interface field is defined here") f.cf_pos;
-						display_error ctx (error_msg (Unify l)) p;
-					end
-		with
-			| Not_found when not c.cl_interface ->
-				let msg = if !is_overload then
-					let ctx = print_context() in
-					let args = match follow f.cf_type with | TFun(args,_) -> String.concat ", " (List.map (fun (n,o,t) -> (if o then "?" else "") ^ n ^ " : " ^ (s_type ctx t)) args) | _ -> assert false in
-					"No suitable overload for " ^ i ^ "( " ^ args ^ " ), as needed by " ^ s_type_path intf.cl_path ^ " was found"
-				else
-					("Field " ^ i ^ " needed by " ^ s_type_path intf.cl_path ^ " is missing")
-				in
-				display_error ctx msg p
-			| Not_found -> ()
-	in
-	PMap.iter check_field intf.cl_fields;
-	List.iter (fun (i2,p2) ->
-		check_interface ctx c i2 (List.map (apply_params intf.cl_params params) p2)
-	) intf.cl_implements
-
-let check_interfaces ctx c =
-	match c.cl_path with
-	| "Proxy" :: _ , _ -> ()
-	| _ when c.cl_extern && Meta.has Meta.CsNative c.cl_meta -> ()
-	| _ ->
-	List.iter (fun (intf,params) -> check_interface ctx c intf params) c.cl_implements
-
 let rec return_flow ctx e =
 	let error() =
 		display_error ctx (Printf.sprintf "Missing return: %s" (s_type (print_context()) ctx.ret)) e.epos; raise Exit
@@ -1063,20 +1003,6 @@ let is_generic_parameter ctx c =
 	with Not_found ->
 		false
 
-let check_extends ctx c t p = match follow t with
-	| TInst ({ cl_path = [],"Array"; cl_extern = basic_extern },_)
-	| TInst ({ cl_path = [],"String"; cl_extern = basic_extern },_)
-	| TInst ({ cl_path = [],"Date"; cl_extern = basic_extern },_)
-	| TInst ({ cl_path = [],"Xml"; cl_extern = basic_extern },_) when not (c.cl_extern && basic_extern) ->
-		error "Cannot extend basic class" p;
-	| TInst (csup,params) ->
-		if is_parent c csup then error "Recursive class" p;
-		begin match csup.cl_kind with
-			| KTypeParameter _ when not (is_generic_parameter ctx csup) -> error "Cannot extend non-generic type parameters" p
-			| _ -> csup,params
-		end
-	| _ -> error "Should extend by using a class" p
-
 let type_function_arg_value ctx t c =
 	match c with
 		| None -> None
@@ -1338,92 +1264,211 @@ let add_constructor ctx c force_constructor p =
 		(* nothing to do *)
 		()
 
-let set_heritance ctx c herits p =
-	let is_lib = Meta.has Meta.LibType c.cl_meta in
-	let ctx = { ctx with curclass = c; type_params = c.cl_params; } in
-	let old_meta = c.cl_meta in
-	let process_meta csup =
-		List.iter (fun m ->
-			match m with
-			| Meta.Final, _, _ -> if not (Meta.has Meta.Hack c.cl_meta || (match c.cl_kind with KTypeParameter _ -> true | _ -> false)) then error "Cannot extend a final class" p;
-			| Meta.AutoBuild, el, p -> c.cl_meta <- (Meta.Build,el,p) :: m :: c.cl_meta
-			| _ -> ()
-		) csup.cl_meta
-	in
-	let cancel_build csup =
-		(* for macros reason, our super class is not yet built - see #2177 *)
-		(* let's reset our build and delay it until we are done *)
-		c.cl_meta <- old_meta;
-		c.cl_array_access <- None;
-		c.cl_dynamic <- None;
-		c.cl_implements <- [];
-		c.cl_super <- None;
-		raise Exit
-	in
-	let has_interf = ref false in
-	let rec loop = function
-		| HPrivate | HExtern | HInterface ->
-			()
-		| HExtends t ->
-			if c.cl_super <> None then error "Cannot extend several classes" p;
-			let t = load_instance ctx t p false in
-			let csup,params = check_extends ctx c t p in
-			if not (csup.cl_build()) then cancel_build csup;
-			process_meta csup;
-			if c.cl_interface then begin
-				if not csup.cl_interface then error "Cannot extend by using a class" p;
-				c.cl_implements <- (csup,params) :: c.cl_implements;
-				if not !has_interf then begin
-					if not is_lib then delay ctx PForce (fun() -> check_interfaces ctx c);
-					has_interf := true;
-				end
-			end else begin
-				if csup.cl_interface then error "Cannot extend by using an interface" p;
-				c.cl_super <- Some (csup,params)
+let check_struct_init_constructor ctx c p = match c.cl_constructor with
+	| Some _ ->
+		()
+	| None ->
+		let params = List.map snd c.cl_params in
+		let ethis = mk (TConst TThis) (TInst(c,params)) p in
+		let args,el,tl = List.fold_left (fun (args,el,tl) cf -> match cf.cf_kind with
+			| Var _ ->
+				let opt = Meta.has Meta.Optional cf.cf_meta in
+				let t = if opt then ctx.t.tnull cf.cf_type else cf.cf_type in
+				let v = alloc_var cf.cf_name t in
+				let ef = mk (TField(ethis,FInstance(c,params,cf))) t p in
+				let ev = mk (TLocal v) v.v_type p in
+				let e = mk (TBinop(OpAssign,ef,ev)) ev.etype p in
+				(v,None) :: args,e :: el,(cf.cf_name,opt,t) :: tl
+			| Method _ ->
+				args,el,tl
+		) ([],[],[]) (List.rev c.cl_ordered_fields) in
+		let tf = {
+			tf_args = args;
+			tf_type = ctx.t.tvoid;
+			tf_expr = mk (TBlock el) ctx.t.tvoid p
+		} in
+		let e = mk (TFunction tf) (TFun(tl,ctx.t.tvoid)) p in
+		let cf = mk_field "new" e.etype p in
+		cf.cf_expr <- Some e;
+		cf.cf_type <- e.etype;
+		cf.cf_meta <- [Meta.CompilerGenerated,[],p];
+		cf.cf_kind <- Method MethNormal;
+		c.cl_constructor <- Some cf
+
+module Inheritance = struct
+	let check_extends ctx c t p = match follow t with
+		| TInst ({ cl_path = [],"Array"; cl_extern = basic_extern },_)
+		| TInst ({ cl_path = [],"String"; cl_extern = basic_extern },_)
+		| TInst ({ cl_path = [],"Date"; cl_extern = basic_extern },_)
+		| TInst ({ cl_path = [],"Xml"; cl_extern = basic_extern },_) when not (c.cl_extern && basic_extern) ->
+			error "Cannot extend basic class" p;
+		| TInst (csup,params) ->
+			if is_parent c csup then error "Recursive class" p;
+			begin match csup.cl_kind with
+				| KTypeParameter _ when not (is_generic_parameter ctx csup) -> error "Cannot extend non-generic type parameters" p
+				| _ -> csup,params
 			end
-		| HImplements t ->
-			let t = load_instance ctx t p false in
-			(match follow t with
-			| TInst ({ cl_path = [],"ArrayAccess"; cl_extern = true; },[t]) ->
-				if c.cl_array_access <> None then error "Duplicate array access" p;
-				c.cl_array_access <- Some t
-			| TInst (intf,params) ->
-				if is_parent c intf then error "Recursive class" p;
-				if not (intf.cl_build()) then cancel_build intf;
-				if c.cl_interface then error "Interfaces cannot implement another interface (use extends instead)" p;
-				if not intf.cl_interface then error "You can only implement an interface" p;
-				process_meta intf;
-				c.cl_implements <- (intf, params) :: c.cl_implements;
-				if not !has_interf && not is_lib && not (Meta.has (Meta.Custom "$do_not_check_interf") c.cl_meta) then begin
-					delay ctx PForce (fun() -> check_interfaces ctx c);
-					has_interf := true;
-				end
-			| TDynamic t ->
-				if c.cl_dynamic <> None then error "Cannot have several dynamics" p;
-				c.cl_dynamic <- Some t
-			| _ -> error "Should implement by using an interface" p)
-	in
-	(*
-		resolve imports before calling build_inheritance, since it requires full paths.
-		that means that typedefs are not working, but that's a fair limitation
-	*)
-	let resolve_imports t =
-		match t.tpackage with
-		| _ :: _ -> t
-		| [] ->
+		| _ -> error "Should extend by using a class" p
+
+	let rec check_interface ctx c intf params =
+		let p = c.cl_pos in
+		let rec check_field i f =
+			(if ctx.com.config.pf_overload then
+				List.iter (function
+					| f2 when f != f2 ->
+							check_field i f2
+					| _ -> ()) f.cf_overloads);
+			let is_overload = ref false in
 			try
-				let find = List.find (fun lt -> snd (t_path lt) = t.tname) in
-				let lt = try find ctx.m.curmod.m_types with Not_found -> find ctx.m.module_types in
-				{ t with tpackage = fst (t_path lt) }
+				let t2, f2 = class_field_no_interf c i in
+				let t2, f2 =
+					if ctx.com.config.pf_overload && (f2.cf_overloads <> [] || Meta.has Meta.Overload f2.cf_meta) then
+						let overloads = get_overloads c i in
+						is_overload := true;
+						let t = (apply_params intf.cl_params params f.cf_type) in
+						List.find (fun (t1,f1) -> same_overload_args t t1 f f1) overloads
+					else
+						t2, f2
+				in
+
+				ignore(follow f2.cf_type); (* force evaluation *)
+				let p = (match f2.cf_expr with None -> p | Some e -> e.epos) in
+				let mkind = function
+					| MethNormal | MethInline -> 0
+					| MethDynamic -> 1
+					| MethMacro -> 2
+				in
+				if f.cf_public && not f2.cf_public && not (Meta.has Meta.CompilerGenerated f.cf_meta) then
+					display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
+				else if not (unify_kind f2.cf_kind f.cf_kind) || not (match f.cf_kind, f2.cf_kind with Var _ , Var _ -> true | Method m1, Method m2 -> mkind m1 = mkind m2 | _ -> false) then
+					display_error ctx ("Field " ^ i ^ " has different property access than in " ^ s_type_path intf.cl_path ^ " (" ^ s_kind f2.cf_kind ^ " should be " ^ s_kind f.cf_kind ^ ")") p
+				else try
+					valid_redefinition ctx f2 t2 f (apply_params intf.cl_params params f.cf_type)
+				with
+					Unify_error l ->
+						if not (Meta.has Meta.CsNative c.cl_meta && c.cl_extern) then begin
+							display_error ctx ("Field " ^ i ^ " has different type than in " ^ s_type_path intf.cl_path) p;
+							display_error ctx ("Interface field is defined here") f.cf_pos;
+							display_error ctx (error_msg (Unify l)) p;
+						end
 			with
-				Not_found -> t
-	in
-	let herits = List.map (function
-		| HExtends t -> HExtends (resolve_imports t)
-		| HImplements t -> HImplements (resolve_imports t)
-		| h -> h
-	) herits in
-	List.iter loop (List.filter (ctx.g.do_inherit ctx c p) herits)
+				| Not_found when not c.cl_interface ->
+					let msg = if !is_overload then
+						let ctx = print_context() in
+						let args = match follow f.cf_type with | TFun(args,_) -> String.concat ", " (List.map (fun (n,o,t) -> (if o then "?" else "") ^ n ^ " : " ^ (s_type ctx t)) args) | _ -> assert false in
+						"No suitable overload for " ^ i ^ "( " ^ args ^ " ), as needed by " ^ s_type_path intf.cl_path ^ " was found"
+					else
+						("Field " ^ i ^ " needed by " ^ s_type_path intf.cl_path ^ " is missing")
+					in
+					display_error ctx msg p
+				| Not_found -> ()
+		in
+		PMap.iter check_field intf.cl_fields;
+		List.iter (fun (i2,p2) ->
+			check_interface ctx c i2 (List.map (apply_params intf.cl_params params) p2)
+		) intf.cl_implements
+
+	let check_interfaces ctx c =
+		match c.cl_path with
+		| "Proxy" :: _ , _ -> ()
+		| _ when c.cl_extern && Meta.has Meta.CsNative c.cl_meta -> ()
+		| _ ->
+		List.iter (fun (intf,params) -> check_interface ctx c intf params) c.cl_implements
+
+	let set_heritance ctx c herits p =
+		let is_lib = Meta.has Meta.LibType c.cl_meta in
+		let ctx = { ctx with curclass = c; type_params = c.cl_params; } in
+		let old_meta = c.cl_meta in
+		let process_meta csup =
+			List.iter (fun m ->
+				match m with
+				| Meta.Final, _, _ -> if not (Meta.has Meta.Hack c.cl_meta || (match c.cl_kind with KTypeParameter _ -> true | _ -> false)) then error "Cannot extend a final class" p;
+				| Meta.AutoBuild, el, p -> c.cl_meta <- (Meta.Build,el,p) :: m :: c.cl_meta
+				| _ -> ()
+			) csup.cl_meta
+		in
+		let cancel_build csup =
+			(* for macros reason, our super class is not yet built - see #2177 *)
+			(* let's reset our build and delay it until we are done *)
+			c.cl_meta <- old_meta;
+(* 			c.cl_array_access <- None;
+			c.cl_dynamic <- None;
+			c.cl_implements <- [];
+			c.cl_super <- None; *)
+			raise Exit
+		in
+		let has_interf = ref false in
+		(*
+			resolve imports before calling build_inheritance, since it requires full paths.
+			that means that typedefs are not working, but that's a fair limitation
+		*)
+		let resolve_imports t =
+			match t.tpackage with
+			| _ :: _ -> t
+			| [] ->
+				try
+					let find = List.find (fun lt -> snd (t_path lt) = t.tname) in
+					let lt = try find ctx.m.curmod.m_types with Not_found -> find ctx.m.module_types in
+					{ t with tpackage = fst (t_path lt) }
+				with
+					Not_found -> t
+		in
+		let herits = ExtList.List.filter_map (function
+			| HExtends t -> Some(true,resolve_imports t)
+			| HImplements t -> Some(false,resolve_imports t)
+			| t -> None
+		) herits in
+		let herits = List.filter (ctx.g.do_inherit ctx c p) herits in
+		(* Pass 1: Check and set relations *)
+		let fl = List.map (fun (is_extends,t) ->
+			let t = load_instance ctx t p false in
+			if is_extends then begin
+				if c.cl_super <> None then error "Cannot extend several classes" p;
+				let csup,params = check_extends ctx c t p in
+				if c.cl_interface then begin
+					if not csup.cl_interface then error "Cannot extend by using a class" p;
+					c.cl_implements <- (csup,params) :: c.cl_implements;
+					if not !has_interf then begin
+						if not is_lib then delay ctx PForce (fun() -> check_interfaces ctx c);
+						has_interf := true;
+					end
+				end else begin
+					if csup.cl_interface then error "Cannot extend by using an interface" p;
+					c.cl_super <- Some (csup,params)
+				end;
+				(fun () ->
+					if not (csup.cl_build()) then cancel_build csup;
+					process_meta csup;
+				)
+			end else begin match follow t with
+				| TInst ({ cl_path = [],"ArrayAccess"; cl_extern = true; },[t]) ->
+					if c.cl_array_access <> None then error "Duplicate array access" p;
+					c.cl_array_access <- Some t;
+					(fun () -> ())
+				| TInst (intf,params) ->
+					if is_parent c intf then error "Recursive class" p;
+					if c.cl_interface then error "Interfaces cannot implement another interface (use extends instead)" p;
+					if not intf.cl_interface then error "You can only implement an interface" p;
+					c.cl_implements <- (intf, params) :: c.cl_implements;
+					if not !has_interf && not is_lib && not (Meta.has (Meta.Custom "$do_not_check_interf") c.cl_meta) then begin
+						delay ctx PForce (fun() -> check_interfaces ctx c);
+						has_interf := true;
+					end;
+					(fun () ->
+						if not (intf.cl_build()) then cancel_build intf;
+						process_meta intf;
+					)
+				| TDynamic t ->
+					if c.cl_dynamic <> None then error "Cannot have several dynamics" p;
+					c.cl_dynamic <- Some t;
+					(fun () -> ())
+				| _ ->
+					error "Should implement by using an interface" p
+			end
+		) herits in
+		(* Pass 2: Build classes and check metadata *)
+		List.iter (fun f -> f()) fl
+end
 
 let rec type_type_param ?(enum_constructor=false) ctx path get_params p tp =
 	let n = tp.tp_name in
@@ -1794,13 +1839,21 @@ let build_enum_abstract ctx c a fields p =
 	List.iter (fun field ->
 		match field.cff_kind with
 		| FVar(ct,eo) when not (List.mem AStatic field.cff_access) ->
-			field.cff_access <- [AStatic;APublic;AInline];
+			field.cff_access <- [AStatic;APublic];
 			field.cff_meta <- (Meta.Enum,[],field.cff_pos) :: (Meta.Impl,[],field.cff_pos) :: field.cff_meta;
-			let e = match eo with
-				| None -> error "Value required" field.cff_pos
-				| Some e -> (ECast(e,None),field.cff_pos)
+			let ct = match ct with
+				| Some _ -> ct
+				| None -> Some (TExprToExpr.convert_type (TAbstract(a,List.map snd a.a_params)))
 			in
-			field.cff_kind <- FVar(ct,Some e)
+			begin match eo with
+				| None ->
+					if not c.cl_extern then error "Value required" field.cff_pos
+					else field.cff_kind <- FProp("default","never",ct,None)
+				| Some e ->
+					field.cff_access <- AInline :: field.cff_access;
+					let e = (ECast(e,None),field.cff_pos) in
+					field.cff_kind <- FVar(ct,Some e)
+			end
 		| _ ->
 			()
 	) fields;
@@ -2739,6 +2792,7 @@ module ClassInitializer = struct
 		*)
 		(* add_constructor does not deal with overloads correctly *)
 		if not ctx.com.config.pf_overload then add_constructor ctx c cctx.force_constructor p;
+		if Meta.has Meta.StructInit c.cl_meta then check_struct_init_constructor ctx c p;
 		(* check overloaded constructors *)
 		(if ctx.com.config.pf_overload && not cctx.is_lib then match c.cl_constructor with
 		| Some ctor ->
@@ -2952,7 +3006,7 @@ let init_module_type ctx context_init do_init (decl,p) =
 		let rec build() =
 			c.cl_build <- (fun()-> false);
 			try
-				set_heritance ctx c herits p;
+				Inheritance.set_heritance ctx c herits p;
 				ClassInitializer.init_class ctx c p do_init d.d_flags d.d_data;
 				c.cl_build <- (fun()-> true);
 				List.iter (fun (_,t) -> ignore(follow t)) c.cl_params;
@@ -3182,6 +3236,8 @@ let init_module_type ctx context_init do_init (decl,p) =
 				);
 				a.a_this <- at;
 				is_type := true;
+			| AExtern ->
+				(match a.a_impl with Some c -> c.cl_extern <- true | None -> (* Hmmmm.... *) ())
 			| APrivAbstract -> ()
 		) d.d_flags;
 		if not !is_type then begin
@@ -3252,7 +3308,6 @@ let type_types_into_module ctx m tdecls p =
 		type_params = [];
 		curfun = FunStatic;
 		untyped = false;
-		in_super_call = false;
 		in_macro = ctx.in_macro;
 		in_display = false;
 		in_loop = false;
@@ -3269,27 +3324,36 @@ let type_types_into_module ctx m tdecls p =
 
 let handle_import_hx ctx m decls p =
 	let path_split = List.tl (List.rev (get_path_parts m.m_extra.m_file)) in
-	let join l = String.concat "/" (List.rev ("import.hx" :: l)) in
+	let join l = String.concat (if Sys.os_type = "Win32" || Sys.os_type = "Cygwin" then "\\" else "/") (List.rev ("import.hx" :: l)) in
 	let rec loop path pack = match path,pack with
 		| _,[] -> [join path]
 		| (p :: path),(_ :: pack) -> (join (p :: path)) :: (loop path pack)
 		| _ -> []
 	in
 	let candidates = loop path_split (fst m.m_path) in
+	let make_import_module path r =
+		Hashtbl.replace ctx.com.parser_cache path r;
+		(* We use the file path as module name to make it unique. This may or may not be a good idea... *)
+		let m_import = make_module ctx ([],path) path p in
+		add_module ctx m_import p;
+		m_import
+	in
 	List.fold_left (fun acc path ->
-		let path = Common.unique_full_path path in
-		let _,decls = try
-			Hashtbl.find ctx.com.parser_cache path
+		let decls = try
+			let r = Hashtbl.find ctx.com.parser_cache path in
+			let mimport = Hashtbl.find ctx.g.modules ([],path) in
+			if mimport.m_extra.m_kind <> MFake then add_dependency m mimport;
+			r
 		with Not_found ->
 			if Sys.file_exists path then begin
-				let r = parse_file ctx.com path p in
-				List.iter (fun (d,p) -> match d with EImport _ | EUsing _ -> () | _ -> error "Only import and using is allowed in import.hx files" p) (snd r);
-				Hashtbl.replace ctx.com.parser_cache path r;
+				let _,r = parse_file ctx.com path p in
+				List.iter (fun (d,p) -> match d with EImport _ | EUsing _ -> () | _ -> error "Only import and using is allowed in import.hx files" p) r;
+				add_dependency m (make_import_module path r);
 				r
 			end else begin
-				let r = ([],[]) in
+				let r = [] in
 				(* Add empty decls so we don't check the file system all the time. *)
-				Hashtbl.replace ctx.com.parser_cache path r;
+				(make_import_module path r).m_extra.m_kind <- MFake;
 				r
 			end
 		in

ファイルの差分が大きいため隠しています
+ 553 - 579
typer.ml


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません