浏览代码

support display on metadata arguments (closes #5635)

Simon Krajewski 9 年之前
父节点
当前提交
fef1e48192

+ 17 - 0
src/display/display.ml

@@ -179,6 +179,23 @@ module DisplayEmitter = struct
 		| DMUsage _ -> ef.ef_meta <- (Meta.Usage,[],p) :: ef.ef_meta;
 		| DMType -> raise (DisplayType (ef.ef_type,p,ef.ef_doc))
 		| _ -> ()
+
+	let display_meta dm meta = match dm.dms_kind with
+		| DMType ->
+			begin match meta with
+			| Meta.Custom _ | Meta.Dollar _ -> ()
+			| _ -> match MetaInfo.get_documentation meta with
+				| None -> ()
+				| Some (_,s) ->
+					(* TODO: hack until we support proper output for hover display mode *)
+					raise (Metadata ("<metadata>" ^ s ^ "</metadata>"));
+			end
+		| DMField ->
+			let all,_ = MetaInfo.get_documentation_list() in
+			let all = List.map (fun (s,doc) -> (s,FKMetadata,Some doc)) all in
+			raise (DisplayFields all)
+		| _ ->
+			()
 end
 
 module DocumentSymbols = struct

+ 1 - 1
src/display/displayOutput.ml

@@ -639,7 +639,7 @@ let handle_display_argument com file_pos pre_compilation did_something =
 		com.display <- DisplayMode.create (DMDiagnostics true);
 		Common.display_default := DMDiagnostics true;
 	| _ ->
-		let file, pos = try ExtString.String.split file_pos "@" with _ -> failwith ("Invalid format : " ^ file_pos) in
+		let file, pos = try ExtString.String.split file_pos "@" with _ -> failwith ("Invalid format: " ^ file_pos) in
 		let file = unquote file in
 		let pos, smode = try ExtString.String.split pos "@" with _ -> pos,"" in
 		let mode = match smode with

+ 10 - 20
src/typing/typeload.ml

@@ -1819,27 +1819,17 @@ let check_global_metadata ctx meta f_add mpath tpath so =
 		let add = ((field_mode && to_fields) || (not field_mode && to_types)) && (match_path recursive sl1 sl2) in
 		if add then f_add m
 	) ctx.g.global_metadata;
-	if ctx.is_display_file then match ctx.com.display.dms_kind with
-		| DMType ->
-			List.iter (fun (meta,_,p) ->
-				if Display.is_display_position p then match meta with
-				| Meta.Custom _ | Meta.Dollar _ -> ()
-				| _ -> match MetaInfo.get_documentation meta with
-					| None -> ()
-					| Some (_,s) ->
-						(* TODO: hack until we support proper output for hover display mode *)
-						 raise (Display.Metadata ("<metadata>" ^ s ^ "</metadata>"));
-			) meta
-		| DMField ->
-			List.iter (fun (meta,_,p) ->
-				if Display.is_display_position p then begin
-					let all,_ = MetaInfo.get_documentation_list() in
-					let all = List.map (fun (s,doc) -> (s,Display.FKMetadata,Some doc)) all in
-					raise (Display.DisplayFields all)
+	if ctx.is_display_file then begin
+		List.iter (fun (meta,args,p) ->
+			if Display.is_display_position p then Display.DisplayEmitter.display_meta ctx.com.display meta;
+			List.iter (fun e ->
+				if Display.is_display_position (pos e) then begin
+					let e = Display.ExprPreprocessing.process_expr ctx.com e in
+					ignore(type_expr ctx e Value);
 				end
-			) meta
-		| _ ->
-			()
+			) args
+		) meta
+	end
 
 let patch_class ctx c fields =
 	let path = match c.cl_kind with

+ 1 - 0
tests/display/src/DisplayTestCase.hx

@@ -20,6 +20,7 @@ class DisplayTestCase {
 	inline function usage(pos) return ctx.usage(pos);
 	inline function range(pos1, pos2) return ctx.range(pos1, pos2);
 	inline function signature(pos1) return ctx.signature(pos1);
+	inline function metadataDoc(pos1) return ctx.metadataDoc(pos1);
 
 	function assert(v:Bool) if (!v) throw "assertion failed";
 

+ 13 - 0
tests/display/src/DisplayTestContext.hx

@@ -73,6 +73,10 @@ class DisplayTestContext {
 		return haxe.Json.parse(callHaxe('$pos@signature'));
 	}
 
+	public function metadataDoc(pos:Position):String {
+		return extractMetadata(callHaxe('$pos@type'));
+	}
+
 	function callHaxe(displayPart:String):String {
 		var args = [
 			"-cp", "src",
@@ -153,6 +157,15 @@ class DisplayTestContext {
 		return ret;
 	}
 
+	static function extractMetadata(result:String) {
+		var xml = Xml.parse(result);
+		xml = xml.firstElement();
+		if (xml.nodeName != "metadata") {
+			return null;
+		}
+		return xml.firstChild().nodeValue;
+	}
+
 	static function normalizePath(p:String):String {
 		if (!haxe.io.Path.isAbsolute(p)) {
 			p = Sys.getCwd() + p;

+ 30 - 0
tests/display/src/cases/Metadata.hx

@@ -0,0 +1,30 @@
+package cases;
+
+class Metadata extends DisplayTestCase {
+	/**
+	@{-1-}
+	class Some { }
+	**/
+	function testCompletion() {
+		eq(true, hasPath(fields(pos(1)), "@:generic"));
+	}
+
+	/**
+	@:gen{-1-}eric
+	class Some { }
+	**/
+	function testHover() {
+		eq("Marks a class or class field as generic so each type parameter combination generates its own type/field", metadataDoc(pos(1)));
+	}
+
+	/**
+	{-1-}class SomeOther { }{-2-}
+
+	@:myMeta(Som{-3-}eOther)
+	class Some { }
+	**/
+	function testArgs() {
+		eq(range(1, 2), position(pos(3)));
+		eq("Class<cases.SomeOther>", type(pos(3)));
+	}
+}