Browse Source

enforce the error when 'null' is used for a basic type on all static platforms

Nicolas Cannasse 13 years ago
parent
commit
f5289d5e1e
6 changed files with 27 additions and 18 deletions
  1. 5 0
      common.ml
  2. 5 1
      doc/ImportAll.hx
  3. 1 4
      genswf9.ml
  4. 8 1
      optimizer.ml
  5. 6 6
      type.ml
  6. 2 6
      typer.ml

+ 5 - 0
common.ml

@@ -224,6 +224,11 @@ let error msg p = raise (Abort (msg,p))
 
 
 let platform ctx p = ctx.platform = p
 let platform ctx p = ctx.platform = p
 
 
+let is_static_platform ctx =
+	match ctx.platform with
+	| Cpp | Flash | Cs | Java -> true
+	| _ -> false
+
 let add_filter ctx f =
 let add_filter ctx f =
 	ctx.filters <- f :: ctx.filters
 	ctx.filters <- f :: ctx.filters
 
 

+ 5 - 1
doc/ImportAll.hx

@@ -48,7 +48,11 @@ class ImportAll {
 			return;
 			return;
 		case "sys":
 		case "sys":
 			if( !Context.defined("neko") && !Context.defined("php") && !Context.defined("cpp") ) return;
 			if( !Context.defined("neko") && !Context.defined("php") && !Context.defined("cpp") ) return;
-		case "tools", "jvm", "cs":
+		case "java":
+			if( !Context.defined("java") ) return;
+		case "cs":
+			if( !Context.defined("cs") ) return;
+		case "tools":
 			return;
 			return;
 		}
 		}
 		for( p in Context.getClassPath() ) {
 		for( p in Context.getClassPath() ) {

+ 1 - 4
genswf9.ml

@@ -566,10 +566,7 @@ let gen_constant ctx c t p =
 		write ctx (if b then HTrue else HFalse);
 		write ctx (if b then HTrue else HFalse);
 	| TNull ->
 	| TNull ->
 		write ctx HNull;
 		write ctx HNull;
-		(match classify ctx t with
-		| KInt | KBool | KUInt | KFloat ->
-			error ("In Flash9, null can't be used as basic type " ^ s_type (print_context()) t) p
-		| x -> coerce ctx x)
+		coerce ctx (classify ctx t)
 	| TThis ->
 	| TThis ->
 		write ctx HThis
 		write ctx HThis
 	| TSuper ->
 	| TSuper ->

+ 8 - 1
optimizer.ml

@@ -125,7 +125,7 @@ let rec type_inline ctx cf f ethis params tret p force =
 				if we pass a Null<T> var to an inlined method that needs a T.
 				if we pass a Null<T> var to an inlined method that needs a T.
 				we need to force a local var to be created on some platforms.
 				we need to force a local var to be created on some platforms.
 			*)
 			*)
-			if is_nullable v.v_type && is_null e.etype && (match ctx.com.platform with Flash | Cpp -> true | _ -> false) then (local v).i_write <- true;
+			if is_static_platform ctx.com && not (is_nullable v.v_type) && is_null e.etype then (local v).i_write <- true;
 			(match e.eexpr, opt with
 			(match e.eexpr, opt with
 			| TConst TNull , Some c -> mk (TConst c) v.v_type e.epos
 			| TConst TNull , Some c -> mk (TConst c) v.v_type e.epos
 			| _ -> e) :: loop pl al
 			| _ -> e) :: loop pl al
@@ -514,6 +514,13 @@ let sanitize_expr com e =
 		| _ -> false
 		| _ -> false
 	in
 	in
 	match e.eexpr with
 	match e.eexpr with
