Skip to content

Commit 2606dc7

Browse files
authored
Follow coro when retyping abstract and getting field return type (#12481)
1 parent 66b868e commit 2606dc7

File tree

1 file changed

+48
-42
lines changed

1 file changed

+48
-42
lines changed

src/generators/cpp/cppRetyper.ml

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,14 @@ let expression ctx request_type function_args function_type expression_tree forI
352352
new_ctx, resolver
353353
in
354354

355-
let cpp_return_type haxe_type =
356-
match haxe_type with TFun (_, ret) -> cpp_type_of with_stack_value_type ret | _ -> TCppDynamic
355+
let cpp_return_type ctx haxe_type =
356+
match follow_with_coro haxe_type with
357+
| Coro (args, ret) -> Common.expand_coro_type ctx.ctx_common.basic args ret |> snd |> cpp_type_of with_stack_value_type
358+
| NotCoro TFun (_, ret) -> cpp_type_of with_stack_value_type ret
359+
| _ -> TCppDynamic
357360
in
358361

359-
let cpp_member_return_type member = cpp_return_type member.cf_type in
362+
let cpp_member_return_type ctx member = cpp_return_type ctx member.cf_type in
360363

361364
let is_cpp_objc_type cpptype =
362365
match cpptype with TCppObjC _ -> true | _ -> false
@@ -652,7 +655,7 @@ let expression ctx request_type function_args function_type expression_tree forI
652655
match field with
653656
| FInstance (clazz, params, member)
654657
| FClosure (Some (clazz, params), member) -> (
655-
let funcReturn = cpp_member_return_type member in
658+
let funcReturn = cpp_member_return_type ctx member in
656659
let clazzType = cpp_instance_type clazz params with_reference_value_type in
657660
let retyper_ctx, retypedObj = retype retyper_ctx clazzType obj in
658661
(* Value types in haxe classes are always promoted, with value type externs treat them as stack types so the auto casting deals with conversion *)
@@ -774,7 +777,7 @@ let expression ctx request_type function_args function_type expression_tree forI
774777
funcReturn ),
775778
exprType ))
776779
| FStatic (_, ({ cf_name = "nativeFromStaticFunction" } as member)) ->
777-
let funcReturn = cpp_member_return_type member in
780+
let funcReturn = cpp_member_return_type ctx member in
778781
let exprType = cpp_type_of member.cf_type in
779782
(retyper_ctx, CppFunction (FuncFromStaticFunction, funcReturn), exprType)
780783
| FStatic (({ cl_kind = KAbstractImpl abs }), member) when is_marshalling_native_enum abs ->
@@ -789,7 +792,7 @@ let expression ctx request_type function_args function_type expression_tree forI
789792
(retyper_ctx, CppVar (VarStatic (clazz, objC, member)), exprType)
790793
else
791794
( retyper_ctx,
792-
CppFunction (FuncStatic (clazz, objC, member, []), cpp_member_return_type member),
795+
CppFunction (FuncStatic (clazz, objC, member, []), cpp_member_return_type ctx member),
793796
exprType )
794797
| FClosure (None, field)
795798
| FAnon field ->
@@ -799,7 +802,7 @@ let expression ctx request_type function_args function_type expression_tree forI
799802
(retyper_ctx, CppExtern (fieldName, true), cpp_type_of expr.etype)
800803
else if obj.cpptype = TCppNull then (retyper_ctx, CppNullAccess, TCppDynamic)
801804
else if is_internal_member fieldName then
802-
let cppType = cpp_return_type expr.etype in
805+
let cppType = cpp_return_type ctx expr.etype in
803806
if obj.cpptype = TCppString then
804807
( retyper_ctx,
805808
CppFunction (FuncInternal (obj, fieldName, "."), cppType),
@@ -824,7 +827,7 @@ let expression ctx request_type function_args function_type expression_tree forI
824827
else if fieldName = "__Index" then
825828
(retyper_ctx, CppEnumIndex obj, TCppScalar "int")
826829
else if is_internal_member fieldName || cpp_is_real_array obj then
827-
let cppType = cpp_return_type expr.etype in
830+
let cppType = cpp_return_type ctx expr.etype in
828831
if obj.cpptype = TCppString then
829832
( retyper_ctx,
830833
CppFunction (FuncInternal (obj, fieldName, "."), cppType),
@@ -1669,41 +1672,44 @@ let rec tcpp_class_from_tclass ctx ids slots class_def class_params =
16691672
| Method MethNormal, _ when has_class_field_flag field CfAbstract ->
16701673
(* We need to fetch the default values for abstract functions from the @:Value meta *)
16711674
let abstract_tfunc =
1672-
match field.cf_type with
1673-
| TFun (args, ret) ->
1674-
let get_default_value name =
1675-
try
1676-
match Meta.get Meta.Value field.cf_meta with
1677-
| _, [ (EObjectDecl decls, _) ], _ ->
1678-
Some
1679-
(decls
1680-
|> List.find (fun ((n, _, _), _) -> n = name)
1681-
|> snd
1682-
|> type_constant_value ctx.ctx_common.basic)
1683-
| _ -> None
1684-
with Not_found -> None
1685-
in
1675+
let args, ret =
1676+
match follow_with_coro field.cf_type with
1677+
| Coro (t, r) -> Common.expand_coro_type ctx.ctx_common.basic t r
1678+
| NotCoro TFun (t, r) -> t, r
1679+
| _ -> cpp_abort InternalError field.cf_pos
1680+
in
16861681

1687-
(* Generate a no op tfunc for our abstract *)
1688-
(* This allows it to go through the rest of the generator with no special cases *)
1689-
(* We can't implement abstract functions as pure virtual due to cppia needing to construct the class *)
1690-
let map_arg (name, _, t) =
1691-
( (alloc_var VGenerated name t null_pos), (get_default_value name) ) in
1692-
let expr =
1693-
match follow ret with
1694-
| TAbstract ({ a_path = ([], "Void") }, _) ->
1695-
{ eexpr = TReturn None; etype = ret; epos = null_pos }
1696-
| _ ->
1697-
let zero_val = Some { eexpr = TConst (TInt Int32.zero); etype = ret; epos = null_pos } in
1698-
{ eexpr = TReturn zero_val; etype = ret; epos = null_pos } in
1699-
1700-
{
1701-
tf_args = args |> List.map map_arg;
1702-
tf_type = ret;
1703-
tf_expr = expr;
1704-
}
1705-
| _ ->
1706-
die "expected abstract field type to be TFun" __LOC__
1682+
let get_default_value name =
1683+
try
1684+
match Meta.get Meta.Value field.cf_meta with
1685+
| _, [ (EObjectDecl decls, _) ], _ ->
1686+
Some
1687+
(decls
1688+
|> List.find (fun ((n, _, _), _) -> n = name)
1689+
|> snd
1690+
|> type_constant_value ctx.ctx_common.basic)
1691+
| _ -> None
1692+
with Not_found -> None
1693+
in
1694+
1695+
(* Generate a no op tfunc for our abstract *)
1696+
(* This allows it to go through the rest of the generator with no special cases *)
1697+
(* We can't implement abstract functions as pure virtual due to cppia needing to construct the class *)
1698+
let map_arg (name, _, t) =
1699+
( (alloc_var VGenerated name t null_pos), (get_default_value name) ) in
1700+
let expr =
1701+
match follow ret with
1702+
| TAbstract ({ a_path = ([], "Void") }, _) ->
1703+
{ eexpr = TReturn None; etype = ret; epos = null_pos }
1704+
| _ ->
1705+
let zero_val = Some { eexpr = TConst (TInt Int32.zero); etype = ret; epos = null_pos } in
1706+
{ eexpr = TReturn zero_val; etype = ret; epos = null_pos } in
1707+
1708+
{
1709+
tf_args = args |> List.map map_arg;
1710+
tf_type = ret;
1711+
tf_expr = expr;
1712+
}
17071713
in
17081714

17091715
Some (create_function field with_stack_value_type abstract_tfunc)

0 commit comments

Comments
 (0)