Răsfoiți Sursa

allowed parametrized type parameters at syntax level

Nicolas Cannasse 13 ani în urmă
părinte
comite
a6418590b1
6 a modificat fișierele cu 65 adăugiri și 37 ștergeri
  1. 12 5
      ast.ml
  2. 17 13
      interp.ml
  3. 16 7
      parser.ml
  4. 8 2
      std/haxe/macro/Expr.hx
  5. 10 8
      typeload.ml
  6. 2 2
      typer.ml

+ 12 - 5
ast.ml

@@ -196,7 +196,11 @@ and expr_def =
 
 and expr = expr_def * pos
 
-and type_param = string * complex_type list
+and type_param = {
+	tp_name : string;
+	tp_params :	type_param list;
+	tp_constraints : complex_type list;
+}
 
 and documentation = string option
 
@@ -477,9 +481,11 @@ let map_expr loop (e,p) =
 		| CTParent t -> CTParent (ctype t)
 		| CTExtend (t,fl) -> CTExtend (tpath t, List.map cfield fl)
 		| CTOptional t -> CTOptional (ctype t)
+	and tparamdecl t =
+		{ tp_name = t.tp_name; tp_constraints = List.map ctype t.tp_constraints; tp_params = List.map tparamdecl t.tp_params }
 	and func f =
 		{	
-			f_params = List.map (fun (n,tl) -> n,List.map ctype tl)  f.f_params;
+			f_params = List.map tparamdecl f.f_params;
 			f_args = List.map (fun (n,o,t,e) -> n,o,opt ctype t,opt loop e) f.f_args;
 			f_type = opt ctype f.f_type;
 			f_expr = opt loop f.f_expr;
@@ -618,10 +624,11 @@ let reify in_macro =
 			] in
 			to_obj (match e with None -> fields | Some e -> fields @ ["value",to_expr e p]) p
 		in
-		let fparam (n,tl) p =
+		let rec fparam t p =
 			let fields = [
-				"name", to_string n p;
-				"constraints", to_array to_ctype tl p;
+				"name", to_string t.tp_name p;
+				"constraints", to_array to_ctype t.tp_constraints p;
+				"params", to_array fparam t.tp_params p;
 			] in
 			to_obj fields p
 		in

+ 17 - 13
interp.ml

@@ -3426,14 +3426,16 @@ and encode_ctype t =
 	in
 	enc_enum ICType tag pl
 
