From 2aa1b528f9782e506f0e370f3203f1af7460bc11 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Thu, 4 Apr 2024 07:46:18 +0200 Subject: [PATCH] Apply @:using after build macros (#11625) * Apply @:using after running build macro Allows build macro to provide such metadata * [tests] Add test for @:using added by build macro * Factorize t_infos calls --- src/typing/typeloadFields.ml | 44 +++++++++++---------- tests/misc/projects/Issue11625/Macro.hx | 5 +++ tests/misc/projects/Issue11625/Main.hx | 10 +++++ tests/misc/projects/Issue11625/compile.hxml | 1 + 4 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 tests/misc/projects/Issue11625/Macro.hx create mode 100644 tests/misc/projects/Issue11625/Main.hx create mode 100644 tests/misc/projects/Issue11625/compile.hxml diff --git a/src/typing/typeloadFields.ml b/src/typing/typeloadFields.ml index 55860c9ef63..92f67fef2e6 100644 --- a/src/typing/typeloadFields.ml +++ b/src/typing/typeloadFields.ml @@ -377,7 +377,11 @@ let resolve_type_import ctx p i = [i] let build_module_def ctx mt meta fvars fbuild = - let is_typedef = match mt with TTypeDecl _ -> true | _ -> false in + let is_typedef, ti = match mt with + | TClassDecl { cl_kind = KAbstractImpl a } -> false, t_infos (TAbstractDecl a) + | TTypeDecl _ -> true, t_infos mt + | _ -> false, t_infos mt + in let loop f_build = function | Meta.Build,args,p when not is_typedef -> (fun () -> let epath, el = (match args with @@ -394,31 +398,13 @@ let build_module_def ctx mt meta fvars fbuild = in if ctx.com.is_macro_context then raise_typing_error "You cannot use @:build inside a macro : make sure that your type is not used in macro" p; let old = ctx.c.get_build_infos in - ctx.c.get_build_infos <- (fun() -> Some (mt, extract_param_types (t_infos mt).mt_params, fvars())); + ctx.c.get_build_infos <- (fun() -> Some (mt, extract_param_types ti.mt_params, fvars())); let r = try ctx.g.do_macro ctx MBuild cpath meth el p with e -> ctx.c.get_build_infos <- old; raise e in ctx.c.get_build_infos <- old; (match r with | MError | MMacroInMacro -> raise_typing_error "Build failure" p | MSuccess e -> fbuild e) ) :: f_build - | Meta.Using,el,p -> (fun () -> - List.iter (fun e -> - try - let path = List.rev (string_pos_list_of_expr_path_raise e) in - let types,filter_classes = ImportHandling.handle_using ctx path (pos e) in - let ti = - match mt with - | TClassDecl { cl_kind = KAbstractImpl a } -> t_infos (TAbstractDecl a) - | _ -> t_infos mt - in - (* Delay for #10107, but use delay_late to make sure base classes run before their children do. *) - delay_late ctx.g PConnectField (fun () -> - ti.mt_using <- (filter_classes types) @ ti.mt_using - ) - with Exit -> - raise_typing_error "dot path expected" (pos e) - ) el; - ) :: f_build | _ -> f_build in @@ -432,7 +418,6 @@ let build_module_def ctx mt meta fvars fbuild = ) | TClassDecl { cl_super = csup; cl_implements = interfaces; cl_kind = kind } -> (* Go for @:using in parents and interfaces *) - let ti = t_infos mt in let inherit_using (c,_) = ti.mt_using <- ti.mt_using @ (t_infos (TClassDecl c)).mt_using in @@ -445,6 +430,23 @@ let build_module_def ctx mt meta fvars fbuild = None in List.iter (fun f -> f()) (List.rev f_build); + let apply_using = function + | Meta.Using,el,p -> + List.iter (fun e -> + try + let path = List.rev (string_pos_list_of_expr_path_raise e) in + let types,filter_classes = ImportHandling.handle_using ctx path (pos e) in + (* Delay for #10107, but use delay_late to make sure base classes run before their children do. *) + delay_late ctx.g PConnectField (fun () -> + ti.mt_using <- (filter_classes types) @ ti.mt_using + ) + with Exit -> + raise_typing_error "dot path expected" (pos e) + ) el; + | _ -> + () + in + List.iter apply_using ti.mt_meta; (match f_enum with None -> () | Some f -> f()) let create_class_context c p = diff --git a/tests/misc/projects/Issue11625/Macro.hx b/tests/misc/projects/Issue11625/Macro.hx new file mode 100644 index 00000000000..f4cd459cbd3 --- /dev/null +++ b/tests/misc/projects/Issue11625/Macro.hx @@ -0,0 +1,5 @@ +function build() { + var cls = haxe.macro.Context.getLocalClass().get(); + cls.meta.add(":using", [macro Main.Extensions], cls.pos); + return null; +} diff --git a/tests/misc/projects/Issue11625/Main.hx b/tests/misc/projects/Issue11625/Main.hx new file mode 100644 index 00000000000..aa17ed4e317 --- /dev/null +++ b/tests/misc/projects/Issue11625/Main.hx @@ -0,0 +1,10 @@ +function main() { + Foo.test(); +} + +class Extensions { + public static function test(c:Class) trace("ok"); +} + +@:build(Macro.build()) +class Foo {} diff --git a/tests/misc/projects/Issue11625/compile.hxml b/tests/misc/projects/Issue11625/compile.hxml new file mode 100644 index 00000000000..42409e72918 --- /dev/null +++ b/tests/misc/projects/Issue11625/compile.hxml @@ -0,0 +1 @@ +-main Main