瀏覽代碼

Ast.doc_block: preparation for @:inheritDoc (#8854)

Aleksandr Kuzmenko 5 年之前
父節點
當前提交
279f459a5b

+ 1 - 1
src/codegen/genxml.ml

@@ -52,7 +52,7 @@ let gen_doc s =
 let gen_doc_opt d =
 	match d with
 	| None -> []
-	| Some s -> [gen_doc s]
+	| Some d -> [gen_doc (Ast.gen_doc_text d)]
 
 let gen_arg_name (name,opt,_) =
 	(if opt then "?" else "") ^ name

+ 7 - 7
src/compiler/displayOutput.ml

@@ -71,8 +71,8 @@ let print_fields fields =
 		| ITModule path -> "type",snd path,"",None
 		| ITMetadata  meta ->
 			let s,(doc,_) = Meta.get_info meta in
-			"metadata","@" ^ s,"",Some doc
-		| ITTimer(name,value) -> "timer",name,"",Some value
+			"metadata","@" ^ s,"",doc_from_string doc
+		| ITTimer(name,value) -> "timer",name,"",doc_from_string value
 		| ITLiteral s ->
 			let t = match k.ci_type with None -> t_dynamic | Some (t,_) -> t in
 			"literal",s,s_type (print_context()) t,None
@@ -83,14 +83,14 @@ let print_fields fields =
 	let fields = List.sort (fun k1 k2 -> compare (legacy_sort k1) (legacy_sort k2)) fields in
 	let fields = List.map convert fields in
 	List.iter (fun(k,n,t,d) ->
-		let d = match d with None -> "" | Some d -> d in
+		let d = match d with None -> "" | Some d -> gen_doc_text d in
 		Buffer.add_string b (Printf.sprintf "<i n=\"%s\" k=\"%s\"><t>%s</t><d>%s</d></i>\n" n k (htmlescape t) (htmlescape d))
 	) fields;
 	Buffer.add_string b "</list>\n";
 	Buffer.contents b
 
-let maybe_print_doc d =
-	Option.map_default (fun s -> Printf.sprintf " d=\"%s\"" (htmlescape s)) "" d
+let maybe_print_doc d_opt =
+	Option.map_default (fun d -> Printf.sprintf " d=\"%s\"" (htmlescape (gen_doc_text d))) "" d_opt
 
 let print_toplevel il =
 	let b = Buffer.create 0 in
@@ -155,7 +155,7 @@ let print_signatures tl =
 	let b = Buffer.create 0 in
 	List.iter (fun (((args,ret),_),doc) ->
 		Buffer.add_string b "<type";
-		Option.may (fun s -> Buffer.add_string b (Printf.sprintf " d=\"%s\"" (htmlescape s))) doc;
+		Option.may (fun d -> Buffer.add_string b (Printf.sprintf " d=\"%s\"" (htmlescape (gen_doc_text d)))) doc;
 		Buffer.add_string b ">\n";
 		Buffer.add_string b (htmlescape (s_type (print_context()) (TFun(args,ret))));
 		Buffer.add_string b "\n</type>\n";
@@ -197,7 +197,7 @@ let print_signature tl display_arg =
 			"label",JString label;
 			"parameters",JArray parameters;
 		] in
-		JObject (match doc with None -> js | Some s -> ("documentation",JString s) :: js)
+		JObject (match doc with None -> js | Some d -> ("documentation",JString (gen_doc_text d)) :: js)
 	) tl in
 	let jo = JObject [
 		"signatures",JArray siginf;

+ 2 - 2
src/context/display/displayException.ml

@@ -154,7 +154,7 @@ let to_json ctx de =
 		let ctx = Genjson.create_context GMFull in
 		let fsig ((_,signature),doc) =
 			let fl = CompletionType.generate_function' ctx signature in
-			let fl = (match doc with None -> fl | Some s -> ("documentation",jstring s) :: fl) in
+			let fl = (match doc with None -> fl | Some d -> ("documentation",jstring (gen_doc_text d)) :: fl) in
 			jobject fl
 		in
 		let sigkind = match kind with
@@ -196,7 +196,7 @@ let to_json ctx de =
 			| _ -> jnull
 		in
 		jobject [
-			"documentation",jopt jstring (CompletionItem.get_documentation hover.hitem);
+			"documentation",jopt jstring (gen_doc_text_opt (CompletionItem.get_documentation hover.hitem));
 			"range",generate_pos_as_range hover.hpos;
 			"item",CompletionItem.to_json ctx None hover.hitem;
 			"expected",expected;

+ 1 - 1
src/context/display/displayFields.ml

@@ -265,7 +265,7 @@ let collect ctx e_ast e dk with_type p =
 	let items = match fst e_ast with
 		| EConst(String(s,_)) when String.length s = 1 ->
 			let cf = mk_field "code" ctx.t.tint e.epos null_pos in
-			cf.cf_doc <- Some "The character code of this character (inlined at compile-time).";
+			cf.cf_doc <- doc_from_string "The character code of this character (inlined at compile-time).";
 			cf.cf_kind <- Var { v_read = AccNormal; v_write = AccNever };
 			let ct = CompletionType.from_type (get_import_status ctx) ~values:(get_value_meta cf.cf_meta) cf.cf_type in
 			let item = make_ci_class_field (CompletionClassField.make cf CFSMember BuiltIn true) (cf.cf_type,ct) in

+ 22 - 2
src/core/ast.ml

@@ -234,7 +234,12 @@ and type_param = {
 	tp_meta : metadata;
 }
 
-and documentation = string option
+and doc_block = {
+	doc_own: string option;
+	mutable doc_inherited: (unit -> (string option)) list
+}
+
+and documentation = doc_block option
 
 and metadata_entry = (Meta.strict_meta * expr list * pos)
 and metadata = metadata_entry list
@@ -337,6 +342,21 @@ let is_lower_ident i =
 
 let pos = snd
 
+let doc_from_string s = Some { doc_own = Some s; doc_inherited = []; }
+
+let doc_from_string_opt = Option.map (fun s -> { doc_own = Some s; doc_inherited = []; })
+
+let gen_doc_text d =
+	let docs =
+		match d.doc_own with Some s -> [s] | None -> []
+	in
+	String.concat "\n" docs
+
+
+let gen_doc_text_opt = Option.map gen_doc_text
+
+let get_own_doc_opt = Option.map_default (fun d -> d.doc_own) None
+
 let rec is_postfix (e,_) op = match op with
 	| Increment | Decrement | Not -> true
 	| Neg | NegBits -> false
@@ -805,7 +825,7 @@ module Printer = struct
 		| CTIntersection tl -> String.concat "&" (List.map (fun (t,_) -> s_complex_type tabs t) tl)
 	and s_class_field tabs f =
 		match f.cff_doc with
-		| Some s -> "/**\n\t" ^ tabs ^ s ^ "\n**/\n"
+		| Some d -> "/**\n\t" ^ tabs ^ (gen_doc_text d) ^ "\n**/\n"
 		| None -> "" ^
 		if List.length f.cff_meta > 0 then String.concat ("\n" ^ tabs) (List.map (s_metadata tabs) f.cff_meta) else "" ^
 		if List.length f.cff_access > 0 then String.concat " " (List.map s_placed_access f.cff_access) else "" ^

+ 1 - 1
src/core/display/completionItem.ml

@@ -235,7 +235,7 @@ module CompletionModuleType = struct
 				("params",jlist (generate_ast_type_param ctx) cm.params) ::
 				("isExtern",jbool cm.is_extern) ::
 				("isFinal",jbool cm.is_final) ::
-				(if ctx.generation_mode = GMFull then ["doc",jopt jstring cm.doc] else [])
+				(if ctx.generation_mode = GMFull then ["doc",jopt jstring (gen_doc_text_opt cm.doc)] else [])
 			| GMMinimum ->
 				match generate_minimum_metadata ctx cm.meta with
 					| None -> []

+ 1 - 1
src/core/json/genjson.ml

@@ -72,7 +72,7 @@ let generate_expr_pos ctx p =
 	jtodo
 
 let generate_doc ctx d = match ctx.generation_mode with
-	| GMFull -> jopt jstring d
+	| GMFull -> jopt jstring (gen_doc_text_opt d)
 	| GMWithoutDoc | GMMinimum -> jnull
 
 (** return a range JSON structure for given position

+ 5 - 2
src/core/tPrinting.ml

@@ -452,7 +452,10 @@ module Printer = struct
 	let s_pmap fk fv pm =
 		"{" ^ (String.concat ", " (PMap.foldi (fun k v acc -> (Printf.sprintf "%s = %s" (fk k) (fv v)) :: acc) pm [])) ^ "}"
 
-	let s_doc = s_opt (fun s -> s)
+	let s_doc doc_opt =
+		match doc_opt with
+		| None -> "None"
+		| Some d -> gen_doc_text d
 
 	let s_metadata_entry (s,el,_) =
 		Printf.sprintf "@%s%s" (Meta.to_string s) (match el with [] -> "" | el -> "(" ^ (String.concat ", " (List.map Ast.Printer.s_expr el)) ^ ")")
@@ -638,7 +641,7 @@ module Printer = struct
 	let s_class_field cff =
 		s_record_fields "" [
 			"cff_name",s_placed (fun s -> s) cff.cff_name;
-			"cff_doc",s_opt (fun s -> s) cff.cff_doc;
+			"cff_doc",s_doc cff.cff_doc;
 			"cff_pos",s_pos cff.cff_pos;
 			"cff_meta",s_metadata cff.cff_meta;
 			"cff_access",s_list ", " Ast.s_placed_access cff.cff_access;

+ 7 - 7
src/generators/genphp7.ml

@@ -3199,7 +3199,7 @@ class enum_builder ctx (enm:tenum) =
 			E.g. "class SomeClass extends Another implements IFace"
 		*)
 		method private write_declaration =
-			self#write_doc (DocClass enm.e_doc);
+			self#write_doc (DocClass (gen_doc_text_opt enm.e_doc));
 			writer#write ("class " ^ self#get_name ^ " extends " ^ (writer#use hxenum_type_path))
 		(**
 			Writes type body to output buffer.
@@ -3228,7 +3228,7 @@ class enum_builder ctx (enm:tenum) =
 					| _ -> fail field.ef_pos __POS__
 			in
 			writer#indent 1;
-			self#write_doc (DocMethod (args, TEnum (enm, []), field.ef_doc));
+			self#write_doc (DocMethod (args, TEnum (enm, []), (gen_doc_text_opt field.ef_doc)));
 			writer#write_with_indentation ("static public function " ^ name ^ " (");
 			write_args writer#write (writer#write_arg true) args;
 			writer#write ") {\n";
@@ -3419,7 +3419,7 @@ class class_builder ctx (cls:tclass) =
 			E.g. "class SomeClass extends Another implements IFace"
 		*)
 		method private write_declaration =
-			self#write_doc (DocClass cls.cl_doc);
+			self#write_doc (DocClass (gen_doc_text_opt cls.cl_doc));
 			if self#is_final then writer#write "final ";
 			writer#write (if cls.cl_interface then "interface " else "class ");
 			writer#write self#get_name;
@@ -3652,7 +3652,7 @@ class class_builder ctx (cls:tclass) =
 		*)
 		method private write_var field is_static =
 			writer#indent 1;
-			self#write_doc (DocVar (writer#use_t field.cf_type, field.cf_doc));
+			self#write_doc (DocVar (writer#use_t field.cf_type, (gen_doc_text_opt field.cf_doc)));
 			writer#write_indentation;
 			if is_static then writer#write "static ";
 			let visibility = get_visibility field.cf_meta in
@@ -3679,7 +3679,7 @@ class class_builder ctx (cls:tclass) =
 				| Some expr when not (is_constant expr) -> ()
 				| Some expr ->
 					writer#indent 1;
-					self#write_doc (DocVar (writer#use_t field.cf_type, field.cf_doc));
+					self#write_doc (DocVar (writer#use_t field.cf_type, (gen_doc_text_opt field.cf_doc)));
 					writer#write_with_indentation ("const " ^ (field_name field) ^ " = ");
 					writer#write_expr expr;
 					writer#write ";\n"
@@ -3692,7 +3692,7 @@ class class_builder ctx (cls:tclass) =
 			writer#indent 1;
 			let (args, return_type) = get_function_signature field in
 			List.iter (fun (arg_name, _, _) -> writer#declared_local_var arg_name) args;
-			self#write_doc (DocMethod (args, return_type, field.cf_doc));
+			self#write_doc (DocMethod (args, return_type, (gen_doc_text_opt field.cf_doc)));
 			writer#write_indentation;
 			if self#is_final_field field then writer#write "final ";
 			writer#write ((get_visibility field.cf_meta) ^ " ");
@@ -3718,7 +3718,7 @@ class class_builder ctx (cls:tclass) =
 			writer#indent 1;
 			let (args, return_type) = get_function_signature field in
 			List.iter (fun (arg_name, _, _) -> writer#declared_local_var arg_name) args;
-			self#write_doc (DocMethod (args, return_type, field.cf_doc));
+			self#write_doc (DocMethod (args, return_type, (gen_doc_text_opt field.cf_doc)));
 			writer#write_with_indentation ((get_visibility field.cf_meta) ^ " function " ^ (field_name field));
 			(match field.cf_expr with
 				| None -> (* interface *)

+ 10 - 8
src/macro/macroApi.ml

@@ -336,7 +336,7 @@ and encode_field (f:class_field) =
 	encode_obj [
 		"name",encode_placed_name f.cff_name;
 		"name_pos", encode_pos (pos f.cff_name);
-		"doc", null encode_string f.cff_doc;
+		"doc", null encode_string (gen_doc_text_opt f.cff_doc);
 		"pos", encode_pos f.cff_pos;
 		"kind", encode_enum IField tag pl;
 		"meta", encode_meta_content f.cff_meta;
@@ -673,6 +673,8 @@ and decode_meta_entry v =
 
 and decode_meta_content m = decode_opt_array decode_meta_entry m
 
+and decode_doc = opt (fun s -> { doc_own = Some (decode_string s); doc_inherited = [] })
+
 and decode_field v =
 	let fkind = match decode_enum (field v "kind") with
 		| 0, [t;e] ->
@@ -687,7 +689,7 @@ and decode_field v =
 	let pos = decode_pos (field v "pos") in
 	{
 		cff_name = (decode_string (field v "name"),decode_pos_default (field v "name_pos") pos);
-		cff_doc = opt decode_string (field v "doc");
+		cff_doc = decode_doc (field v "doc");
 		cff_pos = pos;
 		cff_kind = fkind;
 		cff_access = List.map decode_access (opt_list decode_array (field v "access"));
@@ -880,7 +882,7 @@ let rec encode_mtype t fields =
 		"module", encode_string (s_type_path i.mt_module.m_path);
 		"isPrivate", vbool i.mt_private;
 		"meta", encode_meta i.mt_meta (fun m -> i.mt_meta <- m);
-		"doc", null encode_string i.mt_doc;
+		"doc", null encode_string (get_own_doc_opt i.mt_doc);
 		"params", encode_type_params i.mt_params;
 	] @ fields)
 
@@ -916,7 +918,7 @@ and encode_efield f =
 		"namePos", encode_pos f.ef_name_pos;
 		"index", vint f.ef_index;
 		"meta", encode_meta f.ef_meta (fun m -> f.ef_meta <- m);
-		"doc", null encode_string f.ef_doc;
+		"doc", null encode_string (get_own_doc_opt f.ef_doc);
 		"params", encode_type_params f.ef_params;
 	]
 
@@ -934,7 +936,7 @@ and encode_cfield f =
 		"kind", encode_field_kind f.cf_kind;
 		"pos", encode_pos f.cf_pos;
 		"namePos",encode_pos f.cf_name_pos;
-		"doc", null encode_string f.cf_doc;
+		"doc", null encode_string (get_own_doc_opt f.cf_doc);
 		"overloads", encode_ref f.cf_overloads (encode_and_map_array encode_cfield) (fun() -> "overloads");
 		"isExtern", vbool (has_class_field_flag f CfExtern);
 		"isFinal", vbool (has_class_field_flag f CfFinal);
@@ -1307,7 +1309,7 @@ let decode_cfield v =
 		cf_type = decode_type (field v "type");
 		cf_pos = decode_pos (field v "pos");
 		cf_name_pos = decode_pos (field v "namePos");
-		cf_doc = opt decode_string (field v "doc");
+		cf_doc = decode_doc (field v "doc");
 		cf_meta = []; (* TODO *)
 		cf_kind = decode_field_kind (field v "kind");
 		cf_params = decode_type_params (field v "params");
@@ -1329,7 +1331,7 @@ let decode_efield v =
 		ef_name_pos = decode_pos (field v "namePos");
 		ef_index = decode_int (field v "index");
 		ef_meta = []; (* TODO *)
-		ef_doc = opt decode_string (field v "doc");
+		ef_doc = decode_doc (field v "doc");
 		ef_params = decode_type_params (field v "params")
 	}
 
@@ -1413,7 +1415,7 @@ let decode_type_def v =
 	let pos = decode_pos (field v "pos") in
 	let isExtern = decode_opt_bool (field v "isExtern") in
 	let fields = List.map decode_field (decode_array (field v "fields")) in
-	let doc = opt decode_string (field v "doc") in
+	let doc = decode_doc (field v "doc") in
 	let mk fl dl =
 		{
 			d_name = name;

+ 6 - 6
src/syntax/grammar.mly

@@ -156,7 +156,7 @@ and parse_abstract doc meta flags = parser
 		let flags = (match st with None -> flags | Some t -> AbOver t :: flags) in
 		({
 			d_name = name;
-			d_doc = doc;
+			d_doc = doc_from_string_opt doc;
 			d_meta = meta;
 			d_params = tl;
 			d_flags = flags @ sl;
@@ -176,7 +176,7 @@ and parse_type_decl mode s =
 			| [< name = type_name; tl = parse_constraint_params; '(BrOpen,_); l = plist parse_enum; '(BrClose,p2) >] ->
 				(EEnum {
 					d_name = name;
-					d_doc = doc;
+					d_doc = doc_from_string_opt doc;
 					d_meta = meta;
 					d_params = tl;
 					d_flags = List.map decl_flag_to_enum_flag c;
@@ -218,7 +218,7 @@ and parse_type_decl mode s =
 			let fl, p2 = parse_class_fields false p1 s in
 			(EClass {
 				d_name = name;
-				d_doc = doc;
+				d_doc = doc_from_string_opt doc;
 				d_meta = meta;
 				d_params = tl;
 				d_flags = List.map decl_flag_to_class_flag c @ n @ hl;
@@ -230,7 +230,7 @@ and parse_type_decl mode s =
 			| [< >] -> ());
 			(ETypedef {
 				d_name = name;
-				d_doc = doc;
+				d_doc = doc_from_string_opt doc;
 				d_meta = meta;
 				d_params = tl;
 				d_flags = List.map decl_flag_to_enum_flag c;
@@ -757,7 +757,7 @@ and parse_enum s =
 		) in
 		{
 			ec_name = name,p1;
-			ec_doc = doc;
+			ec_doc = doc_from_string_opt doc;
 			ec_meta = meta;
 			ec_args = args;
 			ec_params = params;
@@ -868,7 +868,7 @@ and parse_class_field tdecl s =
 		in
 		{
 			cff_name = name;
-			cff_doc = doc;
+			cff_doc = doc_from_string_opt doc;
 			cff_meta = meta;
 			cff_access = al;
 			cff_pos = pos;

+ 1 - 1
src/syntax/reification.ml

@@ -195,7 +195,7 @@ let reify in_macro =
 		in
 		let fields = [
 			Some ("name", to_placed_name f.cff_name);
-			(match f.cff_doc with None -> None | Some s -> Some ("doc", to_string s p));
+			(match f.cff_doc with None -> None | Some d -> Some ("doc", to_string (gen_doc_text d) p));
 			(match f.cff_access with [] -> None | l -> Some ("access", to_array to_access l p));
 			Some ("kind", to_kind f.cff_kind);
 			Some ("pos", to_pos f.cff_pos);

+ 1 - 1
src/typing/typeloadParse.ml

@@ -182,7 +182,7 @@ module ConditionDisplay = struct
 								cf_type = t;
 								cf_pos = null_pos;
 								cf_name_pos = null_pos;
-								cf_doc = Some (
+								cf_doc = doc_from_string (
 "Allows comparing defines (such as the version of a Haxelib or Haxe) with SemVer semantics.
 Both the define and the string passed to `version()` must be valid semantic versions.
 

+ 3 - 3
src/typing/typerDisplay.ml

@@ -149,7 +149,7 @@ let raise_toplevel ctx dk with_type (subject,psubject) =
 
 let display_dollar_type ctx p make_type =
 	let mono = mk_mono() in
-	let doc = Some "Outputs type of argument as a warning and uses argument as value" in
+	let doc = doc_from_string "Outputs type of argument as a warning and uses argument as value" in
 	let arg = ["expression",false,mono] in
 	begin match ctx.com.display.dms_kind with
 	| DMSignature ->
@@ -263,7 +263,7 @@ let rec handle_signature_display ctx e_ast with_type =
 			begin match follow e1.etype with
 			| TInst({cl_path=([],"Array")},[t]) ->
 				let res = convert_function_signature ctx PMap.empty (["index",false,ctx.t.tint],t) in
-				raise_signatures [res,Some "The array index"] 0 0 SKCall
+				raise_signatures [res,doc_from_string "The array index"] 0 0 SKCall
 			| TAbstract(a,tl) ->
 				(match a.a_impl with Some c -> ignore(c.cl_build()) | _ -> ());
 				let sigs = ExtList.List.filter_map (fun cf -> match follow cf.cf_type with
@@ -495,7 +495,7 @@ let handle_display ?resume_typing ctx e_ast dk with_type =
 	| (EConst (Ident "$type"),p),_ ->
 		display_dollar_type ctx p tpair
 	| (EConst (Ident "trace"),_),_ ->
-		let doc = Some "Print given arguments" in
+		let doc = doc_from_string "Print given arguments" in
 		let arg = ["value",false,t_dynamic] in
 		let ret = ctx.com.basic.tvoid in
 		let p = pos e_ast in