+	| TConst TNull ->
+		if is_static_platform com && not (is_nullable e.etype) then 
+			(match follow e.etype with
+			| TMono _ -> () (* in these cases the null will cast to default value *)
+			| TFun _ -> () (* this is a bit a particular case, maybe flash-specific actually *)
+			| _ -> error ("On static platforms, null can't be used as basic type " ^ s_type (print_context()) e.etype) e.epos);
+		e
 	| TBinop (op,e1,e2) ->
 	| TBinop (op,e1,e2) ->
 		let swap op1 op2 =
 		let swap op1 op2 =
 			let p1, left1 = standard_precedence op1 in
 			let p1, left1 = standard_precedence op1 in

+ 6 - 6
type.ml

@@ -525,27 +525,27 @@ let rec follow t =
 
 
 let rec is_nullable = function
 let rec is_nullable = function
 	| TMono r ->
 	| TMono r ->
-		(match !r with None -> true | Some t -> is_nullable t)
+		(match !r with None -> false | Some t -> is_nullable t)
 	| TType ({ t_path = ([],"Null") },[_]) ->
 	| TType ({ t_path = ([],"Null") },[_]) ->
-		false
+		true
 	| TLazy f ->
 	| TLazy f ->
 		is_nullable (!f())
 		is_nullable (!f())
 	| TType (t,tl) ->
 	| TType (t,tl) ->
 		is_nullable (apply_params t.t_types tl t.t_type)
 		is_nullable (apply_params t.t_types tl t.t_type)
 	| TFun _ ->
 	| TFun _ ->
-		true
+		false
 	| TInst ({ cl_path = (["haxe"],"Int32") },[])
 	| TInst ({ cl_path = (["haxe"],"Int32") },[])
 	| TInst ({ cl_path = ([],"Int") },[])
 	| TInst ({ cl_path = ([],"Int") },[])
 	| TInst ({ cl_path = ([],"Float") },[])
 	| TInst ({ cl_path = ([],"Float") },[])
-	| TEnum ({ e_path = ([],"Bool") },[]) -> true
+	| TEnum ({ e_path = ([],"Bool") },[]) -> false
 	| _ ->
 	| _ ->
-		false
+		true
 
 
 let rec is_null = function
 let rec is_null = function
 	| TMono r ->
 	| TMono r ->
 		(match !r with None -> false | Some t -> is_null t)
 		(match !r with None -> false | Some t -> is_null t)
 	| TType ({ t_path = ([],"Null") },[t]) ->
 	| TType ({ t_path = ([],"Null") },[t]) ->
-		is_nullable t
+		not (is_nullable t)
 	| TLazy f ->
 	| TLazy f ->
 		is_null (!f())
 		is_null (!f())
 	| TType (t,tl) ->
 	| TType (t,tl) ->

+ 2 - 6
typer.ml

@@ -166,7 +166,7 @@ let rec unify_call_params ctx name el args r p inline =
 			let e = type_expr ctx infos true in
 			let e = type_expr ctx infos true in
 			(e, true)
 			(e, true)
 		else
 		else
-			(null t p, true)
+			(null (if ctx.com.platform = Cpp then ctx.t.tnull t else t) p, true)
 	in
 	in
 	let rec loop acc l l2 skip =
 	let rec loop acc l l2 skip =
 		match l , l2 with
 		match l , l2 with
@@ -2701,11 +2701,7 @@ let rec create com =
 		| TTypeDecl td ->
 		| TTypeDecl td ->
 			(match snd td.t_path with
 			(match snd td.t_path with
 			| "Null" ->
 			| "Null" ->
-				let f9 = platform com Flash in
-				let cpp = platform com Cpp in
-				let cs = platform com Cs in
-				let java = platform com Java in
-				ctx.t.tnull <- if not (f9 || cpp || cs || java) then (fun t -> t) else (fun t -> if is_nullable t then TType (td,[t]) else t);
+				ctx.t.tnull <- if not (is_static_platform com) then (fun t -> t) else (fun t -> if not (is_nullable t) then TType (td,[t]) else t);
 			| _ -> ());
 			| _ -> ());
 	) ctx.g.std.m_types;
 	) ctx.g.std.m_types;
 	let m = Typeload.load_module ctx ([],"String") null_pos in
 	let m = Typeload.load_module ctx ([],"String") null_pos in