|
@@ -4335,6 +4335,8 @@ let typing_timer ctx f =
|
|
|
exit();
|
|
|
raise e
|
|
|
|
|
|
+let load_macro_ref : (typer -> path -> string -> pos -> (typer * ((string * bool * t) list * t * tclass * Type.tclass_field) * (Interp.value list -> Interp.value option))) ref = ref (fun _ _ _ _ -> assert false)
|
|
|
+
|
|
|
let make_macro_api ctx p =
|
|
|
let parse_expr_string s p inl =
|
|
|
typing_timer ctx (fun() -> parse_expr_string ctx s p inl)
|
|
@@ -4392,6 +4394,15 @@ let make_macro_api ctx p =
|
|
|
Interp.type_expr = (fun e ->
|
|
|
typing_timer ctx (fun() -> (type_expr ctx e Value))
|
|
|
);
|
|
|
+ Interp.type_macro_expr = (fun e ->
|
|
|
+ let e = typing_timer ctx (fun() -> (type_expr ctx e Value)) in
|
|
|
+ let rec loop e = match e.eexpr with
|
|
|
+ | TField(_,FStatic(c,({cf_kind = Method _} as cf))) -> ignore(!load_macro_ref ctx c.cl_path cf.cf_name e.epos)
|
|
|
+ | _ -> Type.iter loop e
|
|
|
+ in
|
|
|
+ loop e;
|
|
|
+ e
|
|
|
+ );
|
|
|
Interp.store_typed_expr = (fun te ->
|
|
|
let p = te.epos in
|
|
|
let id = get_next_stored_typed_expr_id() in
|
|
@@ -4776,6 +4787,11 @@ let load_macro ctx cpath f p =
|
|
|
in
|
|
|
mctx, meth, call
|
|
|
|
|
|
+type macro_arg_type =
|
|
|
+ | MAExpr
|
|
|
+ | MAFunction
|
|
|
+ | MAOther
|
|
|
+
|
|
|
let type_macro ctx mode cpath f (el:Ast.expr list) p =
|
|
|
let mctx, (margs,mret,mclass,mfield), call_macro = load_macro ctx cpath f p in
|
|
|
let mpos = mfield.cf_pos in
|
|
@@ -4829,7 +4845,14 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
|
|
|
(*
|
|
|
force default parameter types to haxe.macro.Expr, and if success allow to pass any value type since it will be encoded
|
|
|
*)
|
|
|
- let eargs = List.map (fun (n,o,t) -> try unify_raise mctx t expr p; (n, o, t_dynamic), true with Error (Unify _,_) -> (n,o,t), false) margs in
|
|
|
+ let eargs = List.map (fun (n,o,t) ->
|
|
|
+ try unify_raise mctx t expr p; (n, o, t_dynamic), MAExpr
|
|
|
+ with Error (Unify _,_) -> match follow t with
|
|
|
+ | TFun _ ->
|
|
|
+ (n,o,t_dynamic), MAFunction
|
|
|
+ | _ ->
|
|
|
+ (n,o,t), MAOther
|
|
|
+ ) margs in
|
|
|
(*
|
|
|
this is quite tricky here : we want to use unify_call_args which will type our AST expr
|
|
|
but we want to be able to get it back after it's been padded with nulls
|
|
@@ -4857,7 +4880,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
|
|
|
) el in
|
|
|
let elt, _ = unify_call_args mctx constants (List.map fst eargs) t_dynamic p false false in
|
|
|
List.iter (fun f -> f()) (!todo);
|
|
|
- List.map2 (fun (_,ise) e ->
|
|
|
+ List.map2 (fun (_,mct) e ->
|
|
|
let e, et = (match e.eexpr with
|
|
|
(* get back our index and real expression *)
|
|
|
| TArray ({ eexpr = TArrayDecl [e] }, { eexpr = TConst (TInt index) }) -> List.nth el (Int32.to_int index), e
|
|
@@ -4865,9 +4888,17 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
|
|
|
| TConst TNull -> (EConst (Ident "null"),e.epos), e
|
|
|
| _ -> assert false
|
|
|
) in
|
|
|
- if ise then
|
|
|
+ let ictx = Interp.get_ctx() in
|
|
|
+ match mct with
|
|
|
+ | MAExpr ->
|
|
|
Interp.encode_expr e
|
|
|
- else match Interp.eval_expr (Interp.get_ctx()) et with
|
|
|
+ | MAFunction ->
|
|
|
+ let e = ictx.Interp.curapi.Interp.type_macro_expr e in
|
|
|
+ begin match Interp.eval_expr ictx e with
|
|
|
+ | Some v -> v
|
|
|
+ | None -> Interp.VNull
|
|
|
+ end
|
|
|
+ | MAOther -> match Interp.eval_expr ictx et with
|
|
|
| None -> assert false
|
|
|
| Some v -> v
|
|
|
) eargs elt
|
|
@@ -5100,4 +5131,5 @@ get_constructor_ref := get_constructor;
|
|
|
cast_or_unify_ref := Codegen.AbstractCast.cast_or_unify_raise;
|
|
|
type_module_type_ref := type_module_type;
|
|
|
find_array_access_raise_ref := Codegen.AbstractCast.find_array_access_raise;
|
|
|
-build_call_ref := build_call
|
|
|
+build_call_ref := build_call;
|
|
|
+load_macro_ref := load_macro
|