Browse Source

Add -w (#10612)

* let's go

* this isn't overengineered

* maybe like this

* increase global warning

* deal with all warning situations

* fail nicer
Simon Krajewski 3 years ago
parent
commit
b687030868

+ 6 - 0
src-json/meta.json

@@ -1286,6 +1286,12 @@
 		"targets": ["TClassField"],
 		"targets": ["TClassField"],
 		"internal": true
 		"internal": true
 	},
 	},
+	{
+		"name": "HaxeWarning",
+		"metadata": ":haxe.warning",
+		"doc": "Modifies warning options, equivalent to the -w CLI argument",
+		"targets": ["TClass","TClassField"]
+	},
 	{
 	{
 		"name": "Void",
 		"name": "Void",
 		"metadata": ":void",
 		"metadata": ":void",

+ 10 - 11
src/codegen/gencommon/castDetect.ml

@@ -650,7 +650,6 @@ let choose_ctor gen cl tparams etl maybe_empty_t p =
 				unify et t;
 				unify et t;
 				check_arg arglist elist
 				check_arg arglist elist
 			with Unify_error el ->
 			with Unify_error el ->
-				(* List.iter (fun el -> gen.gcon.warning (Error.unify_error_msg (print_context()) el) p) el; *)
 				false
 				false
 			)
 			)
 		| _ ->
 		| _ ->
@@ -768,12 +767,12 @@ let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist
 						| [Cannot_unify (b, TAbstract(a,params))] ->
 						| [Cannot_unify (b, TAbstract(a,params))] ->
 							let a = apply_params a.a_params params a.a_this in
 							let a = apply_params a.a_params params a.a_this in
 							if not (shallow_eq a b) then
 							if not (shallow_eq a b) then
-								gen.gcon.warning ("This expression may be invalid") pos
+								gen.gwarning WGencommon ("This expression may be invalid") pos
 						| _ ->
 						| _ ->
-							gen.gcon.warning ("This expression may be invalid") pos
+							gen.gwarning WGencommon ("This expression may be invalid") pos
 						)
 						)
 				| Invalid_argument _ ->
 				| Invalid_argument _ ->
-						gen.gcon.warning ("This expression may be invalid") pos
+						gen.gwarning WGencommon ("This expression may be invalid") pos
 			);
 			);
 
 
 			List.map (fun t ->
 			List.map (fun t ->
@@ -825,7 +824,7 @@ let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist
 						(* f,f.cf_type, false *)
 						(* f,f.cf_type, false *)
 						select_overload gen e1.etype ((f.cf_type,f) :: List.map (fun f -> f.cf_type,f) f.cf_overloads) [] [], true
 						select_overload gen e1.etype ((f.cf_type,f) :: List.map (fun f -> f.cf_type,f) f.cf_overloads) [] [], true
 					| _ ->
 					| _ ->
-						gen.gcon.warning "Overloaded classfield typed as anonymous" ecall.epos;
+						gen.gwarning WGencommon "Overloaded classfield typed as anonymous" ecall.epos;
 						(cf, actual_t, true), true
 						(cf, actual_t, true), true
 				in
 				in
 
 
@@ -848,7 +847,7 @@ let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist
 					end;
 					end;
 					{ cf_orig with cf_name = cf.cf_name },actual_t,false
 					{ cf_orig with cf_name = cf.cf_name },actual_t,false
 				| None ->
 				| None ->
-					gen.gcon.warning "Cannot find matching overload" ecall.epos;
+					gen.gwarning WGencommon "Cannot find matching overload" ecall.epos;
 					cf, actual_t, true
 					cf, actual_t, true
 				else
 				else
 					cf,actual_t,error
 					cf,actual_t,error
@@ -930,7 +929,7 @@ let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist
 							elist);
 							elist);
 					}, elist
 					}, elist
 				with Invalid_argument _ ->
 				with Invalid_argument _ ->
-					gen.gcon.warning ("This expression may be invalid" ) ecall.epos;
+					gen.gwarning WGencommon ("This expression may be invalid" ) ecall.epos;
 					{ ecall with eexpr = TCall({ e1 with eexpr = TField(!ef, f) }, elist) }, elist
 					{ ecall with eexpr = TCall({ e1 with eexpr = TField(!ef, f) }, elist) }, elist
 				in
 				in
 				let new_ecall = if fparams <> [] then gen.gparam_func_call new_ecall { e1 with eexpr = TField(!ef, f) } fparams elist else new_ecall in
 				let new_ecall = if fparams <> [] then gen.gparam_func_call new_ecall { e1 with eexpr = TField(!ef, f) } fparams elist else new_ecall in
@@ -960,7 +959,7 @@ let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist
 		*)
 		*)
 			| _ ->
 			| _ ->
 				let pt = match e with | None -> real_type | Some _ -> snd (get_fun e1.etype) in
 				let pt = match e with | None -> real_type | Some _ -> snd (get_fun e1.etype) in
-				let _params = match follow pt with | TEnum(_, p) -> p | _ -> gen.gcon.warning (debug_expr e1) e1.epos; die "" __LOC__ in
+				let _params = match follow pt with | TEnum(_, p) -> p | _ -> gen.gwarning WGencommon (debug_expr e1) e1.epos; die "" __LOC__ in
 				let args, ret = get_fun efield.ef_type in
 				let args, ret = get_fun efield.ef_type in
 				let actual_t = TFun(List.map (fun (n,o,t) -> (n,o,gen.greal_type t)) args, gen.greal_type ret) in
 				let actual_t = TFun(List.map (fun (n,o,t) -> (n,o,gen.greal_type t)) args, gen.greal_type ret) in
 				(*
 				(*
@@ -1144,7 +1143,7 @@ let configure gen ?(overloads_cast_to_base = false) maybe_empty_t calls_paramete
 				let base_type = match follow et with
 				let base_type = match follow et with
 					| TInst({ cl_path = ([], "Array") } as cl, bt) -> gen.greal_type_param (TClassDecl cl) bt
 					| TInst({ cl_path = ([], "Array") } as cl, bt) -> gen.greal_type_param (TClassDecl cl) bt
 					| _ ->
 					| _ ->
-						gen.gcon.warning (debug_type et) e.epos;
+						gen.gwarning WGencommon (debug_type et) e.epos;
 						(match gen.gcurrent_class with
 						(match gen.gcurrent_class with
 							| Some cl -> print_endline (s_type_path cl.cl_path)
 							| Some cl -> print_endline (s_type_path cl.cl_path)
 							| _ -> ());
 							| _ -> ());
@@ -1188,7 +1187,7 @@ let configure gen ?(overloads_cast_to_base = false) maybe_empty_t calls_paramete
 					) (wrap_rest_args gen (TFun (args,rt)) eparams e.epos) args in
 					) (wrap_rest_args gen (TFun (args,rt)) eparams e.epos) args in
 					{ e with eexpr = TCall(ef, eparams) }
 					{ e with eexpr = TCall(ef, eparams) }
 				with | Not_found ->
 				with | Not_found ->
-					gen.gcon.warning "No overload found for this constructor call" e.epos;
+					gen.gwarning WGencommon "No overload found for this constructor call" e.epos;
 					{ e with eexpr = TCall(ef, List.map run eparams) })
 					{ e with eexpr = TCall(ef, List.map run eparams) })
 			| TCall (ef, eparams) ->
 			| TCall (ef, eparams) ->
 				(match ef.etype with
 				(match ef.etype with
@@ -1216,7 +1215,7 @@ let configure gen ?(overloads_cast_to_base = false) maybe_empty_t calls_paramete
 				) (wrap_rest_args gen (TFun (args,rt)) eparams e.epos) args in
 				) (wrap_rest_args gen (TFun (args,rt)) eparams e.epos) args in
 				{ e with eexpr = TNew(cl, tparams, eparams) }
 				{ e with eexpr = TNew(cl, tparams, eparams) }
 			with | Not_found ->
 			with | Not_found ->
-				gen.gcon.warning "No overload found for this constructor call" e.epos;
+				gen.gwarning WGencommon "No overload found for this constructor call" e.epos;
 				{ e with eexpr = TNew(cl, tparams, List.map run eparams) })
 				{ e with eexpr = TNew(cl, tparams, List.map run eparams) })
 			| TUnop((Increment | Decrement) as op, flag, ({ eexpr = TArray (arr, idx) } as e2))
 			| TUnop((Increment | Decrement) as op, flag, ({ eexpr = TArray (arr, idx) } as e2))
 				when (match follow arr.etype with TInst({ cl_path = ["cs"],"NativeArray" },_) -> true | _ -> false) ->
 				when (match follow arr.etype with TInst({ cl_path = ["cs"],"NativeArray" },_) -> true | _ -> false) ->

+ 3 - 3
src/codegen/gencommon/closuresToClass.ml

@@ -627,7 +627,7 @@ let configure gen ft =
 		with
 		with
 			| Not_found ->
 			| Not_found ->
 				if in_tparam then begin
 				if in_tparam then begin
-					gen.gcon.warning "This expression may be invalid" e.epos;
+					gen.gwarning WGencommon "This expression may be invalid" e.epos;
 					e
 					e
 				end else
 				end else
 					(* It is possible that we are recursively calling a function
 					(* It is possible that we are recursively calling a function
@@ -642,8 +642,8 @@ let configure gen ft =
 						(Meta.Custom(":tparamcall"), [], e.epos), e
 						(Meta.Custom(":tparamcall"), [], e.epos), e
 					) }
 					) }
 			| Unify_error el ->
 			| Unify_error el ->
