Forráskód Böngészése

added haxe.macro.Context.resolveContextType

Nicolas Cannasse 2 éve
szülő
commit
1a57e42bdb
3 módosított fájl, 70 hozzáadás és 0 törlés
  1. 4 0
      src/macro/macroApi.ml
  2. 53 0
      src/typing/macroContext.ml
  3. 13 0
      std/haxe/macro/Context.hx

+ 4 - 0
src/macro/macroApi.ml

@@ -34,6 +34,7 @@ type 'value compiler_api = {
 	parse : 'a . ((Ast.token * Globals.pos) Stream.t -> 'a) -> string -> 'a;
 	parse : 'a . ((Ast.token * Globals.pos) Stream.t -> 'a) -> string -> 'a;
 	type_expr : Ast.expr -> Type.texpr;
 	type_expr : Ast.expr -> Type.texpr;
 	resolve_type  : Ast.complex_type -> Globals.pos -> t;
 	resolve_type  : Ast.complex_type -> Globals.pos -> t;
+	resolve_complex_type : Ast.type_hint -> Ast.type_hint;
 	store_typed_expr : Type.texpr -> Ast.expr;
 	store_typed_expr : Type.texpr -> Ast.expr;
 	allow_package : string -> unit;
 	allow_package : string -> unit;
 	type_patch : string -> string -> bool -> string option -> unit;
 	type_patch : string -> string -> bool -> string option -> unit;
@@ -1933,6 +1934,9 @@ let macro_api ccom get_api =
 		"resolve_type", vfun2 (fun t p ->
 		"resolve_type", vfun2 (fun t p ->
 			encode_type ((get_api()).resolve_type (fst (decode_ctype t)) (decode_pos p));
 			encode_type ((get_api()).resolve_type (fst (decode_ctype t)) (decode_pos p));
 		);
 		);
+		"resolve_complex_type", vfun2 (fun ct p ->
+			encode_ctype ((get_api()).resolve_complex_type (fst (decode_ctype ct),decode_pos p))
+		);
 		"s_type", vfun1 (fun v ->
 		"s_type", vfun1 (fun v ->
 			encode_string (Type.s_type (print_context()) (decode_type v))
 			encode_string (Type.s_type (print_context()) (decode_type v))
 		);
 		);

+ 53 - 0
src/typing/macroContext.ml

@@ -321,6 +321,59 @@ let make_macro_api ctx p =
 		MacroApi.resolve_type = (fun t p ->
 		MacroApi.resolve_type = (fun t p ->
 			typing_timer ctx false (fun() -> Typeload.load_complex_type ctx false (t,p))
 			typing_timer ctx false (fun() -> Typeload.load_complex_type ctx false (t,p))
 		);
 		);
+		MacroApi.resolve_complex_type = (fun t ->
+			typing_timer ctx false (fun() ->
+				let rec load (t,pos) =
+					((match t with
+					| CTPath p ->
+						CTPath (load_path p pos)
+					| CTFunction (args,ret) ->
+						CTFunction (List.map load args, load ret)
+					| CTAnonymous fl ->
+						CTAnonymous (List.map load_cf fl)
+					| CTParent t ->
+						CTParent (load t)
+					| CTExtend (pl, fl) ->
+						CTExtend (List.map (fun (p,pos) -> load_path p pos, pos) pl,List.map load_cf fl)
+					| CTOptional t ->
+						CTOptional t
+					| CTNamed (n,t) ->
+						CTNamed (n, load t)
+					| CTIntersection tl ->
+						CTIntersection (List.map load tl)
+					),p)
+				and load_cf f =
+					let k = match f.cff_kind with
+					| FVar (t, e) -> FVar ((match t with None -> None | Some t -> Some (load t)), e)
+					| FProp (n1,n2,t,e) -> FProp(n1,n2,(match t with None -> None | Some t -> Some (load t)),e)
+					| FFun f ->
+						FFun {
+							f_params = List.map load_tparam f.f_params;
+							f_args = List.map (fun (n,o,m,t,e) -> n,o,m,(match t with None -> None | Some t -> Some (load t)),e) f.f_args;
+							f_type = (match f.f_type with None -> None | Some t -> Some (load t));
+							f_expr = f.f_expr;
+						}
+					in
+					{ f with cff_kind = k }
+				and load_tparam ft =
+					{ ft with
+						tp_params = List.map load_tparam ft.tp_params;
+						tp_constraints = (match ft.tp_constraints with None -> None | Some t -> Some (load t));
+						tp_default = (match ft.tp_default with None -> None | Some t -> Some (load t));
+					}
+				and load_path p pos =
+					let t = t_infos (Typeload.load_type_def ctx pos p) in
+					let is_sub = t.mt_module.m_path <> t.mt_path in
+					{
+						tpackage = fst t.mt_path;
+						tname = (if is_sub then snd t.mt_module.m_path else snd t.mt_path);
+						tparams = List.map (fun ct -> match ct with TPType t -> TPType (load t) | TPExpr _ -> ct) p.tparams;
+						tsub = (if is_sub then Some (snd t.mt_path) else None);
+					}
+				in
+				load t
+			)
+		);
 		MacroApi.get_module = (fun s ->
 		MacroApi.get_module = (fun s ->
 			typing_timer ctx false (fun() ->
 			typing_timer ctx false (fun() ->
 				let path = parse_path s in
 				let path = parse_path s in

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

@@ -524,6 +524,19 @@ class Context {
 		return load("resolve_type", 2)(t, p);
 		return load("resolve_type", 2)(t, p);
 	}
 	}
 
 
+	/**
+		Resolve type `t` and returns the corresponding `ComplexType`.
+
+		Resolving the type may result in a compiler error which can be
+		caught using `try ... catch`.
+		Resolution is performed based on the current context in which the macro is called.
+		The difference with `resolveType` is that it only performs type resolution, it does not
+		build any type or trigger macros.
+	**/
+	public static function resolveComplexType(t:ComplexType, p:Position):ComplexType {
+		return load("resolve_complex_type", 2)(t, p);
+	}
+
 	/**
 	/**
 		Returns the `ComplexType` corresponding to the given `Type` `t`.
 		Returns the `ComplexType` corresponding to the given `Type` `t`.