Skip to content

Commit

Permalink
Change Null<T> to an abstract (#6380)
Browse files Browse the repository at this point in the history
* use abstract instead of typedef for Null<T>

* make Null<T> a @:coreType (broken on C#/Java)

* fix infinite recursion

* fix flash

* fix overloads
  • Loading branch information
Simn authored Jun 27, 2017
1 parent bfd7db1 commit bdfb602
Show file tree
Hide file tree
Showing 20 changed files with 139 additions and 119 deletions.
2 changes: 1 addition & 1 deletion src/filters/defaultArguments.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ open Codegen.ExprBuilder

let gen_check basic t nullable_var const pos =
let needs_cast t1 t2 =
let is_null t = match t with TType ({t_path = ([],"Null")}, _) -> true | _ -> false in
let is_null t = match t with TAbstract ({a_path = ([],"Null")}, _) -> true | _ -> false in
(is_null t1) <> (is_null t2)
in

Expand Down
17 changes: 7 additions & 10 deletions src/generators/genas3.ml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,13 @@ let rec type_str ctx t p =
match t with
| TEnum _ | TInst _ when List.memq t ctx.local_types ->
"*"
| TAbstract ({a_path = [],"Null"},[t]) ->
(match follow t with
| TAbstract ({ a_path = [],"UInt" },_)
| TAbstract ({ a_path = [],"Int" },_)
| TAbstract ({ a_path = [],"Float" },_)
| TAbstract ({ a_path = [],"Bool" },_) -> "*"
| _ -> type_str ctx t p)
| TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) ->
type_str ctx (Abstract.get_underlying_type a pl) p
| TAbstract (a,_) ->
Expand Down Expand Up @@ -291,16 +298,6 @@ let rec type_str ctx t p =
| TType (t,args) ->
(match t.t_path with
| [], "UInt" -> "uint"
| [] , "Null" ->
(match args with
| [t] ->
(match follow t with
| TAbstract ({ a_path = [],"UInt" },_)
| TAbstract ({ a_path = [],"Int" },_)
| TAbstract ({ a_path = [],"Float" },_)
| TAbstract ({ a_path = [],"Bool" },_) -> "*"
| _ -> type_str ctx t p)
| _ -> assert false);
| _ -> type_str ctx (apply_params t.t_params args t.t_type) p)
| TLazy f ->
type_str ctx ((!f)()) p
Expand Down
4 changes: 4 additions & 0 deletions src/generators/gencommon.ml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ let follow_once t =
!f()
| TType (t,tl) ->
apply_params t.t_params tl t.t_type
| TAbstract({a_path = [],"Null"},[t]) ->
t
| _ ->
t

Expand Down Expand Up @@ -657,6 +659,8 @@ let init_ctx gen =
follow_f (!f())
| TType (t,tl) ->
follow_f (apply_params t.t_params tl t.t_type)
| TAbstract({a_path = [],"Null"},[t]) ->
follow_f t
| _ -> Some t
in
gen.gfollow#add "final" PLast follow
Expand Down
2 changes: 1 addition & 1 deletion src/generators/gencommon/closuresToClass.ml
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ struct
in

let rettype_real_to_func t = match run_follow gen t with
| TType({ t_path = [],"Null" }, _) ->
| TAbstract({ a_path = [],"Null" }, _) ->
0,t_dynamic
| _ when like_float t && not (like_i64 t) ->
(1, basic.tfloat)
Expand Down
8 changes: 4 additions & 4 deletions src/generators/gencommon/hardNullableSynf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ let name = "hard_nullable"
let priority = solve_deps name [DAfter CastDetect.ReturnCast.priority]

let rec is_null_t gen t = match gen.greal_type t with
| TType( { t_path = ([], "Null") }, [of_t])
| TAbstract( { a_path = ([], "Null") }, [of_t])
| TInst( { cl_path = (["haxe";"lang"], "Null") }, [of_t]) ->
let rec take_off_null t =
match is_null_t gen t with | None -> t | Some s -> take_off_null s
Expand All @@ -63,13 +63,13 @@ let follow_addon gen t =
let t = gen.gfollow#run_f t in
match t with
(* haxe.lang.Null<haxe.lang.Null<>> wouldn't be a valid construct, so only follow Null<> *)
| TType ( { t_path = ([], "Null") }, [of_t] ) -> strip_off_nullable of_t
| TAbstract ( { a_path = ([], "Null") }, [of_t] ) -> strip_off_nullable of_t
| _ -> t
in

match t with
| TType( ({ t_path = ([], "Null") } as tdef), [of_t]) ->
Some( TType(tdef, [ strip_off_nullable of_t ]) )
| TAbstract( ({ a_path = ([], "Null") } as tab), [of_t]) ->
Some( TAbstract(tab, [ strip_off_nullable of_t ]) )
| _ -> None

let configure gen unwrap_null wrap_val null_to_dynamic has_value opeq_handler =
Expand Down
2 changes: 2 additions & 0 deletions src/generators/gencommon/normalize.ml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ let rec filter_param t =
TEnum(e,List.map filter_param tl)
| TAbstract({ a_path = (["haxe";"extern"],"Rest") } as a,tl) ->
TAbstract(a, List.map filter_param tl)
| TAbstract({a_path = [],"Null"} as a,[t]) ->
TAbstract(a,[filter_param t])
| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) ->
filter_param (Abstract.get_underlying_type a tl)
| TAbstract(a,tl) ->
Expand Down
4 changes: 2 additions & 2 deletions src/generators/gencommon/switchToIf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ let configure gen (should_convert:texpr->bool) =
| TSwitch (cond, cases, default) when should_convert e ->
let cond_etype, should_cache =
match gen.gfollow#run_f cond.etype with
| TType ({ t_path = [], "Null" }, [t]) ->
| TAbstract ({ a_path = [], "Null" }, [t]) ->
let rec take_off_nullable t =
match gen.gfollow#run_f t with
| TType ({ t_path = [], "Null" }, [t]) -> take_off_nullable t
| TAbstract ({ a_path = [], "Null" }, [t]) -> take_off_nullable t
| _ -> t
in
take_off_nullable t, true
Expand Down
19 changes: 8 additions & 11 deletions src/generators/gencpp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -760,20 +760,17 @@ and type_string_suff suffix haxe_type remap =
| TAbstract ({ a_path = ([],"Int") },[]) -> "int"
| TAbstract ({ a_path = (["cpp"],"UInt8") },[]) -> "unsigned char"
| TAbstract( { a_path = ([], "EnumValue") }, _ ) -> "Dynamic"
| TAbstract ({ a_path = ([],"Null") }, [t]) ->
(match follow t with
| TAbstract ({ a_path = [],"Int" },_)
| TAbstract ({ a_path = [],"Float" },_)
| TAbstract ({ a_path = [],"Bool" },_) -> "Dynamic" ^ suffix
| t when type_has_meta_key t Meta.NotNull -> "Dynamic" ^ suffix
| _ -> type_string_suff suffix t remap)
| TEnum (enum,params) -> "::" ^ (join_class_path_remap enum.e_path "::") ^ suffix
| TInst (klass,params) -> (class_string klass suffix params remap)
| TType (type_def,params) ->
(match type_def.t_path with
| [] , "Null" ->
(match params with
| [t] ->
(match follow t with
| TAbstract ({ a_path = [],"Int" },_)
| TAbstract ({ a_path = [],"Float" },_)
| TAbstract ({ a_path = [],"Bool" },_) -> "Dynamic" ^ suffix
| t when type_has_meta_key t Meta.NotNull -> "Dynamic" ^ suffix
| _ -> type_string_suff suffix t remap)
| _ -> assert false);
| [] , "Array" ->
(match params with
| [t] when (type_string (follow t) ) = "Dynamic" -> "Dynamic"
Expand Down Expand Up @@ -6770,7 +6767,7 @@ let is_assign_op op =

let rec script_type_string haxe_type =
match haxe_type with
| TType ({ t_path = ([],"Null") },[t]) ->
| TAbstract ({ a_path = ([],"Null") },[t]) ->
(match follow t with
| TAbstract ({ a_path = [],"Int" },_)
| TAbstract ({ a_path = [],"Float" },_)
Expand Down
42 changes: 21 additions & 21 deletions src/generators/gencs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ let is_pointer gen t =
let rec is_null t =
match t with
| TInst( { cl_path = (["haxe"; "lang"], "Null") }, _ )
| TType( { t_path = ([], "Null") }, _ ) -> true
| TAbstract( { a_path = ([], "Null") }, _ ) -> true
| TType( t, tl ) -> is_null (apply_params t.t_params tl t.t_type)
| TMono r ->
(match !r with
Expand Down Expand Up @@ -786,8 +786,8 @@ let generate con =
| TAbstract ({ a_path = ["cs"],"Out" },_)
| TType ({ t_path = [],"Single" },[])
| TAbstract ({ a_path = [],"Single" },[]) -> Some t
| TType (({ t_path = [],"Null" } as tdef),[t2]) ->
Some (TType(tdef,[follow (gen.gfollow#run_f t2)]))
| TAbstract (({ a_path = [],"Null" } as tab),[t2]) ->
Some (TAbstract(tab,[follow (gen.gfollow#run_f t2)]))
| TAbstract({ a_path = ["cs"],"PointerAccess" },[t]) ->
Some (TAbstract(ptr,[t]))
| TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) ->
Expand Down Expand Up @@ -827,6 +827,23 @@ let generate con =
let rec real_type t =
let t = gen.gfollow#run_f t in
let ret = match t with
| TAbstract({ a_path = ([], "Null") }, [t]) ->
(*
Null<> handling is a little tricky.
It will only change to haxe.lang.Null<> when the actual type is non-nullable or a type parameter
It works on cases such as Hash<T> returning Null<T> since cast_detect will invoke real_type at the original type,
Null<T>, which will then return the type haxe.lang.Null<>
*)
if erase_generics then
if is_cs_basic_type t then
t_dynamic
else
real_type t
else
(match real_type t with
| TInst( { cl_kind = KTypeParameter _ }, _ ) -> TInst(null_t, [t])
| t when is_cs_basic_type t -> TInst(null_t, [t])
| _ -> real_type t)
| TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) ->
real_type (Abstract.get_underlying_type a pl)
| TAbstract ({ a_path = (["cs";"_Flags"], "EnumUnderlying") }, [t]) ->
Expand Down Expand Up @@ -854,23 +871,6 @@ let generate con =
| TInst(cl, params) when Meta.has Meta.Enum cl.cl_meta ->
TInst(cl, List.map (fun _ -> t_dynamic) params)
| TInst(cl, params) -> TInst(cl, change_param_type (TClassDecl cl) params)
| TType({ t_path = ([], "Null") }, [t]) ->
(*
Null<> handling is a little tricky.
It will only change to haxe.lang.Null<> when the actual type is non-nullable or a type parameter
It works on cases such as Hash<T> returning Null<T> since cast_detect will invoke real_type at the original type,
Null<T>, which will then return the type haxe.lang.Null<>
*)
if erase_generics then
if is_cs_basic_type t then
t_dynamic
else
real_type t
else
(match real_type t with
| TInst( { cl_kind = KTypeParameter _ }, _ ) -> TInst(null_t, [t])
| t when is_cs_basic_type t -> TInst(null_t, [t])
| _ -> real_type t)
| TAbstract _
| TType _ -> t
| TAnon (anon) when (match !(anon.a_status) with | Statics _ | EnumStatics _ | AbstractStatics _ -> true | _ -> false) -> t
Expand Down Expand Up @@ -2944,7 +2944,7 @@ let generate con =
in

let may_nullable t = match gen.gfollow#run_f t with
| TType({ t_path = ([], "Null") }, [t]) ->
| TAbstract({ a_path = ([], "Null") }, [t]) ->
(match follow t with
| TInst({ cl_path = ([], "String") }, [])
| TAbstract ({ a_path = ([], "Float") },[])
Expand Down
13 changes: 10 additions & 3 deletions src/generators/genhl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ let make_debug ctx arr =
done;
out

let fake_tnull =
{null_abstract with
a_path = [],"Null";
a_params = ["T",t_dynamic];
}

let rec to_type ?tref ctx t =
match t with
| TMono r ->
Expand All @@ -353,7 +359,6 @@ let rec to_type ?tref ctx t =
t
) in
(match td.t_path with
| [], "Null" when not (is_nullable t) -> HNull t
| ["haxe";"macro"], name -> Hashtbl.replace ctx.macro_typedefs name t; t
| _ -> t)
| TLazy f ->
Expand Down Expand Up @@ -425,6 +430,9 @@ let rec to_type ?tref ctx t =
in
loop tl
| _ -> class_type ~tref ctx c pl false)
| TAbstract ({a_path = [],"Null"},[t1]) ->
let t = to_type ?tref ctx t1 in
if not (is_nullable t) then HNull t else t
| TAbstract (a,pl) ->
if Meta.has Meta.CoreType a.a_meta then
(match a.a_path with
Expand Down Expand Up @@ -501,8 +509,7 @@ and real_type ctx e =
If we have a number, it is more accurate to cast it to the type parameter before wrapping it as dynamic
*)
| TInst ({cl_kind=KTypeParameter _},_), t when is_number (to_type ctx t) ->
let tnull = { t_path = [],"Null"; t_module = null_module; t_pos = null_pos; t_name_pos = null_pos; t_private = false; t_doc = None; t_meta = []; t_params = ["T",t_dynamic]; t_type = t_dynamic } in
(name, opt, TType (tnull,[t]))
(name, opt, TAbstract (fake_tnull,[t]))
| _ ->
a
) args args2, ret)
Expand Down
41 changes: 21 additions & 20 deletions src/generators/genjava.ml
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ let generate con =
let fn_cl = get_cl (get_type gen (["haxe";"lang"],"Function")) in

let runtime_cl = get_cl (get_type gen (["haxe";"lang"],"Runtime")) in
let nulltdef = match (get_type gen ([],"Null")) with TTypeDecl t -> t | _ -> assert false in
let nulltabstract = get_abstract (get_type gen ([],"Null")) in

(*let string_ref = get_cl ( get_type gen (["haxe";"lang"], "StringRefl")) in*)

Expand Down Expand Up @@ -1035,8 +1035,8 @@ let generate con =
| TAbstract ({ a_path = ["java"],"Char16" },[])
| TType ({ t_path = [],"Single" },[])
| TAbstract ({ a_path = [],"Single" },[]) ->
TType(nulltdef, [f_t])
(*| TType ({ t_path = [], "Null"*)
TAbstract(nulltabstract, [f_t])
(*| TAbstract ({ a_path = [], "Null"*)
| TInst (cl, ((_ :: _) as p)) when cl.cl_path <> (["java"],"NativeArray") ->
(* TInst(cl, List.map (fun _ -> t_dynamic) p) *)
TInst(cl,p)
Expand Down Expand Up @@ -1078,8 +1078,8 @@ let generate con =
| TType ({ t_path = [],"Single" },[])
| TAbstract ({ a_path = [],"Single" },[]) ->
Some t
| TType (({ t_path = [],"Null" } as tdef),[t2]) ->
Some (TType(tdef,[gen.gfollow#run_f t2]))
| TAbstract (({ a_path = [],"Null" } as tab),[t2]) ->
Some (TAbstract(tab,[gen.gfollow#run_f t2]))
| TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) ->
Some (gen.gfollow#run_f ( Abstract.get_underlying_type a pl) )
| TAbstract( { a_path = ([], "EnumValue") }, _ )
Expand Down Expand Up @@ -1114,20 +1114,8 @@ let generate con =
let rec real_type t =
let t = gen.gfollow#run_f t in
match t with
| TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) ->
real_type (Abstract.get_underlying_type a pl)
| TInst( { cl_path = (["haxe"], "Int32") }, [] ) -> gen.gcon.basic.tint
| TInst( { cl_path = (["haxe"], "Int64") }, [] ) -> ti64
| TAbstract( { a_path = ([], "Class") }, p )
| TAbstract( { a_path = ([], "Enum") }, p )
| TInst( { cl_path = ([], "Class") }, p )
| TInst( { cl_path = ([], "Enum") }, p ) -> TInst(cl_cl,[t_dynamic])
| TEnum(e,params) -> TEnum(e, List.map (fun _ -> t_dynamic) params)
| TInst(c,params) when Meta.has Meta.Enum c.cl_meta ->
TInst(c, List.map (fun _ -> t_dynamic) params)
| TInst({ cl_kind = KExpr _ }, _) -> t_dynamic
| TInst _ -> t
| TType({ t_path = ([], "Null") }, [t]) -> (
| TAbstract({ a_path = ([], "Null") }, [t]) when is_java_basic_type (gen.gfollow#run_f t) -> t_dynamic
| TAbstract({ a_path = ([], "Null") }, [t]) -> (
match gen.gfollow#run_f t with
| TAbstract( { a_path = ([], "Bool") }, [] ) ->
TInst(cl_boolean, [])
Expand All @@ -1152,6 +1140,19 @@ let generate con =
| _ -> real_type t
)
)
| TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) ->
real_type (Abstract.get_underlying_type a pl)
| TInst( { cl_path = (["haxe"], "Int32") }, [] ) -> gen.gcon.basic.tint
| TInst( { cl_path = (["haxe"], "Int64") }, [] ) -> ti64
| TAbstract( { a_path = ([], "Class") }, p )
| TAbstract( { a_path = ([], "Enum") }, p )
| TInst( { cl_path = ([], "Class") }, p )
| TInst( { cl_path = ([], "Enum") }, p ) -> TInst(cl_cl,[t_dynamic])
| TEnum(e,params) -> TEnum(e, List.map (fun _ -> t_dynamic) params)
| TInst(c,params) when Meta.has Meta.Enum c.cl_meta ->
TInst(c, List.map (fun _ -> t_dynamic) params)
| TInst({ cl_kind = KExpr _ }, _) -> t_dynamic
| TInst _ -> t
| TType _ | TAbstract _ -> t
| TAnon (anon) -> (match !(anon.a_status) with
| Statics _ | EnumStatics _ | AbstractStatics _ -> t
Expand Down Expand Up @@ -2459,7 +2460,7 @@ let generate con =
in

let may_nullable t = match gen.gfollow#run_f t with
| TType({ t_path = ([], "Null") }, [t]) ->
| TAbstract({ a_path = ([], "Null") }, [t]) ->
(match follow t with
| TInst({ cl_path = ([], "String") }, [])
| TAbstract ({ a_path = ([], "Float") },[])
Expand Down
15 changes: 6 additions & 9 deletions src/generators/genphp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,17 @@ and type_string_suff suffix haxe_type =
| TAbstract ({ a_path = [],"Float" },[]) -> "double"
| TAbstract ({ a_path = [],"Bool" },[]) -> "bool"
| TAbstract ({ a_path = [],"Void" },[]) -> "Void"
| TAbstract ({ a_path = [],"Null"},[t]) ->
(match follow t with
| TInst ({ cl_path = [],"Int" },_)
| TInst ({ cl_path = [],"Float" },_)
| TEnum ({ e_path = [],"Bool" },_) -> "Dynamic"
| _ -> type_string_suff suffix t)
| TEnum (enum,params) -> (join_class_path enum.e_path "::") ^ suffix
| TInst (klass,params) -> (class_string klass suffix params)
| TAbstract (abs,params) -> (join_class_path abs.a_path "::") ^ suffix
| TType (type_def,params) ->
(match type_def.t_path with
| [] , "Null" ->
(match params with
| [t] ->
(match follow t with
| TInst ({ cl_path = [],"Int" },_)
| TInst ({ cl_path = [],"Float" },_)
| TEnum ({ e_path = [],"Bool" },_) -> "Dynamic"
| _ -> type_string_suff suffix t)
| _ -> assert false);
| [] , "Array" ->
(match params with
| [t] -> "Array<" ^ (type_string (follow t) ) ^ " >"
Expand Down
6 changes: 4 additions & 2 deletions src/generators/genswf9.ml
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ let rec follow_basic t =
| _ -> t)
| TLazy f ->
follow_basic (!f())
| TType ({ t_path = [],"Null" },[tp]) ->
| TAbstract ({ a_path = [],"Null" },[tp]) ->
(match follow_basic tp with
| TMono _
| TFun _
Expand Down Expand Up @@ -228,7 +228,9 @@ let rec type_id ctx t =
| _ -> type_path ctx ([],"Object"))
| _ ->
type_path ctx c.cl_path)
| TAbstract (a,_) ->
| TAbstract ({ a_path = [],"Null"},_) ->
HMPath ([],"Object")
| TAbstract (a,_) when Meta.has Meta.CoreType a.a_meta ->
type_path ctx a.a_path
| TFun _ | TType ({ t_path = ["flash";"utils"],"Function" },[]) ->
type_path ctx ([],"Function")
Expand Down
Loading

0 comments on commit bdfb602

Please sign in to comment.