+and encode_tparam_decl tp =
+	enc_obj [
+		"name", enc_string tp.tp_name;
+		"params", enc_array (List.map encode_tparam_decl tp.tp_params);
+		"constraints", enc_array (List.map encode_ctype tp.tp_constraints);
+	]
+
 and encode_fun f =
 	enc_obj [
-		"params", enc_array (List.map (fun (n,cl) ->
-			enc_obj [
-				"name", enc_string n;
-				"constraints", enc_array (List.map encode_ctype cl);
-			]
-		) f.f_params);
+		"params", enc_array (List.map encode_tparam_decl f.f_params);
 		"args", enc_array (List.map (fun (n,opt,t,e) ->
 			enc_obj [
 				"name", enc_string n;
@@ -3636,11 +3638,16 @@ and decode_tparam v =
 	| 1,[e] -> TPExpr (decode_expr e)
 	| _ -> raise Invalid_expr
 
+and decode_tparam_decl v =
+	{
+		tp_name = dec_string (field v "name");
+		tp_constraints = (match field v "constraints" with VNull -> [] | a -> List.map decode_ctype (dec_array a));
+		tp_params = (match field v "params" with VNull -> [] | a -> List.map decode_tparam_decl (dec_array a));
+	}
+
 and decode_fun v =
 	{
-		f_params = List.map (fun v ->
-			(dec_string (field v "name"), List.map decode_ctype (dec_array (field v "constraints")))
-		) (dec_array (field v "params"));
+		f_params = List.map decode_tparam_decl (dec_array (field v "params"));
 		f_args = List.map (fun o ->
 			(dec_string (field o "name"),dec_bool (field o "opt"),opt decode_ctype (field o "type"),opt decode_expr (field o "value"))
 		) (dec_array (field v "args"));
@@ -4038,15 +4045,12 @@ let decode_type_def v =
 	let meta = decode_meta_content (field v "meta") in
 	let pos = decode_pos (field v "pos") in
 	let isExtern = dec_bool (field v "isExtern") in
-	let params = List.map (fun v ->
-		(dec_string (field v "name"), List.map decode_ctype (dec_array (field v "constraints")))
-	) (dec_array (field v "params")) in
 	let fields = List.map decode_field (dec_array (field v "fields")) in
 	let mk fl dl =
 		{
 			d_name = name;
 			d_doc = None;
-			d_params = params;
+			d_params = List.map decode_tparam_decl (dec_array (field v "params"));
 			d_meta = meta;
 			d_flags = fl;
 			d_data = dl;

+ 16 - 7
parser.ml

@@ -536,13 +536,22 @@ and parse_constraint_params = parser
 
 and parse_constraint_param = parser
 	| [< name = type_name; s >] ->
-		match s with parser
-		| [< '(DblDot,_); s >] ->
-			(match s with parser
-			| [< '(POpen,_); l = psep Comma parse_complex_type; '(PClose,_) >] -> (name,l)
-			| [< t = parse_complex_type >] -> (name,[t])
-			| [< >] -> serror())
-		| [< >] -> (name,[])
+		let params = (match s with parser
+			| [< >] -> []
+		) in
+		let ctl = (match s with parser
+			| [< '(DblDot,_); s >] ->
+				(match s with parser
+				| [< '(POpen,_); l = psep Comma parse_complex_type; '(PClose,_) >] -> l
+				| [< t = parse_complex_type >] -> [t]
+				| [< >] -> serror())
+			| [< >] -> []
+		) in
+		{
+			tp_name = name;
+			tp_params = params;
+			tp_constraints = ctl;
+		}
 
 and parse_class_herit = parser
 	| [< '(Kwd Extends,_); t = parse_type_path >] -> HExtends t

+ 8 - 2
std/haxe/macro/Expr.hx

@@ -147,11 +147,17 @@ enum TypeParam {
 	TPExpr( e : Expr );
 }
 
+typedef TypeParamDecl = {
+	var name : String;
+	@:optional var constraints : Array<ComplexType>;
+	@:optional var params : Array<TypeParamDecl>;
+}
+
 typedef Function = {
 	var args : Array<FunctionArg>;
 	var ret : Null<ComplexType>;
 	var expr : Null<Expr>;
-	var params : Array<{ name : String, constraints : Array<ComplexType> }>;
+	var params : Array<TypeParamDecl>;
 }
 
 typedef FunctionArg = {
@@ -192,7 +198,7 @@ typedef TypeDefinition = {
 	var name : String;
 	var pos : Position;
 	var meta : Metadata;
-	var params : Array<{ name : String, constraints : Array<ComplexType> }>;
+	var params : Array<TypeParamDecl>;
 	var isExtern : Bool;
 	var kind : TypeDefKind;
 	var fields : Array<Field>;

+ 10 - 8
typeload.ml

@@ -616,10 +616,12 @@ let set_heritance ctx c herits p =
 	) herits in
 	List.iter loop (List.filter (ctx.g.do_inherit ctx c p) herits)
 
-let type_type_params ctx path get_params p (n,flags) =
+let rec type_type_params ctx path get_params p tp =
+	let n = tp.tp_name in
 	let c = mk_class ctx.current (fst path @ [snd path],n) p in
-	let t = TInst (c,[]) in
-	match flags with
+	c.cl_types <- List.map (type_type_params ctx c.cl_path get_params p) tp.tp_params;
+	let t = TInst (c,List.map snd c.cl_types) in	
+	match tp.tp_constraints with
 	| [] -> 
 		c.cl_kind <- KTypeParameter [];
 		n, t
@@ -627,7 +629,7 @@ let type_type_params ctx path get_params p (n,flags) =
 		let r = exc_protect ctx (fun r ->
 			r := (fun _ -> t);
 			let ctx = { ctx with type_params = ctx.type_params @ get_params() } in
-			c.cl_kind <- KTypeParameter (List.map (load_complex_type ctx p) flags);
+			c.cl_kind <- KTypeParameter (List.map (load_complex_type ctx p) tp.tp_constraints);
 			t
 		) in
 		delay ctx (fun () -> ignore(!r()));
@@ -635,8 +637,8 @@ let type_type_params ctx path get_params p (n,flags) =
 
 let type_function_params ctx fd fname p =
 	let params = ref [] in
-	params := List.map (fun (n,flags) ->
-		type_type_params ctx ([],fname) (fun() -> !params) p (n,flags)
+	params := List.map (fun tp ->
+		type_type_params ctx ([],fname) (fun() -> !params) p tp
 	) fd.f_params;
 	!params
 
@@ -1569,8 +1571,8 @@ let parse_module ctx m p =
 						{
 							tpackage = !remap;
 							tname = d.d_name;
-							tparams = List.map (fun (s,_) ->
-								TPType (CTPath { tpackage = []; tname = s; tparams = []; tsub = None; })
+							tparams = List.map (fun tp ->
+								TPType (CTPath { tpackage = []; tname = tp.tp_name; tparams = []; tsub = None; })
 							) d.d_params;
 							tsub = None;
 						});

+ 2 - 2
typer.ml

@@ -1996,12 +1996,12 @@ and type_expr ctx ?(need_val=true) (e,p) =
 	| EUnop (op,flag,e) ->
 		type_unop ctx op flag e p
 	| EFunction (name,f) ->
-		let params = Typeload.type_function_params ctx f "localfun" p in
+		let params = Typeload.type_function_params ctx f (match name with None -> "localfun" | Some n -> n) p in
 		if params <> [] then begin
 			if name = None then display_error ctx "Type parameters not supported in unnamed local functions" p;
 			if need_val then error "Type parameters are not supported for rvalue functions" p
 		end else
-			List.iter (fun (_,c) -> if c <> [] then display_error ctx "Type parameters constraints are not supported for local functions" p) f.f_params;
+			List.iter (fun tp -> if tp.tp_constraints <> [] then display_error ctx "Type parameters constraints are not supported for local functions" p) f.f_params;
 		let old = ctx.type_params in
 		ctx.type_params <- params @ ctx.type_params;
 		let rt = Typeload.load_type_opt ctx p f.f_type in