Ver código fonte

allow field completion on @ for metadata

Simon Krajewski 9 anos atrás
pai
commit
09af1eee07
4 arquivos alterados com 47 adições e 27 exclusões
  1. 2 13
      src/main.ml
  2. 9 5
      src/syntax/parser.ml
  3. 15 0
      src/typing/common.ml
  4. 21 9
      src/typing/typeload.ml

+ 2 - 13
src/main.ml

@@ -1407,19 +1407,8 @@ try
 			did_something := true
 		),": print help for all compiler specific defines");
 		("--help-metas", Arg.Unit (fun() ->
-			let m = ref 0 in
-			let rec loop i =
-				let d = Obj.magic i in
-				if d <> Meta.Last then begin match MetaInfo.get_documentation d with
-					| None -> loop (i + 1)
-					| Some (str,desc) ->
-						if String.length str > !m then m := String.length str;
-						 (str,desc) :: loop (i + 1)
-				end else
-					[]
-			in
-			let all = List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) (loop 0) in
-			let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" !m n (limit_string doc (!m + 3))) all in
+			let all,max_length = MetaInfo.get_documentation_list() in
+			let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" max_length n (limit_string doc (max_length + 3))) all in
 			List.iter (fun msg -> ctx.com.print (msg ^ "\n")) all;
 			did_something := true
 		),": print help for all compiler metadatas");

+ 9 - 5
src/syntax/parser.ml

@@ -842,17 +842,21 @@ and parse_meta_params pname s = match s with parser
 	| [< >] -> []
 
 and parse_meta_entry = parser
-	[< '(At,_); name,p = meta_name; params = parse_meta_params p; s >] -> (name,params,p)
+	[< '(At,p1); s >] ->
+		match s with parser
+		| [< name,p = meta_name p1; params = parse_meta_params p; s >] -> (name,params,p)
+		| [< >] ->
+			if is_resuming p1 then (Meta.Last,[],p1) else serror()
 
 and parse_meta = parser
 	| [< entry = parse_meta_entry; s >] ->
 		entry :: parse_meta s
 	| [< >] -> []
 
-and meta_name = parser
-	| [< '(Const (Ident i),p) >] -> (Meta.Custom i), p
-	| [< '(Kwd k,p) >] -> (Meta.Custom (s_keyword k)),p
-	| [< '(DblDot,_); s >] -> match s with parser
+and meta_name p1 = parser
+	| [< '(Const (Ident i),p) when p.pmin = p1.pmax >] -> (Meta.Custom i), p
+	| [< '(Kwd k,p) when p.pmin = p1.pmax >] -> (Meta.Custom (s_keyword k)),p
+	| [< '(DblDot,p) when p.pmin = p1.pmax; s >] -> match s with parser
 		| [< '(Const (Ident i),p) >] -> (Common.MetaInfo.parse i), p
 		| [< '(Kwd k,p) >] -> (Common.MetaInfo.parse (s_keyword k)),p
 

+ 15 - 0
src/typing/common.ml

@@ -762,6 +762,21 @@ module MetaInfo = struct
 			Some (str,params ^ doc ^ pfs)
 		end else
 			None
+
+	let get_documentation_list () =
+		let m = ref 0 in
+		let rec loop i =
+			let d = Obj.magic i in
+			if d <> Meta.Last then begin match get_documentation d with
+				| None -> loop (i + 1)
+				| Some (str,desc) ->
+					if String.length str > !m then m := String.length str;
+						(str,desc) :: loop (i + 1)
+			end else
+				[]
+		in
+		let all = List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) (loop 0) in
+		all,!m
 end
 
 let stats =

+ 21 - 9
src/typing/typeload.ml

@@ -1820,15 +1820,27 @@ 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 && ctx.com.display.dms_kind = DMType then
-		List.iter (fun (meta,_,p) -> 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 *)
-					if Display.is_display_position p then raise (Display.Metadata ("<metadata>" ^ s ^ "</metadata>"));
-		) meta
+	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
+		| DMDefault ->
+			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,t_dynamic,None,Some doc)) all in
+					raise (Display.DisplayFields all)
+				end
+			) meta
+		| _ ->
+			()
 
 let patch_class ctx c fields =
 	let path = match c.cl_kind with