浏览代码

[display] resolve all macro class fields to their macro version

closes #7703
Simon Krajewski 5 年之前
父节点
当前提交
92a707446b

+ 24 - 0
src/context/display/displayToplevel.ml

@@ -27,6 +27,14 @@ open DisplayTypes
 open Genjson
 open Globals
 
+let maybe_resolve_macro_field ctx t c cf =
+	try
+		if cf.cf_kind <> Method MethMacro then raise Exit;
+		let _,_,(tl,tr,c,cf) = ctx.g.do_load_macro ctx false c.cl_path cf.cf_name null_pos in
+		(TFun(tl,tr)),c,cf
+	with _ ->
+		t,c,cf
+
 let exclude : string list ref = ref []
 
 class explore_class_path_task cs com recursive f_pack f_module dir pack = object(self)
@@ -268,6 +276,22 @@ let collect ctx tk with_type sort =
 		) ctx.locals;
 
 		let add_field scope origin cf =
+			let origin,cf = match origin with
+				| Self (TClassDecl c) ->
+					let _,c,cf = maybe_resolve_macro_field ctx cf.cf_type c cf in
+					Self (TClassDecl c),cf
+				| StaticImport (TClassDecl c) ->
+					let _,c,cf = maybe_resolve_macro_field ctx cf.cf_type c cf in
+					StaticImport (TClassDecl c),cf
+				| Parent (TClassDecl c) ->
+					let _,c,cf = maybe_resolve_macro_field ctx cf.cf_type c cf in
+					Parent (TClassDecl c),cf
+				| StaticExtension (TClassDecl c) ->
+					let _,c,cf = maybe_resolve_macro_field ctx cf.cf_type c cf in
+					StaticExtension (TClassDecl c),cf
+				| _ ->
+					origin,cf
+			in
 			let is_qualified = is_qualified cctx cf.cf_name in
 			add (make_ci_class_field (CompletionClassField.make cf scope origin is_qualified) (tpair ~values:(get_value_meta cf.cf_meta) cf.cf_type)) (Some cf.cf_name)
 		in

+ 1 - 0
src/context/typecore.ml

@@ -88,6 +88,7 @@ type typer_globals = {
 	do_inherit : typer -> Type.tclass -> pos -> (bool * placed_type_path) -> bool;
 	do_create : Common.context -> typer;
 	do_macro : typer -> macro_mode -> path -> string -> expr list -> pos -> expr option;
+	do_load_macro : typer -> bool -> path -> string -> pos -> (path * string option * (((string * bool * t) list * t * tclass * Type.tclass_field)));
 	do_load_module : typer -> path -> pos -> module_def;
 	do_load_type_def : typer -> pos -> type_path -> module_type;
 	do_optimize : typer -> texpr -> texpr;

+ 6 - 1
src/typing/macroContext.ml

@@ -516,7 +516,7 @@ let load_macro_module ctx cpath display p =
 	};
 	mloaded,(fun () -> mctx.com.display <- old)
 