-				List.iter (fun el -> gen.gcon.warning (Error.unify_error_msg (print_context()) el) e.epos) el;
-				gen.gcon.warning "This expression may be invalid" e.epos;
+				List.iter (fun el -> gen.gwarning WGencommon (Error.unify_error_msg (print_context()) el) e.epos) el;
+				gen.gwarning WGencommon "This expression may be invalid" e.epos;
 				e
 				e
 		)
 		)
 		(* (handle_anon_func:texpr->tfunc->texpr) (dynamic_func_call:texpr->texpr->texpr list->texpr) *)
 		(* (handle_anon_func:texpr->tfunc->texpr) (dynamic_func_call:texpr->texpr->texpr list->texpr) *)

+ 8 - 1
src/codegen/gencommon/gencommon.ml

@@ -384,6 +384,8 @@ type generator_ctx =
 
 
 	gtools : gen_tools;
 	gtools : gen_tools;
 
 
+	gwarning : Warning.warning -> string -> pos -> unit;
+
 	(*
 	(*
 		module filters run before module filters and they should generate valid haxe syntax as a result.
 		module filters run before module filters and they should generate valid haxe syntax as a result.
 		Module filters shouldn't go through the expressions as it adds an unnecessary burden to the GC,
 		Module filters shouldn't go through the expressions as it adds an unnecessary burden to the GC,
@@ -573,6 +575,11 @@ let new_ctx con =
 
 
 	let rec gen = {
 	let rec gen = {
 		gcon = con;
 		gcon = con;
+		gwarning = (fun w msg p ->
+			let options = Option.map_default (fun c -> Warning.from_meta c.cl_meta) [] gen.gcurrent_class in
+			let options = options @ Option.map_default (fun cf -> Warning.from_meta cf.cf_meta) [] gen.gcurrent_classfield in
+			con.warning w options msg p
+		);
 		gentry_point = get_entry_point con;
 		gentry_point = get_entry_point con;
 		gclasses = {
 		gclasses = {
 			cl_reflect = get_cl (get_type ([], "Reflect"));
 			cl_reflect = get_cl (get_type ([], "Reflect"));
@@ -612,7 +619,7 @@ let new_ctx con =
 
 
 		greal_field_types = Hashtbl.create 0;
 		greal_field_types = Hashtbl.create 0;
 		ghandle_cast = (fun to_t from_t e -> mk_cast to_t e);
 		ghandle_cast = (fun to_t from_t e -> mk_cast to_t e);
-		gon_unsafe_cast = (fun t t2 pos -> (gen.gcon.warning ("Type " ^ (debug_type t2) ^ " is being cast to the unrelated type " ^ (s_type (print_context()) t)) pos));
+		gon_unsafe_cast = (fun t t2 pos -> (gen.gwarning WGencommon ("Type " ^ (debug_type t2) ^ " is being cast to the unrelated type " ^ (s_type (print_context()) t)) pos));
 		gneeds_box = (fun t -> false);
 		gneeds_box = (fun t -> false);
 		gspecial_needs_cast = (fun to_t from_t -> false);
 		gspecial_needs_cast = (fun to_t from_t -> false);
 		gsupported_conversions = Hashtbl.create 0;
 		gsupported_conversions = Hashtbl.create 0;

+ 9 - 8
src/codegen/gencommon/initFunction.ml

@@ -70,7 +70,8 @@ let handle_override_dynfun acc e this field =
 	| None -> e :: acc
 	| None -> e :: acc
 	| Some add_expr -> add_expr :: e :: acc
 	| Some add_expr -> add_expr :: e :: acc
 
 
-let handle_class com cl =
+let handle_class gen cl =
+	let com = gen.gcon in
 	let init = match cl.cl_init with
 	let init = match cl.cl_init with
 		| None -> []
 		| None -> []
 		| Some i -> [i]
 		| Some i -> [i]
@@ -78,10 +79,10 @@ let handle_class com cl =
 	let init = List.fold_left (fun acc cf ->
 	let init = List.fold_left (fun acc cf ->
 		match cf.cf_kind with
 		match cf.cf_kind with
 			| Var v when Meta.has Meta.ReadOnly cf.cf_meta ->
 			| Var v when Meta.has Meta.ReadOnly cf.cf_meta ->
-					if v.v_write <> AccNever && not (Meta.has Meta.CoreApi cl.cl_meta) then com.warning "@:readOnly variable declared without `never` setter modifier" cf.cf_pos;
+					if v.v_write <> AccNever && not (Meta.has Meta.CoreApi cl.cl_meta) then gen.gwarning WGencommon "@:readOnly variable declared without `never` setter modifier" cf.cf_pos;
 					(match cf.cf_expr with
 					(match cf.cf_expr with
-					| None -> com.warning "Uninitialized readonly variable" cf.cf_pos
-					| Some e -> ensure_simple_expr com e);
+					| None -> gen.gwarning WGencommon "Uninitialized readonly variable" cf.cf_pos
+					| Some e -> ensure_simple_expr gen.gcon e);
 					acc
 					acc
 			| Var _
 			| Var _
 			| Method MethDynamic when Type.is_physical_field cf ->
 			| Method MethDynamic when Type.is_physical_field cf ->
@@ -115,7 +116,7 @@ let handle_class com cl =
 	let vars, funs = List.fold_left (fun (acc_vars,acc_funs) cf ->
 	let vars, funs = List.fold_left (fun (acc_vars,acc_funs) cf ->
 		match cf.cf_kind with
 		match cf.cf_kind with
 		| Var v when Meta.has Meta.ReadOnly cf.cf_meta ->
 		| Var v when Meta.has Meta.ReadOnly cf.cf_meta ->
-				if v.v_write <> AccNever && not (Meta.has Meta.CoreApi cl.cl_meta) then com.warning "@:readOnly variable declared without `never` setter modifier" cf.cf_pos;
+				if v.v_write <> AccNever && not (Meta.has Meta.CoreApi cl.cl_meta) then gen.gwarning WGencommon "@:readOnly variable declared without `never` setter modifier" cf.cf_pos;
 				Option.may (ensure_simple_expr com) cf.cf_expr;
 				Option.may (ensure_simple_expr com) cf.cf_expr;
 				(acc_vars,acc_funs)
 				(acc_vars,acc_funs)
 		| Var _
 		| Var _
@@ -224,15 +225,15 @@ let handle_class com cl =
 		List.iter process (ctors :: ctors.cf_overloads)
 		List.iter process (ctors :: ctors.cf_overloads)
 	)
 	)
 
 
-let mod_filter com md =
+let mod_filter gen md =
 	match md with
 	match md with
 	| TClassDecl cl when not (has_class_flag cl CExtern) ->
 	| TClassDecl cl when not (has_class_flag cl CExtern) ->
-		handle_class com cl
+		handle_class gen cl
 	| _ -> ()
 	| _ -> ()
 
 
 let name = "init_funcs"
 let name = "init_funcs"
 let priority = solve_deps name [DBefore OverloadingConstructor.priority]
 let priority = solve_deps name [DBefore OverloadingConstructor.priority]
 
 
 let configure gen =
 let configure gen =
-	let run = (fun md -> mod_filter gen.gcon md; md) in
+	let run = (fun md -> mod_filter gen md; md) in
 	gen.gmodule_filters#add name (PCustom priority) run
 	gen.gmodule_filters#add name (PCustom priority) run

+ 3 - 3
src/codegen/gencommon/unreachableCodeEliminationSynf.ml

@@ -63,11 +63,11 @@ let rec get_constant_expr e =
 		| TParenthesis(e) | TMeta(_,e) -> get_constant_expr e
 		| TParenthesis(e) | TMeta(_,e) -> get_constant_expr e
 		| _ -> None
 		| _ -> None
 
 
-let init com java_mode =
+let init gen java_mode =
 	let should_warn = false in
 	let should_warn = false in
 
 
 	let do_warn =
 	let do_warn =
-		if should_warn then com.warning "Unreachable code" else (fun pos -> ())
+		if should_warn then gen.gwarning WGencommon "Unreachable code" else (fun pos -> ())
 	in
 	in
 
 
 	let return_loop expr kind =
 	let return_loop expr kind =
@@ -208,5 +208,5 @@ let init com java_mode =
 let priority = min_dep -. 100.0
 let priority = min_dep -. 100.0
 
 
 let configure gen java_mode =
 let configure gen java_mode =
-	let run = init gen.gcon java_mode in
+	let run = init gen java_mode in
 	gen.gsyntax_filters#add "unreachable_synf" (PCustom priority) run
 	gen.gsyntax_filters#add "unreachable_synf" (PCustom priority) run

+ 26 - 3
src/compiler/haxe.ml

@@ -391,7 +391,13 @@ let setup_common_context ctx com =
 	Common.raw_define com "true";
 	Common.raw_define com "true";
 	Common.define_value com Define.Dce "std";
 	Common.define_value com Define.Dce "std";
 	com.info <- (fun msg p -> message ctx (CMInfo(msg,p)));
 	com.info <- (fun msg p -> message ctx (CMInfo(msg,p)));
-	com.warning <- (fun msg p -> message ctx (CMWarning(msg,p)));
+	com.warning <- (fun w options msg p ->
+		match Warning.get_mode w (com.warning_options @ options) with
+		| WMEnable ->
+			message ctx (CMWarning(msg,p))
+		| WMDisable ->
+			()
+	);
 	com.error <- error ctx;
 	com.error <- error ctx;
 	let filter_messages = (fun keep_errors predicate -> (List.filter (fun msg ->
 	let filter_messages = (fun keep_errors predicate -> (List.filter (fun msg ->
 		(match msg with
 		(match msg with
@@ -446,9 +452,21 @@ let process_display_configuration ctx =
 	if com.display.dms_kind <> DMNone then begin
 	if com.display.dms_kind <> DMNone then begin
 		com.warning <-
 		com.warning <-
 			if com.display.dms_error_policy = EPCollect then
 			if com.display.dms_error_policy = EPCollect then
-				(fun s p -> add_diagnostics_message com s p DKCompilerError DisplayTypes.DiagnosticsSeverity.Warning)
+				(fun w options s p ->
+					match Warning.get_mode w (com.warning_options @ options) with
+					| WMEnable ->
+						add_diagnostics_message com s p DKCompilerError DisplayTypes.DiagnosticsSeverity.Warning
+					| WMDisable ->
+						()
+				)
 			else
 			else
-				(fun msg p -> message ctx (CMWarning(msg,p)));
+				(fun w options msg p ->
+					match Warning.get_mode w (com.warning_options @ options) with
+					| WMEnable ->
+						message ctx (CMWarning(msg,p))
+					| WMDisable ->
+						()
+				);
 		com.error <- error ctx;
 		com.error <- error ctx;
 	end;
 	end;
 	Lexer.old_format := Common.defined com Define.OldErrorFormat;
 	Lexer.old_format := Common.defined com Define.OldErrorFormat;
@@ -956,6 +974,11 @@ try
 			did_something := true;
 			did_something := true;
 		),"<directory>","set current working directory");
 		),"<directory>","set current working directory");
 		("Compilation",["--haxelib-global"],[], Arg.Unit (fun () -> ()),"","pass --global argument to haxelib");
 		("Compilation",["--haxelib-global"],[], Arg.Unit (fun () -> ()),"","pass --global argument to haxelib");
+		("Compilation",["-w"],[], Arg.String (fun s ->
+			let p = { pfile = "-w " ^ s; pmin = 0; pmax = 0 } in
+			let l = Warning.parse_options s p in
+			com.warning_options <- l :: com.warning_options
+		),"<warning list>","enable or disable specific warnings");
 	] in
 	] in
 	let args_callback cl =
 	let args_callback cl =
 		begin try
 		begin try

+ 5 - 2
src/context/common.ml

@@ -23,6 +23,7 @@ open Type
 open Globals
 open Globals
 open Define
 open Define
 open NativeLibraries
 open NativeLibraries
+open Warning
 
 
 type package_rule =
 type package_rule =
 	| Forbidden
 	| Forbidden
@@ -307,7 +308,8 @@ type context = {
 	mutable package_rules : (string,package_rule) PMap.t;
 	mutable package_rules : (string,package_rule) PMap.t;
 	mutable error : string -> pos -> unit;
 	mutable error : string -> pos -> unit;
 	mutable info : string -> pos -> unit;
 	mutable info : string -> pos -> unit;
-	mutable warning : string -> pos -> unit;
+	mutable warning : warning -> Warning.warning_option list list -> string -> pos -> unit;
+	mutable warning_options : Warning.warning_option list list;
 	mutable get_messages : unit -> compiler_message list;
 	mutable get_messages : unit -> compiler_message list;
 	mutable filter_messages : (compiler_message -> bool) -> unit;
 	mutable filter_messages : (compiler_message -> bool) -> unit;
 	mutable load_extern_type : (string * (path -> pos -> Ast.package option)) list; (* allow finding types which are not in sources *)
 	mutable load_extern_type : (string * (path -> pos -> Ast.package option)) list; (* allow finding types which are not in sources *)
@@ -743,7 +745,8 @@ let create version args =
 		};
 		};
 		get_macros = (fun() -> None);
 		get_macros = (fun() -> None);
 		info = (fun _ _ -> die "" __LOC__);
 		info = (fun _ _ -> die "" __LOC__);
-		warning = (fun _ _ -> die "" __LOC__);
+		warning = (fun _ _ _ -> die "" __LOC__);
+		warning_options = [];
 		error = (fun _ _ -> die "" __LOC__);
 		error = (fun _ _ -> die "" __LOC__);
 		get_messages = (fun() -> []);
 		get_messages = (fun() -> []);
 		filter_messages = (fun _ -> ());
 		filter_messages = (fun _ -> ());

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

@@ -4,6 +4,7 @@ open Common
 open Ast
 open Ast
 
 
 let curclass = ref null_class
 let curclass = ref null_class
+let curfield = ref null_field
 
 
 let warned_positions = Hashtbl.create 0
 let warned_positions = Hashtbl.create 0
 
 
@@ -12,8 +13,11 @@ let warn_deprecation com s p_usage =
 	if not (Hashtbl.mem warned_positions (pkey p_usage)) then begin
 	if not (Hashtbl.mem warned_positions (pkey p_usage)) then begin
 		Hashtbl.add warned_positions (pkey p_usage) (s,p_usage);
 		Hashtbl.add warned_positions (pkey p_usage) (s,p_usage);
 		match com.display.dms_kind with
 		match com.display.dms_kind with
-		| DMDiagnostics _ -> ()
-		| _ -> com.warning s p_usage;
+		| DMDiagnostics _ ->
+			()
+		| _ ->
+			let options = Warning.from_meta (!curclass.cl_meta @ !curfield.cf_meta) in
+			com.warning WDeprecated options s p_usage;
 	end
 	end
 
 
 let print_deprecation_message com meta s p_usage =
 let print_deprecation_message com meta s p_usage =
@@ -81,7 +85,14 @@ let run_on_expr com e =
 	in
 	in
 	expr e
 	expr e
 
 
-let run_on_field com cf = match cf.cf_expr with None -> () | Some e -> run_on_expr com e
+let run_on_field com cf =
+	match cf.cf_expr with
+	| None ->
+		()
+	| Some e ->
+		curfield := cf;
+		run_on_expr com e;
+		curfield := null_field
 
 
 let run com =
 let run com =
 	List.iter (fun t -> match t with
 	List.iter (fun t -> match t with

+ 6 - 2
src/context/typecore.ml

@@ -232,6 +232,10 @@ let display_error ctx msg p = match ctx.com.display.DisplayMode.dms_error_policy
 	| DisplayMode.EPShow | DisplayMode.EPIgnore -> ctx.on_error ctx msg p
 	| DisplayMode.EPShow | DisplayMode.EPIgnore -> ctx.on_error ctx msg p
 	| DisplayMode.EPCollect -> add_diagnostics_message ctx.com msg p DisplayTypes.DiagnosticsKind.DKCompilerError DisplayTypes.DiagnosticsSeverity.Error
 	| DisplayMode.EPCollect -> add_diagnostics_message ctx.com msg p DisplayTypes.DiagnosticsKind.DKCompilerError DisplayTypes.DiagnosticsSeverity.Error
 
 
+let warning ctx w msg p =
+	let options = (Warning.from_meta ctx.curclass.cl_meta) @ (Warning.from_meta ctx.curfield.cf_meta) in
+	ctx.com.warning w options msg p
+
 let make_call ctx e el t p = (!make_call_ref) ctx e el t p
 let make_call ctx e el t p = (!make_call_ref) ctx e el t p
 
 
 let type_expr ?(mode=MGet) ctx e with_type = (!type_expr_ref) ~mode ctx e with_type
 let type_expr ?(mode=MGet) ctx e with_type = (!type_expr_ref) ~mode ctx e with_type
@@ -298,8 +302,8 @@ let add_local ctx k n t p =
 			let v' = PMap.find n ctx.locals in
 			let v' = PMap.find n ctx.locals in
 			(* ignore std lib *)
 			(* ignore std lib *)
 			if not (List.exists (ExtLib.String.starts_with p.pfile) ctx.com.std_path) then begin
 			if not (List.exists (ExtLib.String.starts_with p.pfile) ctx.com.std_path) then begin
-				ctx.com.warning "This variable shadows a previously declared variable" p;
-				ctx.com.warning (compl_msg "Previous variable was here") v'.v_pos
+				warning ctx WVarShadow "This variable shadows a previously declared variable" p;
+				warning ctx WVarShadow (compl_msg "Previous variable was here") v'.v_pos
 			end
 			end
 		with Not_found ->
 		with Not_found ->
 			()
 			()

+ 143 - 0
src/core/warning.ml

@@ -0,0 +1,143 @@
+open Globals
+open Error
+
+type warning =
+	(* general *)
+	| WInternal
+	| WInfo
+	| WUser
+	| WTemp
+	(* subsystem *)
+	| WTyper
+	| WMatcher
+	| WMacro
+	| WAnalyzer
+	| WInliner
+	| WGencommon
+	| WGenerator
+	(* specific *)
+	| WDeprecated
+	| WVarShadow
+	| WExternInit
+	| WStaticInitOrder
+	| WClosureCompare
+	| WVarInit
+	| WReservedTypePath
+
+type warning_range =
+	| WRExact of int
+	| WRRange of int * int
+
+type warning_mode =
+	| WMEnable
+	| WMDisable
+
+type warning_option = {
+	wo_range : warning_range;
+	wo_mode  : warning_mode;
+}
+
+let warning_id = function
+	| WInternal -> 0
+	| WInfo -> 1
+	| WUser -> 2
+	| WTemp -> 3
+	(* subsystem *)
+	| WTyper -> 100
+	| WMacro -> 200
+	| WMatcher -> 300
+	| WInliner -> 400
+	| WAnalyzer -> 500
+	| WGencommon -> 600
+	| WGenerator -> 700
+	(* specific *)
+	| WDeprecated -> 101
+	| WVarInit -> 102
+	| WVarShadow -> 103
+	| WExternInit -> 104
+	| WStaticInitOrder -> 105
+	| WClosureCompare -> 106
+	| WReservedTypePath -> 107
+
+let parse_options s ps lexbuf =
+	let fail msg p =
+		Error.typing_error msg {p with pmin = ps.pmin + p.pmin; pmax = ps.pmin + p.pmax}
+	in
+	let parse_range () = match Lexer.token lexbuf with
+		| Const (Int(i,_)),_ ->
+			WRExact (int_of_string i)
+		| IntInterval i1,_ ->
+			begin match Lexer.token lexbuf with
+			| Const (Int(i2,_)),_ ->
+				WRRange(int_of_string i1,int_of_string i2)
+			| (_,p) ->
+				fail "Expected number" p
+			end
+		| (_,p) ->
+			fail "Expected number" p
+	in
+	let add acc mode range =
+		{ wo_range = range; wo_mode = mode } :: acc
+	in
+	let rec next acc = match Lexer.token lexbuf with
+		| Binop OpAdd,_ ->
+			next (add acc WMEnable (parse_range()))
+		| Binop OpSub,_ ->
+			next (add acc WMDisable (parse_range()))
+		| Eof,_ ->
+			List.rev acc
+		| (_,p) ->
+			fail "Expected + or -" p
+	in
+	next []
+
+let parse_options s ps =
+	let restore = Lexer.reinit ps.pfile in
+	Std.finally (fun () ->
+		restore()
+	) (fun () ->
+		let lexbuf = Sedlexing.Utf8.from_string s in
+		parse_options s ps lexbuf
+	) ()
+
+let from_meta ml =
+	let parse_arg e = match fst e with
+		| Ast.EConst (String(s,_)) ->
+			let p = snd e in
+			parse_options s {p with pmin = p.pmin + 1; pmax = p.pmax - 1} (* pmin is on the quote *)
+		| _ ->
+			Error.typing_error "String expected" (snd e)
+	in
+	let rec loop acc ml = match ml with
+		| (Meta.HaxeWarning,args,_) :: ml ->
+			let acc = List.fold_left (fun acc arg ->
+				(parse_arg arg) :: acc
+			) acc args in
+			loop acc ml
+		| _ :: ml ->
+			loop acc ml
+		| [] ->
+			List.rev acc
+	in
+	loop [] ml
+
+let get_mode w (l : warning_option list list) =
+	let code = warning_id w in
+	let in_range range = match range with
+		| WRExact i -> i = code
+		| WRRange(i1,i2) -> code >= i1 && code <= i2
+	in
+	let rec loop mode l = match l with
+		| [] ->
+			mode
+		| l2 :: l ->
+			let rec loop2 mode l = match l with
+				| [] ->
+					mode
+				| opt :: l ->
+					let mode = if in_range opt.wo_range then opt.wo_mode else mode in
+					loop2 mode l
+			in
+			loop (loop2 mode l2) l
+	in
+	loop WMEnable (* ? *) l

+ 16 - 7
src/filters/filters.ml

@@ -128,7 +128,7 @@ end
 (* -------------------------------------------------------------------------- *)
 (* -------------------------------------------------------------------------- *)
 (* CHECK LOCAL VARS INIT *)
 (* CHECK LOCAL VARS INIT *)
 
 
-let check_local_vars_init com e =
+let check_local_vars_init ctx e =
 	let intersect vl1 vl2 =
 	let intersect vl1 vl2 =
 		PMap.mapi (fun v t -> t && PMap.find v vl2) vl1
 		PMap.mapi (fun v t -> t && PMap.find v vl2) vl1
 	in
 	in
@@ -153,8 +153,8 @@ let check_local_vars_init com e =
 			let init = (try PMap.find v.v_id !vars with Not_found -> true) in
 			let init = (try PMap.find v.v_id !vars with Not_found -> true) in
 			if not init then begin
 			if not init then begin
 				if IntMap.mem v.v_id !outside_vars then
 				if IntMap.mem v.v_id !outside_vars then
-					if v.v_name = "this" then com.warning "this might be used before assigning a value to it" e.epos
-					else com.warning ("Local variable " ^ v.v_name ^ " might be used before being initialized") e.epos
+					if v.v_name = "this" then warning ctx WVarInit "this might be used before assigning a value to it" e.epos
+					else warning ctx WVarInit ("Local variable " ^ v.v_name ^ " might be used before being initialized") e.epos
 				else
 				else
 					if v.v_name = "this" then typing_error "Missing this = value" e.epos
 					if v.v_name = "this" then typing_error "Missing this = value" e.epos
 					else typing_error ("Local variable " ^ v.v_name ^ " used without being initialized") e.epos
 					else typing_error ("Local variable " ^ v.v_name ^ " used without being initialized") e.epos
@@ -706,8 +706,9 @@ let commit_features ctx t =
 
 
 let check_reserved_type_paths ctx t =
 let check_reserved_type_paths ctx t =
 	let check path pos =
 	let check path pos =
-		if List.mem path ctx.com.config.pf_reserved_type_paths then
-			ctx.com.warning ("Type path " ^ (s_type_path path) ^ " is reserved on this target") pos
+		if List.mem path ctx.com.config.pf_reserved_type_paths then begin
+			warning ctx WReservedTypePath ("Type path " ^ (s_type_path path) ^ " is reserved on this target") pos
+		end
 	in
 	in
 	match t with
 	match t with
 	| TClassDecl c when not (has_class_flag c CExtern) -> check c.cl_path c.cl_pos
 	| TClassDecl c when not (has_class_flag c CExtern) -> check c.cl_path c.cl_pos
@@ -806,7 +807,7 @@ let run com tctx main =
 	let filters = [
 	let filters = [
 		"local_statics",LocalStatic.run tctx;
 		"local_statics",LocalStatic.run tctx;
 		"fix_return_dynamic_from_void_function",fix_return_dynamic_from_void_function tctx true;
 		"fix_return_dynamic_from_void_function",fix_return_dynamic_from_void_function tctx true;
-		"check_local_vars_init",check_local_vars_init tctx.com;
+		"check_local_vars_init",check_local_vars_init tctx;
 		"check_abstract_as_value",check_abstract_as_value;
 		"check_abstract_as_value",check_abstract_as_value;
 		"Tre",if defined com Define.AnalyzerOptimize then Tre.run tctx else (fun e -> e);
 		"Tre",if defined com Define.AnalyzerOptimize then Tre.run tctx else (fun e -> e);
 		"reduce_expression",Optimizer.reduce_expression tctx;
 		"reduce_expression",Optimizer.reduce_expression tctx;
@@ -916,7 +917,15 @@ let run com tctx main =
 		| _ -> type_filters
 		| _ -> type_filters
 	in
 	in
 	let t = filter_timer detail_times ["type 3"] in
 	let t = filter_timer detail_times ["type 3"] in
-	List.iter (fun t -> List.iter (fun f -> f tctx t) type_filters) com.types;
+	List.iter (fun t ->
+		begin match t with
+		| TClassDecl c ->
+			tctx.curclass <- c
+		| _ ->
+			()
+		end;
+		List.iter (fun f -> f tctx t) type_filters
+	) com.types;
 	t();
 	t();
 	List.iter (fun f -> f()) (List.rev com.callbacks#get_after_filters);
 	List.iter (fun f -> f()) (List.rev com.callbacks#get_after_filters);
 	com.stage <- CFilteringDone
 	com.stage <- CFilteringDone

+ 6 - 6
src/generators/gencs.ml

@@ -2436,7 +2436,7 @@ let generate con =
 					let args,ret = get_fun cf.cf_type in
 					let args,ret = get_fun cf.cf_type in
 					match args with
 					match args with
 					| [_,_,idx] -> pairs := PMap.add (t_s idx) ( t_s ret, Some cf, None ) !pairs
 					| [_,_,idx] -> pairs := PMap.add (t_s idx) ( t_s ret, Some cf, None ) !pairs
-					| _ -> gen.gcon.warning "The __get function must have exactly one argument (the index)" cf.cf_pos
+					| _ -> gen.gwarning WGenerator "The __get function must have exactly one argument (the index)" cf.cf_pos
 				) (get :: get.cf_overloads)
 				) (get :: get.cf_overloads)
 			with | Not_found -> ());
 			with | Not_found -> ());
 			(try
 			(try
@@ -2447,12 +2447,12 @@ let generate con =
 					| [_,_,idx; _,_,v] -> (try
 					| [_,_,idx; _,_,v] -> (try
 						let vt, g, _ = PMap.find (t_s idx) !pairs in
 						let vt, g, _ = PMap.find (t_s idx) !pairs in
 						let tvt = t_s v in
 						let tvt = t_s v in
-						if vt <> tvt then gen.gcon.warning "The __get function of same index has a different type from this __set function" cf.cf_pos;
+						if vt <> tvt then gen.gwarning WGenerator "The __get function of same index has a different type from this __set function" cf.cf_pos;
 						pairs := PMap.add (t_s idx) (vt, g, Some cf) !pairs
 						pairs := PMap.add (t_s idx) (vt, g, Some cf) !pairs
 					with | Not_found ->
 					with | Not_found ->
 						pairs := PMap.add (t_s idx) (t_s v, None, Some cf) !pairs)
 						pairs := PMap.add (t_s idx) (t_s v, None, Some cf) !pairs)
 					| _ ->
 					| _ ->
-						gen.gcon.warning "The __set function must have exactly two arguments (index, value)" cf.cf_pos
+						gen.gwarning WGenerator "The __set function must have exactly two arguments (index, value)" cf.cf_pos
 				) (set :: set.cf_overloads)
 				) (set :: set.cf_overloads)
 			with | Not_found -> ());
 			with | Not_found -> ());
 			PMap.iter (fun idx (v, get, set) ->
 			PMap.iter (fun idx (v, get, set) ->
@@ -3134,7 +3134,7 @@ let generate con =
 
 
 		add_cast_handler gen;
 		add_cast_handler gen;
 		if not erase_generics then
 		if not erase_generics then
-			RealTypeParams.configure gen (fun e t -> gen.gcon.warning ("Cannot cast to " ^ (debug_type t)) e.epos; mk_cast t e) ifaces (get_cl (get_type gen (["haxe";"lang"], "IGenericObject")))
+			RealTypeParams.configure gen (fun e t -> gen.gwarning WGenerator ("Cannot cast to " ^ (debug_type t)) e.epos; mk_cast t e) ifaces (get_cl (get_type gen (["haxe";"lang"], "IGenericObject")))
 		else
 		else
 			RealTypeParams.RealTypeParamsModf.configure gen (RealTypeParams.RealTypeParamsModf.set_only_hxgeneric gen);
 			RealTypeParams.RealTypeParamsModf.configure gen (RealTypeParams.RealTypeParamsModf.set_only_hxgeneric gen);
 
 
@@ -3464,11 +3464,11 @@ let generate con =
 			let net_lib = List.find (function net_lib -> is_some (net_lib#lookup (["haxe";"lang"], "FieldLookup"))) gen.gcon.native_libs.net_libs in
 			let net_lib = List.find (function net_lib -> is_some (net_lib#lookup (["haxe";"lang"], "FieldLookup"))) gen.gcon.native_libs.net_libs in
 			let name = net_lib#get_name in
 			let name = net_lib#get_name in
 			if not (Common.defined gen.gcon Define.DllImport) then begin
 			if not (Common.defined gen.gcon Define.DllImport) then begin
-				gen.gcon.warning ("The -net-lib with path " ^ name ^ " contains a Haxe-generated assembly. Please define `-D dll_import` to handle Haxe-generated dll import correctly") null_pos;
+				gen.gwarning WGenerator ("The -net-lib with path " ^ name ^ " contains a Haxe-generated assembly. Please define `-D dll_import` to handle Haxe-generated dll import correctly") null_pos;
 				raise Not_found
 				raise Not_found
 			end;
 			end;
 			if not (List.exists (function net_lib -> net_lib#get_name = name) haxe_libs) then
 			if not (List.exists (function net_lib -> net_lib#get_name = name) haxe_libs) then
-				gen.gcon.warning ("The -net-lib with path " ^ name ^ " contains a Haxe-generated assembly, however it wasn't compiled with `-dce no`. Recompilation with `-dce no` is recommended") null_pos;
+				gen.gwarning WGenerator ("The -net-lib with path " ^ name ^ " contains a Haxe-generated assembly, however it wasn't compiled with `-dce no`. Recompilation with `-dce no` is recommended") null_pos;
 			(* it has; in this case, we need to add the used fields on each __init__ *)
 			(* it has; in this case, we need to add the used fields on each __init__ *)
 			add_class_flag flookup_cl CExtern;
 			add_class_flag flookup_cl CExtern;
 			let hashs_by_path = Hashtbl.create !nhash in
 			let hashs_by_path = Hashtbl.create !nhash in

+ 1 - 1
src/generators/genswf.ml

@@ -343,7 +343,7 @@ let build_swf9 com file swc =
 								(match h.Png.png_color with
 								(match h.Png.png_color with
 								| Png.ClTrueColor (Png.TBits8,Png.NoAlpha) ->
 								| Png.ClTrueColor (Png.TBits8,Png.NoAlpha) ->
 									if h.Png.png_width * h.Png.png_height * 4 > Sys.max_string_length then begin
 									if h.Png.png_width * h.Png.png_height * 4 > Sys.max_string_length then begin
-										com.warning "Flash will loose some color information for this file, add alpha channel to preserve it" p;
+										com.warning WGenerator [] "Flash will loose some color information for this file, add alpha channel to preserve it" p;
 										raise Exit;
 										raise Exit;
 									end;
 									end;
 									let data = Extc.unzip (Png.data png) in
 									let data = Extc.unzip (Png.data png) in

+ 5 - 4
src/macro/macroApi.ml

@@ -52,6 +52,7 @@ type 'value compiler_api = {
 	flush_context : (unit -> t) -> t;
 	flush_context : (unit -> t) -> t;
 	display_error : (string -> pos -> unit);
 	display_error : (string -> pos -> unit);
 	with_imports : 'a . import list -> placed_name list list -> (unit -> 'a) -> 'a;
 	with_imports : 'a . import list -> placed_name list list -> (unit -> 'a) -> 'a;
+	warning : Warning.warning -> string -> pos -> unit;
 }
 }
 
 
 
 
@@ -1589,7 +1590,7 @@ let macro_api ccom get_api =
 		"warning", vfun2 (fun msg p ->
 		"warning", vfun2 (fun msg p ->
 			let msg = decode_string msg in
 			let msg = decode_string msg in
 			let p = decode_pos p in
 			let p = decode_pos p in
-			(ccom()).warning msg p;
+			(get_api()).warning WUser msg p;
 			vnull
 			vnull
 		);
 		);
 		"info", vfun2 (fun msg p ->
 		"info", vfun2 (fun msg p ->
@@ -1620,7 +1621,7 @@ let macro_api ccom get_api =
 			let com = ccom() in
 			let com = ccom() in
 			if com.stage <> CInitMacrosStart then begin
 			if com.stage <> CInitMacrosStart then begin
 				let v = if v = vnull then "" else ", " ^ (decode_string v) in
 				let v = if v = vnull then "" else ", " ^ (decode_string v) in
-				com.warning ("Should be used in initialization macros only: haxe.macro.Compiler.define(" ^ s ^ v ^ ")") Globals.null_pos;
+				(get_api()).warning WMacro ("Should be used in initialization macros only: haxe.macro.Compiler.define(" ^ s ^ v ^ ")") Globals.null_pos;
 			end;
 			end;
 			(* TODO: use external_define and external_define_value for #8690 *)
 			(* TODO: use external_define and external_define_value for #8690 *)
 			if v = vnull then
 			if v = vnull then
@@ -1873,7 +1874,7 @@ let macro_api ccom get_api =
 			let com = ccom() in
 			let com = ccom() in
 			let cp = decode_string cp in
 			let cp = decode_string cp in
 			if com.stage <> CInitMacrosStart then
 			if com.stage <> CInitMacrosStart then
-				com.warning ("Should be used in initialization macros only: haxe.macro.Compiler.addClassPath(" ^ cp ^ ")") Globals.null_pos;
+				(get_api()).warning WMacro ("Should be used in initialization macros only: haxe.macro.Compiler.addClassPath(" ^ cp ^ ")") Globals.null_pos;
 			let cp = Path.add_trailing_slash cp in
 			let cp = Path.add_trailing_slash cp in
 			com.class_path <- cp :: com.class_path;
 			com.class_path <- cp :: com.class_path;
 			(match com.get_macros() with
 			(match com.get_macros() with
@@ -1889,7 +1890,7 @@ let macro_api ccom get_api =
 			let file = decode_string file in
 			let file = decode_string file in
 			let com = ccom() in
 			let com = ccom() in
 			if com.stage <> CInitMacrosStart then
 			if com.stage <> CInitMacrosStart then
-				com.warning ("Should be used in initialization macros only: haxe.macro.Compiler.addNativeLib(" ^ file ^ ")") Globals.null_pos;
+				(get_api()).warning WMacro ("Should be used in initialization macros only: haxe.macro.Compiler.addNativeLib(" ^ file ^ ")") Globals.null_pos;
 			NativeLibraryHandler.add_native_lib com file false ();
 			NativeLibraryHandler.add_native_lib com file false ();
 			vnull
 			vnull
 		);
 		);

+ 6 - 4
src/optimization/analyzerConfig.ml

@@ -76,7 +76,7 @@ let get_base_config com =
 		fusion_debug = false;
 		fusion_debug = false;
 	}
 	}
 
 
-let update_config_from_meta com config meta =
+let update_config_from_meta com config ml =
 	List.fold_left (fun config meta -> match meta with
 	List.fold_left (fun config meta -> match meta with
 		| (Meta.Analyzer,el,_) ->
 		| (Meta.Analyzer,el,_) ->
 			List.fold_left (fun config e -> match fst e with
 			List.fold_left (fun config e -> match fst e with
@@ -99,19 +99,21 @@ let update_config_from_meta com config meta =
 						| "fusion_debug" -> { config with fusion_debug = true }
 						| "fusion_debug" -> { config with fusion_debug = true }
 						| "as_var" -> config
 						| "as_var" -> config
 						| _ ->
 						| _ ->
-							com.warning (StringError.string_error s all_flags ("Unrecognized analyzer option: " ^ s)) (pos e);
+							let options = Warning.from_meta ml in
+							com.warning WAnalyzer options (StringError.string_error s all_flags ("Unrecognized analyzer option: " ^ s)) (pos e);
 							config
 							config
 					end
 					end
 				| _ ->
 				| _ ->
 					let s = Ast.Printer.s_expr e in
 					let s = Ast.Printer.s_expr e in
-					com.warning (StringError.string_error s all_flags ("Unrecognized analyzer option: " ^ s)) (pos e);
+					let options = Warning.from_meta ml in
+					com.warning WAnalyzer options (StringError.string_error s all_flags ("Unrecognized analyzer option: " ^ s)) (pos e);
 					config
 					config
 			) config el
 			) config el
 		| (Meta.HasUntyped,_,_) ->
 		| (Meta.HasUntyped,_,_) ->
 			{config with optimize = false}
 			{config with optimize = false}
 		| _ ->
 		| _ ->
 			config
 			config
-	) config meta
+	) config ml
 
 
 let get_class_config com c =
 let get_class_config com c =
 	let config = get_base_config com in
 	let config = get_base_config com in

+ 1 - 1
src/optimization/inlineConstructors.ml

@@ -317,7 +317,7 @@ let inline_constructors ctx original_e =
 						if is_lvalue && iv_is_const fiv then raise Not_found;
 						if is_lvalue && iv_is_const fiv then raise Not_found;
 						if fiv.iv_closed then raise Not_found;
 						if fiv.iv_closed then raise Not_found;
 						if not is_lvalue && fiv.iv_state == IVSUnassigned then (
 						if not is_lvalue && fiv.iv_state == IVSUnassigned then (
-							ctx.com.warning ("Constructor inlining cancelled because of use of uninitialized member field " ^ fname) ethis.epos;
+							warning ctx WInliner ("Constructor inlining cancelled because of use of uninitialized member field " ^ fname) ethis.epos;
 							raise Not_found
 							raise Not_found
 						);
 						);
 						if not captured then cancel_iv fiv efield.epos;
 						if not captured then cancel_iv fiv efield.epos;

+ 9 - 0
src/syntax/lexer.ml

@@ -153,6 +153,15 @@ let init file =
 let save() =
 let save() =
 	!cur
 	!cur
 
 
+let reinit file =
+	let old_file = try Some (Hashtbl.find all_files file) with Not_found -> None in
+	let old_cur = !cur in
+	init file;
+	(fun () ->
+		cur := old_cur;
+		Option.may (Hashtbl.replace all_files file) old_file;
+	)
+
 let restore c =
 let restore c =
 	cur := c
 	cur := c
 
 

+ 1 - 1
src/typing/fields.ml

@@ -222,7 +222,7 @@ let field_access ctx mode f fh e pfield =
 				)
 				)
 			in
 			in
 			if bypass_accessor then (
 			if bypass_accessor then (
-				(match e.eexpr with TLocal _ when Common.defined ctx.com Define.Haxe3Compat -> ctx.com.warning "Field set has changed here in Haxe 4: call setter explicitly to keep Haxe 3.x behaviour" pfield | _ -> ());
+				(match e.eexpr with TLocal _ when Common.defined ctx.com Define.Haxe3Compat -> warning ctx WTemp "Field set has changed here in Haxe 4: call setter explicitly to keep Haxe 3.x behaviour" pfield | _ -> ());
 				if not (is_physical_field f) then begin
 				if not (is_physical_field f) then begin
 					display_error ctx "This field cannot be accessed because it is not a real variable" pfield;
 					display_error ctx "This field cannot be accessed because it is not a real variable" pfield;
 					display_error ctx "Add @:isVar here to enable it" f.cf_pos;
 					display_error ctx "Add @:isVar here to enable it" f.cf_pos;

+ 1 - 1
src/typing/finalization.ml

@@ -113,7 +113,7 @@ let sort_types com modules =
 		match state p with
 		match state p with
 		| Done -> ()
 		| Done -> ()
 		| Generating ->
 		| Generating ->
-			com.warning ("Warning : maybe loop in static generation of " ^ s_type_path p) (t_infos t).mt_pos;
+			com.warning WStaticInitOrder [] ("Warning : maybe loop in static generation of " ^ s_type_path p) (t_infos t).mt_pos;
 		| NotYet ->
 		| NotYet ->
 			Hashtbl.add states p Generating;
 			Hashtbl.add states p Generating;
 			let t = (match t with
 			let t = (match t with

+ 4 - 1
src/typing/macroContext.ml

@@ -413,6 +413,9 @@ let make_macro_api ctx p =
 			in
 			in
 			Std.finally restore run ()
 			Std.finally restore run ()
 		);
 		);
+		MacroApi.warning = (fun w msg p ->
+			warning ctx w msg p
+		);
 	}
 	}
 
 
 let rec init_macro_interp ctx mctx mint =
 let rec init_macro_interp ctx mctx mint =
@@ -650,7 +653,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 		try
 		try
 			unify_raise mctx mret ttype mpos;
 			unify_raise mctx mret ttype mpos;
 			(* TODO: enable this again in the future *)
 			(* TODO: enable this again in the future *)
-			(* ctx.com.warning "Returning Type from @:genericBuild macros is deprecated, consider returning ComplexType instead" p; *)
+			(* warning ctx WDeprecated "Returning Type from @:genericBuild macros is deprecated, consider returning ComplexType instead" p; *)
 		with Error (Unify _,_) ->
 		with Error (Unify _,_) ->
 			let cttype = mk_type_path ~sub:"ComplexType" (["haxe";"macro"],"Expr") in
 			let cttype = mk_type_path ~sub:"ComplexType" (["haxe";"macro"],"Expr") in
 			let ttype = Typeload.load_instance mctx (cttype,p) false in
 			let ttype = Typeload.load_instance mctx (cttype,p) false in

+ 9 - 9
src/typing/matcher.ml

@@ -252,7 +252,7 @@ module Pattern = struct
 								| _ -> ""
 								| _ -> ""
 							in
 							in
 							let fields = List.map (fun (el) -> tpath ^ el) l in
 							let fields = List.map (fun (el) -> tpath ^ el) l in
-							pctx.ctx.com.warning ("Potential typo detected (expected similar values are " ^ (String.concat ", " fields) ^ ")") p
+							warning pctx.ctx WMatcher ("Potential typo detected (expected similar values are " ^ (String.concat ", " fields) ^ ")") p
 					end;
 					end;
 					raise (Bad_pattern "Only inline or read-only (default, never) fields can be used as a pattern")
 					raise (Bad_pattern "Only inline or read-only (default, never) fields can be used as a pattern")
 				| TTypeExpr mt ->
 				| TTypeExpr mt ->
@@ -318,8 +318,8 @@ module Pattern = struct
 						| [] ->
 						| [] ->
 							()
 							()
 							(* if toplevel then
 							(* if toplevel then
-								pctx.ctx.com.warning (Printf.sprintf "`case %s` has been deprecated, use `case var %s` instead" s s) p *)
-						| l -> pctx.ctx.com.warning ("Potential typo detected (expected similar values are " ^ (String.concat ", " l) ^ "). Consider using `var " ^ s ^ "` instead") p
+								warning pctx.ctx (Printf.sprintf "`case %s` has been deprecated, use `case var %s` instead" s s) p *)
+						| l -> warning pctx.ctx WMatcher ("Potential typo detected (expected similar values are " ^ (String.concat ", " l) ^ "). Consider using `var " ^ s ^ "` instead") p
 					end;
 					end;
 					let v = add_local false s p in
 					let v = add_local false s p in
 					PatVariable v
 					PatVariable v
@@ -930,16 +930,16 @@ module Useless = struct
 
 
 	(* Sane part *)
 	(* Sane part *)
 
 
-	let check_case com p (case,bindings,patterns) =
+	let check_case ctx p (case,bindings,patterns) =
 		let p = List.map (fun (_,_,patterns) -> patterns) p in
 		let p = List.map (fun (_,_,patterns) -> patterns) p in
 		match u' p (copy p) (copy p) patterns [] [] with
 		match u' p (copy p) (copy p) patterns [] [] with
-			| False -> com.warning "This case is unused" case.case_pos
-			| Pos p -> com.warning "This pattern is unused" p
+			| False -> Typecore.warning ctx WMatcher "This case is unused" case.case_pos
+			| Pos p -> Typecore.warning ctx WMatcher "This pattern is unused" p
 			| True -> ()
 			| True -> ()
 
 
-	let check com cases =
+	let check ctx cases =
 		ignore(List.fold_left (fun acc (case,bindings,patterns) ->
 		ignore(List.fold_left (fun acc (case,bindings,patterns) ->
-			check_case com acc (case,bindings,patterns);
+			check_case ctx acc (case,bindings,patterns);
 			if case.case_guard = None then acc @ [case,bindings,patterns] else acc
 			if case.case_guard = None then acc @ [case,bindings,patterns] else acc
 		) [] cases)
 		) [] cases)
 end
 end
@@ -1279,7 +1279,7 @@ module Compile = struct
 			switch mctx subject [] dt_fail
 			switch mctx subject [] dt_fail
 		| _ ->
 		| _ ->
 			let dt = compile mctx subjects cases in
 			let dt = compile mctx subjects cases in
-			Useless.check mctx.ctx.com cases;
+			Useless.check mctx.ctx cases;
 			match vars with
 			match vars with
 				| [] -> dt
 				| [] -> dt
 				| _ -> bind mctx vars dt
 				| _ -> bind mctx vars dt

+ 1 - 1
src/typing/operators.ml

@@ -332,7 +332,7 @@ let make_binop ctx op e1 e2 is_assign_op with_type p =
 		| TConst TNull , _ | _ , TConst TNull -> ()
 		| TConst TNull , _ | _ , TConst TNull -> ()
 		| _ ->
 		| _ ->
 			match follow e1.etype, follow e2.etype with
 			match follow e1.etype, follow e2.etype with
-			| TFun _ , _ | _, TFun _ -> ctx.com.warning "Comparison of function values is unspecified on this target, use Reflect.compareMethods instead" p
+			| TFun _ , _ | _, TFun _ -> warning ctx WClosureCompare "Comparison of function values is unspecified on this target, use Reflect.compareMethods instead" p
 			| _ -> ()
 			| _ -> ()
 		end;
 		end;
 		mk_op e1 e2 ctx.t.tbool
 		mk_op e1 e2 ctx.t.tbool

+ 2 - 2
src/typing/typeload.ml

@@ -529,7 +529,7 @@ and load_complex_type' ctx allow_display (t,p) =
 				| None -> typing_error ("Explicit type required for field " ^ n) p
 				| None -> typing_error ("Explicit type required for field " ^ n) p
 				| Some t -> load_complex_type ctx allow_display t
 				| Some t -> load_complex_type ctx allow_display t
 			in
 			in
-			if n = "new" then ctx.com.warning "Structures with new are deprecated, use haxe.Constraints.Constructible instead" p;
+			if n = "new" then warning ctx WDeprecated "Structures with new are deprecated, use haxe.Constraints.Constructible instead" p;
 			let no_expr = function
 			let no_expr = function
 				| None -> ()
 				| None -> ()
 				| Some (_,p) -> typing_error "Expression not allowed here" p
 				| Some (_,p) -> typing_error "Expression not allowed here" p
@@ -545,7 +545,7 @@ and load_complex_type' ctx allow_display (t,p) =
 				| APrivate ->
 				| APrivate ->
 					let p = pos a in
 					let p = pos a in
 					if Filename.basename p.pfile <> "NativeIterable.hx" then (* Terrible workaround for #7436 *)
 					if Filename.basename p.pfile <> "NativeIterable.hx" then (* Terrible workaround for #7436 *)
-						ctx.com.warning "private structure fields are deprecated" p;
+						warning ctx WDeprecated "private structure fields are deprecated" p;
 					pub := false;
 					pub := false;
 				| ADynamic when (match f.cff_kind with FFun _ -> true | _ -> false) -> dyn := true
 				| ADynamic when (match f.cff_kind with FFun _ -> true | _ -> false) -> dyn := true
 				| AFinal -> final := true
 				| AFinal -> final := true

+ 7 - 7
src/typing/typeloadFields.ml

@@ -126,7 +126,7 @@ let dump_field_context fctx =
 let is_java_native_function ctx meta pos = try
 let is_java_native_function ctx meta pos = try
 	match Meta.get Meta.Native meta with
 	match Meta.get Meta.Native meta with
 		| (Meta.Native,[],_) ->
 		| (Meta.Native,[],_) ->
-			ctx.com.warning "@:native metadata for jni functions is deprecated. Use @:java.native instead." pos;
+			warning ctx WDeprecated "@:native metadata for jni functions is deprecated. Use @:java.native instead." pos;
 			true
 			true
 		| _ -> false
 		| _ -> false
 	with | Not_found -> Meta.has Meta.NativeJni meta
 	with | Not_found -> Meta.has Meta.NativeJni meta
@@ -497,7 +497,7 @@ let build_module_def ctx mt meta fvars context_init fbuild =
 		| TClassDecl ({cl_kind = KAbstractImpl a} as c) when a.a_enum ->
 		| TClassDecl ({cl_kind = KAbstractImpl a} as c) when a.a_enum ->
 			Some (fun () ->
 			Some (fun () ->
 				(* if p <> null_pos && not (Define.is_haxe3_compat ctx.com.defines) then
 				(* if p <> null_pos && not (Define.is_haxe3_compat ctx.com.defines) then
-					ctx.com.warning "`@:enum abstract` is deprecated in favor of `enum abstract`" p; *)
+					warning ctx WDeprecated "`@:enum abstract` is deprecated in favor of `enum abstract`" p; *)
 				context_init#run;
 				context_init#run;
 				let e = build_enum_abstract ctx c a (fvars()) a.a_name_pos in
 				let e = build_enum_abstract ctx c a (fvars()) a.a_name_pos in
 				fbuild e;
 				fbuild e;
@@ -591,10 +591,10 @@ let create_field_context (ctx,cctx) c cff =
 		| Meta.Final ->
 		| Meta.Final ->
 			is_final := true;
 			is_final := true;
 			(* if p <> null_pos && not (Define.is_haxe3_compat ctx.com.defines) then
 			(* if p <> null_pos && not (Define.is_haxe3_compat ctx.com.defines) then
-				ctx.com.warning "`@:final` is deprecated in favor of `final`" p; *)
+				warning ctx WDeprecated "`@:final` is deprecated in favor of `final`" p; *)
 		| Meta.Extern ->
 		| Meta.Extern ->
 			(* if not (Define.is_haxe3_compat ctx.com.defines) then
 			(* if not (Define.is_haxe3_compat ctx.com.defines) then
-				ctx.com.warning "`@:extern` on fields is deprecated in favor of `extern`" (pos cff.cff_name); *)
+				warning ctx WDeprecated "`@:extern` on fields is deprecated in favor of `extern`" (pos cff.cff_name); *)
 			is_extern := true;
 			is_extern := true;
 		| _ ->
 		| _ ->
 			()
 			()
@@ -937,7 +937,7 @@ module TypeBinding = struct
 			begin match ctx.com.platform with
 			begin match ctx.com.platform with
 				| Java when is_java_native_function ctx cf.cf_meta cf.cf_pos ->
 				| Java when is_java_native_function ctx cf.cf_meta cf.cf_pos ->
 					if e <> None then
 					if e <> None then
-						ctx.com.warning "@:java.native function definitions shouldn't include an expression. This behaviour is deprecated." cf.cf_pos;
+						warning ctx WDeprecated "@:java.native function definitions shouldn't include an expression. This behaviour is deprecated." cf.cf_pos;
 					cf.cf_expr <- None;
 					cf.cf_expr <- None;
 					cf.cf_type <- t
 					cf.cf_type <- t
 				| _ ->
 				| _ ->
@@ -949,7 +949,7 @@ module TypeBinding = struct
 					end;
 					end;
 					(* Disabled for now, see https://github.com/HaxeFoundation/haxe/issues/3033 *)
 					(* Disabled for now, see https://github.com/HaxeFoundation/haxe/issues/3033 *)
 					(* List.iter (fun (v,_) ->
 					(* List.iter (fun (v,_) ->
-						if v.v_name <> "_" && has_mono v.v_type then ctx.com.warning "Uninferred function argument, please add a type-hint" v.v_pos;
+						if v.v_name <> "_" && has_mono v.v_type then warning ctx WTemp "Uninferred function argument, please add a type-hint" v.v_pos;
 					) fargs; *)
 					) fargs; *)
 					let tf = {
 					let tf = {
 						tf_args = args#for_expr;
 						tf_args = args#for_expr;
@@ -1403,7 +1403,7 @@ let create_method (ctx,cctx,fctx) c f fd p =
 			delay ctx PTypeField (fun () -> args#verify_extern);
 			delay ctx PTypeField (fun () -> args#verify_extern);
 		if fd.f_expr <> None then begin
 		if fd.f_expr <> None then begin
 			if fctx.is_abstract then display_error ctx "Abstract methods may not have an expression" p
 			if fctx.is_abstract then display_error ctx "Abstract methods may not have an expression" p
-			else if not (fctx.is_inline || fctx.is_macro) then ctx.com.warning "Extern non-inline function may not have an expression" p;
+			else if not (fctx.is_inline || fctx.is_macro) then warning ctx WExternInit "Extern non-inline function may not have an expression" p;
 		end;
 		end;
 	end;
 	end;
 	cf
 	cf

+ 0 - 2
src/typing/typeloadModule.ml

@@ -502,8 +502,6 @@ let init_module_type ctx context_init (decl,p) =
 		List.iter (fun (m,_,p) ->
 		List.iter (fun (m,_,p) ->
 			if m = Meta.Final then begin
 			if m = Meta.Final then begin
 				add_class_flag c CFinal;
 				add_class_flag c CFinal;
-				(* if p <> null_pos && not (Define.is_haxe3_compat ctx.com.defines) then
-					ctx.com.warning "`@:final class` is deprecated in favor of `final class`" p; *)
 			end
 			end
 		) d.d_meta;
 		) d.d_meta;
 		let prev_build_count = ref (!build_count - 1) in
 		let prev_build_count = ref (!build_count - 1) in

+ 2 - 2
src/typing/typer.ml

@@ -1664,11 +1664,11 @@ and type_call ?(mode=MGet) ctx e el (with_type:WithType.t) inline p =
 	| (EConst (Ident "$type"),_) , [e] ->
 	| (EConst (Ident "$type"),_) , [e] ->
 		begin match fst e with
 		begin match fst e with
 		| EConst (Ident "_") ->
 		| EConst (Ident "_") ->
-			ctx.com.warning (WithType.to_string with_type) p;
+			warning ctx WInfo (WithType.to_string with_type) p;
 			mk (TConst TNull) t_dynamic p
 			mk (TConst TNull) t_dynamic p
 		| _ ->
 		| _ ->
 			let e = type_expr ctx e WithType.value in
 			let e = type_expr ctx e WithType.value in
-			ctx.com.warning (s_type (print_context()) e.etype) e.epos;
+			warning ctx WInfo (s_type (print_context()) e.etype) e.epos;
 			let e = Diagnostics.secure_generated_code ctx e in
 			let e = Diagnostics.secure_generated_code ctx e in
 			e
 			e
 		end
 		end

+ 1 - 0
tests/unit/compile-each.hxml

@@ -10,3 +10,4 @@
 -lib utest:git:https://github.com/haxe-utest/utest#559b24c9a36533281ba7a2eed8aab83ed6b872b4
 -lib utest:git:https://github.com/haxe-utest/utest#559b24c9a36533281ba7a2eed8aab83ed6b872b4
 -D analyzer-optimize
 -D analyzer-optimize
 -D analyzer-user-var-fusion
 -D analyzer-user-var-fusion
+-w -400-102

+ 18 - 16
tests/unit/src/unit/TestGADT.hx

@@ -6,18 +6,18 @@ enum Constant<T> {
 	CFloat(s:String):Constant<Float>;
 	CFloat(s:String):Constant<Float>;
 }
 }
 
 
-enum Binop<S,T> {
-	OpAdd:Binop<Float,Float>;
-	OpEq:Binop<S,Bool>;
+enum Binop<S, T> {
+	OpAdd:Binop<Float, Float>;
+	OpEq:Binop<S, Bool>;
 }
 }
 
 
 enum Expr<T> {
 enum Expr<T> {
 	EConst(c:Constant<T>):Expr<T>;
 	EConst(c:Constant<T>):Expr<T>;
-	EBinop<C>(op:Binop<C,T>, e1:Expr<C>, e2:Expr<C>):Expr<T>;
+	EBinop<C>
+	(op : Binop<C, T>, e1 : Expr<C>, e2 : Expr<C>) : Expr<T>;
 }
 }
 
 
 class TestGADT extends Test {
 class TestGADT extends Test {
-
 	function testBasic() {
 	function testBasic() {
 		var ti = 1.22;
 		var ti = 1.22;
 		var tb = false;
 		var tb = false;
@@ -26,22 +26,23 @@ class TestGADT extends Test {
 		var e2 = EConst(CFloat("8"));
 		var e2 = EConst(CFloat("8"));
 		var e3 = EConst(CFloat("12"));
 		var e3 = EConst(CFloat("12"));
 
 
-		var eadd = EBinop(OpAdd,e1,e2);
+		var eadd = EBinop(OpAdd, e1, e2);
 		var s = eval(eadd);
 		var s = eval(eadd);
 		HelperMacros.typedAs(s, ti);
 		HelperMacros.typedAs(s, ti);
-		eq(s,20);
+		eq(s, 20);
 
 
-		var eeq = EBinop(OpEq,e1,e2);
+		var eeq = EBinop(OpEq, e1, e2);
 		var s = eval(eeq);
 		var s = eval(eeq);
 		HelperMacros.typedAs(s, tb);
 		HelperMacros.typedAs(s, tb);
-		eq(s,false);
+		eq(s, false);
 
 
-		var eeq = EBinop(OpEq,e1,e3);
+		var eeq = EBinop(OpEq, e1, e3);
 		var s = eval(eeq);
 		var s = eval(eeq);
 		HelperMacros.typedAs(s, tb);
 		HelperMacros.typedAs(s, tb);
-		eq(s,true);
+		eq(s, true);
 	}
 	}
 
 
+	@:haxe.warning("-600")
 	static function evalConst<T>(c:Constant<T>):T {
 	static function evalConst<T>(c:Constant<T>):T {
 		return switch (c) {
 		return switch (c) {
 			case CString(s): s;
 			case CString(s): s;
@@ -50,17 +51,18 @@ class TestGADT extends Test {
 		}
 		}
 	}
 	}
 
 
-	static function evalBinop<T,C>(op:Binop<C,T>, e1:Expr<C>, e2:Expr<C>):T {
-		return switch(op) {
+	@:haxe.warning("-600")
+	static function evalBinop<T, C>(op:Binop<C, T>, e1:Expr<C>, e2:Expr<C>):T {
+		return switch (op) {
 			case OpAdd: eval(e1) + eval(e2);
 			case OpAdd: eval(e1) + eval(e2);
 			case OpEq: eval(e1) == eval(e2);
 			case OpEq: eval(e1) == eval(e2);
 		}
 		}
 	}
 	}
 
 
 	static function eval<T>(e:Expr<T>):T {
 	static function eval<T>(e:Expr<T>):T {
-		return switch(e) {
+		return switch (e) {
 			case EConst(c): evalConst(c);
 			case EConst(c): evalConst(c);
-			case EBinop(_op,_e1,_e2): evalBinop(_op,_e1,_e2); // TODO: this generates some unused variable warnings in macro context (issue #1675?)
+			case EBinop(_op, _e1, _e2): evalBinop(_op, _e1, _e2); // TODO: this generates some unused variable warnings in macro context (issue #1675?)
 		}
 		}
 	}
 	}
-}
+}

+ 26 - 25
tests/unit/src/unit/issues/Issue10073.hx

@@ -1,41 +1,42 @@
 package unit.issues;
 package unit.issues;
 
 
 private abstract Foo(Array<Int>) from Array<Int> {
 private abstract Foo(Array<Int>) from Array<Int> {
-  @:op([])
-  function get(index: Int): Int;
+	@:op([])
+	function get(index:Int):Int;
 
 
-  @:op([])
-  function set(index: Int, value: Int): Void;
+	@:op([])
+	function set(index:Int, value:Int):Void;
 }
 }
 
 
 #if eval
 #if eval
 abstract Bar(Int) from Int {
 abstract Bar(Int) from Int {
-  @:op(_ + _)
-  extern function add(other: Int): Int;
+	@:op(_ + _)
+	extern function add(other:Int):Int;
 
 
-  @:op([])
-  extern function get(index: Int): Int;
+	@:op([])
+	extern function get(index:Int):Int;
 
 
-  @:native('add')
-  function doAdd(other: Int): Int
-    return 39;
+	@:native('add')
+	function doAdd(other:Int):Int
+		return 39;
 
 
-  @:native('get')
-  function doGet(index: Int)
-    return (this + index) * 2;
+	@:native('get')
+	function doGet(index:Int)
+		return (this + index) * 2;
 }
 }
 #end
 #end
 
 
+@:haxe.warning("-600")
 class Issue10073 extends Test {
 class Issue10073 extends Test {
-  function test() {
-    var foo: Foo = [];
-    foo[0] = 3;
-    eq(3, foo[0]);
-
-    #if eval
-    var bar: Bar = 71;
-    eq(39, bar + 1);
-    eq(144, bar[1]);
-    #end
-  }
+	function test() {
+		var foo:Foo = [];
+		foo[0] = 3;
+		eq(3, foo[0]);
+
+		#if eval
+		var bar:Bar = 71;
+		eq(39, bar + 1);
+		eq(144, bar[1]);
+		#end
+	}
 }
 }

+ 2 - 2
tests/unit/src/unit/issues/Issue2778.hx

@@ -6,7 +6,6 @@ enum E<T> {
 }
 }
 
 
 class Issue2778 extends Test {
 class Issue2778 extends Test {
-
 	function test() {
 	function test() {
 		eq(true, sameType(BoolLit(true), BoolLit(true)));
 		eq(true, sameType(BoolLit(true), BoolLit(true)));
 		eq(false, sameType(BoolLit(false), BoolLit(true)));
 		eq(false, sameType(BoolLit(false), BoolLit(true)));
@@ -17,10 +16,11 @@ class Issue2778 extends Test {
 		t(unit.HelperMacros.typeError(sameType(BoolLit(true), IntLit(1))));
 		t(unit.HelperMacros.typeError(sameType(BoolLit(true), IntLit(1))));
 	}
 	}
 
 
+	@:haxe.warning("-600")
 	static function sameType<S>(o1:E<S>, o2:E<S>):S {
 	static function sameType<S>(o1:E<S>, o2:E<S>):S {
 		return switch [o1, o2] {
 		return switch [o1, o2] {
 			case [BoolLit(b1), BoolLit(b2)]: b1 && b2;
 			case [BoolLit(b1), BoolLit(b2)]: b1 && b2;
 			case [IntLit(i1), IntLit(i2)]: i1 + i2;
 			case [IntLit(i1), IntLit(i2)]: i1 + i2;
 		}
 		}
 	}
 	}
-}
+}

+ 13 - 11
tests/unit/src/unit/issues/Issue4578.hx

@@ -1,33 +1,35 @@
 package unit.issues;
 package unit.issues;
 
 
 private class TList {}
 private class TList {}
-private class TCons<U,V:TList> extends TList {}
+private class TCons<U, V:TList> extends TList {}
 private class TNil extends TList {}
 private class TNil extends TList {}
 
 
 private enum Stack<L:TList> {
 private enum Stack<L:TList> {
-	Nil: Stack<TNil>;
-	Cons<X,L:TList>(x: X, xs: Stack<L>): Stack<TCons<X,L>>;
+	Nil:Stack<TNil>;
+	Cons<X, L:TList>
+	(x : X, xs : Stack<L>) : Stack<TCons<X, L>>;
 }
 }
 
 
-private interface Instr<L1:TList,L2:TList> {
-	function denote(s: Stack<L1>): Stack<L2>;
+private interface Instr<L1:TList, L2:TList> {
+	function denote(s:Stack<L1>):Stack<L2>;
 }
 }
 
 
-private class IUnOp<X,Y,S:TList> implements Instr<TCons<X,S>,TCons<Y,S>> {
-	var f: X->Y;
+private class IUnOp<X, Y, S:TList> implements Instr<TCons<X, S>, TCons<Y, S>> {
+	var f:X->Y;
 
 
 	public function new(f) {
 	public function new(f) {
 		this.f = f;
 		this.f = f;
 	}
 	}
 
 
-	public function denote(s: Stack<TCons<X,S>>): Stack<TCons<Y,S>> {
-		return switch(s) {
+	public function denote(s:Stack<TCons<X, S>>):Stack<TCons<Y, S>> {
+		return switch (s) {
 			case Cons(x, s):
 			case Cons(x, s):
 				Cons(f(x), s);
 				Cons(f(x), s);
 		}
 		}
 	}
 	}
 }
 }
 
 
+@:haxe.warning("-600")
 class Issue4578 extends Test {
 class Issue4578 extends Test {
 	function test() {
 	function test() {
 		var i = new IUnOp(function(x) return x * 2);
 		var i = new IUnOp(function(x) return x * 2);
@@ -35,9 +37,9 @@ class Issue4578 extends Test {
 		eq(20, getHead(v));
 		eq(20, getHead(v));
 	}
 	}
 
 
-	static function getHead<S, T:TList>(s:Stack<TCons<S,T>>):S {
+	static function getHead<S, T:TList>(s:Stack<TCons<S, T>>):S {
 		return switch (s) {
 		return switch (s) {
 			case Cons(x, _): x;
 			case Cons(x, _): x;
 		}
 		}
 	}
 	}
-}
+}

+ 5 - 5
tests/unit/src/unit/issues/Issue6561.hx

@@ -4,16 +4,16 @@ private enum Log<A> {
 	NotLog(msg:String):Log<String>;
 	NotLog(msg:String):Log<String>;
 }
 }
 
 
-
 class Issue6561 extends unit.Test {
 class Issue6561 extends unit.Test {
 	function test() {
 	function test() {
 		eq("hello", apply(NotLog("hello")));
 		eq("hello", apply(NotLog("hello")));
 	}
 	}
 
 
-  	static function apply<A>(f:Log<A>):A {
+	@:haxe.warning("-600")
+	static function apply<A>(f:Log<A>):A {
 		return switch f {
 		return switch f {
 			case NotLog(msg):
 			case NotLog(msg):
-      			msg;
+				msg;
 		}
 		}
-  	}
-}
+	}
+}