Explorar o código

add Context.get_constructor_arguments for use in @:genericBuild macros

Simon Krajewski %!s(int64=11) %!d(string=hai) anos
pai
achega
83beb94577
Modificáronse 5 ficheiros con 30 adicións e 1 borrados
  1. 6 0
      interp.ml
  2. 12 0
      std/haxe/macro/Context.hx
  3. 1 0
      typecore.ml
  4. 1 0
      typeload.ml
  5. 10 1
      typer.ml

+ 6 - 0
interp.ml

@@ -110,6 +110,7 @@ type extern_api = {
 	set_js_generator : (value -> unit) -> unit;
 	get_local_type : unit -> t option;
 	get_expected_type : unit -> t option;
+	get_constructor_arguments : unit -> Ast.expr list option;
 	get_local_method : unit -> string;
 	get_local_using : unit -> tclass list;
 	get_local_vars : unit -> (string, Type.tvar) PMap.t;
@@ -2437,6 +2438,11 @@ let macro_lib =
 			| None -> VNull
 			| Some t -> encode_type t
 		);
+		"constructor_arguments", Fun0 (fun() ->
+			match (get_ctx()).curapi.get_constructor_arguments() with
+			| None -> VNull
+			| Some el -> enc_array (List.map encode_expr el)
+		);
 		"local_method", Fun0 (fun() ->
 			VString ((get_ctx()).curapi.get_local_method())
 		);

+ 12 - 0
std/haxe/macro/Context.hx

@@ -113,6 +113,18 @@ class Context {
 		return l;
 	}
 
+	/**
+		Returns the constructor arguments that are used to construct the
+		current `@:genericBuild` class, if available.
+
+		Returns `null` if the current macro is not a build-macro which was
+		called from constructing a `@:genericBuild` instance.
+	**/
+	@:require(haxe_ver >= 3.2)
+	public static function getConstructorArguments():Null<Array<Expr>> {
+		return load("constructor_arguments", 0)();
+	}
+
 	/**
 		Returns the current class in which the macro was called.
 

+ 1 - 0
typecore.ml

@@ -96,6 +96,7 @@ and typer = {
 	mutable meta : metadata;
 	mutable this_stack : texpr list;
 	mutable with_type_stack : with_type list;
+	mutable constructor_argument_stack : Ast.expr list list;
 	(* variable *)
 	mutable pass : typer_pass;
 	(* per-module *)

+ 1 - 0
typeload.ml

@@ -2619,6 +2619,7 @@ let type_module ctx m file tdecls p =
 		meta = [];
 		this_stack = [];
 		with_type_stack = [];
+		constructor_argument_stack = [];
 		pass = PBuildModule;
 		on_error = (fun ctx msg p -> ctx.com.error msg p);
 		macro_depth = ctx.macro_depth;

+ 10 - 1
typer.ml

@@ -3157,7 +3157,10 @@ and type_expr ctx (e,p) (with_type:with_type) =
 				error "Constructor is not a function" p
 		in
 		let t = try
-			follow (Typeload.load_instance ctx t p true)
+			ctx.constructor_argument_stack <- el :: ctx.constructor_argument_stack;
+			let t = follow (Typeload.load_instance ctx t p true) in
+			ctx.constructor_argument_stack <- List.tl ctx.constructor_argument_stack;
+			t
 		with Codegen.Generic_Exception _ ->
 			(* Try to infer generic parameters from the argument list (issue #2044) *)
 			match Typeload.load_type_def ctx p t with
@@ -4192,6 +4195,11 @@ let make_macro_api ctx p =
 				| (WithType t | WithTypeResume t) :: _ -> Some t
 				| _ -> None
 		);
+		Interp.get_constructor_arguments = (fun() ->
+			match ctx.constructor_argument_stack with
+				| [] -> None
+				| el :: _ -> Some el
+		);
 		Interp.get_local_method = (fun() ->
 			ctx.curfield.cf_name;
 		);
@@ -4618,6 +4626,7 @@ let rec create com =
 		meta = [];
 		this_stack = [];
 		with_type_stack = [];
+		constructor_argument_stack = [];
 		pass = PBuildModule;
 		macro_depth = 0;
 		untyped = false;