-let load_macro ctx display cpath f p =
+let load_macro' ctx display cpath f p =
 	let api, mctx = get_macro_context ctx p in
 	let mint = Interp.get_ctx() in
 	let cpath, sub = (match List.rev (fst cpath) with
@@ -552,6 +552,11 @@ let load_macro ctx display cpath f p =
 		meth
 	in
 	add_dependency ctx.m.curmod mloaded;
+	cpath,sub,meth
+
+let load_macro ctx display cpath f p =
+	let cpath,sub,meth = load_macro' ctx display cpath f p in
+	let api, mctx = get_macro_context ctx p in
 	let call args =
 		if ctx.com.verbose then Common.log ctx.com ("Calling macro " ^ s_type_path cpath ^ "." ^ f ^ " (" ^ p.pfile ^ ":" ^ string_of_int (Lexer.get_error_line p) ^ ")");
 		let t = macro_timer ctx ["execution";s_type_path cpath ^ "." ^ f] in

+ 3 - 2
src/typing/typer.ml

@@ -1250,7 +1250,7 @@ and type_ident ctx i p mode =
 			end
 
 and handle_efield ctx e p0 mode =
-	let open TyperDotPath in 
+	let open TyperDotPath in
 
 	let dot_path first pnext =
 		let name,_,p = first in
@@ -1291,7 +1291,7 @@ and handle_efield ctx e p0 mode =
 							else
 								DisplayToplevel.collect_and_raise ctx TKType WithType.no_value (CRToplevel None) (String.concat "." sl,p0) p0
 						end;
-						raise e						
+						raise e
 	in
 
 	(* loop through the given EField expression to figure out whether it's a dot-path that we have to resolve,
@@ -2527,6 +2527,7 @@ let rec create com =
 			do_inherit = MagicTypes.on_inherit;
 			do_create = create;
 			do_macro = MacroContext.type_macro;
+			do_load_macro = MacroContext.load_macro';
 			do_load_module = TypeloadModule.load_module;
 			do_load_type_def = Typeload.load_type_def;
 			do_optimize = Optimizer.reduce_expression;

+ 12 - 6
src/typing/typerDisplay.ml

@@ -49,6 +49,7 @@ let completion_item_of_expr ctx e =
 	let rec loop e = match e.eexpr with
 		| TLocal v | TVar(v,_) -> make_ci_local v (tpair ~values:(get_value_meta v.v_meta) v.v_type)
 		| TField(e1,FStatic(c,cf)) ->
+			let te,c,cf = DisplayToplevel.maybe_resolve_macro_field ctx e.etype c cf in
 			Display.merge_core_doc ctx (TClassDecl c);
 			let decl = decl_of_class c in
 			let origin = match c.cl_kind,e1.eexpr with
@@ -60,8 +61,9 @@ let completion_item_of_expr ctx e =
 				| KAbstractImpl a when Meta.has Meta.Enum cf.cf_meta -> make_ci_enum_abstract_field a
 				| _ -> make_ci_class_field
 			in
-			of_field e origin cf CFSStatic make_ci
+			of_field {e with etype = te} origin cf CFSStatic make_ci
 		| TField(e1,(FInstance(c,_,cf) | FClosure(Some(c,_),cf))) ->
+			let te,c,cf = DisplayToplevel.maybe_resolve_macro_field ctx e.etype c cf in
 			Display.merge_core_doc ctx (TClassDecl c);
 			let origin = match follow e1.etype with
 			| TInst(c',_) when c != c' ->
@@ -69,7 +71,7 @@ let completion_item_of_expr ctx e =
 			| _ ->
 				Self (TClassDecl c)
 			in
-			of_field e origin cf CFSMember make_ci_class_field
+			of_field {e with etype = te} origin cf CFSMember make_ci_class_field
 		| TField(_,FEnum(en,ef)) -> of_enum_field e (Self (TEnumDecl en)) ef
 		| TField(e1,(FAnon cf | FClosure(None,cf))) ->
 			begin match follow e1.etype with
@@ -244,10 +246,14 @@ let rec handle_signature_display ctx e_ast with_type =
 			in
 			let tl = match e1.eexpr with
 				| TField(_,fa) ->
-					begin match extract_field fa with
-						| Some cf -> (e1.etype,cf.cf_doc,get_value_meta cf.cf_meta) :: List.rev_map (fun cf' -> cf'.cf_type,cf.cf_doc,get_value_meta cf'.cf_meta) cf.cf_overloads
-						| None -> [e1.etype,None,PMap.empty]
-					end
+					let f (t,_,cf) =
+						(t,cf.cf_doc,get_value_meta cf.cf_meta) :: List.rev_map (fun cf' -> cf'.cf_type,cf.cf_doc,get_value_meta cf'.cf_meta) cf.cf_overloads
+					in
+					begin match fa with
+						| FStatic(c,cf) | FInstance(c,_,cf) -> f (DisplayToplevel.maybe_resolve_macro_field ctx e1.etype c cf)
+						| FAnon cf | FClosure(_,cf) -> f (e1.etype,null_class,cf)
+						| _ -> [e1.etype,None,PMap.empty]
+					end;
 				| TConst TSuper ->
 					find_constructor_types e1.etype
 				| TLocal v ->

+ 23 - 0
tests/display/src/cases/Issue7703.hx

@@ -0,0 +1,23 @@
+package cases;
+
+class Issue7703 extends DisplayTestCase {
+	/**
+		class Main {
+		public static function main() {
+			f{-1-}oo({-2-}"");
+			{-3-}
+		}
+
+		static macro function foo(s:String) {
+			return macro {};
+		}
+		}
+	**/
+	function test() {
+		var expectedType = "(s : String) -> haxe.macro.Expr";
+		var fields = toplevel(pos(1));
+		eq(true, hasToplevel(fields, "static", "foo", expectedType));
+		eq(expectedType, type(pos(1)));
+		sigEq(0, [["s:String"]], signature(pos(2)));
+	}
+}