Explorar o código

add -D deprecation-warnings (see #1346)

Simon Krajewski %!s(int64=11) %!d(string=hai) anos
pai
achega
29a0405419
Modificáronse 2 ficheiros con 71 adicións e 0 borrados
  1. 2 0
      common.ml
  2. 69 0
      filters.ml

+ 2 - 0
common.ml

@@ -170,6 +170,7 @@ module Define = struct
 		| Dce
 		| Dce
 		| DceDebug
 		| DceDebug
 		| Debug
 		| Debug
+		| DeprecationWarnings
 		| Display
 		| Display
 		| DllExport
 		| DllExport
 		| DllImport
 		| DllImport
@@ -241,6 +242,7 @@ module Define = struct
 		| Dce -> ("dce","The current DCE mode")
 		| Dce -> ("dce","The current DCE mode")
 		| DceDebug -> ("dce_debug","Show DCE log")
 		| DceDebug -> ("dce_debug","Show DCE log")
 		| Debug -> ("debug","Activated when compiling with -debug")
 		| Debug -> ("debug","Activated when compiling with -debug")
+		| DeprecationWarnings -> ("deprecation-warnings","Warn if fields annotated with @:deprecated are used")
 		| Display -> ("display","Activated during completion")
 		| Display -> ("display","Activated during completion")
 		| DllExport -> ("dll_export", "GenCPP experimental linking")
 		| DllExport -> ("dll_export", "GenCPP experimental linking")
 		| DllImport -> ("dll_import", "GenCPP experimental linking")
 		| DllImport -> ("dll_import", "GenCPP experimental linking")

+ 69 - 0
filters.ml

@@ -807,6 +807,72 @@ let rename_local_vars com e =
 	loop e;
 	loop e;
 	e
 	e
 
 
+let check_deprecation com =
+	let curclass = ref null_class in
+	let definition_positions = (Common.defined_value_safe com Define.DeprecationWarnings) = "def-pos" in
+	let warned_positions = Hashtbl.create 0 in
+	let get_deprecation_message meta s p_usage p_definition =
+		try
+			let s = match Meta.get Meta.Deprecated meta with
+				| _,[EConst(String s),_],_ -> s
+				| _ -> Printf.sprintf "Usage of this %s is deprecated" s
+			in
+			if not (Hashtbl.mem warned_positions p_usage) then begin
+				Hashtbl.replace warned_positions p_usage true;
+				com.warning s p_usage;
+			end;
+			if definition_positions then com.warning "Defined here" p_definition
+		with Not_found ->
+			()
+	in
+	let check_cf cf p = get_deprecation_message cf.cf_meta "field" p cf.cf_pos in
+	let check_class c p = if c != !curclass then get_deprecation_message c.cl_meta "class" p c.cl_pos in
+	let check_enum en p = get_deprecation_message en.e_meta "enum" p en.e_pos in
+	let check_ef ef p = get_deprecation_message ef.ef_meta "enum field" p ef.ef_pos in
+	let check_module_type mt p = match mt with
+		| TClassDecl c -> check_class c p
+		| TEnumDecl en -> check_enum en p
+		| _ -> ()
+	in
+	let rec expr e = match e.eexpr with
+		| TField(e1,fa) ->
+			expr e1;
+			begin match fa with
+				| FStatic(c,cf) | FInstance(c,cf) ->
+					check_class c e.epos;
+					check_cf cf e.epos
+				| FAnon cf ->
+					check_cf cf e.epos
+				| FClosure(co,cf) ->
+					(match co with None -> () | Some c -> check_class c e.epos);
+					check_cf cf e.epos
+				| FEnum(en,ef) ->
+					check_enum en e.epos;
+					check_ef ef e.epos;
+				| _ ->
+					()
+			end
+		| TNew(c,_,el) ->
+			List.iter expr el;
+			check_class c e.epos;
+			(match c.cl_constructor with None -> () | Some cf -> check_cf cf e.epos)
+		| TTypeExpr(mt) | TCast(_,Some mt) ->
+			check_module_type mt e.epos
+		| _ ->
+			Type.iter expr e
+	in
+	List.iter (fun t -> match t with
+		| TClassDecl c ->
+			curclass := c;
+			let field cf = match cf.cf_expr with None -> () | Some e -> expr e in
+			(match c.cl_constructor with None -> () | Some cf -> field cf);
+			(match c.cl_init with None -> () | Some e -> expr e);
+			List.iter field c.cl_ordered_statics;
+			List.iter field c.cl_ordered_fields;
+		| _ ->
+			()
+	) com.types
+
 (* PASS 1 end *)
 (* PASS 1 end *)
 
 
 (* Saves a class state so it can be restored later, e.g. after DCE or native path rewrite *)
 (* Saves a class state so it can be restored later, e.g. after DCE or native path rewrite *)
@@ -1071,6 +1137,9 @@ let post_process_end() =
 let run com tctx main =
 let run com tctx main =
 	if com.display = DMUsage then
 	if com.display = DMUsage then
 		Codegen.detect_usage com;
 		Codegen.detect_usage com;
+	if Common.defined com Define.DeprecationWarnings then
+		check_deprecation com;
+
 	(* PASS 1: general expression filters *)
 	(* PASS 1: general expression filters *)
  	let filters = [
  	let filters = [
 		Codegen.Abstract.handle_abstract_casts tctx;
 		Codegen.Abstract.handle_abstract_casts tctx;